1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "src/trace_processor/importers/proto/metadata_minimal_module.h"
18
19 #include "perfetto/ext/base/base64.h"
20 #include "src/trace_processor/importers/common/metadata_tracker.h"
21 #include "src/trace_processor/types/trace_processor_context.h"
22
23 #include "protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h"
24 #include "protos/perfetto/trace/chrome/chrome_metadata.pbzero.h"
25
26 namespace perfetto {
27 namespace trace_processor {
28
29 using perfetto::protos::pbzero::TracePacket;
30
MetadataMinimalModule(TraceProcessorContext * context)31 MetadataMinimalModule::MetadataMinimalModule(TraceProcessorContext* context)
32 : context_(context) {
33 RegisterForField(TracePacket::kChromeMetadataFieldNumber, context);
34 RegisterForField(TracePacket::kChromeBenchmarkMetadataFieldNumber, context);
35 }
36
TokenizePacket(const protos::pbzero::TracePacket::Decoder & decoder,TraceBlobView *,int64_t,PacketSequenceState *,uint32_t field_id)37 ModuleResult MetadataMinimalModule::TokenizePacket(
38 const protos::pbzero::TracePacket::Decoder& decoder,
39 TraceBlobView*,
40 int64_t,
41 PacketSequenceState*,
42 uint32_t field_id) {
43 switch (field_id) {
44 case TracePacket::kChromeMetadataFieldNumber: {
45 ParseChromeMetadataPacket(decoder.chrome_metadata());
46 return ModuleResult::Handled();
47 }
48 case TracePacket::kChromeBenchmarkMetadataFieldNumber: {
49 ParseChromeBenchmarkMetadata(decoder.chrome_benchmark_metadata());
50 return ModuleResult::Handled();
51 }
52 }
53 return ModuleResult::Ignored();
54 }
55
ParseChromeBenchmarkMetadata(ConstBytes blob)56 void MetadataMinimalModule::ParseChromeBenchmarkMetadata(ConstBytes blob) {
57 TraceStorage* storage = context_->storage.get();
58 MetadataTracker* metadata = context_->metadata_tracker.get();
59
60 protos::pbzero::ChromeBenchmarkMetadata::Decoder packet(blob.data, blob.size);
61 if (packet.has_benchmark_name()) {
62 auto benchmark_name_id = storage->InternString(packet.benchmark_name());
63 metadata->SetMetadata(metadata::benchmark_name,
64 Variadic::String(benchmark_name_id));
65 }
66 if (packet.has_benchmark_description()) {
67 auto benchmark_description_id =
68 storage->InternString(packet.benchmark_description());
69 metadata->SetMetadata(metadata::benchmark_description,
70 Variadic::String(benchmark_description_id));
71 }
72 if (packet.has_label()) {
73 auto label_id = storage->InternString(packet.label());
74 metadata->SetMetadata(metadata::benchmark_label,
75 Variadic::String(label_id));
76 }
77 if (packet.has_story_name()) {
78 auto story_name_id = storage->InternString(packet.story_name());
79 metadata->SetMetadata(metadata::benchmark_story_name,
80 Variadic::String(story_name_id));
81 }
82 for (auto it = packet.story_tags(); it; ++it) {
83 auto story_tag_id = storage->InternString(*it);
84 metadata->AppendMetadata(metadata::benchmark_story_tags,
85 Variadic::String(story_tag_id));
86 }
87 if (packet.has_benchmark_start_time_us()) {
88 metadata->SetMetadata(metadata::benchmark_start_time_us,
89 Variadic::Integer(packet.benchmark_start_time_us()));
90 }
91 if (packet.has_story_run_time_us()) {
92 metadata->SetMetadata(metadata::benchmark_story_run_time_us,
93 Variadic::Integer(packet.story_run_time_us()));
94 }
95 if (packet.has_story_run_index()) {
96 metadata->SetMetadata(metadata::benchmark_story_run_index,
97 Variadic::Integer(packet.story_run_index()));
98 }
99 if (packet.has_had_failures()) {
100 metadata->SetMetadata(metadata::benchmark_had_failures,
101 Variadic::Integer(packet.had_failures()));
102 }
103 }
104
ParseChromeMetadataPacket(ConstBytes blob)105 void MetadataMinimalModule::ParseChromeMetadataPacket(ConstBytes blob) {
106 TraceStorage* storage = context_->storage.get();
107 MetadataTracker* metadata = context_->metadata_tracker.get();
108
109 // Typed chrome metadata proto. The untyped metadata is parsed below in
110 // ParseChromeEvents().
111 protos::pbzero::ChromeMetadataPacket::Decoder packet_decoder(blob.data,
112 blob.size);
113
114 if (packet_decoder.has_chrome_version_code()) {
115 metadata->SetDynamicMetadata(
116 storage->InternString("cr-playstore_version_code"),
117 Variadic::Integer(packet_decoder.chrome_version_code()));
118 }
119 if (packet_decoder.has_enabled_categories()) {
120 auto categories_id =
121 storage->InternString(packet_decoder.enabled_categories());
122 metadata->SetDynamicMetadata(storage->InternString("cr-enabled_categories"),
123 Variadic::String(categories_id));
124 }
125
126 if (packet_decoder.has_background_tracing_metadata()) {
127 auto background_tracing_metadata =
128 packet_decoder.background_tracing_metadata();
129
130 std::string base64 = base::Base64Encode(background_tracing_metadata.data,
131 background_tracing_metadata.size);
132 metadata->SetDynamicMetadata(
133 storage->InternString("cr-background_tracing_metadata"),
134 Variadic::String(storage->InternString(base::StringView(base64))));
135
136 protos::pbzero::BackgroundTracingMetadata::Decoder metadata_decoder(
137 background_tracing_metadata.data, background_tracing_metadata.size);
138 if (metadata_decoder.has_scenario_name_hash()) {
139 metadata->SetDynamicMetadata(
140 storage->InternString("cr-scenario_name_hash"),
141 Variadic::Integer(metadata_decoder.scenario_name_hash()));
142 }
143 auto triggered_rule = metadata_decoder.triggered_rule();
144 if (!metadata_decoder.has_triggered_rule())
145 return;
146 protos::pbzero::BackgroundTracingMetadata::TriggerRule::Decoder
147 triggered_rule_decoder(triggered_rule.data, triggered_rule.size);
148 if (!triggered_rule_decoder.has_name_hash())
149 return;
150 metadata->SetDynamicMetadata(
151 storage->InternString("cr-triggered_rule_name_hash"),
152 Variadic::Integer(triggered_rule_decoder.name_hash()));
153 }
154 }
155
156 } // namespace trace_processor
157 } // namespace perfetto
158