1#!/bin/bash 2# 3# Copyright (C) 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# 17# Analyze the output from Android Auto app launch test application. 18 19# ITERATION_COUNT decides how many times the test is repeated. 20readonly ITERATION_COUNT=2 21# SCALE decides the precision of fractional part in bc. 22readonly SCALE=9 23 24#################################################### 25# Calculate arithmetic mean and standard deviation. 26# Globals: 27# None 28# Arguments: 29# A sequence of numbers 30# Returns: 31# Count, average and stddev in space-saparated string 32#################################################### 33function calc_stat() { 34 local sum=0 35 local count=0 36 local mean=0 37 local diff_sqrd_sum=0 38 local stddev=0 39 40 # Calculate the mean. 41 for val in "$@"; do 42 sum=$(echo "scale=${SCALE};${sum} + ${val}" | bc) 43 ((count++)) 44 done 45 mean=$(echo "scale=${SCALE};${sum} / ${count}" | bc) 46 47 # Calculate standard deviation. 48 for val in "$@"; do 49 diff_sqrd_sum=$(echo "scale=${SCALE};${diff_sqrd_sum} + (${mean} - ${val}) ^ 2" | bc) 50 done 51 stddev=$(echo "scale=${SCALE};sqrt(${diff_sqrd_sum} / ${count})" | bc) 52 53 echo "${count} ${mean} ${stddev}" 54} 55 56#################################################### 57# Execute app launch performance test. 58# Globals: 59# None 60# Arguments: 61# Type of app launch, cold or hot 62# Whether to press home button, boolean 63# Whether to drop cache, boolean 64# Whether to kill app, boolean 65# Outputs: 66# Writes the analysis result to stdout 67#################################################### 68function run_app_launch_test() { 69 local stat= 70 local package_pattern="INSTRUMENTATION_STATUS: $1_startup_([a-z]+(\.[a-z]+)+)=([0-9]+)" 71 local cmd="adb shell am instrument -w -r -e iterations ${ITERATION_COUNT}\ 72 -e listener android.device.collectors.AppStartupListener\ 73 -e class 'android.platform.test.scenario.dial.OpenAppMicrobenchmark,android.platform.test.scenario.googleplay.OpenAppMicrobenchmark,android.platform.test.scenario.maps.OpenAppMicrobenchmark,android.platform.test.scenario.radio.OpenAppMicrobenchmark,android.platform.test.scenario.settings.OpenAppMicrobenchmark'\ 74 -e favor-shell-commands true -e log false -e suite-timeout_msec 36000000\ 75 -e durationMs 30000 -e press-home $2 -e newRunListenerMode true\ 76 -e timeout_msec 300000 -e drop-cache $3 -e kill-app $4 android.platform.test.scenario/androidx.test.runner.AndroidJUnitRunner" 77 # Example output from ${cmd} 78 # 79 # INSTRUMENTATION_STATUS: class=android.platform.test.scenario.maps.OpenAppMicrobenchmark 80 # INSTRUMENTATION_STATUS: current=1 81 # INSTRUMENTATION_STATUS: id=AndroidJUnitRunner 82 # INSTRUMENTATION_STATUS: numtests=25 83 # INSTRUMENTATION_STATUS: stream= 84 # android.platform.test.scenario.maps.OpenAppMicrobenchmark: 85 # INSTRUMENTATION_STATUS: test=testOpen 86 # INSTRUMENTATION_STATUS_CODE: 1 87 # INSTRUMENTATION_STATUS: cold_startup_com.google.android.apps.maps=2286 88 # INSTRUMENTATION_STATUS: cold_startup_count_com.google.android.apps.maps=1 89 # INSTRUMENTATION_STATUS: cold_startup_total_count=1 90 # INSTRUMENTATION_STATUS_CODE: 2 91 # INSTRUMENTATION_STATUS: class=android.platform.test.scenario.maps.OpenAppMicrobenchmark 92 # INSTRUMENTATION_STATUS: current=1 93 # INSTRUMENTATION_STATUS: id=AndroidJUnitRunner 94 # INSTRUMENTATION_STATUS: numtests=25 95 # INSTRUMENTATION_STATUS: stream=. 96 # INSTRUMENTATION_STATUS: test=testOpen 97 # INSTRUMENTATION_STATUS_CODE: 0 98 99 declare -A app_launch_map 100 printf "Testing $1 start performance....\n" 101 102 while IFS= read -r line; do 103 if [[ ${line} =~ ${package_pattern} ]]; then 104 APP_PACKAGE="${BASH_REMATCH[1]}" 105 LAUNCH_TIME=${BASH_REMATCH[3]} 106 app_launch_map[${APP_PACKAGE}]+="${LAUNCH_TIME} " 107 fi 108 done < <(${cmd}) 109 110 for key in "${!app_launch_map[@]}"; do 111 stat=($(calc_stat ${app_launch_map[${key}]})) 112 printf "[${key}]\n" 113 printf " Count: ${stat[0]}\n" 114 printf " Average: ${stat[1]}\n" 115 printf " StdDev: ${stat[2]}\n" 116 printf "\n" 117 done 118} 119 120# We test two types of app launch performance: cold and hot. 121# Cold start is to launch an app without cache support as if it is executed for the first time. 122# Hot start is to make an app go into the foreground while the app is running in the background. 123run_app_launch_test cold false true true 124echo "" 125run_app_launch_test hot true false false 126