1#!/usr/bin/env python3 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 16import synth_common 17from os import sys 18 19CUJ_PID = 5000 20CUJ_MAIN_TID = 5000 21CUJ_UI_TID = 5020 22BACK_PANEL_UI_THREAD_TID = 5040 23 24PROCESS_TRACK = 1234 25CUJ_ASYNC_TRACK = 535 26CUJ_HARDCODED_UI_THREAD_ASYNC_TRACK = 536 27LAYER = "TX - some_layer#0" 28 29 30def add_ui_thread_atrace(trace, ts, ts_end, buf, tid): 31 trace.add_atrace_begin(ts=ts, tid=tid, pid=CUJ_PID, buf=buf) 32 trace.add_atrace_end(ts=ts_end, tid=tid, pid=CUJ_PID) 33 34 35def add_instant_event_in_thread(trace, ts, buf, pid, tid): 36 trace.add_atrace_instant(ts=ts, tid=tid, pid=pid, buf=buf) 37 38 39def add_frame(trace, vsync, ts_do_frame, ts_end_do_frame, tid): 40 add_ui_thread_atrace( 41 trace, 42 ts=ts_do_frame, 43 ts_end=ts_end_do_frame, 44 buf="Choreographer#doFrame %d" % vsync, 45 tid=tid) 46 47 48def add_expected_surface_frame_events(ts, dur, token): 49 trace.add_expected_surface_frame_start_event( 50 ts=ts, 51 cookie=100000 + token, 52 token=token, 53 display_frame_token=100 + token, 54 pid=CUJ_PID, 55 layer_name='') 56 trace.add_frame_end_event(ts=ts + dur, cookie=100000 + token) 57 58 59def add_actual_surface_frame_events(ts, dur, token): 60 cookie = token + 1 61 trace.add_actual_surface_frame_start_event( 62 ts=ts, 63 cookie=100002 + cookie, 64 token=token, 65 display_frame_token=token + 100, 66 pid=CUJ_PID, 67 present_type=1, 68 on_time_finish=1, 69 gpu_composition=0, 70 jank_type=1, 71 prediction_type=3, 72 layer_name=LAYER) 73 trace.add_frame_end_event(ts=ts + dur, cookie=100002 + cookie) 74 75 76def setup_trace(): 77 trace = synth_common.create_trace() 78 trace.add_packet() 79 package_name = "com.google.android.with.custom.ui.thread" 80 uid = 10001 81 trace.add_package_list(ts=0, name=package_name, uid=uid, version_code=1) 82 trace.add_process(pid=CUJ_PID, ppid=1, cmdline=package_name, uid=uid) 83 trace.add_thread( 84 tid=CUJ_MAIN_TID, tgid=CUJ_PID, cmdline="MainThread", name="MainThread") 85 trace.add_thread( 86 tid=CUJ_UI_TID, tgid=CUJ_PID, cmdline="UIThread", name="UIThread") 87 trace.add_thread( 88 tid=BACK_PANEL_UI_THREAD_TID, 89 tgid=CUJ_PID, 90 cmdline="BackPanelUiThre", 91 name="BackPanelUiThre") 92 trace.add_process_track_descriptor(PROCESS_TRACK, pid=CUJ_PID) 93 trace.add_track_descriptor(CUJ_ASYNC_TRACK, parent=PROCESS_TRACK) 94 trace.add_track_descriptor( 95 CUJ_HARDCODED_UI_THREAD_ASYNC_TRACK, parent=PROCESS_TRACK) 96 trace.add_ftrace_packet(cpu=0) 97 return trace 98 99 100def setup_cujs(trace): 101 # CUJ to test the new behaviour, where the ui thread is get from an instant 102 # event. 103 cuj_name = "J<CUJ_NAME>" 104 # Tests the deprecated behaviour where the ui thread is get from an hardcoded 105 # list. 106 back_panel_cuj = "J<BACK_PANEL_ARROW>" 107 108 # UI Thread marker, soon after cuj start 109 add_instant_event_in_thread( 110 trace, 111 ts=5_000_001, 112 buf=cuj_name + "#UIThread", 113 pid=CUJ_PID, 114 tid=CUJ_UI_TID) 115 116 # The following is a blocking call during theh cuj, on the cuj ui thread. 117 # It is expected to appear in the output 118 trace.add_atrace_begin( 119 ts=14_000_000, buf="measure", tid=CUJ_UI_TID, pid=CUJ_PID) 120 trace.add_atrace_end(ts=16_000_000, tid=CUJ_UI_TID, pid=CUJ_PID) 121 # The following is not expected in the output as it's in another thread! 122 trace.add_atrace_begin( 123 ts=14_000_000, buf="layout", tid=CUJ_MAIN_TID, pid=CUJ_PID) 124 trace.add_atrace_end(ts=16_000_000, tid=CUJ_MAIN_TID, pid=CUJ_PID) 125 126 trace.add_atrace_begin( 127 ts=15_000_000, buf="animation", tid=BACK_PANEL_UI_THREAD_TID, pid=CUJ_PID) 128 trace.add_atrace_end(ts=17_000_000, tid=BACK_PANEL_UI_THREAD_TID, pid=CUJ_PID) 129 130 add_frame( 131 trace, 132 vsync=10, 133 ts_do_frame=10_000_000, 134 ts_end_do_frame=18_000_000, 135 tid=CUJ_UI_TID) 136 137 add_frame( 138 trace, 139 vsync=20, 140 ts_do_frame=10_000_000, 141 ts_end_do_frame=18_000_000, 142 tid=BACK_PANEL_UI_THREAD_TID) 143 144 trace.add_track_event_slice_begin( 145 ts=5_000_000, track=CUJ_ASYNC_TRACK, name=cuj_name) 146 trace.add_track_event_slice_end(ts=20_000_000, track=CUJ_ASYNC_TRACK) 147 148 trace.add_track_event_slice_begin( 149 ts=5_000_000, 150 track=CUJ_HARDCODED_UI_THREAD_ASYNC_TRACK, 151 name=back_panel_cuj) 152 trace.add_track_event_slice_end( 153 ts=20_000_000, track=CUJ_HARDCODED_UI_THREAD_ASYNC_TRACK) 154 155 add_expected_surface_frame_events(ts=0, dur=16_000_000, token=10) 156 add_actual_surface_frame_events(ts=0, dur=16_000_000, token=10) 157 158 add_expected_surface_frame_events(ts=0, dur=16_000_000, token=20) 159 add_actual_surface_frame_events(ts=0, dur=16_000_000, token=20) 160 161 162trace = setup_trace() 163setup_cujs(trace) 164sys.stdout.buffer.write(trace.trace.SerializeToString()) 165