1dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com#!/bin/bash
2dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com#
3dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com# android_perf: utility for running perf on an android device
4bec3634a4a0bc2ca872f8b6b7a9f445929e9f74bmtklein#
5dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com# The basic usage sequence is to run...
6dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com#  1) perf record [gm/tests/bench] # runs profiler on specified app
7dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com#  2) perf report # prints profiler results
8dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com#  3) perf clean # cleans the temporary directory used to store results
9dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com#
10dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
11dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comSCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
12cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.comsource $SCRIPT_DIR/android_setup.sh
13dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comsource $SCRIPT_DIR/utils/setup_adb.sh
14dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
15dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comif [ $(uname) == "Linux" ]; then
16dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    PERFHOST=$SCRIPT_DIR/linux/perfhost
17dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comelif [ $(uname) == "Darwin" ]; then
18dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    PERFHOST=$SCRIPT_DIR/mac/perfhost
19dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comelse
20dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    echo "Could not automatically determine OS!"
21dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    exit 1;
22dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comfi
23dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
24cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com# grab and remove the perf command from the input args
25cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.comPERF_CMD=${APP_ARGS[0]}
26cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.comunset APP_ARGS[0]
27e8846f3d3fbb84e96ea049459377af9b2b1faba6commit-bot@chromium.orgrunVars=("${APP_ARGS[@]}")  # shift array indices
28cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com
29dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com# We need the debug symbols from these files
30dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comPERF_TMP_DIR=$(pwd)/android_perf_tmp
31dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
32dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comTMP_SYS_BIN=$PERF_TMP_DIR/system/bin
33dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comTMP_SYS_LIB=$PERF_TMP_DIR/system/lib
34cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.comTMP_APP_LOC=$PERF_TMP_DIR/data/local/tmp
35dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
36dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comperf_setup() {
37dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
38dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    mkdir -p $TMP_SYS_BIN
39dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    mkdir -p $TMP_SYS_LIB
40cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com    mkdir -p $TMP_APP_LOC
41dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
42dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    echo "Copying symbol files"
43cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com    adb_pull_if_needed /system/lib/libc.so $TMP_SYS_LIB
44cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com    adb_pull_if_needed /system/lib/libstlport.so $TMP_SYS_LIB
45cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com    adb_pull_if_needed /system/lib/libGLESv2.so $TMP_SYS_LIB
46cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com    adb_pull_if_needed /system/lib/libandroid.so $TMP_SYS_LIB
47cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com    adb_pull_if_needed /system/lib/libm.so $TMP_SYS_LIB
48cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com    adb_pull_if_needed /system/lib/libz.so $TMP_SYS_LIB
49cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com
50e8846f3d3fbb84e96ea049459377af9b2b1faba6commit-bot@chromium.org    # BUILDTYPE variable is set by android_setup.sh
51e8846f3d3fbb84e96ea049459377af9b2b1faba6commit-bot@chromium.org    BUILDDIR="${SKIA_OUT}/${BUILDTYPE}"
52e8846f3d3fbb84e96ea049459377af9b2b1faba6commit-bot@chromium.org    if [ ! -f "${BUILDDIR}/lib/lib${runVars[0]}.so" ];
53dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    then
54e8846f3d3fbb84e96ea049459377af9b2b1faba6commit-bot@chromium.org      echo "Unable to find the ${runVars[0]} library in ${BUILDDIR}/lib."
55cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com      exit 1
56dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    fi
57dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
58cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com    echo "Pushing app..."
59e8846f3d3fbb84e96ea049459377af9b2b1faba6commit-bot@chromium.org    for lib_file in \
60e8846f3d3fbb84e96ea049459377af9b2b1faba6commit-bot@chromium.org        "${BUILDDIR}/skia_launcher" \
61e8846f3d3fbb84e96ea049459377af9b2b1faba6commit-bot@chromium.org        "${BUILDDIR}/lib/libskia_android.so" \
62e8846f3d3fbb84e96ea049459377af9b2b1faba6commit-bot@chromium.org        "${BUILDDIR}/lib/lib${runVars[0]}.so" \
63e8846f3d3fbb84e96ea049459377af9b2b1faba6commit-bot@chromium.org      ; do
64e8846f3d3fbb84e96ea049459377af9b2b1faba6commit-bot@chromium.org      adb_push_if_needed "$lib_file" /data/local/tmp
65e8846f3d3fbb84e96ea049459377af9b2b1faba6commit-bot@chromium.org      cp "$lib_file" $TMP_APP_LOC
66e8846f3d3fbb84e96ea049459377af9b2b1faba6commit-bot@chromium.org    done
67dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com}
68dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
69dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comperf_record() {
70dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
71dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    echo "Killing any running Skia processes."
72dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    $ADB shell ps | grep skia_launcher | awk '{print $2}' | xargs $ADB shell kill
73dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
74dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    echo "Starting application"
75cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com    $ADB shell /data/local/tmp/skia_launcher ${runVars[@]} &
76dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
77dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    # WE REALLY REALLY WANT TO BE ABLE TO PASS THE SKIA_LAUNCHER APP DIRECTLY TO
78dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    # PERF, BUT AT THIS POINT THE DATA FILE WE GET WHEN GOING THAT ROUTE IS UNABLE
79dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    # TO BE READ BY THE REPORTING TOOL
80dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    echo "Starting profiler"
81dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    APP_PID=$($ADB shell ps | grep skia_launcher | awk '{print $2}')
82dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    $ADB shell perf record -p ${APP_PID} sleep 70
83dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
84dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    $ADB pull /data/perf.data $PERF_TMP_DIR/perf.data
85dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
86dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    exit 0;
87dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com}
88dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
89dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comperf_report() {
90cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com    adb_pull_if_needed /data/perf.data $PERF_TMP_DIR/perf.data
91cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com    $PERFHOST report -i $PERF_TMP_DIR/perf.data --symfs=$PERF_TMP_DIR ${runVars[@]}
92dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com}
93dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
94dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com# Clean up
95dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comperf_clean() {
96dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    rm -rf $PERF_TMP_DIR
97dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com}
98dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
99dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comcase $PERF_CMD in
100dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com  setup)
101cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com      perf_setup ${runVars[@]}
102dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com      ;;
103dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com  record)
104cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com      perf_setup ${runVars[@]}
105cc95b1aeb8cbb9201712c9982d12149b0e0027f0djsollen@google.com      perf_record ${runVars[@]}
106dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com      ;;
107dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com  report)
108dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com      perf_report
109dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com      ;;
110dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com  clean)
111dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com      perf_clean
112dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com      ;;
113dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com    *)
114dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com      echo -n "ERROR: unknown perf command ($PERF_CMD), valid values: "
115dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com      echo "setup, record, report, clean"
116dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com      exit 1;
117dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com      ;;
118dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comesac
119dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.com
120dcdd57faf02fb4fd23bb8265392b9c22e068907edjsollen@google.comexit 0;
121