diff options
author | Igor Murashkin <iam@google.com> | 2018-09-13 13:56:58 -0700 |
---|---|---|
committer | Igor Murashkin <iam@google.com> | 2018-09-13 13:56:58 -0700 |
commit | 45087deef43f2cab06838596c645f161ea2cda76 (patch) | |
tree | fa2498d88f8b4ace5e220cad4d50a1513882ddc8 /startop/scripts/app_startup | |
parent | 25f394d681649c9cb23622a445ff505bfe55219b (diff) |
startop: Add script to force dex2oat compilation filter for app
Example: ./force_compiler_filter --package com.google.android.apps.maps --compiler-filter speed-profile
Run the app just slightly enough to fully start up, then force it to
dump the profile and recompile the application with dex2oat under the
speed-profile filter.
(Also supports any other compilation filter such as quicken, speed,
etc).
Subsequently, this command can be used to manually validate that the
compiler filter was indeed changed:
$ adb shell dumpsys package com.google.android.apps.maps | grep -A10 "Dexopt state"
Dexopt state:
[com.google.android.apps.maps]
path: /data/app/com.google.android.apps.maps-D7s8PLidqqEq7Jc7UH_a5A==/base.apk
arm64: [status=speed-profile] [reason=unknown]
Test: Manual (see above)
Change-Id: Iea6067f90dc287d1de651d1ab36df69d23b2e9c1
Diffstat (limited to 'startop/scripts/app_startup')
-rwxr-xr-x | startop/scripts/app_startup/force_compiler_filter | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/startop/scripts/app_startup/force_compiler_filter b/startop/scripts/app_startup/force_compiler_filter new file mode 100755 index 000000000000..78e915bb4d53 --- /dev/null +++ b/startop/scripts/app_startup/force_compiler_filter @@ -0,0 +1,173 @@ +#!/bin/bash +# +# Copyright 2018, 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. + +# +# Forces an application APK to be compiled (by ART's dex2oat) +# with a specific compiler filter. +# +# Example usage: +# $> ./force_compiler_filter -p com.google.android.apps.maps -c speed-profile +# +# (The application may be started/stopped as a side effect) +# + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$DIR/lib/common" + +usage() { + cat <<EOF +Usage: $(basename $0) [OPTION]... + + Required: + -p, --package package of the app to recompile + -c, --compiler-filter override the compiler filter if set (default none) + valid options are listed by: adb shell cmd package, under compile -m + + Optional: + -a, --activity activity of the app to recompile + -h, --help usage information (this) + -v, --verbose enable extra verbose printing + -w, --wait_time how long to wait for app startup (default 10) in seconds +EOF +} + +wait_time="10" # seconds + +parse_arguments() { + while [[ $# -gt 0 ]]; do + case "$1" in + -a|--activity) + activity="$2" + shift + ;; + -h|--help) + usage + exit 0 + ;; + -p|--package) + package="$2" + shift + ;; + -w|--wait_time) + wait_time="$2" + shift + ;; + -c|--compiler-filter) + compiler_filter="$2" + shift + ;; + -v|--verbose) + verbose="y" + ;; + esac + shift + done + + if [[ -z "$compiler_filter" ]]; then + echo "Missing required --compiler-filter" >&2 + echo "" + usage + exit 1 + fi + if [[ -z "$package" ]]; then + echo "Missing required --package" >&2 + echo "" + usage + exit 1 + fi + + if [[ "$activity" == "" ]]; then + activity="$(get_activity_name "$package")" + if [[ "$activity" == "" ]]; then + echo "Activity name could not be found, invalid package name?" 1>&2 + exit 1 + else + verbose_print "Activity name inferred: " "$activity" + fi + fi +} + +get_activity_name() { + local package="$1" + local action_key="android.intent.action.MAIN:" + + local activity_line="$(adb shell cmd package query-activities --brief -a android.intent.action.MAIN -c android.intent.category.LAUNCHER | grep "$package")" + verbose_print $activity_line + IFS="/" read -a array <<< "$activity_line" + local activity_name="${array[1]}" + echo "$activity_name" + #adb shell am start "$package/$activity_name" +} + +remote_pidof() { + local procname="$1" + adb shell ps | grep "$procname" | awk '{print $2;}' +} + +remote_pkill() { + local procname="$1" + shift + + local the_pids=$(remote_pidof "$procname") + local pid + + for pid in $the_pids; do + verbose_print adb shell kill "$@" "$pid" + adb shell kill "$@" "$pid" + done +} + +force_package_compilation() { + local arg_compiler_filter="$1" + local arg_package="$2" + + if [[ $arg_compiler_filter == speed-profile ]]; then + # Force the running app to dump its profiles to disk. + remote_pkill "$arg_package" -SIGUSR1 + sleep 1 # give some time for above to complete. + fi + + adb shell cmd package compile -m "$arg_compiler_filter" -f "$arg_package" +} + +main() { + parse_arguments "$@" + + if [[ $compiler_filter == speed-profile ]]; then + # screen needs to be unlocked in order to run an app + "$DIR"/unlock_screen + + am_output="$(adb shell am start -S -W "$package"/"$activity")" + if [[ $? -ne 0 ]]; then + echo "am start failed" >&2 + exit 1 + fi + + verbose_print "$am_output" + # give some time for app startup to complete. + # this is supposed to be an upper bound for measuring startup time. + sleep "$wait_time" + fi + + force_package_compilation "$compiler_filter" "$package" + + # kill the application to ensure next time it's started, + # it picks up the correct compilation filter. + adb shell am force-stop "$package" + remote_pkill "$package" +} + +main "$@" |