Trace Redaction - Convert task rename from primitive to filter

Filter task rename events was one of the first primitives implemented.
Since then, ScrubFtraceEvents has been changed as wrapper for ftrace
event filters.

This changes the scrub task-rename primitive to a filter. This is
important for two reasons:

  1. The iteration logic in the primitive is shared and less likely
     to contain errors.

  2. Re-serialization is minimized.

Bug: 318576499
Change-Id: I3a50c760fd0ffcc97ff3a4a8d17aa79e9a09c397
diff --git a/Android.bp b/Android.bp
index 0c8ab42..dcc140c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12852,6 +12852,7 @@
         "src/trace_redaction/build_timeline.cc",
         "src/trace_redaction/filter_ftrace_using_allowlist.cc",
         "src/trace_redaction/filter_sched_waking_events.cc",
+        "src/trace_redaction/filter_task_rename.cc",
         "src/trace_redaction/find_package_uid.cc",
         "src/trace_redaction/optimize_timeline.cc",
         "src/trace_redaction/populate_allow_lists.cc",
@@ -12861,7 +12862,6 @@
         "src/trace_redaction/redact_sched_switch.cc",
         "src/trace_redaction/scrub_ftrace_events.cc",
         "src/trace_redaction/scrub_process_trees.cc",
-        "src/trace_redaction/scrub_task_rename.cc",
         "src/trace_redaction/scrub_trace_packet.cc",
         "src/trace_redaction/trace_redaction_framework.cc",
         "src/trace_redaction/trace_redactor.cc",
@@ -12875,12 +12875,12 @@
         "src/trace_redaction/build_timeline_unittest.cc",
         "src/trace_redaction/filter_ftrace_using_allowlist_unittest.cc",
         "src/trace_redaction/filter_sched_waking_events_unittest.cc",
+        "src/trace_redaction/filter_task_rename_unittest.cc",
         "src/trace_redaction/find_package_uid_unittest.cc",
         "src/trace_redaction/process_thread_timeline_unittest.cc",
         "src/trace_redaction/proto_util_unittest.cc",
         "src/trace_redaction/prune_package_list_unittest.cc",
         "src/trace_redaction/redact_sched_switch_unittest.cc",
-        "src/trace_redaction/scrub_task_rename_unittest.cc",
         "src/trace_redaction/scrub_trace_packet_unittest.cc",
     ],
 }
diff --git a/src/trace_redaction/BUILD.gn b/src/trace_redaction/BUILD.gn
index f908e96..4e93f6a 100644
--- a/src/trace_redaction/BUILD.gn
+++ b/src/trace_redaction/BUILD.gn
@@ -34,6 +34,8 @@
     "filter_ftrace_using_allowlist.h",
     "filter_sched_waking_events.cc",
     "filter_sched_waking_events.h",
+    "filter_task_rename.cc",
+    "filter_task_rename.h",
     "find_package_uid.cc",
     "find_package_uid.h",
     "optimize_timeline.cc",
@@ -52,8 +54,6 @@
     "scrub_ftrace_events.h",
     "scrub_process_trees.cc",
     "scrub_process_trees.h",
-    "scrub_task_rename.cc",
-    "scrub_task_rename.h",
     "scrub_trace_packet.cc",
     "scrub_trace_packet.h",
     "trace_redaction_framework.cc",
@@ -80,10 +80,10 @@
   sources = [
     "filter_ftrace_using_allowlist_integrationtest.cc",
     "filter_sched_waking_events_integrationtest.cc",
+    "filter_task_rename_integrationtest.cc",
     "redact_sched_switch_integrationtest.cc",
     "scrub_ftrace_events_integrationtest.cc",
     "scrub_process_trees_integrationtest.cc",
-    "scrub_task_rename_integrationtest.cc",
     "trace_redaction_integration_fixture.cc",
     "trace_redaction_integration_fixture.h",
     "trace_redactor_integrationtest.cc",
@@ -107,12 +107,12 @@
     "build_timeline_unittest.cc",
     "filter_ftrace_using_allowlist_unittest.cc",
     "filter_sched_waking_events_unittest.cc",
+    "filter_task_rename_unittest.cc",
     "find_package_uid_unittest.cc",
     "process_thread_timeline_unittest.cc",
     "proto_util_unittest.cc",
     "prune_package_list_unittest.cc",
     "redact_sched_switch_unittest.cc",
-    "scrub_task_rename_unittest.cc",
     "scrub_trace_packet_unittest.cc",
   ]
   deps = [
diff --git a/src/trace_redaction/filter_task_rename.cc b/src/trace_redaction/filter_task_rename.cc
new file mode 100644
index 0000000..65f84fb
--- /dev/null
+++ b/src/trace_redaction/filter_task_rename.cc
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_redaction/filter_task_rename.h"
+
+#include "perfetto/base/status.h"
+#include "src/trace_redaction/trace_redaction_framework.h"
+
+#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
+
+namespace perfetto::trace_redaction {
+
+base::Status FilterTaskRename::VerifyContext(const Context& context) const {
+  if (!context.package_uid.has_value()) {
+    return base::ErrStatus("FilterTaskRename: missing package uid.");
+  }
+
+  if (!context.timeline) {
+    return base::ErrStatus("FilterTaskRename: missing timeline.");
+  }
+
+  return base::OkStatus();
+}
+
+bool FilterTaskRename::KeepEvent(const Context& context,
+                                 protozero::ConstBytes bytes) const {
+  PERFETTO_DCHECK(context.package_uid.has_value());
+  PERFETTO_DCHECK(context.timeline);
+
+  protozero::ProtoDecoder event_decoder(bytes);
+
+  auto rename = event_decoder.FindField(
+      protos::pbzero::FtraceEvent::kTaskRenameFieldNumber);
+
+  // Likely - most events will not have a rename event (that's okay).
+  if (!rename.valid()) {
+    return true;
+  }
+
+  auto pid =
+      event_decoder.FindField(protos::pbzero::FtraceEvent::kPidFieldNumber);
+
+  // Unlikely - all events should have a pid.
+  if (!pid.valid()) {
+    return false;
+  }
+
+  auto timestamp = event_decoder.FindField(
+      protos::pbzero::FtraceEvent::kTimestampFieldNumber);
+
+  // Unlikely - all events should have a timestamp.
+  if (!timestamp.valid()) {
+    return false;
+  }
+
+  auto slice = context.timeline->Search(timestamp.as_uint64(), pid.as_int32());
+  return slice.uid == context.package_uid.value();
+}
+
+}  // namespace perfetto::trace_redaction
diff --git a/src/trace_redaction/scrub_task_rename.h b/src/trace_redaction/filter_task_rename.h
similarity index 62%
rename from src/trace_redaction/scrub_task_rename.h
rename to src/trace_redaction/filter_task_rename.h
index 5b58482..20b119a 100644
--- a/src/trace_redaction/scrub_task_rename.h
+++ b/src/trace_redaction/filter_task_rename.h
@@ -14,24 +14,24 @@
  * limitations under the License.
  */
 
-#ifndef SRC_TRACE_REDACTION_SCRUB_TASK_RENAME_H_
-#define SRC_TRACE_REDACTION_SCRUB_TASK_RENAME_H_
-
-#include <string>
+#ifndef SRC_TRACE_REDACTION_FILTER_TASK_RENAME_H_
+#define SRC_TRACE_REDACTION_FILTER_TASK_RENAME_H_
 
 #include "perfetto/base/status.h"
+#include "src/trace_redaction/scrub_ftrace_events.h"
 #include "src/trace_redaction/trace_redaction_framework.h"
 
 namespace perfetto::trace_redaction {
 
-// Find all task_rename ftrace events and drops the event if the pid does not
-// belong to the target package.
-class ScrubTaskRename final : public TransformPrimitive {
+// Reject rename events that don't belong to the target package.
+class FilterTaskRename final : public FtraceEventFilter {
  public:
-  base::Status Transform(const Context& context,
-                         std::string* packet) const override;
+  base::Status VerifyContext(const Context& context) const override;
+
+  bool KeepEvent(
+      const Context& context, protozero::ConstBytes bytes) const override;
 };
 
 }  // namespace perfetto::trace_redaction
 
-#endif  // SRC_TRACE_REDACTION_SCRUB_TASK_RENAME_H_
+#endif  // SRC_TRACE_REDACTION_FILTER_TASK_RENAME_H_
diff --git a/src/trace_redaction/scrub_task_rename_integrationtest.cc b/src/trace_redaction/filter_task_rename_integrationtest.cc
similarity index 94%
rename from src/trace_redaction/scrub_task_rename_integrationtest.cc
rename to src/trace_redaction/filter_task_rename_integrationtest.cc
index 82903c0..babc2ce 100644
--- a/src/trace_redaction/scrub_task_rename_integrationtest.cc
+++ b/src/trace_redaction/filter_task_rename_integrationtest.cc
@@ -20,14 +20,11 @@
 #include <vector>
 
 #include "perfetto/base/status.h"
-#include "perfetto/ext/base/file_utils.h"
 #include "src/base/test/status_matchers.h"
-#include "src/base/test/tmp_dir_tree.h"
-#include "src/base/test/utils.h"
 #include "src/trace_redaction/build_timeline.h"
 #include "src/trace_redaction/find_package_uid.h"
 #include "src/trace_redaction/optimize_timeline.h"
-#include "src/trace_redaction/scrub_task_rename.h"
+#include "src/trace_redaction/filter_task_rename.h"
 #include "src/trace_redaction/trace_redaction_framework.h"
 #include "src/trace_redaction/trace_redaction_integration_fixture.h"
 #include "src/trace_redaction/trace_redactor.h"
@@ -61,7 +58,10 @@
     trace_redactor()->emplace_collect<FindPackageUid>();
     trace_redactor()->emplace_collect<BuildTimeline>();
     trace_redactor()->emplace_build<OptimizeTimeline>();
-    trace_redactor()->emplace_transform<ScrubTaskRename>();
+
+    auto scrub_ftrace_events =
+        trace_redactor()->emplace_transform<ScrubFtraceEvents>();
+    scrub_ftrace_events->emplace_back<FilterTaskRename>();
 
     context()->package_name = kPackageName;
   }
diff --git a/src/trace_redaction/filter_task_rename_unittest.cc b/src/trace_redaction/filter_task_rename_unittest.cc
new file mode 100644
index 0000000..c11111f
--- /dev/null
+++ b/src/trace_redaction/filter_task_rename_unittest.cc
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+
+#include "src/trace_redaction/filter_task_rename.h"
+#include "src/trace_redaction/process_thread_timeline.h"
+#include "test/gtest_and_gmock.h"
+
+#include "protos/perfetto/trace/ftrace/ftrace_event.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h"
+#include "protos/perfetto/trace/ftrace/sched.gen.h"
+#include "protos/perfetto/trace/ftrace/task.gen.h"
+#include "protos/perfetto/trace/trace_packet.gen.h"
+
+namespace perfetto::trace_redaction {
+
+namespace {
+
+// Used when a single pid is needed.
+constexpr uint32_t kPid = 7971;
+
+constexpr uint64_t kUid = 27;
+
+constexpr uint64_t kJustSomeTime = 6702094131629195;
+
+}  // namespace
+
+class ScrubRenameTaskTest : public testing::Test {
+ protected:
+  //  event {
+  //    timestamp: 6702094131629195
+  //    pid: 7971
+  //    task_rename {
+  //      pid: 7971
+  //      oldcomm: "adbd"
+  //      newcomm: "sh"
+  //      oom_score_adj: -950
+  //    }
+  //  }
+  protos::gen::FtraceEvent CreateRenameEvent(uint64_t ts, uint32_t pid) {
+    protos::gen::FtraceEvent event;
+    event.set_timestamp(ts);
+    event.set_pid(pid);
+
+    auto* rename = event.mutable_task_rename();
+    rename->set_pid(static_cast<int32_t>(pid));
+    rename->set_oldcomm("adbd");
+    rename->set_newcomm("sh");
+    rename->set_oom_score_adj(-950);
+
+    return event;
+  }
+
+  //  event {
+  //    timestamp: 6702094034179654
+  //    pid: 7145
+  //    sched_switch {
+  //      prev_comm: "Job.worker 3"
+  //      prev_pid: 7145
+  //      prev_prio: 120
+  //      prev_state: 1
+  //      next_comm: "swapper/1"
+  //      next_pid: 0
+  //      next_prio: 120
+  //    }
+  //  }
+  protos::gen::FtraceEvent CreateSomeEvent(uint64_t ts, uint32_t pid) {
+    protos::gen::FtraceEvent event;
+    event.set_timestamp(ts);
+    event.set_pid(pid);
+
+    auto* sched = event.mutable_sched_switch();
+    sched->set_prev_comm("Job.worker 3");
+    sched->set_prev_pid(static_cast<int32_t>(pid));
+    sched->set_prev_prio(120);
+    sched->set_prev_state(1);
+    sched->set_next_comm("swapper/1");
+    sched->set_next_pid(0);
+    sched->set_next_prio(120);
+
+    return event;
+  }
+
+  const FilterTaskRename& filter() const { return filter_; }
+
+  Context* context() { return &context_; }
+
+ private:
+  Context context_;
+  FilterTaskRename filter_;
+};
+
+TEST_F(ScrubRenameTaskTest, ReturnErrorForNoPackage) {
+  context()->timeline.reset(new ProcessThreadTimeline());
+
+  ASSERT_FALSE(filter().VerifyContext(*context()).ok());
+}
+
+TEST_F(ScrubRenameTaskTest, ReturnErrorForNoTimeline) {
+  context()->package_name = "package name";
+  context()->package_uid = kUid;
+
+  ASSERT_FALSE(filter().VerifyContext(*context()).ok());
+}
+
+TEST_F(ScrubRenameTaskTest, KeepsNonRenameEvent) {
+  context()->package_name = "package name";
+  context()->package_uid = kUid;
+
+  context()->timeline.reset(new ProcessThreadTimeline());
+
+  auto event = CreateSomeEvent(kJustSomeTime, kPid).SerializeAsArray();
+  ASSERT_TRUE(filter().KeepEvent(*context(), {event.data(), event.size()}));
+}
+
+TEST_F(ScrubRenameTaskTest, RejectsRenameEventOutsidePackage) {
+  context()->package_name = "package name";
+  context()->package_uid = kUid;
+
+  // There's no connection between kPid and kUid. This means the rename packet
+  // should be dropped.
+  context()->timeline.reset(new ProcessThreadTimeline());
+
+  auto event = CreateRenameEvent(kJustSomeTime, kPid).SerializeAsArray();
+  ASSERT_FALSE(filter().KeepEvent(*context(), {event.data(), event.size()}));
+}
+
+TEST_F(ScrubRenameTaskTest, AcceptsRenameEventInPackage) {
+  context()->package_name = "package name";
+  context()->package_uid = kUid;
+
+  context()->timeline.reset(new ProcessThreadTimeline());
+  context()->timeline->Append(
+      ProcessThreadTimeline::Event::Open(0, kPid, 0, kUid));
+  context()->timeline->Sort();
+
+  auto bytes = CreateRenameEvent(kJustSomeTime, kPid).SerializeAsArray();
+  ASSERT_TRUE(filter().KeepEvent(*context(), {bytes.data(), bytes.size()}));
+}
+
+}  // namespace perfetto::trace_redaction
diff --git a/src/trace_redaction/main.cc b/src/trace_redaction/main.cc
index c0061b6..5a55943 100644
--- a/src/trace_redaction/main.cc
+++ b/src/trace_redaction/main.cc
@@ -19,6 +19,7 @@
 #include "src/trace_redaction/build_timeline.h"
 #include "src/trace_redaction/filter_ftrace_using_allowlist.h"
 #include "src/trace_redaction/filter_sched_waking_events.h"
+#include "src/trace_redaction/filter_task_rename.h"
 #include "src/trace_redaction/find_package_uid.h"
 #include "src/trace_redaction/optimize_timeline.h"
 #include "src/trace_redaction/populate_allow_lists.h"
@@ -26,7 +27,6 @@
 #include "src/trace_redaction/redact_sched_switch.h"
 #include "src/trace_redaction/scrub_ftrace_events.h"
 #include "src/trace_redaction/scrub_process_trees.h"
-#include "src/trace_redaction/scrub_task_rename.h"
 #include "src/trace_redaction/scrub_trace_packet.h"
 #include "src/trace_redaction/trace_redaction_framework.h"
 #include "src/trace_redaction/trace_redactor.h"
@@ -56,9 +56,9 @@
   auto scrub_ftrace_events = redactor.emplace_transform<ScrubFtraceEvents>();
   scrub_ftrace_events->emplace_back<FilterFtraceUsingAllowlist>();
   scrub_ftrace_events->emplace_back<FilterSchedWakingEvents>();
+  scrub_ftrace_events->emplace_back<FilterTaskRename>();
 
   redactor.emplace_transform<ScrubProcessTrees>();
-  redactor.emplace_transform<ScrubTaskRename>();
   redactor.emplace_transform<RedactSchedSwitch>();
 
   Context context;
diff --git a/src/trace_redaction/scrub_task_rename.cc b/src/trace_redaction/scrub_task_rename.cc
deleted file mode 100644
index 9593e0c..0000000
--- a/src/trace_redaction/scrub_task_rename.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/trace_redaction/scrub_task_rename.h"
-
-#include <string>
-
-#include "perfetto/base/status.h"
-#include "perfetto/protozero/scattered_heap_buffer.h"
-#include "src/trace_redaction/proto_util.h"
-#include "src/trace_redaction/trace_redaction_framework.h"
-
-#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
-#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
-
-namespace perfetto::trace_redaction {
-
-namespace {
-
-bool ShouldKeepField(const Context& context, protozero::Field event) {
-  PERFETTO_DCHECK(event.id() ==
-                  protos::pbzero::FtraceEventBundle::kEventFieldNumber);
-
-  protozero::ProtoDecoder event_decoder(event.as_bytes());
-
-  protozero::Field pid = {};
-  protozero::Field timestamp = {};
-  protozero::Field rename = {};
-
-  for (auto event_field = event_decoder.ReadField(); event_field.valid();
-       event_field = event_decoder.ReadField()) {
-    switch (event_field.id()) {
-      case protos::pbzero::FtraceEvent::kPidFieldNumber:
-        pid = event_field;
-        break;
-
-      case protos::pbzero::FtraceEvent::kTimestampFieldNumber:
-        timestamp = event_field;
-        break;
-
-      case protos::pbzero::FtraceEvent::kTaskRenameFieldNumber:
-        rename = event_field;
-        break;
-
-      default:
-        break;
-    }
-  }
-
-  if (rename.valid() && timestamp.valid() && pid.valid()) {
-    auto slice =
-        context.timeline->Search(timestamp.as_uint64(), pid.as_int32());
-    return slice.uid == context.package_uid.value();
-  }
-
-  // If there is a rename field, but the time is invalid and/or the pid is
-  // invalid, be defensive and throw the event away.
-  if (rename.valid()) {
-    return false;
-  }
-
-  return true;
-}
-
-}  // namespace
-
-base::Status ScrubTaskRename::Transform(const Context& context,
-                                        std::string* packet) const {
-  if (!context.package_uid.has_value()) {
-    return base::ErrStatus("ScrubTaskRename: missing package uid.");
-  }
-
-  if (!context.timeline) {
-    return base::ErrStatus("ScrubTaskRename: missing timeline.");
-  }
-
-  // Check if there is a ftrace event bundle field.
-  protozero::ProtoDecoder packet_decoder(*packet);
-  auto ftrace_event_bundle = packet_decoder.FindField(
-      protos::pbzero::TracePacket::kFtraceEventsFieldNumber);
-
-  if (!ftrace_event_bundle.valid()) {
-    return base::OkStatus();
-  }
-
-  protozero::HeapBuffered<protos::pbzero::TracePacket> packet_msg;
-
-  // Some decoders will be re-used.
-  packet_decoder.Reset();
-
-  for (auto packet_field = packet_decoder.ReadField(); packet_field.valid();
-       packet_field = packet_decoder.ReadField()) {
-    if (packet_field.id() !=
-        protos::pbzero::TracePacket::kFtraceEventsFieldNumber) {
-      proto_util::AppendField(packet_field, packet_msg.get());
-      continue;
-    }
-
-    auto* bundle_msg = packet_msg->set_ftrace_events();
-
-    protozero::ProtoDecoder bundle_decoder(packet_field.as_bytes());
-
-    for (auto bundle_field = bundle_decoder.ReadField(); bundle_field.valid();
-         bundle_field = bundle_decoder.ReadField()) {
-      bool keep_field = false;
-
-      if (bundle_field.id() ==
-          protos::pbzero::FtraceEventBundle::kEventFieldNumber) {
-        keep_field = ShouldKeepField(context, bundle_field);
-      } else {
-        keep_field = true;
-      }
-
-      if (keep_field) {
-        proto_util::AppendField(bundle_field, bundle_msg);
-      }
-    }
-  }
-
-  packet->assign(packet_msg.SerializeAsString());
-
-  return base::OkStatus();
-}
-
-}  // namespace perfetto::trace_redaction
diff --git a/src/trace_redaction/scrub_task_rename_unittest.cc b/src/trace_redaction/scrub_task_rename_unittest.cc
deleted file mode 100644
index 193c6cc..0000000
--- a/src/trace_redaction/scrub_task_rename_unittest.cc
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string>
-
-#include "src/base/test/status_matchers.h"
-#include "src/trace_redaction/scrub_task_rename.h"
-#include "test/gtest_and_gmock.h"
-
-#include "protos/perfetto/trace/ftrace/ftrace_event.gen.h"
-#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h"
-#include "protos/perfetto/trace/ftrace/sched.gen.h"
-#include "protos/perfetto/trace/ftrace/task.gen.h"
-#include "protos/perfetto/trace/trace_packet.gen.h"
-#include "src/trace_redaction/process_thread_timeline.h"
-
-namespace perfetto::trace_redaction {
-
-namespace {
-
-// Used when a single pid is needed.
-constexpr uint32_t kPid = 7971;
-
-// Used when multiple pids are needed.
-constexpr uint32_t kPidA = 7971;
-constexpr uint32_t kPidB = 7145;
-constexpr uint32_t kPidC = 7945;
-
-constexpr uint64_t kUid = 27;
-
-constexpr uint64_t kJustSomeTime = 6702094131629195;
-
-}  // namespace
-
-class ScrubRenameTaskTest : public testing::Test {
- protected:
-  std::string packet_str_;
-  protos::gen::TracePacket packet_;
-
-  Context context_;
-  ScrubTaskRename transform_;
-
-  //  event {
-  //    timestamp: 6702094131629195
-  //    pid: 7971
-  //    task_rename {
-  //      pid: 7971
-  //      oldcomm: "adbd"
-  //      newcomm: "sh"
-  //      oom_score_adj: -950
-  //    }
-  //  }
-  void AddRenameEvent(uint64_t ts, uint32_t pid) {
-    auto* bundle = packet_.mutable_ftrace_events();
-
-    auto* event = bundle->add_event();
-    event->set_timestamp(ts);
-    event->set_pid(pid);
-
-    auto* rename = event->mutable_task_rename();
-    rename->set_pid(static_cast<int32_t>(pid));
-    rename->set_oldcomm("adbd");
-    rename->set_newcomm("sh");
-    rename->set_oom_score_adj(-950);
-  }
-
-  //  event {
-  //    timestamp: 6702094034179654
-  //    pid: 7145
-  //    sched_switch {
-  //      prev_comm: "Job.worker 3"
-  //      prev_pid: 7145
-  //      prev_prio: 120
-  //      prev_state: 1
-  //      next_comm: "swapper/1"
-  //      next_pid: 0
-  //      next_prio: 120
-  //    }
-  //  }
-  void AddAnEvent(uint64_t ts, uint32_t pid) {
-    auto* bundle = packet_.mutable_ftrace_events();
-
-    auto* event = bundle->add_event();
-    event->set_timestamp(ts);
-    event->set_pid(pid);
-
-    auto* sched = event->mutable_sched_switch();
-    sched->set_prev_comm("Job.worker 3");
-    sched->set_prev_pid(static_cast<int32_t>(pid));
-    sched->set_prev_prio(120);
-    sched->set_prev_state(1);
-    sched->set_next_comm("swapper/1");
-    sched->set_next_pid(0);
-    sched->set_next_prio(120);
-  }
-};
-
-TEST_F(ScrubRenameTaskTest, ReturnErrorForNoPackage) {
-  context_.timeline.reset(new ProcessThreadTimeline());
-  ASSERT_FALSE(transform_.Transform(context_, &packet_str_).ok());
-}
-
-TEST_F(ScrubRenameTaskTest, ReturnErrorForNoTimeline) {
-  context_.package_name = "package name";
-  context_.package_uid = kUid;
-
-  ASSERT_FALSE(transform_.Transform(context_, &packet_str_).ok());
-}
-
-TEST_F(ScrubRenameTaskTest, IgnoresNonRenamePacket) {
-  context_.package_name = "package name";
-  context_.package_uid = kUid;
-
-  context_.timeline.reset(new ProcessThreadTimeline());
-
-  AddAnEvent(kJustSomeTime, kPid);
-  packet_str_ = packet_.SerializeAsString();
-
-  auto copy = packet_str_;
-
-  ASSERT_OK(transform_.Transform(context_, &packet_str_));
-  ASSERT_EQ(copy, packet_str_);
-}
-
-// General description:
-//  - One event in the trace.
-//  - One event is a rename event.
-//  - One event does not connect to the package.
-TEST_F(ScrubRenameTaskTest, RemovesTheOnlyEvent) {
-  context_.package_name = "package name";
-  context_.package_uid = kUid;
-
-  // There's no connection between the later pid (7971) and the above uid (27).
-  // This means the rename packet should be dropped.
-  context_.timeline.reset(new ProcessThreadTimeline());
-
-  AddRenameEvent(kJustSomeTime, kPid);
-  packet_str_ = packet_.SerializeAsString();
-
-  ASSERT_OK(transform_.Transform(context_, &packet_str_));
-
-  protos::gen::TracePacket event_after;
-  event_after.ParseFromString(packet_str_);
-
-  // Be forgiving. If all the events were removed, there won't be a list.
-  if (event_after.has_ftrace_events()) {
-    ASSERT_TRUE(event_after.ftrace_events().event().empty());
-  }
-}
-
-// A very simple case where given a packet with a single rename event (and
-// nothing else) and is connected to the target package, the event is left
-// unredacted.
-TEST_F(ScrubRenameTaskTest, RetainsTheOnlyEvent) {
-  context_.package_name = "package name";
-  context_.package_uid = kUid;
-
-  context_.timeline.reset(new ProcessThreadTimeline());
-  context_.timeline->Append(
-      ProcessThreadTimeline::Event::Open(0, kPid, 0, kUid));
-  context_.timeline->Sort();
-
-  AddRenameEvent(kJustSomeTime, kPid);
-  packet_str_ = packet_.SerializeAsString();
-
-  ASSERT_OK(transform_.Transform(context_, &packet_str_));
-
-  protos::gen::TracePacket event_after;
-  event_after.ParseFromString(packet_str_);
-
-  ASSERT_TRUE(event_after.has_ftrace_events());
-  ASSERT_FALSE(event_after.ftrace_events().event().empty());
-}
-
-// When there are multiple events and multiple rename events, only the one
-// rename that is not connected to package_uid will get removed.
-TEST_F(ScrubRenameTaskTest, PicksOutAndRemovesRenameEvent) {
-  context_.package_name = "package name";
-  context_.package_uid = kUid;
-
-  context_.timeline.reset(new ProcessThreadTimeline());
-  context_.timeline->Append(
-      ProcessThreadTimeline::Event::Open(0, kPidA, 0, kUid));
-  context_.timeline->Sort();
-
-  // pid A and pid B should be safe. Pid C should be removed.
-  AddRenameEvent(kJustSomeTime, kPidA);
-  AddAnEvent(kJustSomeTime, kPidB);
-  AddRenameEvent(kJustSomeTime, kPidC);
-
-  packet_str_ = packet_.SerializeAsString();
-
-  ASSERT_OK(transform_.Transform(context_, &packet_str_));
-
-  protos::gen::TracePacket event_after;
-  event_after.ParseFromString(packet_str_);
-
-  ASSERT_TRUE(event_after.has_ftrace_events());
-  ASSERT_EQ(event_after.ftrace_events().event_size(), 2);
-
-  // Order should not change, so it is safe to assume that at(0) will be rename
-  // and at(1) will be switch.
-  //
-  // For the rename task, verify the pid in addition to the type to make it
-  // clear the right rename event was dropped.
-  ASSERT_TRUE(event_after.ftrace_events().event().at(0).has_task_rename());
-  ASSERT_EQ(event_after.ftrace_events().event().at(0).pid(), kPidA);
-
-  ASSERT_TRUE(event_after.ftrace_events().event().at(1).has_sched_switch());
-}
-
-// Event if the event is dropped, the overall packet structure should be valid.
-TEST_F(ScrubRenameTaskTest, DoesNotInvalidDatePacketStructure) {
-  context_.package_name = "package name";
-  context_.package_uid = kUid;
-
-  context_.timeline.reset(new ProcessThreadTimeline());
-  context_.timeline->Sort();
-
-  // Add one or more values from the rename event all the way up to the packet.
-  packet_.set_trusted_uid(9999);
-  packet_.set_timestamp(kJustSomeTime);
-  packet_.set_trusted_packet_sequence_id(1);
-
-  auto* bundle = packet_.mutable_ftrace_events();
-  bundle->set_cpu(1);
-
-  AddRenameEvent(kJustSomeTime, kPid);
-  packet_str_ = packet_.SerializeAsString();
-
-  ASSERT_OK(transform_.Transform(context_, &packet_str_));
-
-  protos::gen::TracePacket event_after;
-  event_after.ParseFromString(packet_str_);
-
-  ASSERT_TRUE(event_after.has_trusted_uid());
-  ASSERT_EQ(event_after.trusted_uid(), 9999);
-
-  ASSERT_TRUE(event_after.has_timestamp());
-  ASSERT_EQ(event_after.timestamp(), kJustSomeTime);
-
-  ASSERT_TRUE(event_after.has_trusted_packet_sequence_id());
-  ASSERT_EQ(event_after.trusted_packet_sequence_id(), 1u);
-
-  ASSERT_TRUE(event_after.has_ftrace_events());
-
-  ASSERT_TRUE(event_after.ftrace_events().has_cpu());
-  ASSERT_EQ(event_after.ftrace_events().cpu(), 1u);
-
-  // Event through everything else was found, the event was actually dropped.
-  ASSERT_TRUE(event_after.ftrace_events().event().empty());
-}
-
-}  // namespace perfetto::trace_redaction