Skip to content

Instantly share code, notes, and snippets.

@sleekweasel
Created March 11, 2020 17:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sleekweasel/8b2bf2bec4a214d42be15eae3518520a to your computer and use it in GitHub Desktop.
Save sleekweasel/8b2bf2bec4a214d42be15eae3518520a to your computer and use it in GitHub Desktop.
Bash/adb automation for setting up avds
#!/bin/bash
uidump=/tmp/${0##*/}.$$
unsyncd_uidump_matching_lines() {
adb shell 'rm -f /sdcard/dump.* && uiautomator dump /sdcard/dump.xml 2>/sdcard/dump.err && cat /sdcard/dump.xml' |
tr '<' "\n" |
tee $uidump.full |
grep -Ei "$1" |
xargs -rn1 |
tee $uidump
adb shell 'cat /sdcard/dump.err' 1>&2
}
uidump_full_summary() {
cat $uidump.full |
tr '<' "\n" |
grep = |
sed 's/[a-z-]*="\(true\|false\|\)" *//g'
}
wait_max() {
if [ "$lastwait" != "$2" ] ; then
timeout=0
lastwait="$2"
fi
echo "($timeout/$1) $2"
timeout=$[timeout + 1]
if [ $timeout -gt $1 ] ; then
[ -n "$3" ] && echo "DIAGNOSTIC: $(eval $3)"
echo "ABORTING: TIMEOUT exit 1"
${RUN_STUFF:-true} && exit 1
fi
}
wait_uidump_for() {
wait_max 15 "== Waiting for '$1'"
until unsyncd_uidump_matching_lines "$1" | grep bounds ; do
wait_max 15 "== Waiting for '$1'" uidump_full_summary
done
}
wait_uidump_key_for() {
wait_max 15 "== Waiting for '$2'"
until unsyncd_uidump_matching_lines "$2" | grep bounds ; do
adb shell input keyevent $1
wait_max 15 "== Waiting for '$2'" uidump_full_summary
done
}
wait_uidump_gone() {
wait_max 15 "== Waiting for '$1' to go"
while unsyncd_uidump_matching_lines "$1" | grep bounds ; do
wait_max 15 "== Waiting for '$1' to go" uidump_full_summary
done
}
# bounds=[129,48][384,120] extra lines = $5 $6 $7 $8 etc.
bounds_to_numargs='set $(grep bounds $uidump | tr -c 0-9 " ")'
click_first_find_middle() {
eval $bounds_to_numargs
adb shell input tap $[ ($1 + $3) / 2 ] $[ ($2 + $4) / 2 ]
echo == tap $[ ($1 + $3) / 2 ] $[ ($2 + $4) / 2 ]
}
wait_click_dismiss() {
wait_uidump_for "$1"
click_first_find_middle
wait_uidump_gone "$1"
}
wait_prompt_click_dismiss() {
wait_uidump_for "$1"
wait_uidump_for "$2"
click_first_find_middle
wait_uidump_gone "$1"
}
wait_keyboard() {
wait_max 15 "== keyboard $1"
until adb shell dumpsys input_method | tee $uidump.kbdump | grep -E "$1" ; do
sleep 1
wait_max 15 "== keyboard $1"
done
}
adb_shell_script () {
SCRIPT=/tmp/andremu.prefs.sh
rm -rf $SCRIPT
echo Reading from stdin into $SCRIPT
echo "$2" > $SCRIPT
adb push $SCRIPT /sdcard/prefs.sh
adb shell $1 sh /sdcard/prefs.sh
}
adb_sed() {
adb_shell_script "$1" "
set -x
cp $2 $2.orig
sed -i '$3' $2
"
diff -wu <(adb shell su root cat $2) <(adb shell su root cat $2.orig)
}
# #######################################################
keyboard_first_time_nonsense() {
# The blue pop-up appears several times even if dismissed with its 'x'.
# for i in '' 10 11 12 ; do
# am force-stop com.google.android.dialer
# su root date $i$i$i$i
# am start com.google.android.dialer/.extensions.GoogleDialtactsActivity
# input click search box
# verify blue popup.
# done
# before it finally stops pestering the user.
# Found prefs in /data/data/com.google.android.inputmethod.latin/shared_prefs/com.google.android.inputmethod.latin_preferences.xml
# Doesn't work: kill it?! am force-stop com.google.android.inputmethod.latin
# Seems to work: capitulate and click the stupid 'G' button twice to activate and close its menu.
# it causes <boolean name="pref_key_access_points_opened" value="true" />
# Pressing the hint close just updates these:
# <int name="pref_key_access_points_hint_shown_times" value="2" />
# <long name="pref_key_access_points_hint_shown_timestamp" value="1570698626490" />
echo "Start dialler to trigger keyboard 'first time' blue floaty nonsense."
adb shell am force-stop com.google.android.dialer
adb shell am start com.google.android.dialer/.extensions.GoogleDialtactsActivity
wait_uidump_for 'id/(search_view|search_box_start_search)"'
click_first_find_middle
# PIE:
# Configuration={1.0 310mcc260mnc [en_US] ldltr sw360dp w360dp h682dp 240dpi nrml long port
# finger -keyb/v/h tball/v winConfig={ mBounds=Rect(0, 0 - 0, 0) mAppBounds=Rect(0, 0 - 540, 1060)
# mWindowingMode=fullscreen mActivityType=undefined} s.7}
# OREO shell dumpsys input_method|grep ppBoun
# Configuration={1.0 310mcc260mnc [en_US] ldltr sw360dp w360dp h682dp 240dpi nrml long port
# finger qwerty/v/v -nav/h appBounds=Rect(0, 0 - 540, 1060) s.6}
wait_keyboard mInputShown=true
wait_keyboard ppBounds # [Aa]ppBounds - full screen.
set $(grep -o 'ppBounds=.*' $uidump.kbdump | tr -c 0-9 ' ')
schi=$4 # Need this for status bar offset.
# 1024 here looks to be 1060 - status_bar_height, so add nfyhi=( $schi - 1060 ) to all y.
# contentTopInsets=650 visibleTopInsets=650 touchableInsets=3 touchableRegion=SkRegion((0,650,540,1024))
# contentTopInsets=650 visibleTopInsets=650 touchableInsets=3 touchableRegion=SkRegion((18,529,428,650)(0,650,540,1024))
# Oreo has a 'NO, THANKS' button vs Help build a better keyboard, invisible to uiautomator
# Try clicking it: if we get the stupid floaty blue box, try to dismiss it.
case "$DC_API" in
oreo*)
echo Clicking NO THANKS vs Help build a better keyboard
wait_keyboard mInputShown=true
set $(grep SkRegion $uidump.kbdump | tr -c 0-9 ' ')
shift 3
adb shell input tap $[ $3 / 2 ] $[ ($schi - $4) + ( 6 * $4 + $2 ) / 7 ]
sleep 2 # Should have seen ()() by now.
echo Done click and waited slightly for blue floaty.
esac
echo Trying to kill blue floaty
wait_keyboard SkRegion
set $(grep SkRegion $uidump.kbdump | tr -c 0-9 ' ')
shift 3
case $# in
4) echo Did not find two keyboard boxes. Ooh. ;;
8tapbluefloatycross) echo Try blue floaty cross ; adb shell input tap $[ $3 - $1 - $1 / 2 ] $[ ($schi - $8) + $2 + $1 + $1 / 2 ] ;;
8) tap="tap $[ $1 * 2 ] $[ ($schi - $8) * 2 + $6 ]"
echo Try G menu twice: adb shell input $tap
adb shell input $tap
sleep 1
if adb shell su root cat /data/data/com.google.android.inputmethod.latin/shared_prefs/com.google.android.inputmethod.latin_preferences.xml | grep opened ; then
adb shell input $tap
else
echo ==== FAILED to open G menu
exit 1
fi
;;
*) echo Did not match one or two keyboard boxes. Uh-oh. ;;
esac
echo "Returning home - seems to disable blue floaty, at least for a week"
adb shell input keyevent HOME
}
first_time_camera_stuff() {
# Camera moans about location. Pah.
adb shell pm grant com.android.camera2 android.permission.ACCESS_COARSE_LOCATION
adb shell pm grant com.android.camera2 android.permission.ACCESS_FINE_LOCATION
# adb shell pm grant com.android.camera2 android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
adb shell am start com.android.camera2/com.android.camera.CameraLauncher
# Have to quickly stab the Deny/Allow location pop-up, or it brings up System UI has stopped // Close app
wait_click_dismiss NEXT
}
datasaver_chrome_prefs() {
echo Start chrome to ensure prefs file and do ftu login.
adb shell am start com.android.chrome/com.google.android.apps.chrome.Main
wait_click_dismiss 'ACCEPT' # Welcome to chrome
wait_click_dismiss 'THANKS' # Login? no thanks
echo Stop then start chrome seems reliably raise data saver for 'no thanks'
adb shell am force-stop com.android.chrome
adb shell am start com.android.chrome/com.google.android.apps.chrome.Main
wait_click_dismiss 'THANKS'
CHROME_PREFS=/data/data/com.android.chrome/shared_prefs/com.android.chrome_preferences.xml
if adb shell su root cat $CHROME_PREFS | grep data_reduction ; then
echo === Chrome datasaver killed, apparently.
else
echo === FAILED to kill Chrome datasaver
exit 1
fi
}
# #######################################################
echo DC_API=$DC_API
if ${RUN_STUFF:-true} ; then
echo "Waiting for device"
adb wait-for-device
keyboard_first_time_nonsense
first_time_camera_stuff
# Chrome's first time thing
datasaver_chrome_prefs
echo Going home
adb shell input keyevent HOME
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment