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