• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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/android_input_event_parser.h"
18 
19 #include "protos/perfetto/trace/android/android_input_event.pbzero.h"
20 #include "src/trace_processor/importers/common/args_tracker.h"
21 #include "src/trace_processor/importers/proto/args_parser.h"
22 #include "src/trace_processor/importers/proto/winscope/winscope.descriptor.h"
23 #include "src/trace_processor/storage/trace_storage.h"
24 #include "src/trace_processor/tables/android_tables_py.h"
25 #include "src/trace_processor/types/trace_processor_context.h"
26 
27 namespace perfetto::trace_processor {
28 
29 using perfetto::protos::pbzero::AndroidInputEvent;
30 using perfetto::protos::pbzero::AndroidKeyEvent;
31 using perfetto::protos::pbzero::AndroidMotionEvent;
32 using perfetto::protos::pbzero::AndroidWindowInputDispatchEvent;
33 using perfetto::protos::pbzero::TracePacket;
34 
AndroidInputEventParser(TraceProcessorContext * context)35 AndroidInputEventParser::AndroidInputEventParser(TraceProcessorContext* context)
36     : context_(*context), args_parser_{pool_} {
37   pool_.AddFromFileDescriptorSet(kWinscopeDescriptor.data(),
38                                  kWinscopeDescriptor.size());
39 }
40 
ParseAndroidInputEvent(int64_t packet_ts,const protozero::ConstBytes & bytes)41 void AndroidInputEventParser::ParseAndroidInputEvent(
42     int64_t packet_ts,
43     const protozero::ConstBytes& bytes) {
44   auto input_event = AndroidInputEvent::Decoder(bytes);
45 
46   constexpr static auto supported_fields = std::array{
47       AndroidInputEvent::kDispatcherMotionEventFieldNumber,
48       AndroidInputEvent::kDispatcherMotionEventRedactedFieldNumber,
49       AndroidInputEvent::kDispatcherKeyEventFieldNumber,
50       AndroidInputEvent::kDispatcherKeyEventRedactedFieldNumber,
51       AndroidInputEvent::kDispatcherWindowDispatchEventFieldNumber,
52       AndroidInputEvent::kDispatcherWindowDispatchEventRedactedFieldNumber};
53 
54   for (auto sub_field_id : supported_fields) {
55     auto sub_field = input_event.Get(static_cast<uint32_t>(sub_field_id));
56     if (!sub_field.valid())
57       continue;
58 
59     switch (sub_field_id) {
60       case AndroidInputEvent::kDispatcherMotionEventFieldNumber:
61       case AndroidInputEvent::kDispatcherMotionEventRedactedFieldNumber:
62         ParseMotionEvent(packet_ts, sub_field.as_bytes());
63         return;
64       case AndroidInputEvent::kDispatcherKeyEventFieldNumber:
65       case AndroidInputEvent::kDispatcherKeyEventRedactedFieldNumber:
66         ParseKeyEvent(packet_ts, sub_field.as_bytes());
67         return;
68       case AndroidInputEvent::kDispatcherWindowDispatchEventFieldNumber:
69       case AndroidInputEvent::kDispatcherWindowDispatchEventRedactedFieldNumber:
70         ParseWindowDispatchEvent(packet_ts, sub_field.as_bytes());
71         return;
72     }
73   }
74 }
75 
ParseMotionEvent(int64_t packet_ts,const protozero::ConstBytes & bytes)76 void AndroidInputEventParser::ParseMotionEvent(
77     int64_t packet_ts,
78     const protozero::ConstBytes& bytes) {
79   AndroidMotionEvent::Decoder event_proto(bytes);
80   tables::AndroidMotionEventsTable::Row event_row;
81   event_row.event_id = event_proto.event_id();
82   event_row.ts = packet_ts;
83 
84   auto event_row_id = context_.storage->mutable_android_motion_events_table()
85                           ->Insert(event_row)
86                           .id;
87   auto inserter = context_.args_tracker->AddArgsTo(event_row_id);
88   ArgsParser writer{packet_ts, inserter, *context_.storage};
89 
90   base::Status status =
91       args_parser_.ParseMessage(bytes, ".perfetto.protos.AndroidMotionEvent",
92                                 nullptr /*parse all fields*/, writer);
93   if (!status.ok())
94     context_.storage->IncrementStats(stats::android_input_event_parse_errors);
95 }
96 
ParseKeyEvent(int64_t packet_ts,const protozero::ConstBytes & bytes)97 void AndroidInputEventParser::ParseKeyEvent(
98     int64_t packet_ts,
99     const protozero::ConstBytes& bytes) {
100   AndroidKeyEvent::Decoder event_proto(bytes);
101   tables::AndroidKeyEventsTable::Row event_row;
102   event_row.event_id = event_proto.event_id();
103   event_row.ts = packet_ts;
104 
105   auto event_row_id = context_.storage->mutable_android_key_events_table()
106                           ->Insert(event_row)
107                           .id;
108   auto inserter = context_.args_tracker->AddArgsTo(event_row_id);
109   ArgsParser writer{packet_ts, inserter, *context_.storage};
110 
111   base::Status status =
112       args_parser_.ParseMessage(bytes, ".perfetto.protos.AndroidKeyEvent",
113                                 nullptr /*parse all fields*/, writer);
114   if (!status.ok())
115     context_.storage->IncrementStats(stats::android_input_event_parse_errors);
116 }
117 
ParseWindowDispatchEvent(int64_t packet_ts,const protozero::ConstBytes & bytes)118 void AndroidInputEventParser::ParseWindowDispatchEvent(
119     int64_t packet_ts,
120     const protozero::ConstBytes& bytes) {
121   AndroidWindowInputDispatchEvent::Decoder event_proto(bytes);
122   tables::AndroidInputEventDispatchTable::Row event_row;
123   event_row.event_id = event_proto.event_id();
124   event_row.vsync_id = event_proto.vsync_id();
125   event_row.window_id = event_proto.window_id();
126 
127   auto event_row_id =
128       context_.storage->mutable_android_input_event_dispatch_table()
129           ->Insert(event_row)
130           .id;
131   auto inserter = context_.args_tracker->AddArgsTo(event_row_id);
132   ArgsParser writer{packet_ts, inserter, *context_.storage};
133 
134   base::Status status = args_parser_.ParseMessage(
135       bytes, ".perfetto.protos.AndroidWindowInputDispatchEvent",
136       nullptr /*parse all fields*/, writer);
137   if (!status.ok())
138     context_.storage->IncrementStats(stats::android_input_event_parse_errors);
139 }
140 
141 }  // namespace perfetto::trace_processor
142