Shared library track event: API/ABI to emit data

This commit implements:
* New ABIs to emit events to the data source:
  * A low level ABI that allows users to do their own message
    serialization.
  * A high level ABI that accepts a representation of the data to be
    traced and performs serialization in the library.
* The PERFETTO_TE macro (similar to the TRACE_EVENT macro) that can be
  used to emit trace events using the high level ABI.

Bug: 237053982
Change-Id: I0ca1a9b03dfa67f7618e27e176f3113eddca871a
diff --git a/src/shared_lib/BUILD.gn b/src/shared_lib/BUILD.gn
index 20adc15..0e3115b 100644
--- a/src/shared_lib/BUILD.gn
+++ b/src/shared_lib/BUILD.gn
@@ -12,8 +12,23 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("../../gn/test.gni")
+
+source_set("intern_map") {
+  deps = [
+    "../../gn:default_deps",
+    "../../include/perfetto/public",
+    "../base",
+  ]
+  sources = [
+    "intern_map.cc",
+    "intern_map.h",
+  ]
+}
+
 source_set("shared_lib") {
   deps = [
+    ":intern_map",
     "../../gn:default_deps",
     "../../include/perfetto/protozero",
     "../../include/perfetto/public",
@@ -29,6 +44,7 @@
     "reset_for_testing.h",
     "stream_writer.cc",
     "stream_writer.h",
+    "thread_utils.cc",
     "tracing_session.cc",
     "track_event.cc",
   ]
@@ -42,3 +58,15 @@
   ]
   public_deps = [ "../../include/perfetto/public" ]
 }
+
+perfetto_unittest_source_set("unittests") {
+  testonly = true
+  deps = [
+    ":intern_map",
+    "../../gn:default_deps",
+    "../../gn:gtest_and_gmock",
+    "../base",
+    "../base:test_support",
+  ]
+  sources = [ "intern_map_unittest.cc" ]
+}
diff --git a/src/shared_lib/intern_map.cc b/src/shared_lib/intern_map.cc
new file mode 100644
index 0000000..a770287
--- /dev/null
+++ b/src/shared_lib/intern_map.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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/shared_lib/intern_map.h"
+
+namespace perfetto {
+InternMap::InternMap() = default;
+
+InternMap::~InternMap() = default;
+
+InternMap::FindOrAssignRes InternMap::FindOrAssign(int32_t type,
+                                                   const void* value,
+                                                   size_t value_size) {
+  // This would be more efficient with heterogeneous lookups, but C++17 doesn't
+  // support that.
+  auto* it = map_.Find(Key::NonOwning(type, value, value_size));
+  if (it != nullptr) {
+    return {*it, false};
+  }
+  uint64_t iid = ++last_iid_by_type_[type];
+  it = map_.Insert(Key::Owning(type, value, value_size), iid).first;
+  return {iid, true};
+}
+
+}  // namespace perfetto
diff --git a/src/shared_lib/intern_map.h b/src/shared_lib/intern_map.h
new file mode 100644
index 0000000..f5ac5b2
--- /dev/null
+++ b/src/shared_lib/intern_map.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2023 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_SHARED_LIB_INTERN_MAP_H_
+#define SRC_SHARED_LIB_INTERN_MAP_H_
+
+#include "perfetto/ext/base/flat_hash_map.h"
+#include "perfetto/public/fnv1a.h"
+
+namespace perfetto {
+
+// Assigns and maintains the mapping between "interned" data and iids (small
+// integers that can be used to refer to the same data without repeating it)
+// for different types.
+class InternMap {
+ public:
+  // Zero will never be assigned as a valid iid: it is used as the return value
+  // of Find() to signal failure.
+  using Iid = uint64_t;
+
+  InternMap();
+  ~InternMap();
+
+  // Given a value (identified by the memory buffer starting at `value`,
+  // `value_size` bytes long) of a specific `type`, finds if there was an
+  // existing iid associated with it, or assigns a new iid to it. Assigned iids
+  // are unique for a specific type, but are reused across different types.
+  struct FindOrAssignRes {
+    // Iid associated with the passed value.
+    Iid iid;
+    // Whether the iid was newly assigned in this call (i.e. true if the value
+    // was not seen before).
+    bool newly_assigned;
+  };
+  FindOrAssignRes FindOrAssign(int32_t type,
+                               const void* value,
+                               size_t value_size);
+
+ private:
+  // Stores a value of a specific type. If the value is small, it is stored
+  // inline, otherwise it is stored in an external buffer. The Key can own the
+  // external buffer (when the key is stored in the map) or not (when the key is
+  // just used for lookup).
+  class Key {
+   public:
+    static Key NonOwning(int32_t type, const void* value, size_t value_size) {
+      Key key;
+      key.type_ = type;
+      key.val_type_ = ValueStorage::kNonOwnedPtr;
+      key.ptr_ = value;
+      key.value_size_ = value_size;
+      return key;
+    }
+    static Key Owning(int32_t type, const void* value, size_t value_size) {
+      Key key;
+      key.type_ = type;
+      key.value_size_ = value_size;
+      if (value_size < sizeof(value_buf_)) {
+        key.val_type_ = ValueStorage::kInline;
+        memcpy(key.value_buf_, value, value_size);
+      } else {
+        key.val_type_ = ValueStorage::kOwnedPtr;
+        char* newvalue = new char[value_size];
+        memcpy(newvalue, value, value_size);
+        key.owned_ptr_ = newvalue;
+      }
+      return key;
+    }
+    ~Key() {
+      if (val_type_ == ValueStorage::kOwnedPtr) {
+        delete[] owned_ptr_;
+      }
+    }
+    Key(const Key&) = delete;
+    Key(Key&& other) noexcept {
+      type_ = other.type_;
+      value_size_ = other.value_size_;
+      switch (other.val_type_) {
+        case ValueStorage::kNonOwnedPtr:
+          val_type_ = ValueStorage::kNonOwnedPtr;
+          ptr_ = other.ptr_;
+          return;
+        case ValueStorage::kOwnedPtr:
+          val_type_ = ValueStorage::kOwnedPtr;
+          owned_ptr_ = other.owned_ptr_;
+          other.val_type_ = ValueStorage::kInline;
+          other.value_size_ = 0;
+          return;
+        case ValueStorage::kInline:
+          val_type_ = ValueStorage::kInline;
+          memcpy(value_buf_, other.value_buf_, value_size_);
+          return;
+      }
+    }
+    bool operator==(const Key& other) const {
+      if (type_ != other.type_) {
+        return false;
+      }
+      if (value_size_ != other.value_size_) {
+        return false;
+      }
+      return memcmp(value(), other.value(), value_size_) == 0;
+    }
+    const void* value() const {
+      switch (val_type_) {
+        case ValueStorage::kNonOwnedPtr:
+          return ptr_;
+        case ValueStorage::kOwnedPtr:
+          return owned_ptr_;
+        case ValueStorage::kInline:
+          break;
+      }
+      return &value_buf_;
+    }
+    struct Hash {
+      size_t operator()(const Key& obj) const {
+        return std::hash<int32_t>()(obj.type_) ^
+               static_cast<size_t>(PerfettoFnv1a(obj.value(), obj.value_size_));
+      }
+    };
+
+   private:
+    enum class ValueStorage {
+      kInline,       // `value_buf_` is used directly to store the value.
+      kNonOwnedPtr,  // `ptr_` points to an external buffer that stores the
+                     // value. Not owned by this Key.
+      kOwnedPtr,     // `owned_ptr_` points to an external buffer that stores
+                     // the value. Owned by this Key.
+    };
+    Key() = default;
+    int32_t type_;
+    ValueStorage val_type_;
+    size_t value_size_;
+    union {
+      char value_buf_[sizeof(uint64_t)];
+      const void* ptr_;
+      char* owned_ptr_;
+    };
+  };
+
+  base::FlatHashMap<Key, uint64_t, Key::Hash> map_;
+  base::FlatHashMap<int32_t, uint64_t> last_iid_by_type_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_SHARED_LIB_INTERN_MAP_H_
diff --git a/src/shared_lib/intern_map_unittest.cc b/src/shared_lib/intern_map_unittest.cc
new file mode 100644
index 0000000..837c960
--- /dev/null
+++ b/src/shared_lib/intern_map_unittest.cc
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2023 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/shared_lib/intern_map.h"
+
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace {
+
+TEST(InternMapTest, SmallValue) {
+  const char kSmallValue[] = "A";
+  InternMap iids;
+
+  auto res1 = iids.FindOrAssign(/*type=*/0, kSmallValue, sizeof(kSmallValue));
+
+  EXPECT_TRUE(res1.newly_assigned);
+  EXPECT_NE(res1.iid, 0u);
+
+  auto res2 = iids.FindOrAssign(/*type=*/0, kSmallValue, sizeof(kSmallValue));
+
+  EXPECT_FALSE(res2.newly_assigned);
+  EXPECT_EQ(res1.iid, res1.iid);
+}
+
+TEST(InternMapTest, BigValue) {
+  const char kBigValue[] = "ABCDEFGHIJKLMNOP";
+  InternMap iids;
+
+  auto res1 = iids.FindOrAssign(/*type=*/0, kBigValue, sizeof(kBigValue));
+
+  EXPECT_TRUE(res1.newly_assigned);
+  EXPECT_NE(res1.iid, 0u);
+
+  auto res2 = iids.FindOrAssign(/*type=*/0, kBigValue, sizeof(kBigValue));
+
+  EXPECT_FALSE(res2.newly_assigned);
+  EXPECT_EQ(res1.iid, res1.iid);
+}
+
+TEST(InternMapTest, TwoValuesSameType) {
+  const char kValue1[] = "A";
+  const char kValue2[] = "ABCDEFGHIJKLMNOP";
+  InternMap iids;
+
+  auto res1 = iids.FindOrAssign(/*type=*/0, kValue1, sizeof(kValue1));
+
+  EXPECT_TRUE(res1.newly_assigned);
+  EXPECT_NE(res1.iid, 0u);
+
+  auto res2 = iids.FindOrAssign(/*type=*/0, kValue2, sizeof(kValue2));
+
+  EXPECT_TRUE(res1.newly_assigned);
+  EXPECT_NE(res1.iid, res2.iid);
+}
+
+TEST(InternMapTest, SameValueDifferentTypes) {
+  const char kValue[] = "A";
+  InternMap iids;
+
+  auto res1 = iids.FindOrAssign(/*type=*/0, kValue, sizeof(kValue));
+
+  EXPECT_TRUE(res1.newly_assigned);
+  EXPECT_NE(res1.iid, 0u);
+
+  auto res2 = iids.FindOrAssign(/*type=*/1, kValue, sizeof(kValue));
+
+  EXPECT_TRUE(res1.newly_assigned);
+  EXPECT_NE(res2.iid, 0u);
+}
+
+}  // namespace
+}  // namespace perfetto
diff --git a/src/shared_lib/thread_utils.cc b/src/shared_lib/thread_utils.cc
new file mode 100644
index 0000000..372b832
--- /dev/null
+++ b/src/shared_lib/thread_utils.cc
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 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 "perfetto/public/abi/thread_utils_abi.h"
+
+#include "perfetto/base/thread_utils.h"
+
+PerfettoThreadId PerfettoGetThreadIdImpl(void) {
+  return perfetto::base::GetThreadId();
+}
diff --git a/src/shared_lib/track_event.cc b/src/shared_lib/track_event.cc
index 42511cf..01be391 100644
--- a/src/shared_lib/track_event.cc
+++ b/src/shared_lib/track_event.cc
@@ -15,6 +15,8 @@
  */
 
 #include "perfetto/public/abi/track_event_abi.h"
+#include "perfetto/public/abi/track_event_hl_abi.h"
+#include "perfetto/public/abi/track_event_ll_abi.h"
 
 #include <algorithm>
 #include <atomic>
@@ -25,6 +27,7 @@
 #include "perfetto/base/compiler.h"
 #include "perfetto/base/flat_set.h"
 #include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/no_destructor.h"
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/ext/base/thread_utils.h"
@@ -47,12 +50,15 @@
 #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
 #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
 #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+#include "src/shared_lib/intern_map.h"
 #include "src/shared_lib/reset_for_testing.h"
 
 struct PerfettoTeCategoryImpl* perfetto_te_any_categories;
 
 PERFETTO_ATOMIC(bool) * perfetto_te_any_categories_enabled;
 
+uint64_t perfetto_te_process_track_uuid;
+
 struct PerfettoTeCategoryImpl {
   std::atomic<bool> flag{false};
   std::atomic<uint8_t> instances{0};
@@ -192,8 +198,60 @@
 namespace perfetto {
 namespace shlib {
 
+struct TrackEventIncrementalState {
+  // A heap-allocated message for storing newly seen interned data while we are
+  // in the middle of writing a track event. When a track event wants to write
+  // new interned data into the trace, it is first serialized into this message
+  // and then flushed to the real trace in EventContext when the packet ends.
+  // The message is cached here as a part of incremental state so that we can
+  // reuse the underlying buffer allocation for subsequently written interned
+  // data.
+  uint64_t last_timestamp_ns = 0;
+  protozero::HeapBuffered<protos::pbzero::InternedData>
+      serialized_interned_data;
+  bool was_cleared = true;
+  base::FlatSet<uint64_t> seen_track_uuids;
+  // Map from serialized representation of a dynamic category to its enabled
+  // state.
+  base::FlatHashMap<std::string, bool> dynamic_categories;
+  InternMap iids;
+};
+
+struct TrackEventTlsState {
+  template <typename TraceContext>
+  explicit TrackEventTlsState(const TraceContext& trace_context) {
+    auto locked_ds = trace_context.GetDataSourceLocked();
+    bool disable_incremental_timestamps = false;
+    timestamp_unit_multiplier = 1;
+    if (locked_ds.valid()) {
+      const auto& config = locked_ds->GetConfig();
+      disable_incremental_timestamps = config.disable_incremental_timestamps();
+      if (config.has_timestamp_unit_multiplier() &&
+          config.timestamp_unit_multiplier() != 0) {
+        timestamp_unit_multiplier = config.timestamp_unit_multiplier();
+      }
+    }
+    if (disable_incremental_timestamps) {
+      if (timestamp_unit_multiplier == 1) {
+        default_clock_id = PERFETTO_I_CLOCK_INCREMENTAL_UNDERNEATH;
+      } else {
+        default_clock_id = PERFETTO_TE_TIMESTAMP_TYPE_ABSOLUTE;
+      }
+    } else {
+      default_clock_id = PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL;
+    }
+  }
+  uint32_t default_clock_id;
+  uint64_t timestamp_unit_multiplier;
+};
+
+struct TrackEventDataSourceTraits : public perfetto::DefaultDataSourceTraits {
+  using IncrementalStateType = TrackEventIncrementalState;
+  using TlsStateType = TrackEventTlsState;
+};
+
 class TrackEvent
-    : public perfetto::DataSource<TrackEvent, DefaultDataSourceTraits> {
+    : public perfetto::DataSource<TrackEvent, TrackEventDataSourceTraits> {
  public:
   ~TrackEvent() override;
   void OnSetup(const DataSourceBase::SetupArgs& args) override {
@@ -365,9 +423,13 @@
 }  // namespace shlib
 }  // namespace perfetto
 
-PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(perfetto::shlib::TrackEvent);
+PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(
+    perfetto::shlib::TrackEvent,
+    perfetto::shlib::TrackEventDataSourceTraits);
 
-PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(perfetto::shlib::TrackEvent);
+PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(
+    perfetto::shlib::TrackEvent,
+    perfetto::shlib::TrackEventDataSourceTraits);
 
 perfetto::internal::DataSourceType* perfetto::shlib::TrackEvent::GetType() {
   return &perfetto::shlib::TrackEvent::Helper::type();
@@ -378,6 +440,332 @@
   return &tls_state_;
 }
 
+namespace {
+
+using perfetto::internal::TrackEventInternal;
+
+perfetto::protos::pbzero::TrackEvent::Type EventType(int32_t type) {
+  using Type = perfetto::protos::pbzero::TrackEvent::Type;
+  auto enum_type = static_cast<PerfettoTeType>(type);
+  switch (enum_type) {
+    case PERFETTO_TE_TYPE_SLICE_BEGIN:
+      return Type::TYPE_SLICE_BEGIN;
+    case PERFETTO_TE_TYPE_SLICE_END:
+      return Type::TYPE_SLICE_END;
+    case PERFETTO_TE_TYPE_INSTANT:
+      return Type::TYPE_INSTANT;
+    case PERFETTO_TE_TYPE_COUNTER:
+      return Type::TYPE_COUNTER;
+  }
+  return Type::TYPE_UNSPECIFIED;
+}
+
+protozero::MessageHandle<perfetto::protos::pbzero::TracePacket>
+NewTracePacketInternal(perfetto::TraceWriterBase* trace_writer,
+                       perfetto::shlib::TrackEventIncrementalState* incr_state,
+                       const perfetto::shlib::TrackEventTlsState& tls_state,
+                       perfetto::TraceTimestamp timestamp,
+                       uint32_t seq_flags) {
+  // PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL is the default timestamp returned
+  // by TrackEventInternal::GetTraceTime(). If the configuration in `tls_state`
+  // uses a different clock, we have to use that instead.
+  if (PERFETTO_UNLIKELY(tls_state.default_clock_id !=
+                            PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL &&
+                        timestamp.clock_id ==
+                            PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL)) {
+    timestamp.clock_id = tls_state.default_clock_id;
+  }
+  auto packet = trace_writer->NewTracePacket();
+  auto ts_unit_multiplier = tls_state.timestamp_unit_multiplier;
+  if (PERFETTO_LIKELY(timestamp.clock_id ==
+                      PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL)) {
+    if (PERFETTO_LIKELY(incr_state->last_timestamp_ns <= timestamp.value)) {
+      // No need to set the clock id here, since
+      // PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL is the clock id assumed by
+      // default.
+      auto time_diff_ns = timestamp.value - incr_state->last_timestamp_ns;
+      auto time_diff_units = time_diff_ns / ts_unit_multiplier;
+      packet->set_timestamp(time_diff_units);
+      incr_state->last_timestamp_ns += time_diff_units * ts_unit_multiplier;
+    } else {
+      packet->set_timestamp(timestamp.value / ts_unit_multiplier);
+      packet->set_timestamp_clock_id(
+          ts_unit_multiplier == 1
+              ? static_cast<uint32_t>(PERFETTO_I_CLOCK_INCREMENTAL_UNDERNEATH)
+              : static_cast<uint32_t>(PERFETTO_TE_TIMESTAMP_TYPE_ABSOLUTE));
+    }
+  } else if (PERFETTO_LIKELY(timestamp.clock_id ==
+                             tls_state.default_clock_id)) {
+    packet->set_timestamp(timestamp.value / ts_unit_multiplier);
+  } else {
+    packet->set_timestamp(timestamp.value);
+    packet->set_timestamp_clock_id(timestamp.clock_id);
+  }
+  packet->set_sequence_flags(seq_flags);
+  return packet;
+}
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+std::vector<std::string> GetCmdLine() {
+  std::vector<std::string> cmdline_str;
+  std::string cmdline;
+  if (perfetto::base::ReadFile("/proc/self/cmdline", &cmdline)) {
+    perfetto::base::StringSplitter splitter(std::move(cmdline), '\0');
+    while (splitter.Next()) {
+      cmdline_str.emplace_back(splitter.cur_token(), splitter.cur_token_size());
+    }
+  }
+  return cmdline_str;
+}
+#endif
+
+void ResetIncrementalStateIfRequired(
+    perfetto::TraceWriterBase* trace_writer,
+    perfetto::shlib::TrackEventIncrementalState* incr_state,
+    const perfetto::shlib::TrackEventTlsState& tls_state,
+    const perfetto::TraceTimestamp& timestamp) {
+  if (!incr_state->was_cleared) {
+    return;
+  }
+  incr_state->was_cleared = false;
+
+  auto sequence_timestamp = timestamp;
+  if (timestamp.clock_id != PERFETTO_I_CLOCK_INCREMENTAL_UNDERNEATH &&
+      timestamp.clock_id != PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL) {
+    sequence_timestamp = TrackEventInternal::GetTraceTime();
+  }
+
+  incr_state->last_timestamp_ns = sequence_timestamp.value;
+  auto tid = perfetto::base::GetThreadId();
+  auto pid = perfetto::Platform::GetCurrentProcessId();
+  uint64_t thread_track_uuid =
+      perfetto_te_process_track_uuid ^ static_cast<uint64_t>(tid);
+  auto ts_unit_multiplier = tls_state.timestamp_unit_multiplier;
+  {
+    // Mark any incremental state before this point invalid. Also set up
+    // defaults so that we don't need to repeat constant data for each packet.
+    auto packet = NewTracePacketInternal(
+        trace_writer, incr_state, tls_state, timestamp,
+        perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
+    auto defaults = packet->set_trace_packet_defaults();
+    defaults->set_timestamp_clock_id(tls_state.default_clock_id);
+    // Establish the default track for this event sequence.
+    auto track_defaults = defaults->set_track_event_defaults();
+    track_defaults->set_track_uuid(thread_track_uuid);
+
+    if (tls_state.default_clock_id != PERFETTO_I_CLOCK_INCREMENTAL_UNDERNEATH) {
+      perfetto::protos::pbzero::ClockSnapshot* clocks =
+          packet->set_clock_snapshot();
+      // Trace clock.
+      perfetto::protos::pbzero::ClockSnapshot::Clock* trace_clock =
+          clocks->add_clocks();
+      trace_clock->set_clock_id(PERFETTO_I_CLOCK_INCREMENTAL_UNDERNEATH);
+      trace_clock->set_timestamp(sequence_timestamp.value);
+
+      if (PERFETTO_LIKELY(tls_state.default_clock_id ==
+                          PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL)) {
+        // Delta-encoded incremental clock in nanoseconds by default but
+        // configurable by |tls_state.timestamp_unit_multiplier|.
+        perfetto::protos::pbzero::ClockSnapshot::Clock* clock_incremental =
+            clocks->add_clocks();
+        clock_incremental->set_clock_id(PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL);
+        clock_incremental->set_timestamp(sequence_timestamp.value /
+                                         ts_unit_multiplier);
+        clock_incremental->set_is_incremental(true);
+        clock_incremental->set_unit_multiplier_ns(ts_unit_multiplier);
+      }
+      if (ts_unit_multiplier > 1) {
+        // absolute clock with custom timestamp_unit_multiplier.
+        perfetto::protos::pbzero::ClockSnapshot::Clock* absolute_clock =
+            clocks->add_clocks();
+        absolute_clock->set_clock_id(PERFETTO_TE_TIMESTAMP_TYPE_ABSOLUTE);
+        absolute_clock->set_timestamp(sequence_timestamp.value /
+                                      ts_unit_multiplier);
+        absolute_clock->set_is_incremental(false);
+        absolute_clock->set_unit_multiplier_ns(ts_unit_multiplier);
+      }
+    }
+  }
+
+  // Every thread should write a descriptor for its default track, because most
+  // trace points won't explicitly reference it. We also write the process
+  // descriptor from every thread that writes trace events to ensure it gets
+  // emitted at least once.
+  {
+    auto packet = NewTracePacketInternal(
+        trace_writer, incr_state, tls_state, timestamp,
+        perfetto::protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE);
+    auto* track = packet->set_track_descriptor();
+    track->set_uuid(thread_track_uuid);
+    track->set_parent_uuid(perfetto_te_process_track_uuid);
+    auto* td = track->set_thread();
+
+    td->set_pid(static_cast<int32_t>(pid));
+    td->set_tid(static_cast<int32_t>(tid));
+    std::string thread_name;
+    if (perfetto::base::GetThreadName(thread_name))
+      td->set_thread_name(thread_name);
+  }
+  {
+    auto packet = NewTracePacketInternal(
+        trace_writer, incr_state, tls_state, timestamp,
+        perfetto::protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE);
+    auto* track = packet->set_track_descriptor();
+    track->set_uuid(perfetto_te_process_track_uuid);
+    auto* pd = track->set_process();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+    static perfetto::base::NoDestructor<std::vector<std::string>> cmdline(
+        GetCmdLine());
+    if (!cmdline.ref().empty()) {
+      // Since cmdline is a zero-terminated list of arguments, this ends up
+      // writing just the first element, i.e., the process name, into the
+      // process name field.
+      pd->set_process_name(cmdline.ref()[0]);
+      for (const std::string& arg : cmdline.ref()) {
+        pd->add_cmdline(arg);
+      }
+    }
+#endif
+    pd->set_pid(static_cast<int32_t>(pid));
+  }
+}
+
+void WriteTrackEvent(perfetto::shlib::TrackEventIncrementalState* incr,
+                     perfetto::protos::pbzero::TrackEvent* event,
+                     PerfettoTeCategoryImpl* cat,
+                     perfetto::protos::pbzero::TrackEvent::Type type,
+                     const char* name,
+                     const PerfettoTeHlExtra* extra_data,
+                     std::optional<uint64_t> track_uuid,
+                     const PerfettoTeCategoryDescriptor* dynamic_cat) {
+  if (type != perfetto::protos::pbzero::TrackEvent::TYPE_UNSPECIFIED) {
+    event->set_type(type);
+  }
+
+  if (!dynamic_cat &&
+      type != perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END &&
+      type != perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER) {
+    uint64_t iid = cat->cat_iid;
+    auto res = incr->iids.FindOrAssign(
+        perfetto::protos::pbzero::InternedData::kEventCategoriesFieldNumber,
+        &iid, sizeof(iid));
+    if (res.newly_assigned) {
+      auto* ser = incr->serialized_interned_data->add_event_categories();
+      ser->set_iid(iid);
+      ser->set_name(cat->desc->name);
+    }
+    event->add_category_iids(iid);
+  }
+
+  if (type != perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END) {
+    if (name) {
+      event->set_name(name);
+    }
+  }
+
+  if (dynamic_cat &&
+      type != perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END &&
+      type != perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER) {
+    event->add_categories(dynamic_cat->name);
+  }
+
+  if (track_uuid) {
+    event->set_track_uuid(*track_uuid);
+  }
+
+  for (const auto* it = extra_data; it; it = it->next) {
+    if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_COUNTER_INT64 &&
+        type == perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER) {
+      event->set_counter_value(
+          reinterpret_cast<const struct PerfettoTeHlExtraCounterInt64*>(it)
+              ->value);
+    } else if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_COUNTER_DOUBLE) {
+      event->set_double_counter_value(
+          reinterpret_cast<const struct PerfettoTeHlExtraCounterDouble*>(it)
+              ->value);
+    }
+  }
+
+  for (const auto* it = extra_data; it; it = it->next) {
+    if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_BOOL ||
+        it->type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_UINT64 ||
+        it->type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_INT64 ||
+        it->type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_DOUBLE ||
+        it->type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_STRING ||
+        it->type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_POINTER) {
+      auto* dbg = event->add_debug_annotations();
+      const char* arg_name = nullptr;
+      if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_BOOL) {
+        auto* arg =
+            reinterpret_cast<const struct PerfettoTeHlExtraDebugArgBool*>(it);
+        dbg->set_bool_value(arg->value);
+        arg_name = arg->name;
+      } else if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_UINT64) {
+        auto* arg =
+            reinterpret_cast<const struct PerfettoTeHlExtraDebugArgUint64*>(it);
+        dbg->set_uint_value(arg->value);
+        arg_name = arg->name;
+      } else if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_INT64) {
+        auto* arg =
+            reinterpret_cast<const struct PerfettoTeHlExtraDebugArgInt64*>(it);
+        dbg->set_int_value(arg->value);
+        arg_name = arg->name;
+      } else if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_DOUBLE) {
+        auto* arg =
+            reinterpret_cast<const struct PerfettoTeHlExtraDebugArgDouble*>(it);
+        dbg->set_double_value(arg->value);
+        arg_name = arg->name;
+      } else if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_STRING) {
+        auto* arg =
+            reinterpret_cast<const struct PerfettoTeHlExtraDebugArgString*>(it);
+        dbg->set_string_value(arg->value);
+        arg_name = arg->name;
+      } else if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_POINTER) {
+        auto* arg =
+            reinterpret_cast<const struct PerfettoTeHlExtraDebugArgPointer*>(
+                it);
+        dbg->set_pointer_value(arg->value);
+        arg_name = arg->name;
+      }
+
+      if (arg_name != nullptr) {
+        const void* str = arg_name;
+        size_t len = strlen(arg_name);
+        auto res =
+            incr->iids.FindOrAssign(perfetto::protos::pbzero::InternedData::
+                                        kDebugAnnotationNamesFieldNumber,
+                                    str, len);
+        if (res.newly_assigned) {
+          auto* ser =
+              incr->serialized_interned_data->add_debug_annotation_names();
+          ser->set_iid(res.iid);
+          ser->set_name(arg_name);
+        }
+        dbg->set_name_iid(res.iid);
+      }
+    }
+  }
+
+  for (const auto* it = extra_data; it; it = it->next) {
+    if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_FLOW) {
+      event->add_flow_ids(
+          reinterpret_cast<const struct PerfettoTeHlExtraFlow*>(it)->id);
+    }
+  }
+
+  for (const auto* it = extra_data; it; it = it->next) {
+    if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_TERMINATING_FLOW) {
+      event->add_terminating_flow_ids(
+          reinterpret_cast<const struct PerfettoTeHlExtraFlow*>(it)->id);
+    }
+  }
+}
+
+}  // namespace
+
 struct PerfettoTeCategoryImpl* PerfettoTeCategoryImplCreate(
     struct PerfettoTeCategoryDescriptor* desc) {
   auto* cat = new PerfettoTeCategoryImpl;
@@ -412,4 +800,366 @@
 
 void PerfettoTeInit(void) {
   perfetto::shlib::TrackEvent::Init();
+  perfetto_te_process_track_uuid =
+      perfetto::internal::TrackRegistry::ComputeProcessUuid();
+}
+
+struct PerfettoTeTimestamp PerfettoTeGetTimestamp(void) {
+  struct PerfettoTeTimestamp ret;
+  ret.clock_id = PERFETTO_TE_TIMESTAMP_TYPE_BOOT;
+  ret.value = TrackEventInternal::GetTimeNs();
+  return ret;
+}
+
+static bool IsDynamicCategoryEnabled(
+    uint32_t inst_idx,
+    perfetto::shlib::TrackEventIncrementalState* incr_state,
+    const struct PerfettoTeCategoryDescriptor& desc) {
+  constexpr size_t kMaxCacheSize = 20;
+  perfetto::internal::DataSourceType* ds =
+      perfetto::shlib::TrackEvent::GetType();
+  auto& cache = incr_state->dynamic_categories;
+  protozero::HeapBuffered<perfetto::protos::pbzero::TrackEventDescriptor> ted;
+  SerializeCategory(desc, ted.get());
+  std::string serialized = ted.SerializeAsString();
+  auto* cached = cache.Find(serialized);
+  if (cached) {
+    return *cached;
+  }
+
+  auto* internal_state = ds->static_state()->TryGet(inst_idx);
+  if (!internal_state)
+    return false;
+  std::unique_lock<std::recursive_mutex> lock(internal_state->lock);
+  auto* sds = static_cast<perfetto::shlib::TrackEvent*>(
+      internal_state->data_source.get());
+
+  bool res = IsSingleCategoryEnabled(desc, sds->GetConfig());
+  if (cache.size() < kMaxCacheSize) {
+    cache[serialized] = res;
+  }
+  return res;
+}
+
+static void AdvanceToFirstEnabledDynamicCategory(
+    perfetto::internal::DataSourceType::InstancesIterator* ii,
+    perfetto::internal::DataSourceThreadLocalState* tls_state,
+    perfetto::shlib::TrackEventIncrementalState* incr_state,
+    struct PerfettoTeCategoryImpl* cat,
+    const PerfettoTeCategoryDescriptor& dyn_cat) {
+  perfetto::internal::DataSourceType* ds =
+      perfetto::shlib::TrackEvent::GetType();
+  for (; ii->instance;
+       ds->NextIteration</*Traits=*/perfetto::shlib::TracePointTraits>(
+           ii, tls_state, {cat})) {
+    if (IsDynamicCategoryEnabled(ii->i, incr_state, dyn_cat)) {
+      break;
+    }
+  }
+}
+
+static void InstanceOp(
+    perfetto::internal::DataSourceType* ds,
+    perfetto::internal::DataSourceType::InstancesIterator* ii,
+    perfetto::internal::DataSourceThreadLocalState* tls_state,
+    struct PerfettoTeCategoryImpl* cat,
+    perfetto::protos::pbzero::TrackEvent::Type type,
+    const char* name,
+    const struct PerfettoTeHlExtra* extra_data) {
+  if (!ii->instance) {
+    return;
+  }
+
+  const PerfettoTeRegisteredTrackImpl* registered_track = nullptr;
+  const PerfettoTeHlExtraNamedTrack* named_track = nullptr;
+  std::optional<uint64_t> track_uuid;
+
+  const struct PerfettoTeHlExtraTimestamp* custom_timestamp = nullptr;
+  const struct PerfettoTeCategoryDescriptor* dynamic_cat = nullptr;
+  std::optional<int64_t> int_counter;
+  std::optional<double> double_counter;
+
+  for (const auto* it = extra_data; it; it = it->next) {
+    if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_REGISTERED_TRACK) {
+      auto* cast =
+          reinterpret_cast<const struct PerfettoTeHlExtraRegisteredTrack*>(it);
+      registered_track = cast->track;
+      named_track = nullptr;
+    } else if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_NAMED_TRACK) {
+      registered_track = nullptr;
+      named_track =
+          reinterpret_cast<const struct PerfettoTeHlExtraNamedTrack*>(it);
+    } else if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_TIMESTAMP) {
+      custom_timestamp =
+          reinterpret_cast<const struct PerfettoTeHlExtraTimestamp*>(it);
+    } else if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_DYNAMIC_CATEGORY) {
+      dynamic_cat =
+          reinterpret_cast<const struct PerfettoTeHlExtraDynamicCategory*>(it)
+              ->desc;
+    } else if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_COUNTER_INT64) {
+      int_counter =
+          reinterpret_cast<const struct PerfettoTeHlExtraCounterInt64*>(it)
+              ->value;
+    } else if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_COUNTER_DOUBLE) {
+      double_counter =
+          reinterpret_cast<const struct PerfettoTeHlExtraCounterInt64*>(it)
+              ->value;
+    }
+  }
+
+  perfetto::TraceTimestamp ts;
+  if (custom_timestamp) {
+    ts.clock_id = custom_timestamp->timestamp.clock_id;
+    ts.value = custom_timestamp->timestamp.value;
+  } else {
+    ts = TrackEventInternal::GetTraceTime();
+  }
+
+  const auto& track_event_tls =
+      *static_cast<perfetto::shlib::TrackEventTlsState*>(
+          ii->instance->data_source_custom_tls.get());
+
+  auto* incr_state = static_cast<perfetto::shlib::TrackEventIncrementalState*>(
+      ds->GetIncrementalState(ii->instance, ii->i));
+  ResetIncrementalStateIfRequired(ii->instance->trace_writer.get(), incr_state,
+                                  track_event_tls, ts);
+
+  if (PERFETTO_UNLIKELY(dynamic_cat)) {
+    AdvanceToFirstEnabledDynamicCategory(ii, tls_state, incr_state, cat,
+                                         *dynamic_cat);
+    if (!ii->instance) {
+      return;
+    }
+  }
+
+  if (registered_track) {
+    if (incr_state->seen_track_uuids.insert(registered_track->uuid).second) {
+      auto packet = ii->instance->trace_writer->NewTracePacket();
+      auto* track_descriptor = packet->set_track_descriptor();
+      track_descriptor->AppendRawProtoBytes(registered_track->descriptor,
+                                            registered_track->descriptor_size);
+    }
+    track_uuid = registered_track->uuid;
+  } else if (named_track) {
+    uint64_t uuid = named_track->parent_uuid;
+    uuid ^= PerfettoFnv1a(named_track->name, strlen(named_track->name));
+    uuid ^= named_track->id;
+    if (incr_state->seen_track_uuids.insert(uuid).second) {
+      auto packet = ii->instance->trace_writer->NewTracePacket();
+      auto* track_descriptor = packet->set_track_descriptor();
+      track_descriptor->set_uuid(uuid);
+      if (named_track->parent_uuid) {
+        track_descriptor->set_parent_uuid(named_track->parent_uuid);
+      }
+      track_descriptor->set_name(named_track->name);
+    }
+    track_uuid = uuid;
+  }
+
+  {
+    auto packet = NewTracePacketInternal(
+        ii->instance->trace_writer.get(), incr_state, track_event_tls, ts,
+        perfetto::protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE);
+    auto* track_event = packet->set_track_event();
+    WriteTrackEvent(incr_state, track_event, cat, type, name, extra_data,
+                    track_uuid, dynamic_cat);
+    track_event->Finalize();
+
+    if (!incr_state->serialized_interned_data.empty()) {
+      auto ranges = incr_state->serialized_interned_data.GetRanges();
+      packet->AppendScatteredBytes(
+          perfetto::protos::pbzero::TracePacket::kInternedDataFieldNumber,
+          ranges.data(), ranges.size());
+      incr_state->serialized_interned_data.Reset();
+    }
+  }
+
+  bool flush = false;
+  for (const auto* it = extra_data; it; it = it->next) {
+    if (it->type == PERFETTO_TE_HL_EXTRA_TYPE_FLUSH) {
+      flush = true;
+    }
+  }
+  if (PERFETTO_UNLIKELY(flush)) {
+    ii->instance->trace_writer->Flush();
+  }
+}
+
+void PerfettoTeHlEmitImpl(struct PerfettoTeCategoryImpl* cat,
+                          int32_t type,
+                          const char* name,
+                          const struct PerfettoTeHlExtra* extra_data) {
+  uint32_t cached_instances =
+      perfetto::shlib::TracePointTraits::GetActiveInstances({cat})->load(
+          std::memory_order_relaxed);
+  if (!cached_instances) {
+    return;
+  }
+
+  perfetto::internal::DataSourceType* ds =
+      perfetto::shlib::TrackEvent::GetType();
+
+  perfetto::internal::DataSourceThreadLocalState*& tls_state =
+      *perfetto::shlib::TrackEvent::GetTlsState();
+
+  if (!ds->TracePrologue<perfetto::shlib::TrackEventDataSourceTraits,
+                         perfetto::shlib::TracePointTraits>(
+          &tls_state, &cached_instances, {cat})) {
+    return;
+  }
+
+  for (perfetto::internal::DataSourceType::InstancesIterator ii =
+           ds->BeginIteration<perfetto::shlib::TracePointTraits>(
+               cached_instances, tls_state, {cat});
+       ii.instance;
+       ds->NextIteration</*Traits=*/perfetto::shlib::TracePointTraits>(
+           &ii, tls_state, {cat})) {
+    InstanceOp(ds, &ii, tls_state, cat, EventType(type), name, extra_data);
+  }
+  ds->TraceEpilogue(tls_state);
+}
+
+static void FillIterator(
+    const perfetto::internal::DataSourceType::InstancesIterator* ii,
+    struct PerfettoTeTimestamp ts,
+    struct PerfettoTeLlImplIterator* iterator) {
+  perfetto::internal::DataSourceType* ds =
+      perfetto::shlib::TrackEvent::GetType();
+
+  auto& track_event_tls = *static_cast<perfetto::shlib::TrackEventTlsState*>(
+      ii->instance->data_source_custom_tls.get());
+
+  auto* incr_state = static_cast<perfetto::shlib::TrackEventIncrementalState*>(
+      ds->GetIncrementalState(ii->instance, ii->i));
+  perfetto::TraceTimestamp tts;
+  tts.clock_id = ts.clock_id;
+  tts.value = ts.value;
+  ResetIncrementalStateIfRequired(ii->instance->trace_writer.get(), incr_state,
+                                  track_event_tls, tts);
+
+  iterator->incr = reinterpret_cast<struct PerfettoTeLlImplIncr*>(incr_state);
+  iterator->tls =
+      reinterpret_cast<struct PerfettoTeLlImplTls*>(&track_event_tls);
+}
+
+struct PerfettoTeLlImplIterator PerfettoTeLlImplBegin(
+    struct PerfettoTeCategoryImpl* cat,
+    struct PerfettoTeTimestamp ts) {
+  struct PerfettoTeLlImplIterator ret = {};
+  uint32_t cached_instances =
+      perfetto::shlib::TracePointTraits::GetActiveInstances({cat})->load(
+          std::memory_order_relaxed);
+  if (!cached_instances) {
+    return ret;
+  }
+
+  perfetto::internal::DataSourceType* ds =
+      perfetto::shlib::TrackEvent::GetType();
+
+  perfetto::internal::DataSourceThreadLocalState*& tls_state =
+      *perfetto::shlib::TrackEvent::GetTlsState();
+
+  if (!ds->TracePrologue<perfetto::shlib::TrackEventDataSourceTraits,
+                         perfetto::shlib::TracePointTraits>(
+          &tls_state, &cached_instances, {cat})) {
+    return ret;
+  }
+
+  perfetto::internal::DataSourceType::InstancesIterator ii =
+      ds->BeginIteration<perfetto::shlib::TracePointTraits>(cached_instances,
+                                                            tls_state, {cat});
+
+  ret.ds.inst_id = ii.i;
+  tls_state->root_tls->cached_instances = ii.cached_instances;
+  ret.ds.tracer = reinterpret_cast<struct PerfettoDsTracerImpl*>(ii.instance);
+  if (!ret.ds.tracer) {
+    ds->TraceEpilogue(tls_state);
+    return ret;
+  }
+
+  FillIterator(&ii, ts, &ret);
+
+  ret.ds.tls = reinterpret_cast<struct PerfettoDsTlsImpl*>(tls_state);
+  return ret;
+}
+
+void PerfettoTeLlImplNext(struct PerfettoTeCategoryImpl* cat,
+                          struct PerfettoTeTimestamp ts,
+                          struct PerfettoTeLlImplIterator* iterator) {
+  auto* tls = reinterpret_cast<perfetto::internal::DataSourceThreadLocalState*>(
+      iterator->ds.tls);
+
+  perfetto::internal::DataSourceType::InstancesIterator ii;
+  ii.i = iterator->ds.inst_id;
+  ii.cached_instances = tls->root_tls->cached_instances;
+  ii.instance =
+      reinterpret_cast<perfetto::internal::DataSourceInstanceThreadLocalState*>(
+          iterator->ds.tracer);
+
+  perfetto::internal::DataSourceType* ds =
+      perfetto::shlib::TrackEvent::GetType();
+
+  ds->NextIteration</*Traits=*/perfetto::shlib::TracePointTraits>(&ii, tls,
+                                                                  {cat});
+
+  iterator->ds.inst_id = ii.i;
+  tls->root_tls->cached_instances = ii.cached_instances;
+  iterator->ds.tracer =
+      reinterpret_cast<struct PerfettoDsTracerImpl*>(ii.instance);
+
+  if (!iterator->ds.tracer) {
+    ds->TraceEpilogue(tls);
+    return;
+  }
+
+  FillIterator(&ii, ts, iterator);
+}
+
+void PerfettoTeLlImplBreak(struct PerfettoTeCategoryImpl*,
+                           struct PerfettoTeLlImplIterator* iterator) {
+  auto* tls = reinterpret_cast<perfetto::internal::DataSourceThreadLocalState*>(
+      iterator->ds.tls);
+
+  perfetto::internal::DataSourceType* ds =
+      perfetto::shlib::TrackEvent::GetType();
+
+  ds->TraceEpilogue(tls);
+}
+
+bool PerfettoTeLlImplDynCatEnabled(
+    struct PerfettoDsTracerImpl* tracer,
+    PerfettoDsInstanceIndex inst_id,
+    const struct PerfettoTeCategoryDescriptor* dyn_cat) {
+  perfetto::internal::DataSourceType* ds =
+      perfetto::shlib::TrackEvent::GetType();
+
+  auto* tls_inst =
+      reinterpret_cast<perfetto::internal::DataSourceInstanceThreadLocalState*>(
+          tracer);
+
+  auto* incr_state = static_cast<perfetto::shlib::TrackEventIncrementalState*>(
+      ds->GetIncrementalState(tls_inst, inst_id));
+
+  return IsDynamicCategoryEnabled(inst_id, incr_state, *dyn_cat);
+}
+
+bool PerfettoTeLlImplTrackSeen(struct PerfettoTeLlImplIncr* incr,
+                               uint64_t uuid) {
+  auto* incr_state =
+      reinterpret_cast<perfetto::shlib::TrackEventIncrementalState*>(incr);
+
+  return !incr_state->seen_track_uuids.insert(uuid).second;
+}
+
+uint64_t PerfettoTeLlImplIntern(struct PerfettoTeLlImplIncr* incr,
+                                int32_t type,
+                                const void* data,
+                                size_t data_size,
+                                bool* seen) {
+  auto* incr_state =
+      reinterpret_cast<perfetto::shlib::TrackEventIncrementalState*>(incr);
+
+  auto res = incr_state->iids.FindOrAssign(type, data, data_size);
+  *seen = !res.newly_assigned;
+  return res.iid;
 }
diff --git a/src/tracing/track.cc b/src/tracing/track.cc
index a43cc84..2f57e77 100644
--- a/src/tracing/track.cc
+++ b/src/tracing/track.cc
@@ -181,7 +181,11 @@
   if (instance_)
     return;
   instance_ = new TrackRegistry();
+  Track::process_uuid = ComputeProcessUuid();
+}
 
+// static
+uint64_t TrackRegistry::ComputeProcessUuid() {
   // Use the process start time + pid as the unique identifier for this process.
   // This ensures that if there are two independent copies of the Perfetto SDK
   // in the same process (e.g., one in the app and another in a system
@@ -191,11 +195,11 @@
     base::Hasher hash;
     hash.Update(start_time);
     hash.Update(Platform::GetCurrentProcessId());
-    Track::process_uuid = hash.digest();
-  } else {
-    // Fall back to a randomly generated identifier.
-    Track::process_uuid = static_cast<uint64_t>(base::Uuidv4().lsb());
+    return hash.digest();
   }
+  // Fall back to a randomly generated identifier.
+  static uint64_t random_once = static_cast<uint64_t>(base::Uuidv4().lsb());
+  return random_once;
 }
 
 void TrackRegistry::ResetForTesting() {