1# Script to start a set of apps in order and then in each iteration 2# switch the focus to each one. For each iteration, the time to start 3# the app is reported as measured using atrace events and via am ThisTime. 4# The output also reports if applications are restarted (eg, killed by 5# LMK since previous iteration) or if there were any direct reclaim 6# events. 7# 8# Variation: the "-T" option skips all of the atrace instramentation and 9# attempts to start the apps as quickly as possible. 10# 11# Example 1: start all default apps. 2 iterations 12# 13# ./systemapps.sh -i 2 14# 15# Example 2: just start chrome, feedly, and the home screen in a loop 16# 17# ./systemapps.sh -L "chrome feedly home" -i 5 18# 19# Example 3: just start the default apps as quickly as possible 20# 21# ./systemapps.sh -T 22# 23# Other options are described below. 24# 25iterations=1 26tracecategories="gfx am memreclaim" 27totaltimetest=0 28forcecoldstart=0 29waitTime=3.0 30memstats=0 31 32appList="gmail maps chrome youtube play home" 33 34function processLocalOption { 35 ret=0 36 case "$1" in 37 (-A) unset appList;; 38 (-F) forcecoldstart=1;; 39 (-L) appList=$2; shift; ret=1;; 40 (-T) totaltimetest=1;; 41 (-W) waitTime=$2; shift; ret=1;; 42 (-M) memstats=1;; 43 (*) 44 echo "$0: unrecognized option: $1" 45 echo; echo "Usage: $0 [options]" 46 echo "-A : use all known applications" 47 echo "-F : force cold-start for all apps" 48 echo "-L applist : list of applications" 49 echo " default: $appList" 50 echo "-T : total time to start all apps" 51 echo "-W : time to wait between apps" 52 echo "-g : generate activity strings" 53 echo "-i iterations" 54 echo "-n : keep trace files" 55 echo "-o output file" 56 echo "-s : stop on error" 57 echo "-t trace categories" 58 exit 1;; 59 esac 60 return $ret 61} 62 63CMDDIR=$(dirname $0 2>/dev/null) 64CMDDIR=${CMDDIR:=.} 65. $CMDDIR/defs.sh 66 67tmpTraceOutBase=./tmptrace 68 69if [ $user != "root" -a $totaltimetest -eq 0 ]; then 70 handleError Must be root on device 71 exit 1 72fi 73doKeyevent HOME 74 75function computeStats { 76 label=$1 77 t=$2 78 restart=$3 79 reclaim=$4 80 frames=$5 81 janks=$6 82 l90=$7 83 l95=$8 84 l99=$9 85 curMax=$(eval "echo \$${label}max") 86 curMax=${curMax:=0} 87 curMin=$(eval "echo \$${label}min") 88 curMin=${curMin:=100000} 89 curSum=$(eval "echo \$${label}sum") 90 curSum=${curSum:=0} 91 curRestart=$(eval "echo \$${label}restart") 92 curRestart=${curRestart:=0} 93 curReclaim=$(eval "echo \$${label}reclaim") 94 curReclaim=${curReclaim:=0} 95 curFrames=$(eval "echo \$${label}frames") 96 curFrames=${curFrames:=0} 97 curJanks=$(eval "echo \$${label}janks") 98 curJanks=${curJanks:=0} 99 cur90=$(eval "echo \$${label}90") 100 cur90=${cur90:=0} 101 cur95=$(eval "echo \$${label}95") 102 cur95=${cur95:=0} 103 cur99=$(eval "echo \$${label}99") 104 cur99=${cur99:=0} 105 if [ $curMax -lt $t ]; then 106 eval "${label}max=$t" 107 fi 108 if [ $curMin -gt $t ]; then 109 eval "${label}min=$t" 110 fi 111 ((curSum=curSum+t)) 112 eval "${label}sum=$curSum" 113 114 ((curRestart=curRestart+${restart:=0})) 115 eval "${label}restart=$curRestart" 116 ((curReclaim=curReclaim+${reclaim:=0})) 117 eval "${label}reclaim=$curReclaim" 118 ((curFrames=curFrames+${frames:=0})) 119 eval "${label}frames=$curFrames" 120 ((curJanks=curJanks+${janks:=0})) 121 eval "${label}janks=$curJanks" 122 ((cur90=cur90+${l90:=0})) 123 eval "${label}90=$cur90" 124 ((cur95=cur95+${l95:=0})) 125 eval "${label}95=$cur95" 126 ((cur99=cur99+${l99:=0})) 127 eval "${label}99=$cur99" 128} 129function getStats { 130 label=$1 131 echo $(eval "echo \$${label}max") $(eval "echo \$${label}min") $(eval "echo \$${label}sum") \ 132 $(eval "echo \$${label}restart") $(eval "echo \$${label}reclaim") \ 133 $(eval "echo \$${label}frames") $(eval "echo \$${label}janks") \ 134 $(eval "echo \$${label}90") $(eval "echo \$${label}95") $(eval "echo \$${label}99") 135} 136 137cur=1 138totaltime=0 139startTimestamp=$(date +"%s %N") 140 141while [ $cur -le $iterations ] 142do 143 if [ $iterations -gt 1 ]; then 144 echo ========================================= 145 echo Iteration $cur of $iterations 146 date 147 echo ========================================= 148 fi 149 if [ $iterations -gt 1 -o $cur -eq 1 ]; then 150 if [ $totaltimetest -eq 0 ]; then 151 printf "%-6s %7s(ms) %6s(ms) %s %s %s %s\n" App Time AmTime Restart DirReclaim Jank Latency 152 fi 153 fi 154 155 appnum=-1 156 for app in $appList 157 do 158 vout Starting $app... 159 ((appnum=appnum+1)) 160 loopTimestamp=$(date +"%s %N") 161 resetJankyFrames 162 resetJankyFrames $(getPackageName $app) 163 if [ $totaltimetest -eq 0 ]; then 164 tmpTraceOut="$tmpTraceOutBase-$app.out" 165 >$tmpTraceOut 166 startInstramentation "$app-$cur" 167 else 168 if [ "$memstats" -gt 0 ]; then 169 startInstramentation "$app-$cur" 0 170 fi 171 if [ $appnum -eq 0 ]; then 172 printf "%-8s %5s(ms) %3s(ms) %s %s\n" App Start Iter Jank Latency 173 fi 174 fi 175 if [ $forcecoldstart -eq 0 ]; then 176 t=$(startActivity $app) 177 else 178 t=$(forceStartActivity $app) 179 fi 180 181 # let app finish drawing before checking janks 182 sleep $waitTime 183 set -- $(getJankyFrames $(getPackageName $app)) 184 frames=$1 185 janks=$2 186 l90=$3 187 l95=$4 188 l99=$5 189 set -- $(getJankyFrames) 190 systemFrames=$1 191 systemJanks=$2 192 s90=$3 193 s95=$4 194 s99=$5 195 ((frames=frames+systemFrames)) 196 ((janks=janks+systemJanks)) 197 ((l90=l90+s90)) 198 ((l95=l95+s95)) 199 ((l99=l99+s99)) 200 201 loopEndTimestamp=$(date +"%s %N") 202 diffTime=$(computeTimeDiff $loopTimestamp $loopEndTimestamp) 203 204 if [ $frames -eq 0 ]; then 205 janks=0 206 jankPct=0 207 else 208 ((jankPct=100*janks/frames)) 209 fi 210 if [ $totaltimetest -gt 0 ]; then 211 # Note: using %f since %d doesn't work correctly 212 # when running on lollipop 213 printf "%-10s %5.0f %5.0f %4.0f(%2.0f%%) %2.0f/%2.0f/%2.0f\n" $app $t $diffTime $janks $jankPct $l90 $l95 $l99 214 ((totaltime=totaltime+t)) 215 continue 216 else 217 stopAndDumpInstramentation $tmpTraceOut 218 actName=$(getActivityName $app) 219 pkgName=$(getPackageName $app) 220 stime=$(getStartTime $actName $tmpTraceOut) 221 relaunch=$? 222 etime=$(getEndTime $pkgName $tmpTraceOut) 223 ((tdiff=$etime-$stime)) 224 if [ $etime -eq 0 -o $stime -eq 0 ]; then 225 handleError $app : could not compute start time stime=$stime etime=$etime 226 # use AmTime so statistics make sense 227 tdiff=$t 228 fi 229 checkForDirectReclaim $actName $tmpTraceOut 230 directReclaim=$? 231 232 printf "%-12s %5d %5d %5d %5d %5d(%d%%) %d/%d/%d\n" "$app" "$tdiff" "$t" "$relaunch" "$directReclaim" "$janks" "$jankPct" $l90 $l95 $l99 233 computeStats "$app" "$tdiff" "$relaunch" "$directReclaim" "$frames" "$janks" $l90 $l95 $l99 234 235 if [ $savetmpfiles -eq 0 ]; then 236 rm -f $tmpTraceOut 237 fi 238 fi 239 done 240 ((cur=cur+1)) 241done 242endTimestamp=$(date +"%s %N") 243diffTime=$(computeTimeDiff $startTimestamp $endTimestamp) 244if [ $totaltimetest -gt 0 ]; then 245 printf "%-10s %5.0f %5.0f\n" TOTAL $totaltime $diffTime 246fi 247 248overallSum=0 249appCount=0 250if [ $iterations -gt 1 -a $totaltimetest -eq 0 ]; then 251 echo 252 echo ========================================= 253 printf "Stats after $iterations iterations:\n" 254 echo ========================================= 255 printf "%-6s %7s(ms) %6s(ms) %6s(ms) %s %s %s %s\n" App Max Ave Min Restart DirReclaim Jank Latency 256 for app in $appList 257 do 258 set -- $(getStats $app) 259 sum=$3 260 ((ave=sum/iterations)) 261 frames=$6 262 janks=$7 263 l90=$8 264 l95=$9 265 l99=${10} 266 ((ave90=l90/iterations)) 267 ((ave95=l95/iterations)) 268 ((ave99=l99/iterations)) 269 if [ $frames -gt 0 ]; then 270 ((jankPct=100*janks/frames)) 271 fi 272 printf "%-12s %5d %5d %5d %5d %5d %5d(%d%%) %d/%d/%d\n" $app $1 $ave $2 $4 $5 $janks $jankPct $ave90 $ave95 $ave99 273 ((overallSum=overallSum+ave)) 274 ((appCount=appCount+1)) 275 done 276 if [ $appCount -gt 0 ]; then 277 printf "Average Start Time: %.2f\n", $(echo $overallSum $appCount | awk '{ printf "%.2f\n", $1/$2 }') 278 fi 279fi 280