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