Files
DroidDeck/tools/device-smoke.sh
MaxsTechReview c5577478ca chore: remove source comments and unused code, translate every missing string (#1965)
* chore(i18n): translate every missing string in all locales

Adds the 87 strings the bottom-screen Dashboard and in-game stats pages
introduced to all 32 locales, plus the 51 older settings strings Japanese
and the 50 Chinese locales were still missing. Every locale now has all
3456 translatable strings with the same placeholders as English.

Also translates 36 entries that were still English where the language
does not use the English word, and makes es-419 touch_app_id use the same
%1$s placeholder as English.

* chore(patches): drop comments from the lines downstream patches add

Removes comment lines and trailing comments from lines our patches add,
with hunk headers recounted. Lines that a later patch uses as context
and the upstream backport 0123 are left as they are.

The gamescope, FEX, proot and xodus series still apply to their pinned
sources, and the patched trees differ only in those comments.
test_hud_frames now finds the HUD writer by its first declaration.

* docs: credit Greenlight, Better xCloud, viture-v2, GameNative and DiRTTelemetryErrorFix

These were credited only in source headers and NOTICE files.

* chore: remove source comments and unused functions

Removes explanatory comments from first-party Kotlin, Java, C, C++,
Rust, TypeScript, Python, shell, Gradle, CMake and workflow files.
License and attribution headers stay, and vendored third-party trees,
generated files and license files are untouched. A shellcheck directive
is kept, and udevmon's fallthrough comments became fallthrough attributes.

Syntax trees and token streams match the previous sources apart from the
comments and Python docstrings. Module docstrings that argparse prints
are kept, and device-smoke.sh prints the same --help text from a heredoc.

Also removes 37 functions and 4 fields that nothing referenced.

* chore: remove comments from the Syncthing integration and the latest main sources

* docs: credit Syncthing and the syncthing-android fork

* chore(i18n): translate the Syncthing strings in all locales

The 107 strings the Syncthing integration added are now in all 32 locales.
sync_web_path_locked names the Syncthing tab by its label.

* docs: credit @xXJSONDeruloXx for the HUD metric readers

The CPU, GPU load, thermal and battery readers come from their
PerformanceHudView pull requests #777, #877, #991, #1406 and #1573.
The FusionHUD credit line is unchanged.

* docs: credit the HUD metric readers to @xXJSONDeruloXx's work
2026-11-01 16:27:27 -05:00

302 lines
12 KiB
Bash
Executable File

#!/usr/bin/env bash
set -u
export MSYS_NO_PATHCONV=1 MSYS2_ARG_CONV_EXCL='*'
usage() {
cat <<'EOF'
Smoke test of a DroidDeck build on a real device, over plain adb (no python, no root).
What it does, in order, and restores afterwards:
1. prints the device (model, Android, kernel, page size, SoC);
2. installs --apk when given and launches the app;
3. checks that the app starts and that nothing in the crash buffer belongs to it;
4. changes the display density and the window size and checks the app keeps its process
(and does not recreate the activity that is on top);
5. on a foldable cycles the device state (half-opened, and with --closed also closed) through
`cmd device_state`, then puts the original state back;
6. reads the newest session folder of a debug build: first frame, last frame rate, the
memory page size, the proot that session ran, and the last process exits.
Usage: tools/device-smoke.sh [--serial SERIAL] [--apk FILE] [--pkg PACKAGE]
[--no-density] [--no-size] [--no-fold] [--closed]
Exit status: 0 when no check failed, 1 when one did, 2 for a usage or device problem.
Not a replacement for tools/droiddeck-scenario, which drives a game through the agent bridge;
this covers what that does not: display changes and foldable states.
EOF
}
pkg=com.droiddeck.launcher
serial=${ANDROID_SERIAL:-}
apk=
do_density=1
do_size=1
do_fold=1
do_closed=0
adb_bin=${ADB:-adb}
while [ $# -gt 0 ]; do
case $1 in
--serial) [ $# -ge 2 ] || { echo "--serial needs a value" >&2; exit 2; }; serial=$2; shift ;;
--apk) [ $# -ge 2 ] || { echo "--apk needs a value" >&2; exit 2; }; apk=$2; shift ;;
--pkg) [ $# -ge 2 ] || { echo "--pkg needs a value" >&2; exit 2; }; pkg=$2; shift ;;
--no-density) do_density=0 ;;
--no-size) do_size=0 ;;
--no-fold) do_fold=0 ;;
--closed) do_closed=1 ;;
-h|--help) usage; exit 0 ;;
*) echo "unknown option: $1" >&2; exit 2 ;;
esac
shift
done
adb_cmd=("$adb_bin")
[ -n "$serial" ] && adb_cmd+=(-s "$serial")
A() {
local out rc
out=$("${adb_cmd[@]}" "$@" 2>&1); rc=$?
[ -z "$out" ] || printf '%s\n' "$out" | tr -d '\r'
return $rc
}
sh_() {
local command= arg
for arg in "$@"; do command+="'${arg//\'/\'\\\'\'}' "; done
A shell "$command"
}
pass=0 fail=0 skip=0
ok() { echo " PASS $*"; pass=$((pass + 1)); }
bad() { echo " FAIL $*"; fail=$((fail + 1)); }
note() { echo " SKIP $*"; skip=$((skip + 1)); }
head_() { printf '\n== %s\n' "$*"; }
state=$(A get-state)
if [ "$state" != "device" ]; then
echo "no authorized device (adb get-state: $state)" >&2
exit 2
fi
density_snapshot=$(sh_ wm density) || density_snapshot=
size_snapshot=$(sh_ wm size) || size_snapshot=
orig_density=$(echo "$density_snapshot" | sed -n 's/.*Physical density: \([0-9]*\).*/\1/p' | head -1)
override_density=$(echo "$density_snapshot" | sed -n 's/.*Override density: \([0-9]*\).*/\1/p' | head -1)
override_size=$(echo "$size_snapshot" | sed -n 's/.*Override size: \([0-9]*x[0-9]*\).*/\1/p' | head -1)
ds=$(sh_ cmd device_state state 2>/dev/null)
orig_state=$(echo "$ds" | sed -n "s/.*Committed state: DeviceState{identifier=\([0-9]*\),.*/\1/p" | head -1)
pre_override=$(echo "$ds" | sed -n "s/.*Override state: DeviceState{identifier=\([0-9]*\),.*/\1/p" | head -1)
density_changed=0 size_changed=0 fold_changed=0
wm_override() { sed -n "s/.*Override $1: \\([0-9x]*\\).*/\\1/p" | head -1; }
restore_density() {
sh_ wm density "${override_density:-reset}" >/dev/null || return 1
local current
current=$(sh_ wm density) || return 1
echo "$current" | grep -q 'Physical density:' || return 1
[ "$(echo "$current" | wm_override density)" = "$override_density" ]
}
restore_size() {
sh_ wm size "${override_size:-reset}" >/dev/null || return 1
local current
current=$(sh_ wm size) || return 1
echo "$current" | grep -q 'Physical size:' || return 1
[ "$(echo "$current" | wm_override size)" = "$override_size" ]
}
restore_fold() { if [ -n "$pre_override" ]; then sh_ cmd device_state state "$pre_override" >/dev/null; else sh_ cmd device_state state reset >/dev/null; fi; }
restore() {
local failed=0
if [ "$density_changed" = 1 ]; then
if restore_density; then density_changed=0; else bad "could not restore display density"; failed=1; fi
fi
if [ "$size_changed" = 1 ]; then
if restore_size; then size_changed=0; else bad "could not restore window size"; failed=1; fi
fi
if [ "$fold_changed" = 1 ]; then
if restore_fold; then fold_changed=0; else bad "could not restore fold override"; failed=1; fi
fi
return "$failed"
}
finish() {
local status=$?
restore || status=1
printf '\n%d passed, %d failed, %d skipped\n' "$pass" "$fail" "$skip"
[ "$fail" = 0 ] || status=1
exit "$status"
}
trap finish EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
top_activity() {
sh_ dumpsys activity activities 2>/dev/null | sed -n 's/.*topResumedActivity=ActivityRecord{[^ ]* u[0-9]* \([^ ]*\) .*/\1/p' | head -1
}
app_pid() { sh_ pidof "$pkg" | awk '{print $1}'; }
app_crashes() {
local out pat
out=$(sh_ logcat -b crash -d) || return 1
pat=$(printf '%s' "$pkg" | sed 's/[.[\*^$]/\\&/g')
printf '%s\n' "$out" | grep -c -E "(Process: |Cmdline: |>>> )$pat([ ,<:]|$)" || true
}
relaunches_of() {
sh_ logcat -b events -d 2>/dev/null | grep -E 'wm_(relaunch|destroy|create)_activity' | grep -c "$1"
}
head_ "Device"
echo " model $(sh_ getprop ro.product.manufacturer) $(sh_ getprop ro.product.model)"
echo " android $(sh_ getprop ro.build.version.release) (API $(sh_ getprop ro.build.version.sdk)), One UI $(sh_ getprop ro.build.version.oneui)"
echo " kernel $(sh_ uname -r)"
page=$(sh_ getconf PAGE_SIZE)
echo " page size $page"
echo " soc $(sh_ getprop ro.soc.manufacturer) $(sh_ getprop ro.soc.model) ($(sh_ getprop ro.board.platform))"
echo " gpu $(sh_ cat /sys/class/kgsl/kgsl-3d0/gpu_model 2>/dev/null)"
echo " display $(sh_ wm size | tr '\n' ' ') $(sh_ wm density | tr '\n' ' ')"
[ "$page" = 4096 ] || [ "$page" = 16384 ] && ok "page size is $page" || bad "page size reads '$page'"
head_ "Install and launch"
sh_ logcat -b crash -c >/dev/null
sh_ logcat -b events -c >/dev/null
if [ -n "$apk" ]; then
r=$(A install -r -t "$apk" | tail -1)
case $r in *Success*) ok "installed $(basename "$apk")" ;; *) bad "install: $r"; exit 1 ;; esac
fi
packages=$(sh_ pm list packages "$pkg") || { echo "could not query installed packages" >&2; exit 2; }
if ! printf '%s\n' "$packages" | grep -Fxq "package:$pkg"; then echo "package $pkg is not installed" >&2; exit 2; fi
if ! launch=$(sh_ am start -n "$pkg/.MainActivity") || printf '%s\n' "$launch" | grep -q '^Error'; then
bad "could not launch $pkg/.MainActivity"
fi
sleep 6
pid=$(app_pid)
[ -n "$pid" ] && ok "process running (pid $pid)" || bad "the app has no process after launch"
t=$(top_activity)
case $t in
"$pkg"/*|*permissioncontroller*|*GrantPermissions*) ok "top activity: $t" ;;
*) bad "top activity is '$t'" ;;
esac
if c=$(app_crashes); then
[ "${c:-0}" = 0 ] && ok "nothing in the crash buffer belongs to the app" || bad "$c crash entries mention the app"
else
bad "could not read the crash buffer"
fi
if [ "$do_density" = 1 ] && [ -n "$orig_density" ]; then
head_ "Density change"
target=$((orig_density * 5 / 4))
before=$(top_activity); pid0=$(app_pid)
sh_ logcat -b events -c >/dev/null
density_changed=1
wm_status=0
sh_ wm density "$target" >/dev/null || wm_status=$?
sleep 6
applied=$(sh_ wm density) || wm_status=1
after=$(top_activity); pid1=$(app_pid)
if [ "$wm_status" -ne 0 ] || [ "$(echo "$applied" | wm_override density)" != "$target" ]; then
bad "wm density failed"
else
if [ -n "$pid1" ] && [ "$pid0" = "$pid1" ]; then
ok "same process after $orig_density -> $target dpi"
else
bad "process changed ($pid0 -> $pid1)"
fi
case $before in "$pkg"/*)
n=$(relaunches_of "${before#*/}")
[ "${n:-0}" = 0 ] && ok "$before was not recreated" || bad "$before was recreated ${n}x"
[ "$after" = "$before" ] && ok "same top activity after the change" || bad "top activity changed ($before -> $after)"
;; *) note "top activity was not the app ($before)" ;; esac
fi
if restore_density; then
density_changed=0
else
bad "could not restore display density"
fi
sleep 3
elif [ "$do_density" = 1 ]; then
note "could not read the original display density"
fi
if [ "$do_size" = 1 ]; then
head_ "Window size change"
phys=$(echo "$size_snapshot" | sed -n 's/.*Physical size: \([0-9]*\)x\([0-9]*\).*/\1 \2/p' | head -1)
set -- $phys
if [ -n "${1:-}" ]; then
w=$(( ($2 * 2 / 3) / 2 * 2 )); h=$1
pid0=$(app_pid)
size_changed=1
wm_status=0
sh_ wm size "${w}x${h}" >/dev/null || wm_status=$?
sleep 6
applied=$(sh_ wm size) || wm_status=1
pid1=$(app_pid)
if [ "$wm_status" -ne 0 ] || [ "$(echo "$applied" | wm_override size)" != "${w}x${h}" ]; then
bad "wm size failed"
elif [ -n "$pid1" ] && [ "$pid0" = "$pid1" ]; then
ok "same process at ${w}x${h}"
else
bad "process changed ($pid0 -> $pid1)"
fi
if restore_size; then
size_changed=0
else
bad "could not restore window size"
fi
sleep 3
else
note "could not read the physical size"
fi
fi
if [ "$do_fold" = 1 ]; then
head_ "Foldable states"
states=$(sh_ cmd device_state print-states 2>/dev/null)
if ! echo "$states" | grep -q "identifier"; then
note "no device_state service (not a foldable, or not permitted)"
elif [ -z "$orig_state" ]; then
note "could not read the current device_state identifier"
else
id_of() { echo "$states" | sed -n "s/.*identifier=\([0-9]*\), name='$1'.*/\1/p" | head -1; }
half=$(id_of HALF_OPENED); closed=$(id_of CLOSED)
cycle() {
pid0=$(app_pid)
fold_changed=1
sh_ cmd device_state state "$2" >/dev/null; sleep 8
got=$(sh_ cmd device_state state | sed -n "s/.*Committed state: DeviceState{identifier=[0-9]*, name='\([A-Z_]*\)'.*/\1/p" | head -1)
pid1=$(app_pid)
[ "$got" = "$1" ] && ok "device state is $1" || note "asked for $1, committed '$got'"
[ -n "$pid1" ] && [ "$pid0" = "$pid1" ] && ok "same process in $1" || bad "process changed in $1 ($pid0 -> $pid1)"
restore_fold; sleep 6
}
if [ -n "$half" ]; then cycle HALF_OPENED "$half"; else note "no HALF_OPENED state"; fi
if [ "$do_closed" = 1 ] && [ -n "$closed" ]; then
cycle CLOSED "$closed"
note "CLOSED turns the screens off: the session pauses (Background behaviour), Resume it from the app"
fi
got=$(sh_ cmd device_state state | sed -n "s/.*Committed state: DeviceState{identifier=\([0-9]*\),.*/\1/p" | head -1)
[ "$got" = "$orig_state" ] && ok "device state restored ($orig_state)" || bad "device state is $got, was $orig_state"
fi
fi
head_ "Session log (debug builds)"
dir=$(sh_ run-as "$pkg" ls -t files/logs 2>/dev/null | head -1)
if [ -z "$dir" ] || echo "$dir" | grep -q -i "not debuggable\|unknown package"; then
note "no readable session folder (release build, or no session has run)"
else
echo " newest session $dir"
ev=$(sh_ run-as "$pkg" cat "files/logs/$dir/events.jsonl" 2>/dev/null)
echo "$ev" | grep -q '"frame.first"' && ok "first frame was drawn" || note "no frame.first in $dir"
echo "$ev" | grep -q '"session.failed"' && bad "session.failed: $(echo "$ev" | grep '"session.failed"' | tail -1 | cut -c1-160)"
report=$(sh_ run-as "$pkg" cat "files/logs/$dir/device.txt" 2>/dev/null)
proot_line=$(echo "$report" | grep 'proot binary' | head -1)
case $proot_line in
*"rootfs fallback"*|*"missing"*) bad "session proot is not the patched binary ($proot_line)" ;;
*"apk"*|*"add-on pack"*) ok "patched proot ($proot_line)" ;;
*) note "device report has no proot binary line (build from before the check)" ;;
esac
app_log=$(sh_ run-as "$pkg" cat "files/logs/$dir/app.log" 2>/dev/null)
echo "$app_log" | grep -Fq 'proot: fast path on (' && ok "proot fast path was on" \
|| note "proot fast path activation was not recorded ($(echo "$report" | grep 'proot fast path' | tr '\n' '; '))"
fps=$(sh_ run-as "$pkg" cat "files/logs/$dir/app.log" 2>/dev/null | grep 'last 10 s:' | tail -1 | sed 's/.*last 10 s: //' | cut -c1-70)
[ -n "$fps" ] && echo " last stats $fps"
sh_ run-as "$pkg" cat "files/logs/$dir/device.txt" 2>/dev/null | grep -E 'Memory page size|^Kernel' | sed 's/^/ report /'
fi
[ "$fail" = 0 ]