defs.sh revision 684f65f8602d1e1a79170984acc18421fb8f4c98
1# functions and definitions for workload automation scripts 2# 3# See recentfling.sh, systemapps.sh, and other scripts that use 4# these definitions. 5# 6 7dflttracecategories="gfx input view am rs power sched freq idle load memreclaim" 8dfltAppList="gmail hangouts chrome youtube camera photos play maps calendar earth calculator sheets docs home" 9generateActivities=0 10 11# default activities. Can dynamically generate with -g. 12gmailActivity='com.google.android.gm/com.google.android.gm.ConversationListActivityGmail' 13hangoutsActivity='com.google.android.talk/com.google.android.talk.SigningInActivity' 14chromeActivity='com.android.chrome/com.google.android.apps.chrome.ChromeTabbedActivity' 15chromeLActivity='com.android.chrome/com.google.android.apps.chrome.document.DocumentActivity' 16youtubeActivity='com.google.android.youtube/com.google.android.apps.youtube.app.WatchWhileActivity' 17cameraActivity='com.google.android.GoogleCamera/com.android.camera.CameraActivity' 18playActivity='com.android.vending/com.google.android.finsky.activities.MainActivity' 19feedlyActivity='com.devhd.feedly/com.devhd.feedly.Main' 20photosActivity='com.google.android.apps.plus/com.google.android.apps.photos.phone.PhotosHomeActivity' 21mapsActivity='com.google.android.apps.maps/com.google.android.maps.MapsActivity' 22calendarActivity='com.google.android.calendar/com.android.calendar.AllInOneActivity' 23earthActivity='com.google.earth/com.google.earth.EarthActivity' 24calculatorActivity='com.android.calculator2/com.android.calculator2.Calculator' 25sheetsActivity='com.google.android.apps.docs.editors.sheets/com.google.android.apps.docs.app.NewMainProxyActivity' 26docsActivity='com.google.android.apps.docs.editors.docs/com.google.android.apps.docs.app.NewMainProxyActivity' 27operaActivity='com.opera.mini.native/com.opera.mini.android.Browser' 28firefoxActivity='org.mozilla.firefox/org.mozilla.firefox.App' 29homeActivity='com.google.android.googlequicksearchbox/com.google.android.launcher.GEL' 30 31function showUsage { 32 echo "$0: unrecognized option: $1" 33 echo; echo "Usage: $0 [options]" 34 echo "-e : stop on error" 35 echo "-i iterations" 36 echo "-n : keep trace files" 37 echo "-o output file" 38 echo "-s device : adb device" 39 echo "-t trace categories" 40 echo "-g : generate activity strings" 41} 42 43DEVICE=unknown 44 45# handle args 46while [ $# -gt 0 ] 47do 48 case "$1" in 49 (-d) DEVICE=$2; shift;; 50 (-e) stoponerror=1;; 51 (-n) savetmpfiles=1;; 52 (-t) tracecategories=$2; shift;; 53 (-i) iterations=$2; shift;; 54 (-o) output=$2; shift;; 55 (-v) verbose=1;; 56 (-nz) compress=0;; 57 (-s) deviceName=$2; shift;; 58 (-g) generateActivities=1;; 59 (--) ;; 60 (*) 61 chk1=$(functions 2>/dev/null) 62 chk2=$(typeset -F 2>/dev/null) 63 64 if echo $chk1 $chk2 | grep -q processLocalOption; then 65 if ! processLocalOption "$1" "$2"; then 66 shift 67 fi 68 else 69 showUsage $1 70 exit 1 71 fi;; 72 esac 73 shift 74done 75 76# check if running on a device 77if ls /etc/* 2>/dev/null | grep -q android.hardware; then 78 ADB="" 79 compress=0 80 isOnDevice=1 81else 82 # do a throw-away adb in case the server is out-of-date 83 adb devices -l 2>&1 >/dev/null 84 85 if [ -z "$deviceName" ]; then 86 devInfo=$(adb devices -l | grep -v ^List | head -1) 87 else 88 devInfo=$(adb devices -l | grep $deviceName) 89 fi 90 set -- $devInfo 91 if [ -z $1 ]; then 92 echo Error: could not find device $deviceName 93 exit 1 94 fi 95 deviceName=$1 96 ADB="adb -s $deviceName shell " 97 DEVICE=$(echo $4 | sed 's/product://') 98 isOnDevice=0 99fi 100 101# default values if not set by options or calling script 102appList=${appList:=$dfltAppList} 103savetmpfiles=${savetmpfiles:=0} 104stoponerror=${stoponerror:=0} 105verbose=${verbose:=0} 106compress=${compress:=1} 107iterations=${iterations:=5} 108tracecategories=${tracecategories:=$dflttracecategories} 109ADB=${ADB:=""} 110output=${output:="./out"} 111 112# clear the output file 113> $output 114 115# ADB commands 116AM_FORCE_START="${ADB}am start -W -S" 117AM_START="${ADB}am start -W" 118AM_START_NOWAIT="${ADB}am start" 119AM_STOP="${ADB}am force-stop" 120AM_LIST="${ADB}am stack list" 121WHO="${ADB}whoami" 122INPUT="${ADB}input" 123PS="${ADB}ps" 124 125function vout { 126 # debug output enabled by -v 127 if [ $verbose -gt 0 ]; then 128 echo DEBUG: $* >&2 129 echo DEBUG: $* >&2 >> $output 130 fi 131} 132 133function findtimestamp { 134 # extract timestamp from atrace log entry 135 while [ "$2" != "" -a "$2" != "tracing_mark_write" ] 136 do 137 shift 138 done 139 echo $1 140} 141 142function computeTimeDiff { 143 # Compute time diff given: startSeconds startNs endSeconds endNS 144 145 # strip leading zeros 146 startS=$(expr 0 + $1) 147 endS=$(expr 0 + $3) 148 if [ "$2" = N ]; then 149 startNs=0 150 endNs=0 151 else 152 startNs=$(expr 0 + $2) 153 endNs=$(expr 0 + $4) 154 fi 155 156 ((startMs=startS*1000 + startNs/1000000)) 157 ((endMs=endS*1000 + endNs/1000000)) 158 ((diff=endMs-startMs)) 159 echo $diff 160} 161 162function log2msec { 163 in=$1 164 in=${in:=0.0} 165 set -- $(echo $in | tr . " ") 166 # shell addition via (( )) doesn't like leading zeroes in msecs 167 # field so remove leading zeroes 168 msecfield=$(expr 0 + $2) 169 170 ((msec=$1*1000000+msecfield)) 171 ((msec=msec/1000)) 172 echo $msec 173} 174 175function getStartTime { 176 # extract event indicating beginning of start sequence 177 # a) look for a "launching" event indicating start from scratch 178 # b) look for another activity getting a pause event 179 _app=$1 180 traceout=$2 181 ret=0 182 s=$(grep "Binder.*tracing_mark_write.*launching" $traceout 2>/dev/null | head -1| tr [\(\)\[\] 183:] " ") 184 if [ -z "$s" ]; then 185 s=$(grep activityPause $traceout | head -1 2>/dev/null| tr [\(\)\[\] 186:] " ") 187 else 188 vout $_app was restarted! 189 ret=1 190 fi 191 vout STARTLOG: $s 192 log2msec $(findtimestamp $s) 193 return $ret 194} 195 196function getEndTime { 197 # extract event indicating end of start sequence. We use the 198 # first surfaceflinger event associated with the target activity 199 _app=$1 200 traceout=$2 201 f=$(grep "surfaceflinger.*tracing_mark_write.*$_app" $traceout 2>/dev/null | 202 grep -v Starting | head -1 | tr [\(\)\[\] 203:] " ") 204 if [ -z "$f" ]; then 205 # Hmm. sf symbols may not be there... get the pid 206 pid=$(${ADB}pidof /system/bin/surfaceflinger | tr "[ 207]" "[ ]") 208 f=$(grep " <...>-$pid.*tracing_mark_write.*$_app" $traceout 2>/dev/null | 209 grep -v Starting | head -1 | tr [\(\)\[\] 210:] " ") 211 fi 212 vout ENDLOG: $f 213 log2msec $(findtimestamp $f) 214} 215 216function resetJankyFrames { 217 ${ADB}dumpsys gfxinfo $1 reset 2>&1 >/dev/null 218} 219 220function getJankyFrames { 221 if [ -z "$ADB" ]; then 222 # Note: no awk or sed on devices so have to do this 223 # purely with bash 224 total=0 225 janky=0 226 /system/bin/dumpsys gfxinfo | grep " frames" | while read line 227 do 228 if echo $line | grep -q "Total frames"; then 229 set -- $line 230 ((total=total+$4)) 231 elif echo $line | grep -q "Janky frames"; then 232 set -- $line 233 ((janky=janky+$3)) 234 fi 235 # Note: no tail, awk, or sed on 5.x so get final 236 # sum via most recently written file 237 echo $total $janky > ./janky.$$ 238 done 239 cat ./janky.$$ 240 rm -f ./janky.$$ 241 else 242 ${ADB}dumpsys gfxinfo $1 | sed -e 's/ 243//' | awk ' 244 BEGIN { total=0; janky=0; } 245 /Total frames/ { total+=$4; } 246 /Janky frames/ { janky+=$3; } 247 END { printf "%d %d\n", total, janky; }' 248 fi 249} 250 251function checkForDirectReclaim { 252 # look for any reclaim events in atrace output 253 _app=$1 254 traceout=$2 255 if grep -qi reclaim $traceout; then 256 return 1 257 fi 258 return 0 259} 260 261function startInstramentation { 262 # Called at beginning of loop. Turn on instramentation like atrace 263 vout start instramentation $(date) 264 echo =============================== >> $output 265 echo Before iteration >> $output 266 echo =============================== >> $output 267 ${ADB}cat /proc/meminfo 2>&1 >> $output 268 ${ADB}dumpsys meminfo 2>&1 >> $output 269 if [ "$user" = root ]; then 270 vout ${ADB}atrace -b 32768 --async_start $tracecategories 271 ${ADB}atrace -b 32768 --async_start $tracecategories >> $output 272 echo >> $output 273 fi 274} 275 276function stopInstramentation { 277 if [ "$user" = root ]; then 278 vout ${ADB}atrace --async_stop 279 ${ADB}atrace --async_stop > /dev/null 280 fi 281} 282 283function stopAndDumpInstramentation { 284 # Called at beginning of loop. Turn on instramentation like atrace 285 vout stop instramentation $(date) 286 echo =============================== >> $output 287 echo After iteration >> $output 288 echo =============================== >> $output 289 ${ADB}cat /proc/meminfo 2>&1 >> $output 290 ${ADB}dumpsys meminfo 2>&1 >> $output 291 if [ "$user" = root ]; then 292 traceout=$1 293 traceout=${traceout:=$output} 294 echo =============================== >> $traceout 295 echo TRACE >> $traceout 296 echo =============================== >> $traceout 297 if [ $compress -gt 0 ]; then 298 tmpTrace=./tmptrace.$$ 299 UNCOMPRESS=$CMDDIR/atrace-uncompress.py 300 > $tmpTrace 301 zarg="-z" 302 ${ADB}atrace -z -b 32768 --async_dump >> $tmpTrace 303 python $UNCOMPRESS $tmpTrace >> $traceout 304 rm -f $tmpTrace 305 else 306 ${ADB}atrace $zarg -b 32768 --async_dump >> $traceout 307 fi 308 vout ${ADB}atrace $zarg --async_dump 309 vout ${ADB}atrace --async_stop 310 ${ADB}atrace --async_stop > /dev/null 311 fi 312} 313 314function getActivityName { 315 cmd="actName=\$${1}Activity" 316 eval $cmd 317 echo $actName 318} 319 320function getPackageName { 321 set -- $(getActivityName $1 | tr "[/]" "[ ]") 322 echo $1 323} 324 325function startActivityFromPackage { 326 if [ "$1" = home ]; then 327 doKeyevent HOME 328 echo 0 329 return 0 330 fi 331 vout $AM_START_NOWAIT -p "$(getPackageName $1)" -c android.intent.category.LAUNCHER -a android.intent.action.MAIN 332 $AM_START_NOWAIT -p "$(getPackageName $1)" -c android.intent.category.LAUNCHER -a android.intent.action.MAIN 2>&1 333 echo 0 334} 335 336function startActivity { 337 if [ "$1" = home ]; then 338 doKeyevent HOME 339 echo 0 340 return 0 341 elif [ "$1" = chromeL ]; then 342 vout $AM_START -p "$(getPackageName $1)" http://www.theverge.com 343 set -- $($AM_START -p "$(getPackageName $1)" http://www.theverge.com | grep ThisTime) 344 else 345 vout $AM_START "$(getActivityName $1)" 346 set -- $($AM_START "$(getActivityName $1)" | grep ThisTime) 347 fi 348 echo $2 | tr "[\r]" "[\n]" 349} 350 351function forceStartActivity { 352 if [ "$1" = chromeL ]; then 353 # force start doesn't work for chrome (hangs on startup) 354 startActivity $* 355 return 0 356 else 357 vout $AM_FORCE_START "$(getActivityName $1)" 358 set -- $($AM_FORCE_START "$(getActivityName $1)" | grep ThisTime) 359 fi 360 echo $2 | tr "[\r]" "[\n]" 361} 362 363function checkActivity { 364 # requires root 365 actName="$(getActivityName $1)" 366 $AM_LIST | grep $actName 367} 368 369#function stopActivity { 370# vout $AM_STOP $(getActivityName $1) 371# $AM_STOP $(getActivityName $1) 372#} 373 374function doSwipe { 375 vout ${ADB}input swipe $* 376 ${ADB}input swipe $* 377} 378 379function doTap { 380 vout ${ADB}input tap $* 381 ${ADB}input tap $* 382} 383 384function doKeyevent { 385 vout $INPUT keyevent $* 386 $INPUT keyevent $* 387} 388 389function checkIsRunning { 390 p=$1 391 shift 392 if ! $PS | grep $p | grep -qv grep; then 393 handleError $*: $p is not running 394 exit 1 395 fi 396} 397 398function checkStartTime { 399 vout checkStartTime $1 v $2 400 if [ -z "$2" ]; then 401 echo false 402 return 2 403 fi 404 if [ "$1" -gt "$2" ]; then 405 echo false 406 return 1 407 fi 408 echo true 409 return 0 410} 411 412function handleError { 413 echo Error: $* 414 stopAndDumpInstramentation 415 if [ $stoponerror -gt 0 ]; then 416 exit 1 417 fi 418} 419 420user=root 421if ${ADB}ls /data 2>/dev/null | grep -q "Permission denied"; then 422 user=shell 423fi 424vout User is $user 425 426if [ $generateActivities -gt 0 ]; then 427 if [ $isOnDevice -gt 0 ]; then 428 echo Error: cannot generate activity list when run on device 429 exit 1 430 fi 431 echo Generating activities... 432 for app in $appList 433 do 434 startActivityFromPackage $app 2>&1 > /dev/null 435 act=$(${ADB}am stack list | grep $(getPackageName $app) | sed -e 's/ 436//' | head -1 | awk '{ print $2; }') 437 eval "${app}Activity=$act" 438 echo "ACTIVITY: $app --> $(getActivityName $app)" 439 done 440fi 441 442