blob: 387e45d431bd1df54352ebe644bf823e87a035ec [file] [log] [blame]
Eric Jeong59a56502022-01-31 19:00:37 +00001#!/bin/bash
2#
3# Copyright 2019, The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17DIR_IORAP_COMMON="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
18APP_STARTUP_DIR="$DIR_IORAP_COMMON/../app_startup/"
19source "$APP_STARTUP_DIR/lib/common"
20
21IORAPD_DATA_PATH="/data/misc/iorapd"
22
23iorapd_start() {
24 verbose_print 'iorapd_start'
25 adb shell start iorapd
26 sleep 1
27 # TODO: block until logcat prints successfully connecting
28}
29
30iorapd_stop() {
31 verbose_print 'iorapd_stop'
32 adb shell stop iorapd
33}
34
35iorapd_reset() {
36 iorapd_stop
37 iorapd_start
38}
39
40# Enable perfetto tracing.
41# Subsequent launches of an application will record a perfetto trace protobuf.
42iorapd_perfetto_enable() {
43 verbose_print 'enable perfetto'
44 adb shell setprop iorapd.perfetto.enable true
45 iorapd_reset # iorapd only reads this flag when initializing
46}
47
48# Disable perfetto tracing.
49# Subsequent launches of applications will no longer record perfetto trace protobufs.
50iorapd_perfetto_disable() {
51 verbose_print 'disable perfetto'
52 adb shell setprop iorapd.perfetto.enable false
53 iorapd_reset # iorapd only reads this flag when initializing
54}
55
56# Enable readahead
57# Subsequent launches of an application will be sped up by iorapd readahead prefetching
58# (Provided an appropriate compiled trace exists for that application)
59iorapd_readahead_enable() {
60 if [[ "$(adb shell getprop iorapd.readahead.enable)" == true ]]; then
61 verbose_print 'enable readahead [already enabled]'
62 return 0
63 fi
64 verbose_print 'enable readahead [reset iorapd]'
65 adb shell setprop iorapd.readahead.enable true
66 iorapd_reset # iorapd only reads this flag when initializing
67}
68
69# Disable readahead
70# Subsequent launches of an application will be not be sped up by iorapd readahead prefetching.
71iorapd_readahead_disable() {
72 if [[ "$(adb shell getprop iorapd.readahead.enable)" == false ]]; then
73 verbose_print 'disable readahead [already disabled]'
74 return 0
75 fi
76 verbose_print 'disable readahead [reset iorapd]'
77 adb shell setprop iorapd.readahead.enable false
78 iorapd_reset # iorapd only reads this flag when initializing
79}
80
81_iorapd_path_to_data_file() {
82 local package="$1"
83 local activity="$2"
84 local suffix="$3"
85
86 # Match logic of 'AppComponentName' in iorap::compiler C++ code.
87 echo "${IORAPD_DATA_PATH}/${package}%2F${activity}.${suffix}"
88}
89
90iorapd_perfetto_wait_for_app_trace() {
91 local package="$1"
92 local activity="$2"
93 local timeout="$3"
94 local timestamp="$4"
95
96 local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
97
98 verbose_print "iorapd_perfetto_wait_for_app_trace on file '$remote_path'"
99
100 # see event_manager.cc
101 local pattern="Perfetto TraceBuffer saved to file: $remote_path"
102 logcat_wait_for_pattern "$timeout" "$timestamp" "$pattern"
103}
104
105# Purge all perfetto traces for a given application.
106iorapd_perfetto_purge_app_trace() {
107 local package="$1"
108 local activity="$2"
109
110 local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
111
112 verbose_print 'iorapd-perfetto: purge app trace in ' "$remote_path"
113 adb shell "[[ -f '$remote_path' ]] && rm -f '$remote_path' || exit 0"
114}
115
116# Pull the remote perfetto trace file into a local file.
117iorapd_perfetto_pull_trace_file() {
118 local package="$1"
119 local activity="$2"
120 local output_file="$3" # local path
121
122 local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
123
124 if ! adb shell "[[ -f '$compiled_path' ]]"; then
125 echo "Error: Remote path '$compiled_path' invalid" >&2
126 return 1
127 fi
128 if ! mkdir -p "$(dirname "$output_file")"; then
129 echo "Error: Fail to make output directory for '$output_file'" >&2
130 return 1
131 fi
132 verbose_print adb pull "$compiled_path" "$output_file"
133 adb pull "$compiled_path" "$output_file"
134}
135
136# Compile a perfetto trace for a given application.
137# This requires the app has run at least once with perfetto tracing enabled.
138iorapd_compiler_for_app_trace() {
139 local package="$1"
140 local activity="$2"
141 local inodes="$3" # local path
142
143 # remote path calculations
144 local input_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
145 local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.tmp.pb")"
146 local compiled_path_final="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
147
148 if ! adb shell "[[ -f '$input_path' ]]"; then
149 echo "Error: Missing perfetto traces; nothing to compile. Expected: '$input_path'" >&2
150 return 1
151 fi
152
153 if ! [[ -f $inodes ]]; then
154 # We could compile using 'diskscan' but it's non-deterministic, so refuse instead.
155 echo "Error: Missing inodes textcache at '$inodes'; refusing to compile." >&2
156 return 1
157 fi
158
159 # inodes file needs to be on the device for iorap.cmd.compiler to access it
160 local remote_inodes=/data/local/tmp/prefetch/inodes.txt
161 adb shell "mkdir -p \"$(dirname "$remote_inodes")\"" || return 1
162 verbose_print adb push "$inodes" "$remote_inodes"
163 adb push "$inodes" "$remote_inodes"
164
165 verbose_print 'iorapd-compiler: compile app trace in ' "$input_path"
166 verbose_print adb shell "iorap.cmd.compiler '$input_path' --inode-textcache '$remote_inodes' --output-proto '$compiled_path'"
167 adb shell "iorap.cmd.compiler '$input_path' --inode-textcache '$remote_inodes' --output-proto '$compiled_path'"
168 retcode=$?
169
170 # Don't overwrite the true 'compiled_trace.pb' unless the compiler completed without error.
171 # TODO: The native compiler code should be handling its own transaction-safety.
172 if [[ $retcode -eq 0 ]]; then
173 adb shell "mv '$compiled_path' '$compiled_path_final'"
174 else
175 adb shell "[[ -f '$compiled_path' ]] && rm -f '$compiled_path'"
176 fi
177
178 # Clean up inodes file we just pushed.
179# adb shell "[[ -f '$remote_inodes' ]] && rm -f '$remote_inodes'"
180
181 return $retcode
182}
183
184# Pull the remote compiled trace file into a local file.
185iorapd_compiler_pull_trace_file() {
186 local package="$1"
187 local activity="$2"
188 local output_file="$3" # local path
189
190 local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
191
192 if ! adb shell "[[ -f '$compiled_path' ]]"; then
193 echo "Error: Remote path '$compiled_path' invalid" >&2
194 return 1
195 fi
196 if ! mkdir -p "$(dirname "$output_file")"; then
197 echo "Error: Fail to make output directory for '$output_file'" >&2
198 return 1
199 fi
200 verbose_print adb pull "$compiled_path" "$output_file"
201 adb pull "$compiled_path" "$output_file"
202}
203
204# Install a compiled trace file.
205iorapd_compiler_install_trace_file() {
206 local package="$1"
207 local activity="$2"
208 local input_file="$3" # local path
209
210 # remote path calculations
211 local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
212
213 if ! [[ -f $input_file ]]; then
214 echo "Error: File '$input_file' does not exist." >&2
215 return 1
216 fi
217
218 adb shell "mkdir -p \"$(dirname "$compiled_path")\"" || return 1
219
220 verbose_print adb push "$input_file" "$compiled_path"
221 adb push "$input_file" "$compiled_path"
222}
223
224iorapd_compiler_purge_trace_file() {
225 local package="$1"
226 local activity="$2"
227 local input_file="$3" # local path
228
229 local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
230
231 adb shell "[[ -f '$remote_path' ]] && rm -f '$remote_path' || exit 0"
232}
233
234# Blocks until the readahead for the requested package/activity has finished.
235# This assumes that the trace file was already installed, and also that
236# the application launched but not completed yet.
237iorapd_readahead_wait_until_finished() {
238 local package="$1"
239 local activity="$2"
240 local timestamp="$3"
241 local timeout="$4"
242
243 if [[ $# -lt 4 ]]; then
244 echo "FATAL: Expected 4 arguments (actual $# $@)" >&2
245 exit 1
246 fi
247
248 local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
249
250 # See 'read_ahead.cc' LOG(INFO).
251 local pattern="Description = $remote_path"
252 logcat_wait_for_pattern "$timeout" "$timestamp" "$pattern"
253}