Files
404-Layers/scripts/device.sh
ncode 5f9d89d9fb Collapse mode and layer onto one picker row; fix renderer diagnosis
Only one layer is ever active, so neither mode nor layer needs a scrolling
row. Two pickers side by side cost one 44px row instead of two.

The panel needed that space: .pads uses minmax(34px,1fr) rows and sat
exactly at the 34px floor, so the SP-404 illustration clipped at the
bottom. Measured on device:

  strip   96px -> 44px
  panel  433px -> 485px
  pads   142px -> 194px, rows 34px -> 44.75px
  unit overflow 1px -> 0

The layer list is read out of the reference's own chips at render time,
so its set, ordering and counts cannot drift from renderExplore().

Also corrects the renderer-denial root cause. It is not screen state: a
denial was observed with Reason[screen_on & caller care]. Every failure
followed 'adb install -r' and an immediate relaunch has always succeeded,
so device.sh now retries the force-stop/start cycle instead of blaming
the lockscreen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 23:04:13 +03:00

108 lines
4.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Device helpers for driving the app over adb.
#
# TCL's AppBootManagerService sometimes refuses to let the app bind the
# WebView's renderer process:
#
# W/AppBootManager: Result[false]; Target[...SandboxedProcessService0];
# Caller[dev.ncode.sp404layers]; Reason[screen_on & caller care]
# E/cr_ChildProcessConn: Failed to establish the service connection.
#
# With no renderer the page never parses: no crash, no JS error, an empty
# document.title, and DevTools Runtime.evaluate hangs. It is sticky for the life
# of the process, so reopening from Recents keeps the blank window.
#
# Observed trigger is the window just after `adb install -r` replaces the
# package - every failure followed an install, and an immediate relaunch with no
# install has always succeeded. The Reason string reports the current screen
# state ("screen_on" and "screen_off" have both been seen denying), so screen
# state is not the cause. Hence: launch retries the whole cycle.
set -euo pipefail
ADB="${ADB:-$HOME/Android/Sdk/platform-tools/adb}"
PKG=dev.ncode.sp404layers
ACT="$PKG/.MainActivity"
PORT=9333
ATTEMPTS=3
# Not the cause of the denial, but a locked phone cannot be checked visually
# and input keyevents will not reach the app.
ensure_awake() {
"$ADB" shell input keyevent KEYCODE_WAKEUP >/dev/null 2>&1 || true
"$ADB" shell input keyevent 82 >/dev/null 2>&1 || true
local wake lock
wake=$("$ADB" shell dumpsys power | grep -m1 -o 'mWakefulness=[A-Za-z]*' | cut -d= -f2 | tr -d '\r')
lock=$("$ADB" shell dumpsys window | grep -m1 -o 'mDreamingLockscreen=[a-z]*' | cut -d= -f2 | tr -d '\r')
if [ "$wake" != "Awake" ] || [ "$lock" = "true" ]; then
echo "" >&2
echo " #############################################################" >&2
echo " # UNLOCK THE PHONE #" >&2
echo " # wakefulness=$wake lockscreen=$lock" >&2
echo " # Nothing on screen can be verified while it is locked. #" >&2
echo " #############################################################" >&2
echo "" >&2
return 1
fi
echo "device awake and unlocked"
}
keep_awake() {
"$ADB" shell svc power stayon usb >/dev/null
echo "stay-awake while charging: ON (revert with: scripts/device.sh sleep-normal)"
}
sleep_normal() {
"$ADB" shell svc power stayon false >/dev/null
echo "stay-awake: reverted to system default"
}
# Wait until the page is actually parsed, not merely until the activity is up:
# the activity starts fine even when the renderer was denied.
page_loaded() {
local pid sock i
# Read the pid AFTER starting. `adb install -r` kills the old process, so a pid
# captured earlier points at a dead one and the socket lookup fails while the
# app itself is healthy - that produced one false "page never loaded".
pid=$("$ADB" shell pidof "$PKG" | tr -d '\r')
[ -n "$pid" ] || return 1
for i in $(seq 1 40); do
sock=$("$ADB" shell cat /proc/net/unix | grep -o "webview_devtools_remote_$pid" | head -1)
if [ -n "$sock" ]; then
"$ADB" forward "tcp:$PORT" "localabstract:$sock" >/dev/null 2>&1 || true
if curl -s --max-time 1 "http://127.0.0.1:$PORT/json" | grep -q 'SP-404'; then
echo "app loaded (pid $pid, $i polls)"
return 0
fi
fi
done
return 1
}
launch() {
ensure_awake || return 1
local attempt
for attempt in $(seq 1 $ATTEMPTS); do
"$ADB" shell am force-stop "$PKG"
"$ADB" shell am start -W -n "$ACT" >/dev/null
if page_loaded; then
[ "$attempt" -gt 1 ] && echo "(took $attempt attempts - post-install renderer denial)"
return 0
fi
echo "attempt $attempt: renderer denied, retrying" >&2
done
echo "ERROR: page never loaded after $ATTEMPTS attempts." >&2
"$ADB" logcat -d | grep -E 'AppBootManager.*Result\[false\]|ChildProcessConn: Failed' | tail -4 >&2
return 1
}
case "${1:-}" in
awake) ensure_awake ;;
keep-awake) keep_awake ;;
sleep-normal) sleep_normal ;;
launch) launch ;;
*) echo "usage: $0 {awake|keep-awake|sleep-normal|launch}" >&2; exit 2 ;;
esac