1-- 2-- Copyright 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-- https://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 16INCLUDE PERFETTO MODULE android.frames.timeline; 17INCLUDE PERFETTO MODULE slices.with_context; 18 19CREATE PERFETTO TABLE _input_message_sent 20AS 21SELECT 22 STR_SPLIT(STR_SPLIT(slice.name, '=', 3), ')', 0) AS event_type, 23 STR_SPLIT(STR_SPLIT(slice.name, '=', 2), ',', 0) AS event_seq, 24 STR_SPLIT(STR_SPLIT(slice.name, '=', 1), ',', 0) AS event_channel, 25 thread.tid, 26 thread.name AS thread_name, 27 process.pid, 28 process.name AS process_name, 29 slice.ts, 30 slice.dur, 31 slice.track_id 32FROM slice 33JOIN thread_track 34 ON thread_track.id = slice.track_id 35JOIN thread 36 USING (utid) 37JOIN process 38 USING (upid) 39WHERE slice.name GLOB 'sendMessage(*' 40order by event_seq; 41 42CREATE PERFETTO TABLE _input_message_received 43AS 44SELECT 45 STR_SPLIT(STR_SPLIT(slice.name, '=', 3), ')', 0) AS event_type, 46 STR_SPLIT(STR_SPLIT(slice.name, '=', 2), ',', 0) AS event_seq, 47 STR_SPLIT(STR_SPLIT(slice.name, '=', 1), ',', 0) AS event_channel, 48 thread.tid, 49 thread.name AS thread_name, 50 process.pid, 51 process.name AS process_name, 52 slice.ts, 53 slice.dur, 54 slice.track_id 55FROM slice 56JOIN thread_track 57 ON thread_track.id = slice.track_id 58JOIN thread 59 USING (utid) 60JOIN process 61 USING (upid) 62WHERE slice.name GLOB 'receiveMessage(*' 63ORDER BY event_seq; 64 65CREATE PERFETTO TABLE _input_read_time 66AS 67SELECT 68 name, 69 STR_SPLIT(STR_SPLIT(name, '=', 1), ')', 0) AS input_event_id, 70 ts as read_time 71FROM slice 72WHERE name GLOB 'UnwantedInteractionBlocker::notifyMotion*'; 73 74CREATE PERFETTO TABLE _event_seq_to_input_event_id 75AS 76SELECT 77 STR_SPLIT(STR_SPLIT(send_message_slice.name, '=', 2), ',', 0) AS event_seq, 78 STR_SPLIT(STR_SPLIT(send_message_slice.name, '=', 1), ',', 0) AS event_channel, 79 STR_SPLIT(STR_SPLIT(enqeue_slice.name, '=', 2), ')', 0) AS input_event_id, 80 thread_slice.thread_name 81FROM slice send_message_slice 82JOIN slice publish_slice 83 ON send_message_slice.parent_id = publish_slice.id 84JOIN slice start_dispatch_slice 85 ON publish_slice.parent_id = start_dispatch_slice.id 86JOIN slice enqeue_slice 87 ON start_dispatch_slice.parent_id = enqeue_slice.id 88JOIN thread_slice 89 ON send_message_slice.id = thread_slice.id 90WHERE send_message_slice.name GLOB 'sendMessage(*' AND thread_slice.thread_name = 'InputDispatcher'; 91 92CREATE PERFETTO TABLE _input_event_id_to_android_frame 93AS 94SELECT 95 STR_SPLIT(deliver_input_slice.name, '=', 3) AS input_event_id, 96 STR_SPLIT(STR_SPLIT(dispatch_input_slice.name, '_', 1), ' ', 0) AS event_action, 97 dispatch_input_slice.ts AS consume_time, 98 dispatch_input_slice.ts + dispatch_input_slice.dur AS finish_time, 99 thread_slice.utid, 100 thread_slice.process_name AS process_name, 101 ( 102 SELECT 103 android_frames.frame_id 104 FROM android_frames 105 WHERE android_frames.ts > dispatch_input_slice.ts 106 LIMIT 1 107 ) as frame_id, 108 ( 109 SELECT 110 android_frames.ts 111 FROM android_frames 112 WHERE android_frames.ts > dispatch_input_slice.ts 113 LIMIT 1 114 ) as ts, 115 ( 116 SELECT 117 _input_message_received.event_channel 118 FROM _input_message_received 119 WHERE _input_message_received.ts < deliver_input_slice.ts 120 AND _input_message_received.track_id = deliver_input_slice.track_id 121 ORDER BY _input_message_received.ts DESC 122 LIMIT 1 123 ) as event_channel 124FROM slice deliver_input_slice 125JOIN slice dispatch_input_slice 126 ON deliver_input_slice.parent_id = dispatch_input_slice.id 127JOIN thread_slice 128 ON deliver_input_slice.id = thread_slice.id 129WHERE deliver_input_slice.name GLOB 'deliverInputEvent src=*'; 130 131CREATE PERFETTO TABLE _app_frame_to_surface_flinger_frame 132AS 133SELECT 134 app.surface_frame_token as app_surface_frame_token, 135 surface_flinger.ts as surface_flinger_ts, 136 surface_flinger.dur as surface_flinger_dur, 137 app.ts as app_ts, 138 app.present_type, 139 app.upid 140FROM actual_frame_timeline_slice surface_flinger 141JOIN actual_frame_timeline_slice app 142 ON surface_flinger.display_frame_token = app.display_frame_token 143 AND surface_flinger.id != app.id 144WHERE surface_flinger.surface_frame_token = 0 AND app.present_type != 'Dropped Frame'; 145 146CREATE PERFETTO TABLE _first_non_dropped_frame_after_input 147AS 148SELECT 149 _input_read_time.input_event_id, 150 _input_read_time.read_time, 151 ( 152 SELECT 153 surface_flinger_ts + surface_flinger_dur 154 FROM _app_frame_to_surface_flinger_frame sf_frames 155 WHERE sf_frames.app_ts >= _input_event_id_to_android_frame.ts 156 LIMIT 1 157 ) AS present_time, 158 ( 159 SELECT 160 app_surface_frame_token 161 FROM _app_frame_to_surface_flinger_frame sf_frames 162 WHERE sf_frames.app_ts >= _input_event_id_to_android_frame.ts 163 LIMIT 1 164 ) as frame_id, 165 event_seq, 166 event_action 167FROM _input_event_id_to_android_frame 168RIGHT JOIN _event_seq_to_input_event_id 169 ON _input_event_id_to_android_frame.input_event_id = _event_seq_to_input_event_id.input_event_id 170 AND _input_event_id_to_android_frame.event_channel = _event_seq_to_input_event_id.event_channel 171JOIN _input_read_time 172 ON _input_read_time.input_event_id = _event_seq_to_input_event_id.input_event_id; 173 174-- All input events with round trip latency breakdown. Input delivery is socket based and every 175-- input event sent from the OS needs to be ACK'ed by the app. This gives us 4 subevents to measure 176-- latencies between: 177-- 1. Input dispatch event sent from OS. 178-- 2. Input dispatch event received in app. 179-- 3. Input ACK event sent from app. 180-- 4. Input ACk event received in OS. 181CREATE PERFETTO TABLE android_input_events ( 182 -- Duration from input dispatch to input received. 183 dispatch_latency_dur DURATION, 184 -- Duration from input received to input ACK sent. 185 handling_latency_dur DURATION, 186 -- Duration from input ACK sent to input ACK recieved. 187 ack_latency_dur DURATION, 188 -- Duration from input dispatch to input event ACK received. 189 total_latency_dur DURATION, 190 -- Duration from input read to frame present time. Null if an input event has no associated frame event. 191 end_to_end_latency_dur DURATION, 192 -- Tid of thread receiving the input event. 193 tid LONG, 194 -- Name of thread receiving the input event. 195 thread_name STRING, 196 -- Pid of process receiving the input event. 197 pid LONG, 198 -- Name of process receiving the input event. 199 process_name STRING, 200 -- Input event type. See InputTransport.h: InputMessage#Type 201 event_type STRING, 202 -- Input event action. 203 event_action STRING, 204 -- Input event sequence number, monotonically increasing for an event channel and pid. 205 event_seq STRING, 206 -- Input event channel name. 207 event_channel STRING, 208 -- Unique identifier for the input event. 209 input_event_id STRING, 210 -- Timestamp input event was read by InputReader. 211 read_time LONG, 212 -- Thread track id of input event dispatching thread. 213 dispatch_track_id JOINID(track.id), 214 -- Timestamp input event was dispatched. 215 dispatch_ts TIMESTAMP, 216 -- Duration of input event dispatch. 217 dispatch_dur DURATION, 218 -- Thread track id of input event receiving thread. 219 receive_track_id JOINID(track.id), 220 -- Timestamp input event was received. 221 receive_ts TIMESTAMP, 222 -- Duration of input event receipt. 223 receive_dur DURATION, 224 -- Vsync Id associated with the input. Null if an input event has no associated frame event. 225 frame_id LONG 226 ) 227AS 228WITH dispatch AS MATERIALIZED ( 229 SELECT * FROM _input_message_sent 230 WHERE thread_name = 'InputDispatcher' 231 ORDER BY event_seq, event_channel 232), 233receive AS MATERIALIZED ( 234 SELECT 235 *, 236 REPLACE(event_channel, '(client)', '(server)') AS dispatch_event_channel 237 FROM _input_message_received 238 WHERE event_type NOT IN ('0x2', 'FINISHED') 239 ORDER BY event_seq, dispatch_event_channel 240), 241finish AS MATERIALIZED ( 242 SELECT 243 *, 244 REPLACE(event_channel, '(client)', '(server)') AS dispatch_event_channel 245 FROM _input_message_sent 246 WHERE thread_name != 'InputDispatcher' 247 ORDER BY event_seq, dispatch_event_channel 248), 249finish_ack AS MATERIALIZED( 250 SELECT * FROM _input_message_received 251 WHERE event_type IN ('0x2', 'FINISHED') 252 ORDER BY event_seq, event_channel 253) 254SELECT 255 receive.ts - dispatch.ts AS dispatch_latency_dur, 256 finish.ts - receive.ts AS handling_latency_dur, 257 finish_ack.ts - finish.ts AS ack_latency_dur, 258 finish_ack.ts - dispatch.ts AS total_latency_dur, 259 frame.present_time - frame.read_time AS end_to_end_latency_dur, 260 finish.tid AS tid, 261 finish.thread_name AS thread_name, 262 finish.pid AS pid, 263 finish.process_name AS process_name, 264 dispatch.event_type, 265 frame.event_action, 266 dispatch.event_seq, 267 dispatch.event_channel, 268 frame.input_event_id, 269 frame.read_time, 270 dispatch.track_id AS dispatch_track_id, 271 dispatch.ts AS dispatch_ts, 272 dispatch.dur AS dispatch_dur, 273 receive.ts AS receive_ts, 274 receive.dur AS receive_dur, 275 receive.track_id AS receive_track_id, 276 frame.frame_id 277FROM dispatch 278JOIN receive 279 ON 280 receive.dispatch_event_channel = dispatch.event_channel 281 AND dispatch.event_seq = receive.event_seq 282JOIN finish 283 ON 284 finish.dispatch_event_channel = dispatch.event_channel 285 AND dispatch.event_seq = finish.event_seq 286JOIN finish_ack 287 ON 288 finish_ack.event_channel = dispatch.event_channel 289 AND dispatch.event_seq = finish_ack.event_seq 290LEFT JOIN _first_non_dropped_frame_after_input frame 291 ON frame.event_seq = dispatch.event_seq; 292 293-- Key events processed by the Android framework (from android.input.inputevent data source). 294CREATE PERFETTO VIEW android_key_events( 295 -- ID of the trace entry 296 id LONG, 297 -- The randomly-generated ID associated with each input event processed 298 -- by Android Framework, used to track the event through the input pipeline 299 event_id LONG, 300 -- The timestamp of when the input event was processed by the system 301 ts TIMESTAMP, 302 -- Details of the input event parsed from the proto message 303 arg_set_id ARGSETID, 304 -- Raw proto message encoded in base64 305 base64_proto STRING, 306 -- String id for raw proto message 307 base64_proto_id LONG 308) AS 309SELECT 310 id, 311 event_id, 312 ts, 313 arg_set_id, 314 base64_proto, 315 base64_proto_id 316FROM __intrinsic_android_key_events; 317 318-- Motion events processed by the Android framework (from android.input.inputevent data source). 319CREATE PERFETTO VIEW android_motion_events( 320 -- ID of the trace entry 321 id LONG, 322 -- The randomly-generated ID associated with each input event processed 323 -- by Android Framework, used to track the event through the input pipeline 324 event_id LONG, 325 -- The timestamp of when the input event was processed by the system 326 ts TIMESTAMP, 327 -- Details of the input event parsed from the proto message 328 arg_set_id ARGSETID, 329 -- Raw proto message encoded in base64 330 base64_proto STRING, 331 -- String id for raw proto message 332 base64_proto_id LONG 333) AS 334SELECT 335 id, 336 event_id, 337 ts, 338 arg_set_id, 339 base64_proto, 340 base64_proto_id 341FROM __intrinsic_android_motion_events; 342 343-- Input event dispatching information in Android (from android.input.inputevent data source). 344CREATE PERFETTO VIEW android_input_event_dispatch( 345 -- ID of the trace entry 346 id LONG, 347 -- Event ID of the input event that was dispatched 348 event_id LONG, 349 -- Details of the input event parsed from the proto message 350 arg_set_id ARGSETID, 351 -- Raw proto message encoded in base64 352 base64_proto STRING, 353 -- String id for raw proto message 354 base64_proto_id LONG, 355 -- Vsync ID that identifies the state of the windows during which the dispatch decision was made 356 vsync_id LONG, 357 -- Window ID of the window receiving the event 358 window_id LONG 359) AS 360SELECT 361 id, 362 event_id, 363 arg_set_id, 364 base64_proto, 365 base64_proto_id, 366 vsync_id, 367 window_id 368FROM __intrinsic_android_input_event_dispatch; 369