summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Kjos <tkjos@google.com>2015-05-20 12:47:00 -0700
committerTodd Kjos <tkjos@google.com>2015-05-20 12:51:26 -0700
commit684f65f8602d1e1a79170984acc18421fb8f4c98 (patch)
tree1b1f84a8601323ea66e3bce0e3b3fd4d1c7ab8fb
parent1865679fda9bd1e12bc583268537bccc4e4a43bc (diff)
downloadextras-684f65f8602d1e1a79170984acc18421fb8f4c98.tar.gz
Scripts to automate simple workloads for testing
DO NOT MERGE (already in master) The initial set of scripts: recentsfling.sh : start a set of apps, switch to recents and fling systemapps.sh : start a set of apps, and then loop to move them to the forground, checking whether the app had been LMK'd or required direct reclaims feedly-chrome.sh : automate a feedly, chrome workflow making sure both stay in memory Change-Id: I40f0862623ea0963bb0eaed3a585b41b69bbbbc7
-rw-r--r--tests/workloads/atrace-uncompress.py35
-rwxr-xr-xtests/workloads/capture.sh62
-rwxr-xr-xtests/workloads/defs.sh434
-rwxr-xr-xtests/workloads/feedly-chrome.sh111
-rwxr-xr-xtests/workloads/recentfling.sh132
-rwxr-xr-xtests/workloads/systemapps.sh212
6 files changed, 986 insertions, 0 deletions
diff --git a/tests/workloads/atrace-uncompress.py b/tests/workloads/atrace-uncompress.py
new file mode 100644
index 00000000..5efb6982
--- /dev/null
+++ b/tests/workloads/atrace-uncompress.py
@@ -0,0 +1,35 @@
+#
+# Uncompress a file generated via atrace -z
+#
+# Usage: python atrace-uncompress.py infile > outfile
+#
+import sys, zlib
+
+def main():
+
+ if len(sys.argv) != 2:
+ print >> sys.stderr, ('Usage: %s inputfile' % sys.argv[0])
+ sys.exit(1)
+
+ infile = open(sys.argv[1], "rb")
+ out = infile.read()
+ parts = out.split('\nTRACE:', 1)
+
+ data = ''.join(parts[1])
+
+ # Remove CR characters
+ if data.startswith('\r\n'):
+ data = data.replace('\r\n', '\n')
+
+ # Skip the initial newline.
+ data = data[1:]
+
+ if not data:
+ print >> sys.stderr, ('No trace data found')
+ sys.exit(1)
+
+ out = zlib.decompress(data)
+ print(out)
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/workloads/capture.sh b/tests/workloads/capture.sh
new file mode 100755
index 00000000..721fe8c8
--- /dev/null
+++ b/tests/workloads/capture.sh
@@ -0,0 +1,62 @@
+# Capture and display input events and coordinates
+#
+# Usage: ./capture.sh
+#
+
+# do a throw-away adb in case the server is out-of-date
+adb devices -l 2>&1 >/dev/null
+devInfo=$(adb devices -l | grep -v ^List | head -1)
+
+set -- $devInfo
+echo devInfo=$devInfo
+
+DEVICE=$(echo $4 | sed 's/product://')
+
+function convert {
+ in=$1
+ max=$2
+ scale=$3
+ if [ $max -eq 0 ]; then
+ echo $in
+ else
+ ((out=in*scale/max))
+ echo $out
+ fi
+}
+
+
+case $DEVICE in
+(shamu|hammerhead)
+ # no scaling necessary
+ xmax=0
+ ymax=0;;
+(volantis)
+ xmax=3060
+ xscale=1500
+ ymax=2304
+ yscale=1950;;
+(*)
+ echo "Error: No display information available for $DEVICE"
+ exit 1;;
+esac
+
+echo Capturing input for $DEVICE...
+stdbuf -o0 adb shell getevent -t |
+ stdbuf -o0 grep "event.: 0003" |
+ stdbuf -o0 grep "0003 003[0156a9]" |
+ stdbuf -o0 tr ':[] ' ' ' | while read line
+do
+ set -- $line
+ code=$4
+ value=$((16#$5))
+ case $code in
+ (0035) x=$(convert $value $xmax $xscale);;
+ (0036) y=$(convert $value $ymax $yscale);;
+ (0030) tag="majorTouch";;
+ (0031) tag="minorTouch";;
+ (003a) tag="pressure";;
+ (0039) tag="trackingId";;
+ (--) echo unknown code=$code;;
+ esac
+ printf "%-10s %-4d %-4d\n" $tag $x $y
+done
diff --git a/tests/workloads/defs.sh b/tests/workloads/defs.sh
new file mode 100755
index 00000000..838d04f4
--- /dev/null
+++ b/tests/workloads/defs.sh
@@ -0,0 +1,434 @@
+# functions and definitions for workload automation scripts
+#
+# See recentfling.sh, systemapps.sh, and other scripts that use
+# these definitions.
+#
+
+dflttracecategories="gfx input view am rs power sched freq idle load memreclaim"
+dfltAppList="gmail hangouts chrome youtube camera photos play maps calendar earth calculator sheets docs home"
+generateActivities=0
+
+# default activities. Can dynamically generate with -g.
+gmailActivity='com.google.android.gm/com.google.android.gm.ConversationListActivityGmail'
+hangoutsActivity='com.google.android.talk/com.google.android.talk.SigningInActivity'
+chromeActivity='com.android.chrome/com.google.android.apps.chrome.ChromeTabbedActivity'
+chromeLActivity='com.android.chrome/com.google.android.apps.chrome.document.DocumentActivity'
+youtubeActivity='com.google.android.youtube/com.google.android.apps.youtube.app.WatchWhileActivity'
+cameraActivity='com.google.android.GoogleCamera/com.android.camera.CameraActivity'
+playActivity='com.android.vending/com.google.android.finsky.activities.MainActivity'
+feedlyActivity='com.devhd.feedly/com.devhd.feedly.Main'
+photosActivity='com.google.android.apps.plus/com.google.android.apps.photos.phone.PhotosHomeActivity'
+mapsActivity='com.google.android.apps.maps/com.google.android.maps.MapsActivity'
+calendarActivity='com.google.android.calendar/com.android.calendar.AllInOneActivity'
+earthActivity='com.google.earth/com.google.earth.EarthActivity'
+calculatorActivity='com.android.calculator2/com.android.calculator2.Calculator'
+sheetsActivity='com.google.android.apps.docs.editors.sheets/com.google.android.apps.docs.app.NewMainProxyActivity'
+docsActivity='com.google.android.apps.docs.editors.docs/com.google.android.apps.docs.app.NewMainProxyActivity'
+operaActivity='com.opera.mini.native/com.opera.mini.android.Browser'
+firefoxActivity='org.mozilla.firefox/org.mozilla.firefox.App'
+homeActivity='com.google.android.googlequicksearchbox/com.google.android.launcher.GEL'
+
+function showUsage {
+ echo "$0: unrecognized option: $1"
+ echo; echo "Usage: $0 [options]"
+ echo "-e : stop on error"
+ echo "-i iterations"
+ echo "-n : keep trace files"
+ echo "-o output file"
+ echo "-s device : adb device"
+ echo "-t trace categories"
+ echo "-g : generate activity strings"
+}
+
+DEVICE=unknown
+
+# handle args
+while [ $# -gt 0 ]
+do
+ case "$1" in
+ (-d) DEVICE=$2; shift;;
+ (-e) stoponerror=1;;
+ (-n) savetmpfiles=1;;
+ (-t) tracecategories=$2; shift;;
+ (-i) iterations=$2; shift;;
+ (-o) output=$2; shift;;
+ (-v) verbose=1;;
+ (-nz) compress=0;;
+ (-s) deviceName=$2; shift;;
+ (-g) generateActivities=1;;
+ (--) ;;
+ (*)
+ chk1=$(functions 2>/dev/null)
+ chk2=$(typeset -F 2>/dev/null)
+
+ if echo $chk1 $chk2 | grep -q processLocalOption; then
+ if ! processLocalOption "$1" "$2"; then
+ shift
+ fi
+ else
+ showUsage $1
+ exit 1
+ fi;;
+ esac
+ shift
+done
+
+# check if running on a device
+if ls /etc/* 2>/dev/null | grep -q android.hardware; then
+ ADB=""
+ compress=0
+ isOnDevice=1
+else
+ # do a throw-away adb in case the server is out-of-date
+ adb devices -l 2>&1 >/dev/null
+
+ if [ -z "$deviceName" ]; then
+ devInfo=$(adb devices -l | grep -v ^List | head -1)
+ else
+ devInfo=$(adb devices -l | grep $deviceName)
+ fi
+ set -- $devInfo
+ if [ -z $1 ]; then
+ echo Error: could not find device $deviceName
+ exit 1
+ fi
+ deviceName=$1
+ ADB="adb -s $deviceName shell "
+ DEVICE=$(echo $4 | sed 's/product://')
+ isOnDevice=0
+fi
+
+# default values if not set by options or calling script
+appList=${appList:=$dfltAppList}
+savetmpfiles=${savetmpfiles:=0}
+stoponerror=${stoponerror:=0}
+verbose=${verbose:=0}
+compress=${compress:=1}
+iterations=${iterations:=5}
+tracecategories=${tracecategories:=$dflttracecategories}
+ADB=${ADB:=""}
+output=${output:="./out"}
+
+# clear the output file
+> $output
+
+# ADB commands
+AM_FORCE_START="${ADB}am start -W -S"
+AM_START="${ADB}am start -W"
+AM_START_NOWAIT="${ADB}am start"
+AM_STOP="${ADB}am force-stop"
+AM_LIST="${ADB}am stack list"
+WHO="${ADB}whoami"
+INPUT="${ADB}input"
+PS="${ADB}ps"
+
+function vout {
+ # debug output enabled by -v
+ if [ $verbose -gt 0 ]; then
+ echo DEBUG: $* >&2
+ echo DEBUG: $* >&2 >> $output
+ fi
+}
+
+function findtimestamp {
+ # extract timestamp from atrace log entry
+ while [ "$2" != "" -a "$2" != "tracing_mark_write" ]
+ do
+ shift
+ done
+ echo $1
+}
+
+function computeTimeDiff {
+ # Compute time diff given: startSeconds startNs endSeconds endNS
+
+ # strip leading zeros
+ startS=$(expr 0 + $1)
+ endS=$(expr 0 + $3)
+ if [ "$2" = N ]; then
+ startNs=0
+ endNs=0
+ else
+ startNs=$(expr 0 + $2)
+ endNs=$(expr 0 + $4)
+ fi
+
+ ((startMs=startS*1000 + startNs/1000000))
+ ((endMs=endS*1000 + endNs/1000000))
+ ((diff=endMs-startMs))
+ echo $diff
+}
+
+function log2msec {
+ in=$1
+ in=${in:=0.0}
+ set -- $(echo $in | tr . " ")
+ # shell addition via (( )) doesn't like leading zeroes in msecs
+ # field so remove leading zeroes
+ msecfield=$(expr 0 + $2)
+
+ ((msec=$1*1000000+msecfield))
+ ((msec=msec/1000))
+ echo $msec
+}
+
+function getStartTime {
+ # extract event indicating beginning of start sequence
+ # a) look for a "launching" event indicating start from scratch
+ # b) look for another activity getting a pause event
+ _app=$1
+ traceout=$2
+ ret=0
+ s=$(grep "Binder.*tracing_mark_write.*launching" $traceout 2>/dev/null | head -1| tr [\(\)\[\] :] " ")
+ if [ -z "$s" ]; then
+ s=$(grep activityPause $traceout | head -1 2>/dev/null| tr [\(\)\[\] :] " ")
+ else
+ vout $_app was restarted!
+ ret=1
+ fi
+ vout STARTLOG: $s
+ log2msec $(findtimestamp $s)
+ return $ret
+}
+
+function getEndTime {
+ # extract event indicating end of start sequence. We use the
+ # first surfaceflinger event associated with the target activity
+ _app=$1
+ traceout=$2
+ f=$(grep "surfaceflinger.*tracing_mark_write.*$_app" $traceout 2>/dev/null |
+ grep -v Starting | head -1 | tr [\(\)\[\] :] " ")
+ if [ -z "$f" ]; then
+ # Hmm. sf symbols may not be there... get the pid
+ pid=$(${ADB}pidof /system/bin/surfaceflinger | tr "[ ]" "[ ]")
+ f=$(grep " <...>-$pid.*tracing_mark_write.*$_app" $traceout 2>/dev/null |
+ grep -v Starting | head -1 | tr [\(\)\[\] :] " ")
+ fi
+ vout ENDLOG: $f
+ log2msec $(findtimestamp $f)
+}
+
+function resetJankyFrames {
+ ${ADB}dumpsys gfxinfo $1 reset 2>&1 >/dev/null
+}
+
+function getJankyFrames {
+ if [ -z "$ADB" ]; then
+ # Note: no awk or sed on devices so have to do this
+ # purely with bash
+ total=0
+ janky=0
+ /system/bin/dumpsys gfxinfo | grep " frames" | while read line
+ do
+ if echo $line | grep -q "Total frames"; then
+ set -- $line
+ ((total=total+$4))
+ elif echo $line | grep -q "Janky frames"; then
+ set -- $line
+ ((janky=janky+$3))
+ fi
+ # Note: no tail, awk, or sed on 5.x so get final
+ # sum via most recently written file
+ echo $total $janky > ./janky.$$
+ done
+ cat ./janky.$$
+ rm -f ./janky.$$
+ else
+ ${ADB}dumpsys gfxinfo $1 | sed -e 's/ //' | awk '
+ BEGIN { total=0; janky=0; }
+ /Total frames/ { total+=$4; }
+ /Janky frames/ { janky+=$3; }
+ END { printf "%d %d\n", total, janky; }'
+ fi
+}
+
+function checkForDirectReclaim {
+ # look for any reclaim events in atrace output
+ _app=$1
+ traceout=$2
+ if grep -qi reclaim $traceout; then
+ return 1
+ fi
+ return 0
+}
+
+function startInstramentation {
+ # Called at beginning of loop. Turn on instramentation like atrace
+ vout start instramentation $(date)
+ echo =============================== >> $output
+ echo Before iteration >> $output
+ echo =============================== >> $output
+ ${ADB}cat /proc/meminfo 2>&1 >> $output
+ ${ADB}dumpsys meminfo 2>&1 >> $output
+ if [ "$user" = root ]; then
+ vout ${ADB}atrace -b 32768 --async_start $tracecategories
+ ${ADB}atrace -b 32768 --async_start $tracecategories >> $output
+ echo >> $output
+ fi
+}
+
+function stopInstramentation {
+ if [ "$user" = root ]; then
+ vout ${ADB}atrace --async_stop
+ ${ADB}atrace --async_stop > /dev/null
+ fi
+}
+
+function stopAndDumpInstramentation {
+ # Called at beginning of loop. Turn on instramentation like atrace
+ vout stop instramentation $(date)
+ echo =============================== >> $output
+ echo After iteration >> $output
+ echo =============================== >> $output
+ ${ADB}cat /proc/meminfo 2>&1 >> $output
+ ${ADB}dumpsys meminfo 2>&1 >> $output
+ if [ "$user" = root ]; then
+ traceout=$1
+ traceout=${traceout:=$output}
+ echo =============================== >> $traceout
+ echo TRACE >> $traceout
+ echo =============================== >> $traceout
+ if [ $compress -gt 0 ]; then
+ tmpTrace=./tmptrace.$$
+ UNCOMPRESS=$CMDDIR/atrace-uncompress.py
+ > $tmpTrace
+ zarg="-z"
+ ${ADB}atrace -z -b 32768 --async_dump >> $tmpTrace
+ python $UNCOMPRESS $tmpTrace >> $traceout
+ rm -f $tmpTrace
+ else
+ ${ADB}atrace $zarg -b 32768 --async_dump >> $traceout
+ fi
+ vout ${ADB}atrace $zarg --async_dump
+ vout ${ADB}atrace --async_stop
+ ${ADB}atrace --async_stop > /dev/null
+ fi
+}
+
+function getActivityName {
+ cmd="actName=\$${1}Activity"
+ eval $cmd
+ echo $actName
+}
+
+function getPackageName {
+ set -- $(getActivityName $1 | tr "[/]" "[ ]")
+ echo $1
+}
+
+function startActivityFromPackage {
+ if [ "$1" = home ]; then
+ doKeyevent HOME
+ echo 0
+ return 0
+ fi
+ vout $AM_START_NOWAIT -p "$(getPackageName $1)" -c android.intent.category.LAUNCHER -a android.intent.action.MAIN
+ $AM_START_NOWAIT -p "$(getPackageName $1)" -c android.intent.category.LAUNCHER -a android.intent.action.MAIN 2>&1
+ echo 0
+}
+
+function startActivity {
+ if [ "$1" = home ]; then
+ doKeyevent HOME
+ echo 0
+ return 0
+ elif [ "$1" = chromeL ]; then
+ vout $AM_START -p "$(getPackageName $1)" http://www.theverge.com
+ set -- $($AM_START -p "$(getPackageName $1)" http://www.theverge.com | grep ThisTime)
+ else
+ vout $AM_START "$(getActivityName $1)"
+ set -- $($AM_START "$(getActivityName $1)" | grep ThisTime)
+ fi
+ echo $2 | tr "[\r]" "[\n]"
+}
+
+function forceStartActivity {
+ if [ "$1" = chromeL ]; then
+ # force start doesn't work for chrome (hangs on startup)
+ startActivity $*
+ return 0
+ else
+ vout $AM_FORCE_START "$(getActivityName $1)"
+ set -- $($AM_FORCE_START "$(getActivityName $1)" | grep ThisTime)
+ fi
+ echo $2 | tr "[\r]" "[\n]"
+}
+
+function checkActivity {
+ # requires root
+ actName="$(getActivityName $1)"
+ $AM_LIST | grep $actName
+}
+
+#function stopActivity {
+# vout $AM_STOP $(getActivityName $1)
+# $AM_STOP $(getActivityName $1)
+#}
+
+function doSwipe {
+ vout ${ADB}input swipe $*
+ ${ADB}input swipe $*
+}
+
+function doTap {
+ vout ${ADB}input tap $*
+ ${ADB}input tap $*
+}
+
+function doKeyevent {
+ vout $INPUT keyevent $*
+ $INPUT keyevent $*
+}
+
+function checkIsRunning {
+ p=$1
+ shift
+ if ! $PS | grep $p | grep -qv grep; then
+ handleError $*: $p is not running
+ exit 1
+ fi
+}
+
+function checkStartTime {
+ vout checkStartTime $1 v $2
+ if [ -z "$2" ]; then
+ echo false
+ return 2
+ fi
+ if [ "$1" -gt "$2" ]; then
+ echo false
+ return 1
+ fi
+ echo true
+ return 0
+}
+
+function handleError {
+ echo Error: $*
+ stopAndDumpInstramentation
+ if [ $stoponerror -gt 0 ]; then
+ exit 1
+ fi
+}
+
+user=root
+if ${ADB}ls /data 2>/dev/null | grep -q "Permission denied"; then
+ user=shell
+fi
+vout User is $user
+
+if [ $generateActivities -gt 0 ]; then
+ if [ $isOnDevice -gt 0 ]; then
+ echo Error: cannot generate activity list when run on device
+ exit 1
+ fi
+ echo Generating activities...
+ for app in $appList
+ do
+ startActivityFromPackage $app 2>&1 > /dev/null
+ act=$(${ADB}am stack list | grep $(getPackageName $app) | sed -e 's/ //' | head -1 | awk '{ print $2; }')
+ eval "${app}Activity=$act"
+ echo "ACTIVITY: $app --> $(getActivityName $app)"
+ done
+fi
+
diff --git a/tests/workloads/feedly-chrome.sh b/tests/workloads/feedly-chrome.sh
new file mode 100755
index 00000000..4c7002f9
--- /dev/null
+++ b/tests/workloads/feedly-chrome.sh
@@ -0,0 +1,111 @@
+# Script to automate the following sequence:
+# - Open Feedly
+# - Open an article
+# - Scroll to bottome
+# - Open the same article in Chrome
+# - Scroll the article
+# - Back to Feely (should still be in memory)
+# - Home screen
+# ---- repeat ----
+#
+# Currently works on volantis only (verticle orientation)
+#
+
+CMDDIR=$(dirname $0 2>/dev/null)
+CMDDIR=${CMDDIR:=.}
+. $CMDDIR/defs.sh
+
+case "$DEVICE" in
+(volantis)
+ echo volantis...
+ feedlyArticle="500 700"
+ feedlyOptions="1480 100"
+ feedlyBrowserSelect="1350 650"
+ feedlyArticleSwipeUp="700 700 700 50 50"
+ feedlyArticleSwipeDown="700 200 700 700 50"
+ chromeSwipe="700 700 700 50 50"
+ ;;
+(shamu|*)
+ echo shamu...
+ feedlyArticle="676 500"
+ feedlyOptions="1327 207"
+ feedlyBrowserSelect="1278 1191"
+ feedlyArticleSwipeUp="700 1847 700 400 50"
+ feedlyArticleSwipeDown="700 400 700 1847 50"
+ chromeSwipe="700 1847 700 400 50"
+ ;;
+(hammerhead|*)
+ echo "Error: No feedly screen geometry information available for $DEVICE"
+ exit 1;;
+esac
+
+feedlySwitchToTime=600
+
+# start feedly, if not installed, error out
+t=$(forceStartActivity feedly)
+checkIsRunning feedly "initial start of feedly"
+echo Feedly start time = ${t}ms
+
+# start chrome, if not installed, error out
+t=$(forceStartActivity chrome)
+checkIsRunning chrome "initial start of chrome"
+echo Chrome start time = ${t}ms
+sleep 1
+
+feedlyStartTimes=0
+
+cur=1
+while [ $cur -le $iterations ]
+do
+ echo =======================================
+ echo Iteration $cur of $iterations
+ echo =======================================
+ startInstramentation
+ t=$(startActivity feedly)
+ if [ $(checkStartTime "$t" $feedlySwitchToTime) != true ]; then
+ handleError Feedly took too long to start: $t v $feedlySwitchToTime: $?
+ # for now, not fatal
+ # exit 1
+ fi
+ sleep 2
+ ((feedlyStartTimes=feedlyStartTimes+t))
+ echo feedly started in ${t}ms
+ checkIsRunning chrome "switch back to feedly"
+ checkIsRunning googlequicksearchbox "switch back to feedly"
+
+ # click on first article
+ doTap $feedlyArticle
+ sleep 2
+
+ # scroll through article
+ doSwipe $feedlyArticleSwipeUp
+ sleep 5
+ checkIsRunning chrome "feedly swipe"
+ checkIsRunning googlequicksearchbox "feedly swipe"
+
+ # scroll back to top
+ doSwipe $feedlyArticleSwipeDown
+ sleep 2
+
+ # switch to chrome
+ # 1. click on menu bar
+ doTap $feedlyOptions
+ sleep 1
+ # 2. click on browser
+ doTap $feedlyBrowserSelect
+ sleep 10
+
+ checkIsRunning feedly "switch to chrome"
+ checkIsRunning googlequicksearchbox "switch to chrome"
+
+ # Now we're back in chrome, swipe to bottom of article
+ doSwipe $chromeSwipe
+ sleep 2
+ checkIsRunning feedly "swiped chrome"
+ stopInstramentation
+ ((cur=cur+1))
+done
+((feedlyAve=feedlyStartTimes/iterations))
+echo Avg start times: feedly: ${feedlyAve}ms
+
+doKeyevent HOME
diff --git a/tests/workloads/recentfling.sh b/tests/workloads/recentfling.sh
new file mode 100755
index 00000000..68fdb2ff
--- /dev/null
+++ b/tests/workloads/recentfling.sh
@@ -0,0 +1,132 @@
+#
+# Script to start a set of apps, switch to recents and fling it back and forth.
+# For each iteration, Total frames and janky frames are reported.
+#
+# Options are described below.
+#
+# Works for volantis, shamu, and hammerhead. Can be pushed and executed on
+# the device.
+#
+iterations=10
+startapps=1
+capturesystrace=0
+
+function processLocalOption {
+ ret=0
+ case "$1" in
+ (-N) startapps=0;;
+ (-A) unset appList;;
+ (-L) appList=$2; shift; ret=1;;
+ (-T) capturesystrace=1;;
+ (*)
+ echo "$0: unrecognized option: $1"
+ echo; echo "Usage: $0 [options]"
+ echo "-A : use all known applications"
+ echo "-L applist : list of applications"
+ echo " default: $appList"
+ echo "-N : no app startups, just fling"
+ echo "-g : generate activity strings"
+ echo "-i iterations"
+ echo "-T : capture systrace on each iteration"
+ exit 1;;
+ esac
+ return $ret
+}
+
+CMDDIR=$(dirname $0 2>/dev/null)
+CMDDIR=${CMDDIR:=.}
+. $CMDDIR/defs.sh
+
+case $DEVICE in
+(shamu|hammerhead)
+ flingtime=300
+ downCount=2
+ upCount=6
+ UP="70 400 70 100 $flingtime"
+ DOWN="70 100 70 400 $flingtime";;
+(volantis)
+ flingtime=400
+ downCount=5
+ upCount=6
+ UP="70 400 70 70 $flingtime"
+ DOWN="70 70 70 400 $flingtime";;
+(*)
+ echo "Error: No display information available for $DEVICE"
+ exit 1;;
+esac
+
+doKeyevent HOME
+if [ $startapps -gt 0 ]; then
+
+ # start a bunch of apps
+ for app in $appList
+ do
+ echo Starting $app ...
+ t=$(startActivity $app)
+ done
+fi
+
+cur=1
+
+set -- $(getJankyFrames)
+totalFrames=$1
+jankyFrames=$2
+frameSum=0
+jankSum=0
+
+if [ ${totalFrames:=0} -eq 0 ]; then
+#echo Error: could not read frame info with \"dumpsys graphicsstats\"
+ echo Error: could not read frame info with \"dumpsys gfxinfo\"
+ exit 1
+fi
+
+function swipe {
+ count=0
+ while [ $count -lt $2 ]
+ do
+ doSwipe $1
+ ((count=count+1))
+ done
+}
+
+echo Fling recents...
+doKeyevent APP_SWITCH
+
+while [ $cur -le $iterations ]
+do
+ if [ $capturesystrace -gt 0 ]; then
+ ${ADB}atrace --async_start -z -c -b 16000 freq gfx view idle sched
+ fi
+ swipe "$DOWN" $downCount
+ sleep 1
+ swipe "$UP" $upCount
+ sleep 1
+ swipe "$DOWN" $downCount
+ sleep 1
+ swipe "$UP" $upCount
+ sleep 1
+ if [ $capturesystrace -gt 0 ]; then
+ ${ADB}atrace --async_dump -z -c -b 16000 freq gfx view idle sched > trace.${cur}.out
+ fi
+
+ set -- $(getJankyFrames)
+ newTotalFrames=$1
+ newJankyFrames=$2
+ ((totalDiff=newTotalFrames-totalFrames))
+ ((frameSum=frameSum+totalDiff))
+ ((jankyDiff=newJankyFrames-jankyFrames))
+ ((jankSum=jankSum+jankyDiff))
+ if [ "$totalDiff" -eq 0 ]; then
+ echo Error: no frames detected. Is the display off?
+ exit 1
+ fi
+ ((jankPct=jankyDiff*100/totalDiff))
+ totalFrames=$newTotalFrames
+ jankyFrames=$newJankyFrames
+
+ echo Frames: $totalDiff Janks: $jankyDiff \(${jankPct}%\)
+ ((cur=cur+1))
+done
+doKeyevent HOME
+((aveJankPct=jankSum*100/frameSum))
+echo AVE: Frames: $frameSum Janks: $jankSum \(${aveJankPct}%\)
diff --git a/tests/workloads/systemapps.sh b/tests/workloads/systemapps.sh
new file mode 100755
index 00000000..184c4ee4
--- /dev/null
+++ b/tests/workloads/systemapps.sh
@@ -0,0 +1,212 @@
+# 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 view am input memreclaim"
+totaltimetest=0
+forcecoldstart=0
+
+appList="gmail hangouts 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;;
+ (*)
+ 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 "-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
+ 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}
+ 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"
+}
+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")
+}
+
+cur=1
+totaltime=0
+startTimestamp=$(date +"%s %N")
+
+while [ $cur -le $iterations ]
+do
+ if [ $iterations -gt 1 ]; then
+ echo =========================================
+ echo Iteration $cur of $iterations
+ 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 JankyFrames
+ fi
+ fi
+
+ appnum=-1
+ for app in $appList
+ do
+ vout Starting $app...
+ ((appnum=appnum+1))
+ loopTimestamp=$(date +"%s %N")
+ if [ $totaltimetest -gt 0 ]; then
+ # no instramentation, just cycle through the apps
+ if [ $appnum -eq 0 ]; then
+ printf "%-8s %5s(ms) %3s(ms)\n" App Start Iter
+ fi
+ if [ $forcecoldstart -eq 0 ]; then
+ t=$(startActivity $app)
+ else
+ t=$(forceStartActivity $app)
+ fi
+ loopEndTimestamp=$(date +"%s %N")
+ diffTime=$(computeTimeDiff $loopTimestamp $loopEndTimestamp)
+ # Note: "%d" doesn't work right if run on device
+ printf "%-10s %5.0f %5.0f\n" $app $t $diffTime
+ ((totaltime=totaltime+t))
+ continue
+ fi
+ tmpTraceOut="$tmpTraceOutBase-$app.out"
+ >$tmpTraceOut
+ startInstramentation
+ resetJankyFrames $(getPackageName $app)
+ t=$(startActivity $app)
+ # let app finish drawing before checking janks
+ sleep 3
+ set -- $(getJankyFrames $(getPackageName $app))
+ frames=$1
+ janks=$2
+ ((jankPct=100*janks/frames))
+ stopAndDumpInstramentation $tmpTraceOut
+ actName=$(getActivityName $app)
+ stime=$(getStartTime $actName $tmpTraceOut)
+ relaunch=$?
+ etime=$(getEndTime $actName $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%%)\n" "$app" "$tdiff" "$t" "$relaunch" "$directReclaim" "$janks" "$jankPct"
+ computeStats "$app" "$tdiff" "$relaunch" "$directReclaim" "$frames" "$janks"
+
+ if [ $savetmpfiles -eq 0 ]; then
+ rm -f $tmpTraceOut
+ 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
+
+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 JankyFrames
+ for app in $appList
+ do
+ set -- $(getStats $app)
+ sum=$3
+ ((ave=sum/iterations))
+ frames=$6
+ janks=$7
+ ((jankPct=100*janks/frames))
+ printf "%-12s %5d %5d %5d %5d %5d %5d(%d%%)\n" $app $1 $ave $2 $4 $5 $janks $jankPct
+ done
+fi