# Script to start a set of apps in order and then in each iteration
# switch the focus to each one. For each iteration, the time to start
# the app is reported as measured using atrace events and via am ThisTime.
# The output also reports if applications are restarted (eg, killed by
# LMK since previous iteration) or if there were any direct reclaim
# events.
#
# Variation: the "-T" option skips all of the atrace instramentation and
# attempts to start the apps as quickly as possible.
#
# Example 1: start all default apps. 2 iterations
#
# ./systemapps.sh -i 2
#
# Example 2: just start chrome, feedly, and the home screen in a loop
#
# ./systemapps.sh -L "chrome feedly home" -i 5
#
# Example 3: just start the default apps as quickly as possible
#
# ./systemapps.sh -T
#
# Other options are described below.
#
iterations=1
tracecategories="gfx am memreclaim"
totaltimetest=0
forcecoldstart=0
waitTime=3.0
memstats=0
appList="gmail maps chrome youtube play home"
function processLocalOption {
ret=0
case "$1" in
(-A) unset appList;;
(-F) forcecoldstart=1;;
(-L) appList=$2; shift; ret=1;;
(-T) totaltimetest=1;;
(-W) waitTime=$2; shift; ret=1;;
(-M) memstats=1;;
(*)
echo "$0: unrecognized option: $1"
echo; echo "Usage: $0 [options]"
echo "-A : use all known applications"
echo "-F : force cold-start for all apps"
echo "-L applist : list of applications"
echo " default: $appList"
echo "-T : total time to start all apps"
echo "-W : time to wait between apps"
echo "-g : generate activity strings"
echo "-i iterations"
echo "-n : keep trace files"
echo "-o output file"
echo "-s : stop on error"
echo "-t trace categories"
exit 1;;
esac
return $ret
}
CMDDIR=$(dirname $0 2>/dev/null)
CMDDIR=${CMDDIR:=.}
. $CMDDIR/defs.sh
tmpTraceOutBase=./tmptrace
if [ $user != "root" -a $totaltimetest -eq 0 ]; then
handleError Must be root on device
exit 1
fi
doKeyevent HOME
function computeStats {
label=$1
t=$2
restart=$3
reclaim=$4
frames=$5
janks=$6
l90=$7
l95=$8
l99=$9
curMax=$(eval "echo \$${label}max")
curMax=${curMax:=0}
curMin=$(eval "echo \$${label}min")
curMin=${curMin:=100000}
curSum=$(eval "echo \$${label}sum")
curSum=${curSum:=0}
curRestart=$(eval "echo \$${label}restart")
curRestart=${curRestart:=0}
curReclaim=$(eval "echo \$${label}reclaim")
curReclaim=${curReclaim:=0}
curFrames=$(eval "echo \$${label}frames")
curFrames=${curFrames:=0}
curJanks=$(eval "echo \$${label}janks")
curJanks=${curJanks:=0}
cur90=$(eval "echo \$${label}90")
cur90=${cur90:=0}
cur95=$(eval "echo \$${label}95")
cur95=${cur95:=0}
cur99=$(eval "echo \$${label}99")
cur99=${cur99:=0}
if [ $curMax -lt $t ]; then
eval "${label}max=$t"
fi
if [ $curMin -gt $t ]; then
eval "${label}min=$t"
fi
((curSum=curSum+t))
eval "${label}sum=$curSum"
((curRestart=curRestart+${restart:=0}))
eval "${label}restart=$curRestart"
((curReclaim=curReclaim+${reclaim:=0}))
eval "${label}reclaim=$curReclaim"
((curFrames=curFrames+${frames:=0}))
eval "${label}frames=$curFrames"
((curJanks=curJanks+${janks:=0}))
eval "${label}janks=$curJanks"
((cur90=cur90+${l90:=0}))
eval "${label}90=$cur90"
((cur95=cur95+${l95:=0}))
eval "${label}95=$cur95"
((cur99=cur99+${l99:=0}))
eval "${label}99=$cur99"
}
function getStats {
label=$1
echo $(eval "echo \$${label}max") $(eval "echo \$${label}min") $(eval "echo \$${label}sum") \
$(eval "echo \$${label}restart") $(eval "echo \$${label}reclaim") \
$(eval "echo \$${label}frames") $(eval "echo \$${label}janks") \
$(eval "echo \$${label}90") $(eval "echo \$${label}95") $(eval "echo \$${label}99")
}
cur=1
totaltime=0
startTimestamp=$(date +"%s %N")
while [ $cur -le $iterations ]
do
if [ $iterations -gt 1 ]; then
echo =========================================
echo Iteration $cur of $iterations
date
echo =========================================
fi
if [ $iterations -gt 1 -o $cur -eq 1 ]; then
if [ $totaltimetest -eq 0 ]; then
printf "%-6s %7s(ms) %6s(ms) %s %s %s %s\n" App Time AmTime Restart DirReclaim Jank Latency
fi
fi
appnum=-1
for app in $appList
do
vout Starting $app...
((appnum=appnum+1))
loopTimestamp=$(date +"%s %N")
resetJankyFrames
resetJankyFrames $(getPackageName $app)
if [ $totaltimetest -eq 0 ]; then
tmpTraceOut="$tmpTraceOutBase-$app.out"
>$tmpTraceOut
startInstramentation "$app-$cur"
else
if [ "$memstats" -gt 0 ]; then
startInstramentation "$app-$cur" 0
fi
if [ $appnum -eq 0 ]; then
printf "%-8s %5s(ms) %3s(ms) %s %s\n" App Start Iter Jank Latency
fi
fi
if [ $forcecoldstart -eq 0 ]; then
t=$(startActivity $app)
else
t=$(forceStartActivity $app)
fi
# let app finish drawing before checking janks
sleep $waitTime
set -- $(getJankyFrames $(getPackageName $app))
frames=$1
janks=$2
l90=$3
l95=$4
l99=$5
set -- $(getJankyFrames)
systemFrames=$1
systemJanks=$2
s90=$3
s95=$4
s99=$5
((frames=frames+systemFrames))
((janks=janks+systemJanks))
((l90=l90+s90))
((l95=l95+s95))
((l99=l99+s99))
loopEndTimestamp=$(date +"%s %N")
diffTime=$(computeTimeDiff $loopTimestamp $loopEndTimestamp)
if [ $frames -eq 0 ]; then
janks=0
jankPct=0
else
((jankPct=100*janks/frames))
fi
if [ $totaltimetest -gt 0 ]; then
# Note: using %f since %d doesn't work correctly
# when running on lollipop
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
((totaltime=totaltime+t))
continue
else
stopAndDumpInstramentation $tmpTraceOut
actName=$(getActivityName $app)
pkgName=$(getPackageName $app)
stime=$(getStartTime $actName $tmpTraceOut)
relaunch=$?
etime=$(getEndTime $pkgName $tmpTraceOut)
((tdiff=$etime-$stime))
if [ $etime -eq 0 -o $stime -eq 0 ]; then
handleError $app : could not compute start time stime=$stime etime=$etime
# use AmTime so statistics make sense
tdiff=$t
fi
checkForDirectReclaim $actName $tmpTraceOut
directReclaim=$?
printf "%-12s %5d %5d %5d %5d %5d(%d%%) %d/%d/%d\n" "$app" "$tdiff" "$t" "$relaunch" "$directReclaim" "$janks" "$jankPct" $l90 $l95 $l99
computeStats "$app" "$tdiff" "$relaunch" "$directReclaim" "$frames" "$janks" $l90 $l95 $l99
if [ $savetmpfiles -eq 0 ]; then
rm -f $tmpTraceOut
fi
fi
done
((cur=cur+1))
done
endTimestamp=$(date +"%s %N")
diffTime=$(computeTimeDiff $startTimestamp $endTimestamp)
if [ $totaltimetest -gt 0 ]; then
printf "%-10s %5.0f %5.0f\n" TOTAL $totaltime $diffTime
fi
overallSum=0
appCount=0
if [ $iterations -gt 1 -a $totaltimetest -eq 0 ]; then
echo
echo =========================================
printf "Stats after $iterations iterations:\n"
echo =========================================
printf "%-6s %7s(ms) %6s(ms) %6s(ms) %s %s %s %s\n" App Max Ave Min Restart DirReclaim Jank Latency
for app in $appList
do
set -- $(getStats $app)
sum=$3
((ave=sum/iterations))
frames=$6
janks=$7
l90=$8
l95=$9
l99=${10}
((ave90=l90/iterations))
((ave95=l95/iterations))
((ave99=l99/iterations))
if [ $frames -gt 0 ]; then
((jankPct=100*janks/frames))
fi
printf "%-12s %5d %5d %5d %5d %5d %5d(%d%%) %d/%d/%d\n" $app $1 $ave $2 $4 $5 $janks $jankPct $ave90 $ave95 $ave99
((overallSum=overallSum+ave))
((appCount=appCount+1))
done
if [ $appCount -gt 0 ]; then
printf "Average Start Time: %.2f\n", $(echo $overallSum $appCount | awk '{ printf "%.2f\n", $1/$2 }')
fi
fi