1 # functions and definitions for workload automation scripts
3 # See recentfling.sh, systemapps.sh, and other scripts that use
7 dflttracecategories="gfx input view am rs power sched freq idle load memreclaim"
8 dfltAppList="gmail hangouts chrome youtube camera photos play maps calendar earth calculator sheets docs home"
11 # default activities. Can dynamically generate with -g.
12 gmailActivity='com.google.android.gm/com.google.android.gm.ConversationListActivityGmail'
13 clockActivity='com.google.android.deskclock/com.android.deskclock.DeskClock'
14 hangoutsActivity='com.google.android.talk/com.google.android.talk.SigningInActivity'
15 chromeActivity='com.android.chrome/_not_used'
16 contactsActivity='com.google.android.contacts/com.android.contacts.activities.PeopleActivity'
17 youtubeActivity='com.google.android.youtube/com.google.android.apps.youtube.app.WatchWhileActivity'
18 cameraActivity='com.google.android.GoogleCamera/com.android.camera.CameraActivity'
19 playActivity='com.android.vending/com.google.android.finsky.activities.MainActivity'
20 feedlyActivity='com.devhd.feedly/com.devhd.feedly.Main'
21 photosActivity='com.google.android.apps.photos/com.google.android.apps.photos.home.HomeActivity'
22 mapsActivity='com.google.android.apps.maps/com.google.android.maps.MapsActivity'
23 calendarActivity='com.google.android.calendar/com.android.calendar.AllInOneActivity'
24 earthActivity='com.google.earth/com.google.earth.EarthActivity'
25 calculatorActivity='com.google.android.calculator/com.android.calculator2.Calculator'
26 calculatorLActivity='com.android.calculator2/com.android.calculator2.Calculator'
27 sheetsActivity='com.google.android.apps.docs.editors.sheets/com.google.android.apps.docs.app.NewMainProxyActivity'
28 docsActivity='com.google.android.apps.docs.editors.docs/com.google.android.apps.docs.app.NewMainProxyActivity'
29 operaActivity='com.opera.mini.native/com.opera.mini.android.Browser'
30 firefoxActivity='org.mozilla.firefox/org.mozilla.firefox.App'
31 suntempleActivity='com.BrueComputing.SunTemple/com.epicgames.ue4.GameActivity'
32 homeActivity='com.google.android.googlequicksearchbox/com.google.android.launcher.GEL'
35 echo "$0: unrecognized option: $1"
36 echo; echo "Usage: $0 [options]"
37 echo "-e : stop on error"
39 echo "-n : keep trace files"
41 echo "-s device : adb device"
42 echo "-t trace categories"
43 echo "-g : generate activity strings"
52 (-d) DEVICE=$2; shift;;
55 (-t) tracecategories=$2; shift;;
56 (-i) iterations=$2; shift;;
57 (-o) output=$2; shift;;
60 (-s) deviceName=$2; shift;;
61 (-g) generateActivities=1;;
64 chk1=$(functions 2>/dev/null)
65 chk2=$(typeset -F 2>/dev/null)
67 if echo $chk1 $chk2 | grep -q processLocalOption; then
68 if ! processLocalOption "$1" "$2"; then
79 # check if running on a device
80 if ls /etc/* 2>/dev/null | grep -q android.hardware; then
85 # do a throw-away adb in case the server is out-of-date
86 adb devices -l 2>&1 >/dev/null
88 if [ -z "$deviceName" ]; then
89 devInfo=$(adb devices -l | grep -v ^List | head -1)
91 devInfo=$(adb devices -l | grep $deviceName)
95 echo Error: could not find device $deviceName
99 ADB="adb -s $deviceName shell "
100 if [ "$DEVICE" = "" -o "$DEVICE" = unknown ]; then
101 DEVICE=$(echo $4 | sed 's/product://')
106 if [ $isOnDevice -gt 0 ]; then
109 if ! echo $$ > /dev/cpuset/background/tasks; then
110 echo Could not put PID $$ in background
118 # default values if not set by options or calling script
119 appList=${appList:=$dfltAppList}
120 savetmpfiles=${savetmpfiles:=0}
121 stoponerror=${stoponerror:=0}
122 verbose=${verbose:=0}
123 compress=${compress:=1}
124 iterations=${iterations:=5}
125 tracecategories=${tracecategories:=$dflttracecategories}
127 output=${output:="./out"}
129 # clear the output file
130 if [ -f $output ]; then
135 AM_FORCE_START="${ADB}am start -W -S"
136 AM_START="${ADB}am start -W"
137 AM_START_NOWAIT="${ADB}am start"
138 AM_STOP="${ADB}am force-stop"
139 AM_LIST="${ADB}am stack list"
145 # debug output enabled by -v
146 if [ $verbose -gt 0 ]; then
148 echo DEBUG: $* >&2 >> $output
152 function findtimestamp {
153 # extract timestamp from atrace log entry
154 while [ "$2" != "" -a "$2" != "tracing_mark_write" ]
161 function computeTimeDiff {
162 # Compute time diff given: startSeconds startNs endSeconds endNS
164 # strip leading zeros
165 startS=$(expr 0 + $1)
167 if [ "$2" = N ]; then
171 startNs=$(expr 0 + $2)
175 ((startMs=startS*1000 + startNs/1000000))
176 ((endMs=endS*1000 + endNs/1000000))
177 ((diff=endMs-startMs))
184 set -- $(echo $in | tr . " ")
186 # shell addition via (( )) doesn't like leading zeroes in msecs
187 # field so remove leading zeroes
188 msecfield=$(expr 0 + $2)
190 ((msec=$1*1000000+msecfield))
195 function getStartTime {
196 # extract event indicating beginning of start sequence
197 # a) look for a "launching" event indicating start from scratch
198 # b) look for another activity getting a pause event
202 s=$(grep "Binder.*tracing_mark_write.*launching" $traceout 2>/dev/null | head -1| tr [\(\)\[\]
\r:] " ")
204 s=$(grep activityPause $traceout | head -1 2>/dev/null| tr [\(\)\[\]
\r:] " ")
206 vout $_app was restarted!
210 log2msec $(findtimestamp $s)
214 function getEndTime {
215 # extract event indicating end of start sequence. We use the
216 # first surfaceflinger event associated with the target activity
219 f=$(grep "surfaceflinger.*tracing_mark_write.*$_app" $traceout 2>/dev/null |
220 grep -v Starting | head -1 | tr [\(\)\[\]
\r:] " ")
222 # Hmm. sf symbols may not be there... get the pid
223 pid=$(${ADB}pidof /system/bin/surfaceflinger | tr "[
\r]" "[ ]")
224 f=$(grep " <...>-$pid.*tracing_mark_write.*$_app" $traceout 2>/dev/null |
225 grep -v Starting | head -1 | tr [\(\)\[\]
\r:] " ")
228 log2msec $(findtimestamp $f)
231 function resetJankyFrames {
233 _gfxapp=${_gfxapp:="com.android.systemui"}
234 ${ADB}dumpsys gfxinfo $_gfxapp reset 2>&1 >/dev/null
237 function getJankyFrames {
239 _gfxapp=${_gfxapp:="com.android.systemui"}
241 # Note: no awk or sed on devices so have to do this
246 ${ADB}dumpsys gfxinfo $_gfxapp | tr "\r" " " | egrep "9[059]th| frames" | while read line
248 if echo $line | grep -q "Total frames"; then
251 elif echo $line | grep -q "Janky frames"; then
254 elif echo $line | grep -q "90th"; then
255 set -- $(echo $line | tr m " ")
257 elif echo $line | grep -q "95th"; then
258 set -- $(echo $line | tr m " ")
260 elif echo $line | grep -q "99th"; then
261 set -- $(echo $line | tr m " ")
263 echo $total $janky $l90 $l95 $l99
269 function checkForDirectReclaim {
270 # look for any reclaim events in atrace output
273 if grep -qi reclaim $traceout; then
279 function startInstramentation {
283 enableAtrace=${enableAtrace:=1}
284 # Called at beginning of loop. Turn on instramentation like atrace
285 vout start instramentation $(date)
286 echo =============================== >> $output
287 echo Before iteration $_iter >> $output
288 echo =============================== >> $output
289 ${ADB}cat /proc/meminfo 2>&1 >> $output
290 ${ADB}dumpsys meminfo 2>&1 >> $output
291 if [ "$DEVICE" = volantis ]; then
292 ${ADB}cat /d/nvmap/iovmm/procrank 2>&1 >> $output
294 if [ "$user" = root -a $enableAtrace -gt 0 ]; then
295 vout ${ADB}atrace -b 32768 --async_start $tracecategories
296 ${ADB}atrace -b 32768 --async_start $tracecategories >> $output
301 function stopInstramentation {
303 enableAtrace=${enableAtrace:=1}
304 if [ "$user" = root -a $enableAtrace -gt 0 ]; then
305 vout ${ADB}atrace --async_stop
306 ${ADB}atrace --async_stop > /dev/null
310 function stopAndDumpInstramentation {
311 vout stop instramentation $(date)
312 echo =============================== >> $output
313 echo After iteration >> $output
314 echo =============================== >> $output
315 ${ADB}cat /proc/meminfo 2>&1 >> $output
316 ${ADB}dumpsys meminfo 2>&1 >> $output
317 if [ "$user" = root ]; then
319 traceout=${traceout:=$output}
320 echo =============================== >> $traceout
321 echo TRACE >> $traceout
322 echo =============================== >> $traceout
323 if [ $compress -gt 0 ]; then
324 tmpTrace=./tmptrace.$$
325 UNCOMPRESS=$CMDDIR/atrace-uncompress.py
328 ${ADB}atrace -z -b 32768 --async_dump >> $tmpTrace
329 python $UNCOMPRESS $tmpTrace >> $traceout
332 ${ADB}atrace -b 32768 --async_dump > $traceout
334 vout ${ADB}atrace $zarg -b 32768 --async_dump
335 vout ${ADB}atrace --async_stop
336 ${ADB}atrace --async_stop > /dev/null
340 function getActivityName {
341 cmd="actName=\$${1}Activity"
346 function getPackageName {
347 set -- $(getActivityName $1 | tr "[/]" "[ ]")
351 function startActivityFromPackage {
352 if [ "$1" = home ]; then
357 vout $AM_START_NOWAIT -p "$(getPackageName $1)" -c android.intent.category.LAUNCHER -a android.intent.action.MAIN
358 $AM_START_NOWAIT -p "$(getPackageName $1)" -c android.intent.category.LAUNCHER -a android.intent.action.MAIN 2>&1
362 function startActivity {
363 if [ "$1" = home ]; then
367 elif [ "$1" = chrome ]; then
368 if [ "$DEVICE" = volantis -o "$DEVICE" = ariel ]; then
369 vout $AM_START_NOWAIT -p "$(getPackageName $1)" http://www.theverge.com
370 $AM_START_NOWAIT -p "$(getPackageName $1)" http://www.theverge.com > /dev/null
373 vout $AM_START -p "$(getPackageName $1)" http://www.theverge.com
374 set -- $($AM_START -p "$(getPackageName $1)" http://www.theverge.com | grep ThisTime)
377 vout $AM_START "$(getActivityName $1)"
378 set -- $($AM_START "$(getActivityName $1)" | grep ThisTime)
380 echo $2 | tr "[\r]" "[\n]"
383 function forceStartActivity {
384 if [ "$1" = chrome ]; then
385 vout $AM_START -p "$(getPackageName $1)" http://www.theverge.com
386 set -- $($AM_FORCE_START -p "$(getPackageName $1)" http://www.theverge.com | grep ThisTime)
388 vout $AM_FORCE_START "$(getActivityName $1)"
389 set -- $($AM_FORCE_START "$(getActivityName $1)" | grep ThisTime)
391 echo $2 | tr "[\r]" "[\n]"
394 function checkActivity {
396 actName="$(getActivityName $1)"
397 $AM_LIST | grep $actName
400 #function stopActivity {
401 # vout $AM_STOP $(getActivityName $1)
402 # $AM_STOP $(getActivityName $1)
406 vout ${ADB}input swipe $*
407 ${ADB}nice input swipe $*
411 echo $* > ./tmpOutput
412 vout ${ADB}input text \"$*\"
413 ${ADB}input text "$(cat ./tmpOutput)"
418 vout ${ADB}input tap $*
422 function doKeyevent {
423 vout $INPUT keyevent $*
427 function checkIsRunning {
430 if ! $PS | grep $p | grep -qv grep; then
431 handleError $*: $p is not running
436 function checkStartTime {
437 vout checkStartTime $1 v $2
442 if [ "$1" -gt "$2" ]; then
450 function handleError {
452 stopAndDumpInstramentation
453 if [ $stoponerror -gt 0 ]; then
459 if ${ADB}ls /data 2>/dev/null | grep -q "Permission denied"; then
464 if [ $generateActivities -gt 0 ]; then
465 if [ $isOnDevice -gt 0 ]; then
466 echo Error: cannot generate activity list when run on device
469 echo Generating activities...
472 startActivityFromPackage $app 2>&1 > /dev/null
473 act=$(${ADB}am stack list | grep $(getPackageName $app) | sed -e 's/
\r//' | head -1 | awk '{ print $2; }')
474 eval "${app}Activity=$act"
475 echo "ACTIVITY: $app --> $(getActivityName $app)"