#!/usr/bin/env bash # Launch every user app with a launcher activity, one by one: unfreeze if frozen, cold start, # wait, screenshot, collect its crash/ANR/keystore log lines, check it is alive and in front, # then stop it and re-freeze. Writes OUT_DIR/results.tsv, OUT_DIR/.png, OUT_DIR/.log. # Usage: test-all-apps.sh OUT_DIR [pkg ...] set -uo pipefail out=$1; shift mkdir -p "$out" a() { adb shell "$@" "$out/results.tsv" for p in "${pkgs[@]}"; do wf=0; grep -qx "$p" <<<"$frozen" && wf=1 [ $wf = 1 ] && a "su -c 'pm enable --user 0 $p'" >/dev/null act=$(a "cmd package resolve-activity --brief -c android.intent.category.LAUNCHER $p" | tr -d '\r' | tail -1) if [[ "$act" != */* ]]; then [ $wf = 1 ] && a "su -c 'pm disable-user --user 0 $p'" >/dev/null printf '%s\t%s\t-\t-\t-\t-\t-\t-\tno launcher activity\n' "$p" "$wf" >> "$out/results.tsv"; continue fi a 'logcat -c' ms=$(a "am start -W -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n '$act'" | awk '/TotalTime/{print $2}') sleep "$WAIT" adb exec-out screencap -p > "$out/$p.png" "$out/$p.log" crash=$(grep -cE "FATAL EXCEPTION|Process: $p|Fatal signal" "$out/$p.log") anr=$(grep -cE "ANR in $p" "$out/$p.log") ks=$(grep -ciE "AEADBadTag|KeyStoreException|VERIFICATION_FAILED|KeyPermanentlyInvalidated|UnrecoverableKey|BadPaddingException|file is not a database|SQLiteDatabaseCorrupt" "$out/$p.log") printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t\n' "$p" "$wf" "${ms:-?}" "${pid:+yes}" "$fg" "$crash" "$anr" "$ks" >> "$out/results.tsv" echo "$p frozen=$wf ms=${ms:-?} alive=${pid:+yes} fg=$fg crash=$crash anr=$anr ks=$ks" a "am force-stop $p; input keyevent KEYCODE_HOME" [ $wf = 1 ] && a "su -c 'pm disable-user --user 0 $p'" >/dev/null done