You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
254 lines
8.3 KiB
254 lines
8.3 KiB
#!/bin/bash
|
|
#
|
|
# Copyright 2019, The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
DIR_IORAP_COMMON="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
APP_STARTUP_DIR="$DIR_IORAP_COMMON/../app_startup/"
|
|
source "$APP_STARTUP_DIR/lib/common"
|
|
|
|
IORAPD_DATA_PATH="/data/misc/iorapd"
|
|
|
|
iorapd_start() {
|
|
verbose_print 'iorapd_start'
|
|
adb shell start iorapd
|
|
sleep 1
|
|
# TODO: block until logcat prints successfully connecting
|
|
}
|
|
|
|
iorapd_stop() {
|
|
verbose_print 'iorapd_stop'
|
|
adb shell stop iorapd
|
|
}
|
|
|
|
iorapd_reset() {
|
|
iorapd_stop
|
|
iorapd_start
|
|
}
|
|
|
|
# Enable perfetto tracing.
|
|
# Subsequent launches of an application will record a perfetto trace protobuf.
|
|
iorapd_perfetto_enable() {
|
|
verbose_print 'enable perfetto'
|
|
adb shell setprop iorapd.perfetto.enable true
|
|
iorapd_reset # iorapd only reads this flag when initializing
|
|
}
|
|
|
|
# Disable perfetto tracing.
|
|
# Subsequent launches of applications will no longer record perfetto trace protobufs.
|
|
iorapd_perfetto_disable() {
|
|
verbose_print 'disable perfetto'
|
|
adb shell setprop iorapd.perfetto.enable false
|
|
iorapd_reset # iorapd only reads this flag when initializing
|
|
}
|
|
|
|
# Enable readahead
|
|
# Subsequent launches of an application will be sped up by iorapd readahead prefetching
|
|
# (Provided an appropriate compiled trace exists for that application)
|
|
iorapd_readahead_enable() {
|
|
if [[ "$(adb shell getprop iorapd.readahead.enable)" == true ]]; then
|
|
verbose_print 'enable readahead [already enabled]'
|
|
return 0
|
|
fi
|
|
verbose_print 'enable readahead [reset iorapd]'
|
|
adb shell setprop iorapd.readahead.enable true
|
|
iorapd_reset # iorapd only reads this flag when initializing
|
|
}
|
|
|
|
# Disable readahead
|
|
# Subsequent launches of an application will be not be sped up by iorapd readahead prefetching.
|
|
iorapd_readahead_disable() {
|
|
if [[ "$(adb shell getprop iorapd.readahead.enable)" == false ]]; then
|
|
verbose_print 'disable readahead [already disabled]'
|
|
return 0
|
|
fi
|
|
verbose_print 'disable readahead [reset iorapd]'
|
|
adb shell setprop iorapd.readahead.enable false
|
|
iorapd_reset # iorapd only reads this flag when initializing
|
|
}
|
|
|
|
_iorapd_path_to_data_file() {
|
|
local package="$1"
|
|
local activity="$2"
|
|
local suffix="$3"
|
|
|
|
# Match logic of 'AppComponentName' in iorap::compiler C++ code.
|
|
echo "${IORAPD_DATA_PATH}/${package}%2F${activity}.${suffix}"
|
|
}
|
|
|
|
iorapd_perfetto_wait_for_app_trace() {
|
|
local package="$1"
|
|
local activity="$2"
|
|
local timeout="$3"
|
|
local timestamp="$4"
|
|
|
|
local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
|
|
|
|
verbose_print "iorapd_perfetto_wait_for_app_trace on file '$remote_path'"
|
|
|
|
# see event_manager.cc
|
|
local pattern="Perfetto TraceBuffer saved to file: $remote_path"
|
|
logcat_wait_for_pattern "$timeout" "$timestamp" "$pattern"
|
|
}
|
|
|
|
# Purge all perfetto traces for a given application.
|
|
iorapd_perfetto_purge_app_trace() {
|
|
local package="$1"
|
|
local activity="$2"
|
|
|
|
local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
|
|
|
|
verbose_print 'iorapd-perfetto: purge app trace in ' "$remote_path"
|
|
adb shell "[[ -f '$remote_path' ]] && rm -f '$remote_path' || exit 0"
|
|
}
|
|
|
|
# Pull the remote perfetto trace file into a local file.
|
|
iorapd_perfetto_pull_trace_file() {
|
|
local package="$1"
|
|
local activity="$2"
|
|
local output_file="$3" # local path
|
|
|
|
local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
|
|
|
|
if ! adb shell "[[ -f '$compiled_path' ]]"; then
|
|
echo "Error: Remote path '$compiled_path' invalid" >&2
|
|
return 1
|
|
fi
|
|
if ! mkdir -p "$(dirname "$output_file")"; then
|
|
echo "Error: Fail to make output directory for '$output_file'" >&2
|
|
return 1
|
|
fi
|
|
verbose_print adb pull "$compiled_path" "$output_file"
|
|
adb pull "$compiled_path" "$output_file"
|
|
}
|
|
|
|
# Compile a perfetto trace for a given application.
|
|
# This requires the app has run at least once with perfetto tracing enabled.
|
|
iorapd_compiler_for_app_trace() {
|
|
local package="$1"
|
|
local activity="$2"
|
|
local inodes="$3" # local path
|
|
|
|
# remote path calculations
|
|
local input_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
|
|
local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.tmp.pb")"
|
|
local compiled_path_final="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
|
|
|
|
if ! adb shell "[[ -f '$input_path' ]]"; then
|
|
echo "Error: Missing perfetto traces; nothing to compile. Expected: '$input_path'" >&2
|
|
return 1
|
|
fi
|
|
|
|
if ! [[ -f $inodes ]]; then
|
|
# We could compile using 'diskscan' but it's non-deterministic, so refuse instead.
|
|
echo "Error: Missing inodes textcache at '$inodes'; refusing to compile." >&2
|
|
return 1
|
|
fi
|
|
|
|
# inodes file needs to be on the device for iorap.cmd.compiler to access it
|
|
local remote_inodes=/data/local/tmp/prefetch/inodes.txt
|
|
adb shell "mkdir -p \"$(dirname "$remote_inodes")\"" || return 1
|
|
verbose_print adb push "$inodes" "$remote_inodes"
|
|
adb push "$inodes" "$remote_inodes"
|
|
|
|
verbose_print 'iorapd-compiler: compile app trace in ' "$input_path"
|
|
verbose_print adb shell "iorap.cmd.compiler '$input_path' --inode-textcache '$remote_inodes' --output-proto '$compiled_path'"
|
|
adb shell "iorap.cmd.compiler '$input_path' --inode-textcache '$remote_inodes' --output-proto '$compiled_path'"
|
|
retcode=$?
|
|
|
|
# Don't overwrite the true 'compiled_trace.pb' unless the compiler completed without error.
|
|
# TODO: The native compiler code should be handling its own transaction-safety.
|
|
if [[ $retcode -eq 0 ]]; then
|
|
adb shell "mv '$compiled_path' '$compiled_path_final'"
|
|
else
|
|
adb shell "[[ -f '$compiled_path' ]] && rm -f '$compiled_path'"
|
|
fi
|
|
|
|
# Clean up inodes file we just pushed.
|
|
# adb shell "[[ -f '$remote_inodes' ]] && rm -f '$remote_inodes'"
|
|
|
|
return $retcode
|
|
}
|
|
|
|
# Pull the remote compiled trace file into a local file.
|
|
iorapd_compiler_pull_trace_file() {
|
|
local package="$1"
|
|
local activity="$2"
|
|
local output_file="$3" # local path
|
|
|
|
local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
|
|
|
|
if ! adb shell "[[ -f '$compiled_path' ]]"; then
|
|
echo "Error: Remote path '$compiled_path' invalid" >&2
|
|
return 1
|
|
fi
|
|
if ! mkdir -p "$(dirname "$output_file")"; then
|
|
echo "Error: Fail to make output directory for '$output_file'" >&2
|
|
return 1
|
|
fi
|
|
verbose_print adb pull "$compiled_path" "$output_file"
|
|
adb pull "$compiled_path" "$output_file"
|
|
}
|
|
|
|
# Install a compiled trace file.
|
|
iorapd_compiler_install_trace_file() {
|
|
local package="$1"
|
|
local activity="$2"
|
|
local input_file="$3" # local path
|
|
|
|
# remote path calculations
|
|
local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
|
|
|
|
if ! [[ -f $input_file ]]; then
|
|
echo "Error: File '$input_file' does not exist." >&2
|
|
return 1
|
|
fi
|
|
|
|
adb shell "mkdir -p \"$(dirname "$compiled_path")\"" || return 1
|
|
|
|
verbose_print adb push "$input_file" "$compiled_path"
|
|
adb push "$input_file" "$compiled_path"
|
|
}
|
|
|
|
iorapd_compiler_purge_trace_file() {
|
|
local package="$1"
|
|
local activity="$2"
|
|
local input_file="$3" # local path
|
|
|
|
local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
|
|
|
|
adb shell "[[ -f '$remote_path' ]] && rm -f '$remote_path' || exit 0"
|
|
}
|
|
|
|
# Blocks until the readahead for the requested package/activity has finished.
|
|
# This assumes that the trace file was already installed, and also that
|
|
# the application launched but not completed yet.
|
|
iorapd_readahead_wait_until_finished() {
|
|
local package="$1"
|
|
local activity="$2"
|
|
local timestamp="$3"
|
|
local timeout="$4"
|
|
|
|
if [[ $# -lt 4 ]]; then
|
|
echo "FATAL: Expected 4 arguments (actual $# $@)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
|
|
|
|
# See 'read_ahead.cc' LOG(INFO).
|
|
local pattern="Description = $remote_path"
|
|
logcat_wait_for_pattern "$timeout" "$timestamp" "$pattern"
|
|
}
|