perfetto: add android process state and freezer dump parsing
Update frameworks_base_trace_packet.proto from upstream Android tree
and add Trace Processor parsing for trace-stop dumps.
Specifically, this adds:
- AndroidProcessStateSnapshot message and nested Record message:
- pid (1), uid (2), proc_state (3), oom_score (4), capability_flags (5)
- AndroidFreezerStateSnapshot message and nested Record message:
- pid (1), freeze_unfreeze_time (2), process_name (3), isFreezeSticky (4)
- FrameworksBaseTracePacket extensions:
- android_process_state (1003)
- android_freezer_state (1004)
- AndroidProcessDumpModule to parse fields 1003 and 1004, handling
ProtoOutputStream zero-value omissions for proc_state and capability_flags
by defaulting to 0 when omitted.
diff --git a/Android.bp b/Android.bp
index b50d279..8a8c8e7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -18071,6 +18071,7 @@
"src/trace_processor/importers/proto/android_probes_module.cc",
"src/trace_processor/importers/proto/android_probes_parser.cc",
"src/trace_processor/importers/proto/android_probes_tracker.cc",
+ "src/trace_processor/importers/proto/android_process_dump_module.cc",
"src/trace_processor/importers/proto/content_analyzer.cc",
"src/trace_processor/importers/proto/deobfuscation_module.cc",
"src/trace_processor/importers/proto/deobfuscation_tracker.cc",
diff --git a/BUILD b/BUILD
index 1645703..fec73a2 100644
--- a/BUILD
+++ b/BUILD
@@ -3028,6 +3028,8 @@
"src/trace_processor/importers/proto/android_probes_parser.h",
"src/trace_processor/importers/proto/android_probes_tracker.cc",
"src/trace_processor/importers/proto/android_probes_tracker.h",
+ "src/trace_processor/importers/proto/android_process_dump_module.cc",
+ "src/trace_processor/importers/proto/android_process_dump_module.h",
"src/trace_processor/importers/proto/content_analyzer.cc",
"src/trace_processor/importers/proto/content_analyzer.h",
"src/trace_processor/importers/proto/deobfuscation_module.cc",
diff --git a/protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_trace_packet.proto b/protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_trace_packet.proto
index 9104e6e..bc5adf9 100644
--- a/protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_trace_packet.proto
+++ b/protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_trace_packet.proto
@@ -106,10 +106,34 @@
optional Reason reason = 2;
}
+message AndroidProcessStateSnapshot {
+ message Record {
+ optional int32 pid = 1;
+ optional int32 uid = 2;
+ optional int32 proc_state = 3;
+ optional int32 oom_score = 4;
+ optional int32 capability_flags = 5;
+ }
+ repeated Record record = 1;
+}
+
+message AndroidFreezerStateSnapshot {
+ message Record {
+ optional int32 pid = 1;
+ // Last time app was (un)frozen, 0 for never.
+ optional int64 freeze_unfreeze_time = 2;
+ optional string process_name = 3;
+ optional bool isFreezeSticky = 4;
+ }
+ repeated Record record = 1;
+}
+
message FrameworksBaseTracePacket {
extend perfetto.protos.TracePacket {
optional AppWakelockBundle app_wakelock_bundle = 116;
optional VideoFrame video_frame = 1000;
optional VideoFrameError video_frame_error = 1001;
+ optional AndroidProcessStateSnapshot android_process_state = 1003;
+ optional AndroidFreezerStateSnapshot android_freezer_state = 1004;
}
}
diff --git a/src/trace_processor/importers/proto/BUILD.gn b/src/trace_processor/importers/proto/BUILD.gn
index b1ddc02..5dc5646 100644
--- a/src/trace_processor/importers/proto/BUILD.gn
+++ b/src/trace_processor/importers/proto/BUILD.gn
@@ -151,6 +151,8 @@
"android_probes_parser.h",
"android_probes_tracker.cc",
"android_probes_tracker.h",
+ "android_process_dump_module.cc",
+ "android_process_dump_module.h",
"content_analyzer.cc",
"content_analyzer.h",
"deobfuscation_module.cc",
@@ -232,6 +234,7 @@
"../../../../protos/perfetto/trace/system_info:zero",
"../../../../protos/perfetto/trace/translation:zero",
"../../../../protos/third_party/android/art:art_heap_graph_zero",
+ "../../../../protos/third_party/android/frameworks/base/proto/tracing:frameworks_base_trace_packet_zero",
"../../../../protos/third_party/android/frameworks/native/tracing:frameworks_native_trace_packet_zero",
"../../../../protos/third_party/android/packages/modules/bluetooth/tracing:bluetooth_tracing_zero",
"../../../base",
@@ -382,6 +385,7 @@
"../../../../protos/perfetto/trace/track_event:zero",
"../../../../protos/third_party/android/art:art_heap_graph_zero",
"../../../../protos/third_party/android/connectivity:connectivity_network_trace_zero",
+ "../../../../protos/third_party/android/frameworks/base/proto/tracing:frameworks_base_trace_packet_zero",
"../../../../protos/third_party/chromium:zero",
"../../../base:test_support",
"../../../protozero",
diff --git a/src/trace_processor/importers/proto/additional_modules.cc b/src/trace_processor/importers/proto/additional_modules.cc
index 5a3975e..fc1f60f 100644
--- a/src/trace_processor/importers/proto/additional_modules.cc
+++ b/src/trace_processor/importers/proto/additional_modules.cc
@@ -27,6 +27,7 @@
#include "src/trace_processor/importers/proto/android_extension.descriptor.h"
#include "src/trace_processor/importers/proto/android_kernel_wakelocks_module.h"
#include "src/trace_processor/importers/proto/android_probes_module.h"
+#include "src/trace_processor/importers/proto/android_process_dump_module.h"
#include "src/trace_processor/importers/proto/app_wakelock_module.h"
#include "src/trace_processor/importers/proto/concurrent_sessions_module.h"
#include "src/trace_processor/importers/proto/content_analyzer.h"
@@ -87,6 +88,8 @@
module_context->modules.emplace_back(
new AppWakelockModule(module_context, context));
module_context->modules.emplace_back(
+ new AndroidProcessDumpModule(module_context, context));
+ module_context->modules.emplace_back(
new ConcurrentSessionsModule(module_context, context));
module_context->modules.emplace_back(
new GenericKernelModule(module_context, context));
diff --git a/src/trace_processor/importers/proto/android_process_dump_module.cc b/src/trace_processor/importers/proto/android_process_dump_module.cc
new file mode 100644
index 0000000..9e2ae68
--- /dev/null
+++ b/src/trace_processor/importers/proto/android_process_dump_module.cc
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2026 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_process_dump_module.h"
+
+#include <cstdint>
+
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/protozero/field.h"
+#include "protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_trace_packet.pbzero.h"
+#include "src/trace_processor/importers/common/process_tracker.h"
+#include "src/trace_processor/storage/trace_storage.h"
+#include "src/trace_processor/tables/android_tables_py.h"
+#include "src/trace_processor/types/trace_processor_context.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+using ::com::android::internal::pbzero::AndroidFreezerStateSnapshot;
+using ::com::android::internal::pbzero::AndroidProcessStateSnapshot;
+using ::com::android::internal::pbzero::FrameworksBaseTracePacket;
+
+AndroidProcessDumpModule::AndroidProcessDumpModule(
+ ProtoImporterModuleContext* module_context,
+ TraceProcessorContext* context)
+ : ProtoImporterModule(module_context), context_(context) {
+ RegisterForField(FrameworksBaseTracePacket::kAndroidProcessStateFieldNumber);
+ RegisterForField(FrameworksBaseTracePacket::kAndroidFreezerStateFieldNumber);
+}
+
+AndroidProcessDumpModule::~AndroidProcessDumpModule() = default;
+
+void AndroidProcessDumpModule::ParseField(const ParseFieldArgs& args) {
+ switch (args.field.id()) {
+ case FrameworksBaseTracePacket::kAndroidProcessStateFieldNumber:
+ ParseAndroidProcessState(
+ args.ts,
+ args.field.Cast<FrameworksBaseTracePacket::kAndroidProcessState>());
+ return;
+ case FrameworksBaseTracePacket::kAndroidFreezerStateFieldNumber:
+ ParseAndroidFreezerState(
+ args.ts,
+ args.field.Cast<FrameworksBaseTracePacket::kAndroidFreezerState>());
+ return;
+ }
+}
+
+void AndroidProcessDumpModule::ParseAndroidProcessState(
+ int64_t ts,
+ protozero::ConstBytes blob) {
+ AndroidProcessStateSnapshot::Decoder evt(blob);
+ auto* table = context_->storage->mutable_android_process_state_dump_table();
+ for (auto it = evt.record(); it; ++it) {
+ AndroidProcessStateSnapshot::Record::Decoder proc(*it);
+ if (!proc.has_pid()) {
+ continue;
+ }
+ UniquePid upid = context_->process_tracker->GetOrCreateProcess(
+ static_cast<uint32_t>(proc.pid()));
+ if (proc.has_uid()) {
+ context_->process_tracker->SetProcessUid(
+ upid, static_cast<uint32_t>(proc.uid()));
+ }
+ tables::AndroidProcessStateDumpTable::Row row;
+ row.ts = ts;
+ row.pid = static_cast<uint32_t>(proc.pid());
+ if (proc.has_uid()) {
+ row.uid = static_cast<uint32_t>(proc.uid());
+ }
+ row.proc_state = proc.has_proc_state() ? proc.proc_state() : 0;
+ row.oom_score = proc.has_oom_score() ? proc.oom_score() : 0;
+ row.capability_flags =
+ proc.has_capability_flags() ? proc.capability_flags() : 0;
+ table->Insert(row);
+ }
+}
+
+void AndroidProcessDumpModule::ParseAndroidFreezerState(
+ int64_t ts,
+ protozero::ConstBytes blob) {
+ AndroidFreezerStateSnapshot::Decoder evt(blob);
+ auto* table = context_->storage->mutable_android_freezer_state_dump_table();
+ for (auto it = evt.record(); it; ++it) {
+ AndroidFreezerStateSnapshot::Record::Decoder rec(*it);
+ if (!rec.has_pid()) {
+ continue;
+ }
+ UniquePid upid = context_->process_tracker->GetOrCreateProcess(
+ static_cast<uint32_t>(rec.pid()));
+ if (rec.has_process_name()) {
+ context_->process_tracker->UpdateProcessName(
+ upid, context_->storage->InternString(rec.process_name()),
+ ProcessNamePriority::kOther);
+ }
+ tables::AndroidFreezerStateDumpTable::Row row;
+ row.ts = ts;
+ row.pid = static_cast<uint32_t>(rec.pid());
+ if (rec.has_process_name()) {
+ row.process_name = context_->storage->InternString(rec.process_name());
+ }
+ if (rec.has_freeze_unfreeze_time()) {
+ row.freeze_unfreeze_time = rec.freeze_unfreeze_time();
+ }
+ if (rec.has_isfreezesticky()) {
+ row.is_freeze_sticky = rec.isfreezesticky() ? 1u : 0u;
+ }
+ table->Insert(row);
+ }
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/android_process_dump_module.h b/src/trace_processor/importers/proto/android_process_dump_module.h
new file mode 100644
index 0000000..1fb1c16
--- /dev/null
+++ b/src/trace_processor/importers/proto/android_process_dump_module.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2026 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_PROCESS_DUMP_MODULE_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_PROCESS_DUMP_MODULE_H_
+
+#include "src/trace_processor/importers/proto/proto_importer_module.h"
+#include "src/trace_processor/storage/trace_storage.h"
+
+namespace protozero {
+struct ConstBytes;
+}
+
+namespace perfetto {
+namespace trace_processor {
+
+class TraceProcessorContext;
+
+class AndroidProcessDumpModule : public ProtoImporterModule {
+ public:
+ explicit AndroidProcessDumpModule(ProtoImporterModuleContext* module_context,
+ TraceProcessorContext* context);
+ ~AndroidProcessDumpModule() override;
+
+ void ParseField(const ParseFieldArgs& args) override;
+
+ private:
+ void ParseAndroidProcessState(int64_t ts, protozero::ConstBytes blob);
+ void ParseAndroidFreezerState(int64_t ts, protozero::ConstBytes blob);
+
+ TraceProcessorContext* context_ = nullptr;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_PROCESS_DUMP_MODULE_H_
diff --git a/src/trace_processor/importers/proto/proto_trace_parser_impl_unittest.cc b/src/trace_processor/importers/proto/proto_trace_parser_impl_unittest.cc
index 7ce65de..b1562a2 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser_impl_unittest.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser_impl_unittest.cc
@@ -112,6 +112,7 @@
#include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
#include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+#include "protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_trace_packet.pbzero.h"
#include "protos/third_party/chromium/chrome_enums.pbzero.h"
namespace perfetto::trace_processor {
@@ -3132,10 +3133,8 @@
cpu->set_processor("ARMv8 Processor rev 0 (v8l)");
cpu->set_capacity(1024);
cpu->add_frequencies(1800000);
-
ASSERT_TRUE(Tokenize().ok());
context_.sorter->ExtractEventsForced();
-
EXPECT_EQ(context_.stats_tracker->GetStats(stats::cpu_info_empty), 0);
const auto& cpu_table = context_.storage->cpu_table();
EXPECT_STREQ(context_.storage->GetString(cpu_table[0].processor()).c_str(),
@@ -3143,5 +3142,75 @@
EXPECT_EQ(cpu_table[0].capacity(), 1024u);
}
+TEST_F(ProtoTraceParserTest, AndroidProcessStateSnapshot) {
+ using ::com::android::internal::pbzero::AndroidProcessStateSnapshot;
+ using ::com::android::internal::pbzero::FrameworksBaseTracePacket;
+
+ auto* packet = trace_->add_packet();
+ packet->set_timestamp(100);
+ protozero::HeapBuffered<AndroidProcessStateSnapshot> snapshot;
+ auto* rec = snapshot->add_record();
+ rec->set_pid(1001);
+ rec->set_uid(10001);
+ rec->set_proc_state(2); // PROCESS_STATE_PERSISTENT
+ rec->set_oom_score(-1000);
+ rec->set_capability_flags(4); // PROCESS_CAPABILITY_FOREGROUND_CAMERA
+
+ std::vector<uint8_t> bytes = snapshot.SerializeAsArray();
+ packet->AppendBytes(
+ FrameworksBaseTracePacket::kAndroidProcessStateFieldNumber, bytes.data(),
+ bytes.size());
+
+ ASSERT_TRUE(Tokenize().ok());
+ context_.sorter->ExtractEventsForced();
+
+ const auto& table = context_.storage->android_process_state_dump_table();
+ ASSERT_EQ(table.row_count(), 1u);
+ EXPECT_EQ(table[0].ts(), 100);
+ EXPECT_EQ(table[0].pid(), 1001u);
+ EXPECT_EQ(table[0].uid().value_or(0), 10001u);
+ EXPECT_EQ(table[0].proc_state().value_or(-1), 2);
+ EXPECT_EQ(table[0].oom_score().value_or(0), -1000);
+ EXPECT_EQ(table[0].capability_flags().value_or(0), 4u);
+}
+
+TEST_F(ProtoTraceParserTest, AndroidProcessStateSnapshotOmittedZeroValues) {
+ using ::com::android::internal::pbzero::AndroidProcessStateSnapshot;
+ using ::com::android::internal::pbzero::FrameworksBaseTracePacket;
+
+ auto* packet = trace_->add_packet();
+ packet->set_timestamp(200);
+ protozero::HeapBuffered<AndroidProcessStateSnapshot> snapshot;
+ auto* rec = snapshot->add_record();
+ rec->set_pid(1002);
+ rec->set_uid(10002);
+ // proc_state (0 = PROCESS_STATE_UNKNOWN), oom_score (0 = FOREGROUND_APP_ADJ),
+ // and capability_flags (0 = PROCESS_CAPABILITY_NONE) omitted
+
+ std::vector<uint8_t> bytes = snapshot.SerializeAsArray();
+ packet->AppendBytes(
+ FrameworksBaseTracePacket::kAndroidProcessStateFieldNumber, bytes.data(),
+ bytes.size());
+
+ ASSERT_TRUE(Tokenize().ok());
+ context_.sorter->ExtractEventsForced();
+
+ const auto& table = context_.storage->android_process_state_dump_table();
+ ASSERT_EQ(table.row_count(), 1u);
+ EXPECT_EQ(table[0].ts(), 200);
+ EXPECT_EQ(table[0].pid(), 1002u);
+ EXPECT_EQ(table[0].uid().value_or(0), 10002u);
+ // Default to 0 instead of std::nullopt (NULL)
+ auto proc_state = table[0].proc_state();
+ EXPECT_TRUE(proc_state.has_value());
+ EXPECT_EQ(proc_state.value(), 0);
+ auto oom_score = table[0].oom_score();
+ EXPECT_TRUE(oom_score.has_value());
+ EXPECT_EQ(oom_score.value(), 0);
+ auto capability_flags = table[0].capability_flags();
+ EXPECT_TRUE(capability_flags.has_value());
+ EXPECT_EQ(capability_flags.value(), 0u);
+}
+
} // namespace
} // namespace perfetto::trace_processor
diff --git a/src/trace_processor/plugins/android_framework_track_event/android_framework_track_event.cc b/src/trace_processor/plugins/android_framework_track_event/android_framework_track_event.cc
index 213d152..f95b410 100644
--- a/src/trace_processor/plugins/android_framework_track_event/android_framework_track_event.cc
+++ b/src/trace_processor/plugins/android_framework_track_event/android_framework_track_event.cc
@@ -44,7 +44,10 @@
::com::android::internal::pbzero::AndroidProcessStartEvent;
using AndroidBinderDiedEvent =
::com::android::internal::pbzero::AndroidBinderDiedEvent;
+using AndroidFreezerEvent =
+ ::com::android::internal::pbzero::AndroidFreezerEvent;
using AndroidTrackEventProcessTable = tables::AndroidTrackEventProcessTable;
+using AndroidTrackEventFreezerTable = tables::AndroidTrackEventFreezerTable;
// Records AndroidProcessStartEvent and AndroidBinderDiedEvent into
// __intrinsic_android_track_event_process.
@@ -52,12 +55,15 @@
public:
Parser(TrackEventExtensionParserContext* extension_parser_context,
TraceProcessorContext* context,
- AndroidTrackEventProcessTable* table)
+ AndroidTrackEventProcessTable* process_table,
+ AndroidTrackEventFreezerTable* freezer_table)
: TrackEventExtensionParser(extension_parser_context),
trace_context_(context),
- table_(table) {
+ process_table_(process_table),
+ freezer_table_(freezer_table) {
RegisterTrackEventExtension(FBTE::kProcessStartEventFieldNumber);
RegisterTrackEventExtension(FBTE::kBinderDiedEventFieldNumber);
+ RegisterTrackEventExtension(FBTE::kFreezerEventFieldNumber);
}
~Parser() override = default;
@@ -71,6 +77,9 @@
case FBTE::kBinderDiedEventFieldNumber:
HandleBinderDied(field.Cast<FBTE::kBinderDiedEvent>(), ts);
break;
+ case FBTE::kFreezerEventFieldNumber:
+ HandleFreezerEvent(field.Cast<FBTE::kFreezerEvent>(), ts);
+ break;
default:
break;
}
@@ -97,9 +106,36 @@
if (it_and_ins.second) {
AndroidTrackEventProcessTable::Row row;
row.upid = upid;
- *it_and_ins.first = table_->Insert(row).id;
+ *it_and_ins.first = process_table_->Insert(row).id;
}
- return (*table_)[*it_and_ins.first];
+ return (*process_table_)[*it_and_ins.first];
+ }
+
+ void HandleFreezerEvent(protozero::ConstBytes data, int64_t ts) {
+ AndroidFreezerEvent::Decoder evt(data);
+ tables::AndroidTrackEventFreezerTable::Row row;
+ row.ts = ts;
+ if (evt.has_pid()) {
+ row.pid = evt.pid();
+ std::optional<UniquePid> upid =
+ trace_context_->process_tracker->GetOrCreateProcess(
+ static_cast<uint32_t>(evt.pid()));
+ if (upid) {
+ row.upid = *upid;
+ }
+ }
+ if (evt.has_unfrozen_dur_ms()) {
+ row.unfrozen_dur_ms = evt.unfrozen_dur_ms();
+ }
+ if (evt.has_frozen_dur_ms()) {
+ row.frozen_dur_ms = evt.frozen_dur_ms();
+ }
+ if (evt.has_unfreeze_reason()) {
+ row.unfreeze_reason = InternEnum(
+ unfreeze_reason_cache_, ".com.android.internal.UnfreezeReason",
+ static_cast<int32_t>(evt.unfreeze_reason()));
+ }
+ freezer_table_->Insert(row);
}
void HandleProcessStart(protozero::ConstBytes data, int64_t ts) {
@@ -174,7 +210,9 @@
TraceProcessorContext* trace_context_;
DescriptorPool::CachedDescriptor trigger_type_cache_;
DescriptorPool::CachedDescriptor hosting_type_cache_;
- AndroidTrackEventProcessTable* table_;
+ DescriptorPool::CachedDescriptor unfreeze_reason_cache_;
+ AndroidTrackEventProcessTable* process_table_;
+ AndroidTrackEventFreezerTable* freezer_table_;
base::FlatHashMap<UniquePid, AndroidTrackEventProcessTable::Id> upid_to_row_;
};
@@ -184,28 +222,37 @@
~AndroidFrameworkTrackEventPlugin() override;
void RegisterDataframes(std::vector<PluginDataframe>& out) override {
- EnsureTable();
- out.push_back(
- {&table_->dataframe(), AndroidTrackEventProcessTable::Name(), {}});
+ EnsureTables();
+ out.push_back({&process_table_->dataframe(),
+ AndroidTrackEventProcessTable::Name(),
+ {}});
+ out.push_back({&freezer_table_->dataframe(),
+ AndroidTrackEventFreezerTable::Name(),
+ {}});
}
void RegisterTrackEventExtensions(
TrackEventExtensionParserContext* ctx,
TraceProcessorContext* trace_context) override {
- EnsureTable();
- ctx->parsers.emplace_back(
- std::make_unique<Parser>(ctx, trace_context, table_.get()));
+ EnsureTables();
+ ctx->parsers.emplace_back(std::make_unique<Parser>(
+ ctx, trace_context, process_table_.get(), freezer_table_.get()));
}
private:
- void EnsureTable() {
- if (!table_) {
- table_ = std::make_unique<AndroidTrackEventProcessTable>(
+ void EnsureTables() {
+ if (!process_table_) {
+ process_table_ = std::make_unique<AndroidTrackEventProcessTable>(
+ trace_context_->storage->mutable_string_pool());
+ }
+ if (!freezer_table_) {
+ freezer_table_ = std::make_unique<AndroidTrackEventFreezerTable>(
trace_context_->storage->mutable_string_pool());
}
}
- std::unique_ptr<AndroidTrackEventProcessTable> table_;
+ std::unique_ptr<AndroidTrackEventProcessTable> process_table_;
+ std::unique_ptr<AndroidTrackEventFreezerTable> freezer_table_;
};
AndroidFrameworkTrackEventPlugin::~AndroidFrameworkTrackEventPlugin() = default;
diff --git a/src/trace_processor/plugins/android_framework_track_event/tables.py b/src/trace_processor/plugins/android_framework_track_event/tables.py
index dfc7f3f..044b897 100644
--- a/src/trace_processor/plugins/android_framework_track_event/tables.py
+++ b/src/trace_processor/plugins/android_framework_track_event/tables.py
@@ -80,4 +80,43 @@
),
)
-ALL_TABLES = [ANDROID_TRACK_EVENT_PROCESS_TABLE]
+ANDROID_TRACK_EVENT_FREEZER_TABLE = Table(
+ python_module=__file__,
+ class_name='AndroidTrackEventFreezerTable',
+ sql_name='__intrinsic_android_track_event_freezer',
+ columns=[
+ C('ts', CppInt64(), cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('upid',
+ CppOptional(CppTableId(PROCESS_TABLE)),
+ cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('pid',
+ CppOptional(CppInt64()),
+ cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('unfrozen_dur_ms',
+ CppOptional(CppInt64()),
+ cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('frozen_dur_ms',
+ CppOptional(CppInt64()),
+ cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('unfreeze_reason',
+ CppOptional(CppString()),
+ cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ ],
+ tabledoc=TableDoc(
+ doc='Freezer TrackEvents emitted by Android framework.',
+ group='Android',
+ columns={
+ 'ts': 'Timestamp of the freezer event.',
+ 'upid': 'Unique process ID.',
+ 'pid': 'Process ID.',
+ 'unfrozen_dur_ms': 'Time since last unfrozen in milliseconds.',
+ 'frozen_dur_ms': 'Time since last frozen in milliseconds.',
+ 'unfreeze_reason': 'Reason for unfreezing.',
+ },
+ ),
+)
+
+ALL_TABLES = [
+ ANDROID_TRACK_EVENT_PROCESS_TABLE,
+ ANDROID_TRACK_EVENT_FREEZER_TABLE,
+]
diff --git a/src/trace_processor/plugins/storage_tables/storage_tables.cc b/src/trace_processor/plugins/storage_tables/storage_tables.cc
index 4137548..47ee1be 100644
--- a/src/trace_processor/plugins/storage_tables/storage_tables.cc
+++ b/src/trace_processor/plugins/storage_tables/storage_tables.cc
@@ -101,6 +101,8 @@
AddDataframe(out, s->mutable_android_aflags_table());
AddDataframe(out, s->mutable_android_cpu_per_uid_track_table());
AddDataframe(out, s->mutable_android_dumpstate_table());
+ AddDataframe(out, s->mutable_android_process_state_dump_table());
+ AddDataframe(out, s->mutable_android_freezer_state_dump_table());
AddDataframe(out, s->mutable_android_game_intervenion_list_table());
AddDataframe(out, s->mutable_log_table());
AddDataframe(out, s->mutable_build_flags_table());
diff --git a/src/trace_processor/storage/trace_storage.h b/src/trace_processor/storage/trace_storage.h
index a12d987..a5c4148 100644
--- a/src/trace_processor/storage/trace_storage.h
+++ b/src/trace_processor/storage/trace_storage.h
@@ -369,6 +369,24 @@
return mutable_table<tables::AndroidDumpstateTable>();
}
+ const tables::AndroidProcessStateDumpTable& android_process_state_dump_table()
+ const {
+ return table<tables::AndroidProcessStateDumpTable>();
+ }
+ tables::AndroidProcessStateDumpTable*
+ mutable_android_process_state_dump_table() {
+ return mutable_table<tables::AndroidProcessStateDumpTable>();
+ }
+
+ const tables::AndroidFreezerStateDumpTable& android_freezer_state_dump_table()
+ const {
+ return table<tables::AndroidFreezerStateDumpTable>();
+ }
+ tables::AndroidFreezerStateDumpTable*
+ mutable_android_freezer_state_dump_table() {
+ return mutable_table<tables::AndroidFreezerStateDumpTable>();
+ }
+
const tables::AndroidKeyEventsTable& android_key_events_table() const {
return table<tables::AndroidKeyEventsTable>();
}
diff --git a/src/trace_processor/tables/android_tables.py b/src/trace_processor/tables/android_tables.py
index 214f118..f6eb297 100644
--- a/src/trace_processor/tables/android_tables.py
+++ b/src/trace_processor/tables/android_tables.py
@@ -368,14 +368,86 @@
),
)
+ANDROID_PROCESS_STATE_DUMP_TABLE = Table(
+ python_module=__file__,
+ class_name='AndroidProcessStateDumpTable',
+ sql_name='__intrinsic_android_process_state_dump',
+ wrapping_sql_view=WrappingSqlView('android_process_state_dump'),
+ columns=[
+ C('ts', CppInt64(), cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('pid', CppUint32(), cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('uid',
+ CppOptional(CppUint32()),
+ cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('proc_state',
+ CppOptional(CppInt32()),
+ cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('oom_score',
+ CppOptional(CppInt32()),
+ cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('capability_flags',
+ CppOptional(CppUint32()),
+ cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ ],
+ tabledoc=TableDoc(
+ doc='''
+ Process state snapshot dumped by the android.process_state data source.
+ ''',
+ group='Android',
+ columns={
+ 'ts': 'Timestamp of the snapshot dump.',
+ 'pid': 'Process ID.',
+ 'uid': 'Process UID.',
+ 'proc_state': 'ActivityManager process state integer.',
+ 'oom_score': 'OOM score adjustment integer.',
+ 'capability_flags': 'Capability flags integer.',
+ },
+ ),
+)
+
+ANDROID_FREEZER_STATE_DUMP_TABLE = Table(
+ python_module=__file__,
+ class_name='AndroidFreezerStateDumpTable',
+ sql_name='__intrinsic_android_freezer_state_dump',
+ wrapping_sql_view=WrappingSqlView('android_freezer_state_dump'),
+ columns=[
+ C('ts', CppInt64(), cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('pid', CppUint32(), cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('process_name',
+ CppOptional(CppString()),
+ cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('freeze_unfreeze_time',
+ CppOptional(CppInt64()),
+ cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ C('is_freeze_sticky',
+ CppOptional(CppUint32()),
+ cpp_access=CppAccess.READ_AND_HIGH_PERF_WRITE),
+ ],
+ tabledoc=TableDoc(
+ doc='''
+ Freezer state snapshot dumped by the android.freezer_state data source.
+ ''',
+ group='Android',
+ columns={
+ 'ts': 'Timestamp of the snapshot dump.',
+ 'pid': 'Process ID.',
+ 'process_name': 'Process name.',
+ 'freeze_unfreeze_time': 'Last freeze or unfreeze timestamp.',
+ 'is_freeze_sticky': 'Whether freeze state is sticky (1 or 0).',
+ },
+ ),
+)
+
# Keep this list sorted.
ALL_TABLES = [
ANDROID_AFLAGS_TABLE,
ANDROID_CPU_PER_UID_TRACK_TABLE,
ANDROID_DUMPSTATE_TABLE,
+ ANDROID_FREEZER_STATE_DUMP_TABLE,
ANDROID_GAME_INTERVENTION_LIST_TABLE,
ANDROID_INPUT_EVENT_DISPATCH_TABLE,
ANDROID_KEY_EVENTS_TABLE,
ANDROID_MOTION_EVENTS_TABLE,
+ ANDROID_PROCESS_STATE_DUMP_TABLE,
ANDROID_USER_LIST_TABLE,
]