xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/proto/winscope/winscope_module.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2023 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/winscope/winscope_module.h"
18 #include "perfetto/ext/base/base64.h"
19 #include "protos/perfetto/trace/android/winscope_extensions.pbzero.h"
20 #include "protos/perfetto/trace/android/winscope_extensions_impl.pbzero.h"
21 #include "src/trace_processor/importers/proto/args_parser.h"
22 #include "src/trace_processor/importers/proto/winscope/viewcapture_args_parser.h"
23 #include "src/trace_processor/importers/proto/winscope/winscope.descriptor.h"
24 #include "src/trace_processor/util/winscope_proto_mapping.h"
25 
26 namespace perfetto {
27 namespace trace_processor {
28 
29 using perfetto::protos::pbzero::TracePacket;
30 using perfetto::protos::pbzero::WinscopeExtensionsImpl;
31 
WinscopeModule(TraceProcessorContext * context)32 WinscopeModule::WinscopeModule(TraceProcessorContext* context)
33     : context_{context},
34       args_parser_{*context->descriptor_pool_.get()},
35       surfaceflinger_layers_parser_(context),
36       surfaceflinger_transactions_parser_(context),
37       shell_transitions_parser_(context),
38       protolog_parser_(context),
39       android_input_event_parser_(context) {
40   context->descriptor_pool_->AddFromFileDescriptorSet(
41       kWinscopeDescriptor.data(), kWinscopeDescriptor.size());
42   RegisterForField(TracePacket::kSurfaceflingerLayersSnapshotFieldNumber,
43                    context);
44   RegisterForField(TracePacket::kSurfaceflingerTransactionsFieldNumber,
45                    context);
46   RegisterForField(TracePacket::kShellTransitionFieldNumber, context);
47   RegisterForField(TracePacket::kShellHandlerMappingsFieldNumber, context);
48   RegisterForField(TracePacket::kProtologMessageFieldNumber, context);
49   RegisterForField(TracePacket::kProtologViewerConfigFieldNumber, context);
50   RegisterForField(TracePacket::kWinscopeExtensionsFieldNumber, context);
51 }
52 
TokenizePacket(const protos::pbzero::TracePacket::Decoder & decoder,TraceBlobView *,int64_t,RefPtr<PacketSequenceStateGeneration>,uint32_t field_id)53 ModuleResult WinscopeModule::TokenizePacket(
54     const protos::pbzero::TracePacket::Decoder& decoder,
55     TraceBlobView* /*packet*/,
56     int64_t /*packet_timestamp*/,
57     RefPtr<PacketSequenceStateGeneration> /*state*/,
58     uint32_t field_id) {
59 
60   switch (field_id) {
61     case TracePacket::kProtologViewerConfigFieldNumber:
62       protolog_parser_.ParseAndAddViewerConfigToMessageDecoder(
63           decoder.protolog_viewer_config());
64       return ModuleResult::Handled();
65   }
66 
67   return ModuleResult::Ignored();
68 }
69 
ParseTracePacketData(const TracePacket::Decoder & decoder,int64_t timestamp,const TracePacketData & data,uint32_t field_id)70 void WinscopeModule::ParseTracePacketData(const TracePacket::Decoder& decoder,
71                                           int64_t timestamp,
72                                           const TracePacketData& data,
73                                           uint32_t field_id) {
74   switch (field_id) {
75     case TracePacket::kSurfaceflingerLayersSnapshotFieldNumber:
76       surfaceflinger_layers_parser_.Parse(
77           timestamp, decoder.surfaceflinger_layers_snapshot());
78       return;
79     case TracePacket::kSurfaceflingerTransactionsFieldNumber:
80       surfaceflinger_transactions_parser_.Parse(
81           timestamp, decoder.surfaceflinger_transactions());
82       return;
83     case TracePacket::kShellTransitionFieldNumber:
84       shell_transitions_parser_.ParseTransition(decoder.shell_transition());
85       return;
86     case TracePacket::kShellHandlerMappingsFieldNumber:
87       shell_transitions_parser_.ParseHandlerMappings(
88           decoder.shell_handler_mappings());
89       return;
90     case TracePacket::kProtologMessageFieldNumber:
91       protolog_parser_.ParseProtoLogMessage(
92           data.sequence_state.get(), decoder.protolog_message(), timestamp);
93       return;
94     case TracePacket::kWinscopeExtensionsFieldNumber:
95       ParseWinscopeExtensionsData(decoder.winscope_extensions(), timestamp,
96                                   data);
97       return;
98   }
99 }
100 
ParseWinscopeExtensionsData(protozero::ConstBytes blob,int64_t timestamp,const TracePacketData & data)101 void WinscopeModule::ParseWinscopeExtensionsData(protozero::ConstBytes blob,
102                                                  int64_t timestamp,
103                                                  const TracePacketData& data) {
104   WinscopeExtensionsImpl::Decoder decoder(blob.data, blob.size);
105 
106   if (auto field =
107           decoder.Get(WinscopeExtensionsImpl::kInputmethodClientsFieldNumber);
108       field.valid()) {
109     ParseInputMethodClientsData(timestamp, field.as_bytes());
110   } else if (field = decoder.Get(
111                  WinscopeExtensionsImpl::kInputmethodManagerServiceFieldNumber);
112              field.valid()) {
113     ParseInputMethodManagerServiceData(timestamp, field.as_bytes());
114   } else if (field = decoder.Get(
115                  WinscopeExtensionsImpl::kInputmethodServiceFieldNumber);
116              field.valid()) {
117     ParseInputMethodServiceData(timestamp, field.as_bytes());
118   } else if (field =
119                  decoder.Get(WinscopeExtensionsImpl::kViewcaptureFieldNumber);
120              field.valid()) {
121     ParseViewCaptureData(timestamp, field.as_bytes(),
122                          data.sequence_state.get());
123   } else if (field = decoder.Get(
124                  WinscopeExtensionsImpl::kAndroidInputEventFieldNumber);
125              field.valid()) {
126     android_input_event_parser_.ParseAndroidInputEvent(timestamp,
127                                                        field.as_bytes());
128   } else if (field =
129                  decoder.Get(WinscopeExtensionsImpl::kWindowmanagerFieldNumber);
130              field.valid()) {
131     ParseWindowManagerData(timestamp, field.as_bytes());
132   }
133 }
134 
ParseInputMethodClientsData(int64_t timestamp,protozero::ConstBytes blob)135 void WinscopeModule::ParseInputMethodClientsData(int64_t timestamp,
136                                                  protozero::ConstBytes blob) {
137   tables::InputMethodClientsTable::Row row;
138   row.ts = timestamp;
139   row.base64_proto = context_->storage->mutable_string_pool()->InternString(
140       base::StringView(base::Base64Encode(blob.data, blob.size)));
141   row.base64_proto_id = row.base64_proto.raw_id();
142   auto rowId =
143       context_->storage->mutable_inputmethod_clients_table()->Insert(row).id;
144 
145   ArgsTracker tracker(context_);
146   auto inserter = tracker.AddArgsTo(rowId);
147   ArgsParser writer(timestamp, inserter, *context_->storage.get());
148   base::Status status =
149       args_parser_.ParseMessage(blob,
150                                 *util::winscope_proto_mapping::GetProtoName(
151                                     tables::InputMethodClientsTable::Name()),
152                                 nullptr /* parse all fields */, writer);
153   if (!status.ok()) {
154     context_->storage->IncrementStats(
155         stats::winscope_inputmethod_clients_parse_errors);
156   }
157 }
158 
ParseInputMethodManagerServiceData(int64_t timestamp,protozero::ConstBytes blob)159 void WinscopeModule::ParseInputMethodManagerServiceData(
160     int64_t timestamp,
161     protozero::ConstBytes blob) {
162   tables::InputMethodManagerServiceTable::Row row;
163   row.ts = timestamp;
164   row.base64_proto = context_->storage->mutable_string_pool()->InternString(
165       base::StringView(base::Base64Encode(blob.data, blob.size)));
166   row.base64_proto_id = row.base64_proto.raw_id();
167   auto rowId = context_->storage->mutable_inputmethod_manager_service_table()
168                    ->Insert(row)
169                    .id;
170 
171   ArgsTracker tracker(context_);
172   auto inserter = tracker.AddArgsTo(rowId);
173   ArgsParser writer(timestamp, inserter, *context_->storage.get());
174   base::Status status = args_parser_.ParseMessage(
175       blob,
176       *util::winscope_proto_mapping::GetProtoName(
177           tables::InputMethodManagerServiceTable::Name()),
178       nullptr /* parse all fields */, writer);
179   if (!status.ok()) {
180     context_->storage->IncrementStats(
181         stats::winscope_inputmethod_manager_service_parse_errors);
182   }
183 }
184 
ParseInputMethodServiceData(int64_t timestamp,protozero::ConstBytes blob)185 void WinscopeModule::ParseInputMethodServiceData(int64_t timestamp,
186                                                  protozero::ConstBytes blob) {
187   tables::InputMethodServiceTable::Row row;
188   row.ts = timestamp;
189   row.base64_proto = context_->storage->mutable_string_pool()->InternString(
190       base::StringView(base::Base64Encode(blob.data, blob.size)));
191   row.base64_proto_id = row.base64_proto.raw_id();
192   auto rowId =
193       context_->storage->mutable_inputmethod_service_table()->Insert(row).id;
194 
195   ArgsTracker tracker(context_);
196   auto inserter = tracker.AddArgsTo(rowId);
197   ArgsParser writer(timestamp, inserter, *context_->storage.get());
198   base::Status status =
199       args_parser_.ParseMessage(blob,
200                                 *util::winscope_proto_mapping::GetProtoName(
201                                     tables::InputMethodServiceTable::Name()),
202                                 nullptr /* parse all fields */, writer);
203   if (!status.ok()) {
204     context_->storage->IncrementStats(
205         stats::winscope_inputmethod_service_parse_errors);
206   }
207 }
208 
ParseViewCaptureData(int64_t timestamp,protozero::ConstBytes blob,PacketSequenceStateGeneration * sequence_state)209 void WinscopeModule::ParseViewCaptureData(
210     int64_t timestamp,
211     protozero::ConstBytes blob,
212     PacketSequenceStateGeneration* sequence_state) {
213   tables::ViewCaptureTable::Row row;
214   row.ts = timestamp;
215   row.base64_proto = context_->storage->mutable_string_pool()->InternString(
216       base::StringView(base::Base64Encode(blob.data, blob.size)));
217   row.base64_proto_id = row.base64_proto.raw_id();
218   auto rowId = context_->storage->mutable_viewcapture_table()->Insert(row).id;
219 
220   ArgsTracker tracker(context_);
221   auto inserter = tracker.AddArgsTo(rowId);
222   ViewCaptureArgsParser writer(timestamp, inserter, *context_->storage.get(),
223                                sequence_state);
224   base::Status status =
225       args_parser_.ParseMessage(blob,
226                                 *util::winscope_proto_mapping::GetProtoName(
227                                     tables::ViewCaptureTable::Name()),
228                                 nullptr /* parse all fields */, writer);
229   if (!status.ok()) {
230     context_->storage->IncrementStats(stats::winscope_viewcapture_parse_errors);
231   }
232 }
233 
ParseWindowManagerData(int64_t timestamp,protozero::ConstBytes blob)234 void WinscopeModule::ParseWindowManagerData(int64_t timestamp,
235                                             protozero::ConstBytes blob) {
236   tables::WindowManagerTable::Row row;
237   row.ts = timestamp;
238   row.base64_proto = context_->storage->mutable_string_pool()->InternString(
239       base::StringView(base::Base64Encode(blob.data, blob.size)));
240   row.base64_proto_id = row.base64_proto.raw_id();
241   auto rowId = context_->storage->mutable_windowmanager_table()->Insert(row).id;
242 
243   ArgsTracker tracker(context_);
244   auto inserter = tracker.AddArgsTo(rowId);
245   ArgsParser writer(timestamp, inserter, *context_->storage.get());
246   base::Status status =
247       args_parser_.ParseMessage(blob,
248                                 *util::winscope_proto_mapping::GetProtoName(
249                                     tables::WindowManagerTable::Name()),
250                                 nullptr /* parse all fields */, writer);
251   if (!status.ok()) {
252     context_->storage->IncrementStats(
253         stats::winscope_windowmanager_parse_errors);
254   }
255 }
256 
257 }  // namespace trace_processor
258 }  // namespace perfetto
259