1#!/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} 254