• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "protos/perfetto/trace/android/winscope_extensions.pbzero.h"
19 #include "protos/perfetto/trace/android/winscope_extensions_impl.pbzero.h"
20 #include "src/trace_processor/importers/proto/args_parser.h"
21 #include "src/trace_processor/importers/proto/winscope/viewcapture_args_parser.h"
22 #include "src/trace_processor/importers/proto/winscope/winscope.descriptor.h"
23 
24 namespace perfetto {
25 namespace trace_processor {
26 
27 using perfetto::protos::pbzero::TracePacket;
28 using perfetto::protos::pbzero::WinscopeExtensionsImpl;
29 
WinscopeModule(TraceProcessorContext * context)30 WinscopeModule::WinscopeModule(TraceProcessorContext* context)
31     : context_{context},
32       args_parser_{pool_},
33       surfaceflinger_layers_parser_(context),
34       surfaceflinger_transactions_parser_(context),
35       shell_transitions_parser_(context),
36       protolog_parser_(context),
37       android_input_event_parser_(context) {
38   RegisterForField(TracePacket::kSurfaceflingerLayersSnapshotFieldNumber,
39                    context);
40   RegisterForField(TracePacket::kSurfaceflingerTransactionsFieldNumber,
41                    context);
42   RegisterForField(TracePacket::kShellTransitionFieldNumber, context);
43   RegisterForField(TracePacket::kShellHandlerMappingsFieldNumber, context);
44   RegisterForField(TracePacket::kProtologMessageFieldNumber, context);
45   RegisterForField(TracePacket::kProtologViewerConfigFieldNumber, context);
46   RegisterForField(TracePacket::kWinscopeExtensionsFieldNumber, context);
47 
48   pool_.AddFromFileDescriptorSet(kWinscopeDescriptor.data(),
49                                  kWinscopeDescriptor.size());
50 }
51 
ParseTracePacketData(const TracePacket::Decoder & decoder,int64_t timestamp,const TracePacketData & data,uint32_t field_id)52 void WinscopeModule::ParseTracePacketData(const TracePacket::Decoder& decoder,
53                                           int64_t timestamp,
54                                           const TracePacketData& data,
55                                           uint32_t field_id) {
56   switch (field_id) {
57     case TracePacket::kSurfaceflingerLayersSnapshotFieldNumber:
58       surfaceflinger_layers_parser_.Parse(
59           timestamp, decoder.surfaceflinger_layers_snapshot());
60       return;
61     case TracePacket::kSurfaceflingerTransactionsFieldNumber:
62       surfaceflinger_transactions_parser_.Parse(
63           timestamp, decoder.surfaceflinger_transactions());
64       return;
65     case TracePacket::kShellTransitionFieldNumber:
66       shell_transitions_parser_.ParseTransition(decoder.shell_transition());
67       return;
68     case TracePacket::kShellHandlerMappingsFieldNumber:
69       shell_transitions_parser_.ParseHandlerMappings(
70           decoder.shell_handler_mappings());
71       return;
72     case TracePacket::kProtologMessageFieldNumber:
73       protolog_parser_.ParseProtoLogMessage(
74           data.sequence_state.get(), decoder.protolog_message(), timestamp);
75       return;
76     case TracePacket::kProtologViewerConfigFieldNumber:
77       protolog_parser_.ParseProtoLogViewerConfig(
78           decoder.protolog_viewer_config());
79       return;
80     case TracePacket::kWinscopeExtensionsFieldNumber:
81       ParseWinscopeExtensionsData(decoder.winscope_extensions(), timestamp,
82                                   data);
83       return;
84   }
85 }
86 
ParseWinscopeExtensionsData(protozero::ConstBytes blob,int64_t timestamp,const TracePacketData & data)87 void WinscopeModule::ParseWinscopeExtensionsData(protozero::ConstBytes blob,
88                                                  int64_t timestamp,
89                                                  const TracePacketData& data) {
90   WinscopeExtensionsImpl::Decoder decoder(blob.data, blob.size);
91 
92   if (auto field =
93           decoder.Get(WinscopeExtensionsImpl::kInputmethodClientsFieldNumber);
94       field.valid()) {
95     ParseInputMethodClientsData(timestamp, field.as_bytes());
96   } else if (field = decoder.Get(
97                  WinscopeExtensionsImpl::kInputmethodManagerServiceFieldNumber);
98              field.valid()) {
99     ParseInputMethodManagerServiceData(timestamp, field.as_bytes());
100   } else if (field = decoder.Get(
101                  WinscopeExtensionsImpl::kInputmethodServiceFieldNumber);
102              field.valid()) {
103     ParseInputMethodServiceData(timestamp, field.as_bytes());
104   } else if (field =
105                  decoder.Get(WinscopeExtensionsImpl::kViewcaptureFieldNumber);
106              field.valid()) {
107     ParseViewCaptureData(timestamp, field.as_bytes(),
108                          data.sequence_state.get());
109   } else if (field = decoder.Get(
110                  WinscopeExtensionsImpl::kAndroidInputEventFieldNumber);
111              field.valid()) {
112     android_input_event_parser_.ParseAndroidInputEvent(timestamp,
113                                                        field.as_bytes());
114   }
115 }
116 
ParseInputMethodClientsData(int64_t timestamp,protozero::ConstBytes blob)117 void WinscopeModule::ParseInputMethodClientsData(int64_t timestamp,
118                                                  protozero::ConstBytes blob) {
119   tables::InputMethodClientsTable::Row row;
120   row.ts = timestamp;
121   auto rowId =
122       context_->storage->mutable_inputmethod_clients_table()->Insert(row).id;
123 
124   ArgsTracker tracker(context_);
125   auto inserter = tracker.AddArgsTo(rowId);
126   ArgsParser writer(timestamp, inserter, *context_->storage.get());
127   base::Status status =
128       args_parser_.ParseMessage(blob, kInputMethodClientsProtoName,
129                                 nullptr /* parse all fields */, writer);
130   if (!status.ok()) {
131     context_->storage->IncrementStats(
132         stats::winscope_inputmethod_clients_parse_errors);
133   }
134 }
135 
ParseInputMethodManagerServiceData(int64_t timestamp,protozero::ConstBytes blob)136 void WinscopeModule::ParseInputMethodManagerServiceData(
137     int64_t timestamp,
138     protozero::ConstBytes blob) {
139   tables::InputMethodManagerServiceTable::Row row;
140   row.ts = timestamp;
141   auto rowId = context_->storage->mutable_inputmethod_manager_service_table()
142                    ->Insert(row)
143                    .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, kInputMethodManagerServiceProtoName,
150                                 nullptr /* parse all fields */, writer);
151   if (!status.ok()) {
152     context_->storage->IncrementStats(
153         stats::winscope_inputmethod_manager_service_parse_errors);
154   }
155 }
156 
ParseInputMethodServiceData(int64_t timestamp,protozero::ConstBytes blob)157 void WinscopeModule::ParseInputMethodServiceData(int64_t timestamp,
158                                                  protozero::ConstBytes blob) {
159   tables::InputMethodServiceTable::Row row;
160   row.ts = timestamp;
161   auto rowId =
162       context_->storage->mutable_inputmethod_service_table()->Insert(row).id;
163 
164   ArgsTracker tracker(context_);
165   auto inserter = tracker.AddArgsTo(rowId);
166   ArgsParser writer(timestamp, inserter, *context_->storage.get());
167   base::Status status =
168       args_parser_.ParseMessage(blob, kInputMethodServiceProtoName,
169                                 nullptr /* parse all fields */, writer);
170   if (!status.ok()) {
171     context_->storage->IncrementStats(
172         stats::winscope_inputmethod_service_parse_errors);
173   }
174 }
175 
ParseViewCaptureData(int64_t timestamp,protozero::ConstBytes blob,PacketSequenceStateGeneration * sequence_state)176 void WinscopeModule::ParseViewCaptureData(
177     int64_t timestamp,
178     protozero::ConstBytes blob,
179     PacketSequenceStateGeneration* sequence_state) {
180   tables::ViewCaptureTable::Row row;
181   row.ts = timestamp;
182   auto rowId = context_->storage->mutable_viewcapture_table()->Insert(row).id;
183 
184   ArgsTracker tracker(context_);
185   auto inserter = tracker.AddArgsTo(rowId);
186   ViewCaptureArgsParser writer(timestamp, inserter, *context_->storage.get(),
187                                sequence_state);
188   base::Status status = args_parser_.ParseMessage(
189       blob, kViewCaptureProtoName, nullptr /* parse all fields */, writer);
190   if (!status.ok()) {
191     context_->storage->IncrementStats(stats::winscope_viewcapture_parse_errors);
192   }
193 }
194 
195 }  // namespace trace_processor
196 }  // namespace perfetto
197