tp: add ui state proto and expose it in the metadata table
Doc: go/trace-ui-state
Change-Id: Idf8a28d12c2cb2998a623f9f58bb68797484edaa
diff --git a/Android.bp b/Android.bp
index c3e2ce7..d0dc689 100644
--- a/Android.bp
+++ b/Android.bp
@@ -5139,6 +5139,7 @@
"protos/perfetto/trace/trace.proto",
"protos/perfetto/trace/trace_packet.proto",
"protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/ui_state.proto",
],
tools: [
"aprotoc",
@@ -5152,6 +5153,7 @@
"external/perfetto/protos/perfetto/trace/trace.gen.cc",
"external/perfetto/protos/perfetto/trace/trace_packet.gen.cc",
"external/perfetto/protos/perfetto/trace/trace_packet_defaults.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ui_state.gen.cc",
],
}
@@ -5165,6 +5167,7 @@
"protos/perfetto/trace/trace.proto",
"protos/perfetto/trace/trace_packet.proto",
"protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/ui_state.proto",
],
tools: [
"aprotoc",
@@ -5178,6 +5181,7 @@
"external/perfetto/protos/perfetto/trace/trace.gen.h",
"external/perfetto/protos/perfetto/trace/trace_packet.gen.h",
"external/perfetto/protos/perfetto/trace/trace_packet_defaults.gen.h",
+ "external/perfetto/protos/perfetto/trace/ui_state.gen.h",
],
export_include_dirs: [
".",
@@ -5195,6 +5199,7 @@
"protos/perfetto/trace/trace.proto",
"protos/perfetto/trace/trace_packet.proto",
"protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/ui_state.proto",
],
tools: [
"aprotoc",
@@ -5207,6 +5212,7 @@
"external/perfetto/protos/perfetto/trace/trace.pb.cc",
"external/perfetto/protos/perfetto/trace/trace_packet.pb.cc",
"external/perfetto/protos/perfetto/trace/trace_packet_defaults.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ui_state.pb.cc",
],
}
@@ -5220,6 +5226,7 @@
"protos/perfetto/trace/trace.proto",
"protos/perfetto/trace/trace_packet.proto",
"protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/ui_state.proto",
],
tools: [
"aprotoc",
@@ -5232,6 +5239,7 @@
"external/perfetto/protos/perfetto/trace/trace.pb.h",
"external/perfetto/protos/perfetto/trace/trace_packet.pb.h",
"external/perfetto/protos/perfetto/trace/trace_packet_defaults.pb.h",
+ "external/perfetto/protos/perfetto/trace/ui_state.pb.h",
],
export_include_dirs: [
".",
@@ -5249,6 +5257,7 @@
"protos/perfetto/trace/trace.proto",
"protos/perfetto/trace/trace_packet.proto",
"protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/ui_state.proto",
],
tools: [
"aprotoc",
@@ -5262,6 +5271,7 @@
"external/perfetto/protos/perfetto/trace/trace.pbzero.cc",
"external/perfetto/protos/perfetto/trace/trace_packet.pbzero.cc",
"external/perfetto/protos/perfetto/trace/trace_packet_defaults.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ui_state.pbzero.cc",
],
}
@@ -5275,6 +5285,7 @@
"protos/perfetto/trace/trace.proto",
"protos/perfetto/trace/trace_packet.proto",
"protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/ui_state.proto",
],
tools: [
"aprotoc",
@@ -5288,6 +5299,7 @@
"external/perfetto/protos/perfetto/trace/trace.pbzero.h",
"external/perfetto/protos/perfetto/trace/trace_packet.pbzero.h",
"external/perfetto/protos/perfetto/trace/trace_packet_defaults.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ui_state.pbzero.h",
],
export_include_dirs: [
".",
@@ -7897,6 +7909,7 @@
"src/trace_processor/importers/proto/heap_profile_tracker.cc",
"src/trace_processor/importers/proto/memory_tracker_snapshot_module.cc",
"src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc",
+ "src/trace_processor/importers/proto/metadata_module.cc",
"src/trace_processor/importers/proto/metadata_tracker.cc",
"src/trace_processor/importers/proto/packet_sequence_state.cc",
"src/trace_processor/importers/proto/perf_sample_tracker.cc",
diff --git a/BUILD b/BUILD
index 1699bdb..1c6cea7 100644
--- a/BUILD
+++ b/BUILD
@@ -1271,6 +1271,8 @@
"src/trace_processor/importers/proto/memory_tracker_snapshot_module.h",
"src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc",
"src/trace_processor/importers/proto/memory_tracker_snapshot_parser.h",
+ "src/trace_processor/importers/proto/metadata_module.cc",
+ "src/trace_processor/importers/proto/metadata_module.h",
"src/trace_processor/importers/proto/metadata_tracker.cc",
"src/trace_processor/importers/proto/metadata_tracker.h",
"src/trace_processor/importers/proto/packet_sequence_state.cc",
@@ -2758,6 +2760,7 @@
"protos/perfetto/trace/trace.proto",
"protos/perfetto/trace/trace_packet.proto",
"protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/ui_state.proto",
],
visibility = PERFETTO_CONFIG.public_visibility,
deps = [
diff --git a/include/perfetto/ext/base/string_utils.h b/include/perfetto/ext/base/string_utils.h
index b4a8bf9..7310b01 100644
--- a/include/perfetto/ext/base/string_utils.h
+++ b/include/perfetto/ext/base/string_utils.h
@@ -122,6 +122,7 @@
const std::string& to_replace,
const std::string& replacement);
std::string TrimLeading(const std::string& str);
+std::string Base64Encode(const void* ptr, size_t size);
} // namespace base
} // namespace perfetto
diff --git a/protos/perfetto/trace/BUILD.gn b/protos/perfetto/trace/BUILD.gn
index 9c195e4..7861978 100644
--- a/protos/perfetto/trace/BUILD.gn
+++ b/protos/perfetto/trace/BUILD.gn
@@ -33,6 +33,7 @@
"trace.proto",
"extension_descriptor.proto",
"memory_graph.proto",
+ "ui_state.proto",
]
proto_sources_minimal = [
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 4d0d946..ae2b46c 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -8541,6 +8541,13 @@
// End of protos/perfetto/trace/trigger.proto
+// Begin of protos/perfetto/trace/ui_state.proto
+
+// TODO(lalitm): this will be filled in later with definition from
+// go/trace-ui-state.
+message UiState {}
+// End of protos/perfetto/trace/ui_state.proto
+
// Begin of protos/perfetto/trace/trace_packet.proto
// TracePacket is the root object of a Perfeto trace.
@@ -8563,7 +8570,7 @@
// See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
//
// Next reserved id: 14 (up to 15).
-// Next id: 78.
+// Next id: 79.
message TracePacket {
// The timestamp of the TracePacket.
// By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -8624,6 +8631,7 @@
MemoryTrackerSnapshot memory_tracker_snapshot = 73;
FrameTimelineEvent frame_timeline_event = 76;
AndroidEnergyEstimationBreakdown android_energy_estimation_breakdown = 77;
+ UiState ui_state = 78;
// Only used in profile packets.
ProfiledFrameSymbols profiled_frame_symbols = 55;
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index 0924313..2428427 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -61,6 +61,7 @@
import "protos/perfetto/trace/track_event/track_event.proto";
import "protos/perfetto/trace/trigger.proto";
import "protos/perfetto/trace/test_event.proto";
+import "protos/perfetto/trace/ui_state.proto";
package perfetto.protos;
@@ -84,7 +85,7 @@
// See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
//
// Next reserved id: 14 (up to 15).
-// Next id: 78.
+// Next id: 79.
message TracePacket {
// The timestamp of the TracePacket.
// By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -145,6 +146,7 @@
MemoryTrackerSnapshot memory_tracker_snapshot = 73;
FrameTimelineEvent frame_timeline_event = 76;
AndroidEnergyEstimationBreakdown android_energy_estimation_breakdown = 77;
+ UiState ui_state = 78;
// Only used in profile packets.
ProfiledFrameSymbols profiled_frame_symbols = 55;
diff --git a/protos/perfetto/trace/ui_state.proto b/protos/perfetto/trace/ui_state.proto
new file mode 100644
index 0000000..0e50a6e
--- /dev/null
+++ b/protos/perfetto/trace/ui_state.proto
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+syntax = "proto2";
+
+package perfetto.protos;
+
+// TODO(lalitm): this will be filled in later with definition from
+// go/trace-ui-state.
+message UiState {}
\ No newline at end of file
diff --git a/src/base/string_utils.cc b/src/base/string_utils.cc
index 483f720..ac3b16b 100644
--- a/src/base/string_utils.cc
+++ b/src/base/string_utils.cc
@@ -30,6 +30,11 @@
namespace perfetto {
namespace base {
+namespace {
+constexpr char kBase64Table[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz0123456789+/";
+}
// Locale-independant as possible version of strtod.
double StrToD(const char* nptr, char** endptr) {
@@ -234,5 +239,43 @@
return idx == std::string::npos ? str : str.substr(idx);
}
+std::string Base64Encode(const void* raw, size_t size) {
+ // The following three cases are based on the tables in the example
+ // section in https://en.wikipedia.org/wiki/Base64. We process three
+ // input bytes at a time, emitting 4 output bytes at a time.
+ const uint8_t* ptr = static_cast<const uint8_t*>(raw);
+ size_t ii = 0;
+
+ std::string out;
+ out.reserve((size + 2) * 4 / 3);
+
+ // While possible, process three input bytes.
+ for (; ii + 3 <= size; ii += 3) {
+ uint32_t twentyfour_bits =
+ (uint32_t(ptr[ii]) << 16) | (uint32_t(ptr[ii + 1]) << 8) | ptr[ii + 2];
+ out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
+ out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
+ out.push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
+ out.push_back(kBase64Table[twentyfour_bits & 0x3f]);
+ }
+ if (ii + 2 <= size) { // Process two input bytes.
+ uint32_t twentyfour_bits =
+ (uint32_t(ptr[ii]) << 16) | (uint32_t(ptr[ii + 1]) << 8);
+ out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
+ out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
+ out.push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
+ out.push_back('='); // Emit padding.
+ return out;
+ }
+ if (ii + 1 <= size) { // Process a single input byte.
+ uint32_t twentyfour_bits = (uint32_t(ptr[ii]) << 16);
+ out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
+ out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
+ out.push_back('='); // Emit padding.
+ out.push_back('='); // Emit padding.
+ }
+ return out;
+}
+
} // namespace base
} // namespace perfetto
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index e5164ea..51e2038 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -97,6 +97,8 @@
"importers/proto/memory_tracker_snapshot_module.h",
"importers/proto/memory_tracker_snapshot_parser.cc",
"importers/proto/memory_tracker_snapshot_parser.h",
+ "importers/proto/metadata_module.cc",
+ "importers/proto/metadata_module.h",
"importers/proto/metadata_tracker.cc",
"importers/proto/metadata_tracker.h",
"importers/proto/packet_sequence_state.cc",
diff --git a/src/trace_processor/importers/default_modules.cc b/src/trace_processor/importers/default_modules.cc
index 9e47ddc..19345cf 100644
--- a/src/trace_processor/importers/default_modules.cc
+++ b/src/trace_processor/importers/default_modules.cc
@@ -18,6 +18,7 @@
#include "src/trace_processor/importers/ftrace/ftrace_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"
#include "src/trace_processor/importers/proto/profile_module.h"
#include "src/trace_processor/importers/proto/proto_importer_module.h"
#include "src/trace_processor/importers/proto/track_event_module.h"
@@ -36,6 +37,7 @@
context->modules.emplace_back(new ChromeSystemProbesModule(context));
context->modules.emplace_back(new TrackEventModule(context));
context->modules.emplace_back(new ProfileModule(context));
+ context->modules.emplace_back(new MetadataModule(context));
}
} // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/metadata_module.cc b/src/trace_processor/importers/proto/metadata_module.cc
new file mode 100644
index 0000000..2055261
--- /dev/null
+++ b/src/trace_processor/importers/proto/metadata_module.cc
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 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/metadata_module.h"
+
+#include "perfetto/ext/base/string_utils.h"
+#include "src/trace_processor/importers/proto/metadata_tracker.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+using perfetto::protos::pbzero::TracePacket;
+
+MetadataModule::MetadataModule(TraceProcessorContext* context)
+ : context_(context) {
+ RegisterForField(TracePacket::kUiStateFieldNumber, context);
+}
+
+ModuleResult MetadataModule::TokenizePacket(
+ const protos::pbzero::TracePacket::Decoder& decoder,
+ TraceBlobView*,
+ int64_t,
+ PacketSequenceState*,
+ uint32_t field_id) {
+ switch (field_id) {
+ // TODO(lalitm): move other metadata field parsing here.
+ case TracePacket::kUiStateFieldNumber: {
+ auto ui_state = decoder.ui_state();
+ std::string base64 = base::Base64Encode(ui_state.data, ui_state.size);
+ StringId id = context_->storage->InternString(base::StringView(base64));
+ context_->metadata_tracker->SetMetadata(metadata::ui_state,
+ Variadic::String(id));
+ return ModuleResult::Handled();
+ }
+ }
+ return ModuleResult::Ignored();
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/metadata_module.h b/src/trace_processor/importers/proto/metadata_module.h
new file mode 100644
index 0000000..5182783
--- /dev/null
+++ b/src/trace_processor/importers/proto/metadata_module.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 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_METADATA_MODULE_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_METADATA_MODULE_H_
+
+#include "perfetto/base/build_config.h"
+#include "src/trace_processor/importers/proto/heap_graph_tracker.h"
+#include "src/trace_processor/importers/proto/proto_importer_module.h"
+#include "src/trace_processor/timestamped_trace_piece.h"
+
+#include "protos/perfetto/trace/profiling/deobfuscation.pbzero.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class MetadataModule : public ProtoImporterModule {
+ public:
+ explicit MetadataModule(TraceProcessorContext* context);
+
+ ModuleResult TokenizePacket(
+ const protos::pbzero::TracePacket::Decoder& decoder,
+ TraceBlobView* packet,
+ int64_t packet_timestamp,
+ PacketSequenceState* state,
+ uint32_t field_id) override;
+
+ private:
+ TraceProcessorContext* context_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_METADATA_MODULE_H_
diff --git a/src/trace_processor/storage/metadata.h b/src/trace_processor/storage/metadata.h
index 4f8df9d..ba68793 100644
--- a/src/trace_processor/storage/metadata.h
+++ b/src/trace_processor/storage/metadata.h
@@ -50,7 +50,8 @@
F(all_data_source_started_ns, KeyType::kSingle, Variadic::kInt), \
F(tracing_started_ns, KeyType::kSingle, Variadic::kInt), \
F(tracing_disabled_ns, KeyType::kSingle, Variadic::kInt), \
- F(trace_config_pbtxt, KeyType::kSingle, Variadic::kString)
+ F(trace_config_pbtxt, KeyType::kSingle, Variadic::kString), \
+ F(ui_state, KeyType::kSingle, Variadic::kString)
// clang-format on
// Compile time list of metadata items.