Generate slices for each camera frame from AndroidCameraFrameEvents.

Bug: 202848252
Test: Local build of ui.perfetto.dev shows new track and slices correctly
Change-Id: Iffaea718b3e9574b8877b2848f4e1f0d6e6d1abf
diff --git a/Android.bp b/Android.bp
index fbf6d49..2b69788 100644
--- a/Android.bp
+++ b/Android.bp
@@ -8332,6 +8332,7 @@
         "src/trace_processor/importers/ftrace/ftrace_module.cc",
         "src/trace_processor/importers/json/json_utils.cc",
         "src/trace_processor/importers/ninja/ninja_log_parser.cc",
+        "src/trace_processor/importers/proto/android_camera_event_module.cc",
         "src/trace_processor/importers/proto/async_track_set_tracker.cc",
         "src/trace_processor/importers/proto/chrome_string_lookup.cc",
         "src/trace_processor/importers/proto/chrome_system_probes_module.cc",
diff --git a/BUILD b/BUILD
index ab6cc4c..f67bfb3 100644
--- a/BUILD
+++ b/BUILD
@@ -1475,6 +1475,8 @@
         "src/trace_processor/importers/json/json_utils.h",
         "src/trace_processor/importers/ninja/ninja_log_parser.cc",
         "src/trace_processor/importers/ninja/ninja_log_parser.h",
+        "src/trace_processor/importers/proto/android_camera_event_module.cc",
+        "src/trace_processor/importers/proto/android_camera_event_module.h",
         "src/trace_processor/importers/proto/async_track_set_tracker.cc",
         "src/trace_processor/importers/proto/async_track_set_tracker.h",
         "src/trace_processor/importers/proto/chrome_string_lookup.cc",
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 4ce7cec..8d821bf 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -80,6 +80,8 @@
     "importers/json/json_utils.h",
     "importers/ninja/ninja_log_parser.cc",
     "importers/ninja/ninja_log_parser.h",
+    "importers/proto/android_camera_event_module.cc",
+    "importers/proto/android_camera_event_module.h",
     "importers/proto/async_track_set_tracker.cc",
     "importers/proto/async_track_set_tracker.h",
     "importers/proto/chrome_string_lookup.cc",
diff --git a/src/trace_processor/importers/common/track_tracker.h b/src/trace_processor/importers/common/track_tracker.h
index e38cc66..d51d41a 100644
--- a/src/trace_processor/importers/common/track_tracker.h
+++ b/src/trace_processor/importers/common/track_tracker.h
@@ -95,7 +95,7 @@
                                 StringId description = StringId::Null(),
                                 StringId unit = StringId::Null());
 
-  // Creaates a counter track for values within perf samples.
+  // Creates a counter track for values within perf samples.
   // The tracks themselves are managed by PerfSampleTracker.
   TrackId CreatePerfCounterTrack(StringId name,
                                  uint32_t perf_session_id,
diff --git a/src/trace_processor/importers/default_modules.cc b/src/trace_processor/importers/default_modules.cc
index 19345cf..b14f357 100644
--- a/src/trace_processor/importers/default_modules.cc
+++ b/src/trace_processor/importers/default_modules.cc
@@ -16,6 +16,7 @@
 
 #include "src/trace_processor/importers/default_modules.h"
 #include "src/trace_processor/importers/ftrace/ftrace_module.h"
+#include "src/trace_processor/importers/proto/android_camera_event_module.h"
 #include "src/trace_processor/importers/proto/chrome_system_probes_module.h"
 #include "src/trace_processor/importers/proto/memory_tracker_snapshot_module.h"
 #include "src/trace_processor/importers/proto/metadata_module.h"
@@ -38,6 +39,7 @@
   context->modules.emplace_back(new TrackEventModule(context));
   context->modules.emplace_back(new ProfileModule(context));
   context->modules.emplace_back(new MetadataModule(context));
+  context->modules.emplace_back(new AndroidCameraEventModule(context));
 }
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/android_camera_event_module.cc b/src/trace_processor/importers/proto/android_camera_event_module.cc
new file mode 100644
index 0000000..7855ca7
--- /dev/null
+++ b/src/trace_processor/importers/proto/android_camera_event_module.cc
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2022 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_processor/importers/proto/android_camera_event_module.h"
+
+#include <sstream>
+
+#include "include/perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/protozero/field.h"
+#include "protos/perfetto/trace/android/camera_event.pbzero.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "src/trace_processor/importers/common/slice_tracker.h"
+#include "src/trace_processor/importers/common/track_tracker.h"
+#include "src/trace_processor/importers/proto/async_track_set_tracker.h"
+#include "src/trace_processor/storage/trace_storage.h"
+#include "src/trace_processor/tables/slice_tables.h"
+#include "src/trace_processor/tables/track_tables.h"
+#include "src/trace_processor/timestamped_trace_piece.h"
+#include "src/trace_processor/trace_sorter.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+using perfetto::protos::pbzero::TracePacket;
+
+AndroidCameraEventModule::AndroidCameraEventModule(
+    TraceProcessorContext* context)
+    : context_(context) {
+  RegisterForField(TracePacket::kAndroidCameraFrameEventFieldNumber, context);
+}
+
+AndroidCameraEventModule::~AndroidCameraEventModule() = default;
+
+ModuleResult AndroidCameraEventModule::TokenizePacket(
+    const protos::pbzero::TracePacket::Decoder& decoder,
+    TraceBlobView* packet,
+    int64_t /*packet_timestamp*/,
+    PacketSequenceState* state,
+    uint32_t field_id) {
+  if (field_id != TracePacket::kAndroidCameraFrameEventFieldNumber) {
+    return ModuleResult::Ignored();
+  }
+  const auto android_camera_frame_event =
+      protos::pbzero::AndroidCameraFrameEvent::Decoder(
+          decoder.android_camera_frame_event());
+  context_->sorter->PushTracePacket(
+      android_camera_frame_event.request_processing_started_ns(), state,
+      std::move(*packet));
+  return ModuleResult::Handled();
+}
+
+void AndroidCameraEventModule::ParsePacket(const TracePacket::Decoder& decoder,
+                                           const TimestampedTracePiece& /*ttp*/,
+                                           uint32_t field_id) {
+  if (field_id != TracePacket::kAndroidCameraFrameEventFieldNumber) {
+    return;
+  }
+  InsertCameraFrameSlice(decoder.android_camera_frame_event());
+}
+
+void AndroidCameraEventModule::InsertCameraFrameSlice(
+    protozero::ConstBytes bytes) {
+  const auto android_camera_frame_event =
+      protos::pbzero::AndroidCameraFrameEvent::Decoder(bytes);
+  StringId track_name = context_->storage->InternString(
+      base::StackString<32>("Camera %d Frames",
+                            android_camera_frame_event.camera_id())
+          .string_view());
+  StringId slice_name = context_->storage->InternString(
+      base::StackString<32>("Frame %" PRId64,
+                            android_camera_frame_event.frame_number())
+          .string_view());
+  int64_t ts = android_camera_frame_event.request_processing_started_ns();
+  int64_t dur = android_camera_frame_event.responses_all_sent_ns() -
+                android_camera_frame_event.request_processing_started_ns();
+  auto track_set_id =
+      context_->async_track_set_tracker->InternGlobalTrackSet(track_name);
+  auto track_id =
+      context_->async_track_set_tracker->Scoped(track_set_id, ts, dur);
+  context_->slice_tracker->Scoped(ts, track_id, /*category=*/kNullStringId,
+                                  slice_name, dur);
+}
+
+}  // namespace trace_processor
+}  // namespace perfetto
diff --git a/src/trace_processor/importers/proto/android_camera_event_module.h b/src/trace_processor/importers/proto/android_camera_event_module.h
new file mode 100644
index 0000000..fd117c6
--- /dev/null
+++ b/src/trace_processor/importers/proto/android_camera_event_module.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_CAMERA_EVENT_MODULE_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_CAMERA_EVENT_MODULE_H_
+
+#include <cstdint>
+#include <unordered_map>
+
+#include "perfetto/ext/base/optional.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "src/trace_processor/importers/proto/proto_importer_module.h"
+#include "src/trace_processor/tables/slice_tables.h"
+#include "src/trace_processor/tables/track_tables.h"
+#include "src/trace_processor/types/trace_processor_context.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class AndroidCameraEventModule : public ProtoImporterModule {
+ public:
+  explicit AndroidCameraEventModule(TraceProcessorContext* context);
+
+  ~AndroidCameraEventModule() override;
+
+  ModuleResult TokenizePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+                              TraceBlobView* packet,
+                              int64_t packet_timestamp,
+                              PacketSequenceState* state,
+                              uint32_t field_id) override;
+
+  void ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+                   const TimestampedTracePiece& ttp,
+                   uint32_t field_id) override;
+
+ private:
+  void InsertCameraFrameSlice(protozero::ConstBytes bytes);
+
+  TraceProcessorContext* context_;
+};
+
+}  // namespace trace_processor
+}  // namespace perfetto
+
+#endif  // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_CAMERA_EVENT_MODULE_H_
diff --git a/src/trace_processor/importers/proto/async_track_set_tracker.cc b/src/trace_processor/importers/proto/async_track_set_tracker.cc
index c45148c..2593a12 100644
--- a/src/trace_processor/importers/proto/async_track_set_tracker.cc
+++ b/src/trace_processor/importers/proto/async_track_set_tracker.cc
@@ -133,8 +133,10 @@
         return state.slice_type == TrackState::SliceType::kTimestamp &&
                state.ts_end <= ts;
       });
-  if (it != set.tracks.end())
+  if (it != set.tracks.end()) {
+    it->ts_end = ts + dur;
     return it->id;
+  }
 
   TrackState state;
   state.slice_type = TrackState::SliceType::kTimestamp;