Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e65591431c |
24
CLAUDE.md
24
CLAUDE.md
@@ -76,7 +76,7 @@ Device notes), but nothing on screen can be verified through a lockscreen and
|
||||
| Command | What it does |
|
||||
|---|---|
|
||||
| `npm run device:keep-awake` | Stay awake while charging. Do this at the start of a session. |
|
||||
| `npm run device:launch` | Check awake/unlocked, force-stop, start, wait for the page to actually parse |
|
||||
| `npm run device:launch` | Check awake/unlocked, force-stop, start, wait for the page (debug builds) |
|
||||
| `npm run device:awake` | Just the check — prints a loud warning if locked |
|
||||
| `npm run device:sleep-normal` | Revert the stay-awake setting when finished |
|
||||
|
||||
@@ -84,6 +84,22 @@ Device notes), but nothing on screen can be verified through a lockscreen and
|
||||
starts fine even when the renderer was denied. On failure it prints the
|
||||
`AppBootManager` denial lines rather than leaving a blank window to puzzle over.
|
||||
|
||||
**On a release build it cannot do that, and says so.** A release APK is not
|
||||
`DEBUGGABLE`, so Capacitor never calls `setWebContentsDebuggingEnabled` and
|
||||
`webview_devtools_remote_<pid>` is never opened — the page simply cannot be
|
||||
inspected over adb. Demanding that socket anyway made the helper report
|
||||
`renderer denied` three times for a perfectly healthy app, force-stopping and
|
||||
restarting it each time. It now checks that the process survived and that
|
||||
nothing denied *our* renderer, then prints `page load assumed, not verified`. A
|
||||
blank grey window and a working one are genuinely indistinguishable from here,
|
||||
so that wording is the honest limit, not hedging.
|
||||
|
||||
The denial grep is filtered by package and bounded to the current launch
|
||||
(`logcat -d -T`, timestamp from `adb shell "date +'%m-%d %H:%M:%S.000'"` — the
|
||||
format must be one quoted argument or toybox `date` rejects it). Unfiltered, it
|
||||
printed `com.xiaomi.wearable` denials from minutes earlier and sent one session
|
||||
chasing a denial that had never happened to us.
|
||||
|
||||
It also reads the pid *after* starting the app. `adb install -r` kills the
|
||||
running process, so a pid captured earlier points at a dead process and the
|
||||
devtools socket lookup fails while the app itself is healthy — that produced one
|
||||
@@ -266,8 +282,10 @@ beats an afternoon of synthetic input.
|
||||
|
||||
**Stay awake needs `svc power stayon true`, not `usb`.** The `usb` form writes
|
||||
`stay_on_while_plugged_in = 2`, and this phone charges over AC (`USB powered:
|
||||
false`), so it silently never engages — `mStayOn` stays false. `true` writes 7
|
||||
(any source) and works. The screen timeout is separate and was 30s:
|
||||
false`), so it silently never engages — `mStayOn` stays false. `true` sets every
|
||||
charging-source bit and works; measured as **15** here (AC|USB|wireless|dock),
|
||||
not the 7 an earlier note claimed — 7 predates dock charging. The screen timeout
|
||||
is separate and was 30s:
|
||||
|
||||
```
|
||||
adb shell svc power stayon true
|
||||
|
||||
@@ -49,7 +49,10 @@ ensure_awake() {
|
||||
}
|
||||
|
||||
keep_awake() {
|
||||
"$ADB" shell svc power stayon usb >/dev/null
|
||||
# `usb` writes stay_on_while_plugged_in=2 (USB only) and this phone charges
|
||||
# over AC, so it silently never engages. `true` sets every charging-source bit:
|
||||
# measured as 15 here (AC|USB|wireless|dock), not the 7 that older notes claim.
|
||||
"$ADB" shell svc power stayon true >/dev/null
|
||||
echo "stay-awake while charging: ON (revert with: scripts/device.sh sleep-normal)"
|
||||
}
|
||||
|
||||
@@ -58,6 +61,28 @@ sleep_normal() {
|
||||
echo "stay-awake: reverted to system default"
|
||||
}
|
||||
|
||||
# Release builds are not DEBUGGABLE, so Capacitor never calls
|
||||
# setWebContentsDebuggingEnabled and the devtools socket is never opened. Asking
|
||||
# for it anyway reports "renderer denied" for a perfectly healthy app.
|
||||
is_debuggable() {
|
||||
"$ADB" shell dumpsys package "$PKG" | grep -q DEBUGGABLE
|
||||
}
|
||||
|
||||
# Device-side clock, for bounding logcat to this launch. The format has to be
|
||||
# quoted as one argument: toybox date rejects a bare `+FMT` after `adb shell`.
|
||||
device_now() {
|
||||
"$ADB" shell "date +'%m-%d %H:%M:%S.000'" | tr -d '\r'
|
||||
}
|
||||
|
||||
# Did the renderer get denied since $1? These lines are emitted whether or not
|
||||
# the build is debuggable, and the package filter matters - other apps are
|
||||
# denied constantly and their lines mean nothing here.
|
||||
denied_since() {
|
||||
"$ADB" logcat -d -T "$1" 2>/dev/null \
|
||||
| grep -E "AppBootManager.*Caller\[$PKG\]|cr_ChildProcessConn: Failed" \
|
||||
| grep -v 'Result\[true\]'
|
||||
}
|
||||
|
||||
# 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() {
|
||||
@@ -67,6 +92,19 @@ page_loaded() {
|
||||
# app itself is healthy - that produced one false "page never loaded".
|
||||
pid=$("$ADB" shell pidof "$PKG" | tr -d '\r')
|
||||
[ -n "$pid" ] || return 1
|
||||
|
||||
# Release build: the page cannot be inspected from here at all, so prove what
|
||||
# can be proved - the process survived and nothing denied its renderer. A
|
||||
# blank grey window is indistinguishable from a working one over adb, which is
|
||||
# why this says "assumed" rather than claiming the page loaded.
|
||||
if ! is_debuggable; then
|
||||
sleep 2
|
||||
[ -n "$("$ADB" shell pidof "$PKG" | tr -d '\r')" ] || return 1
|
||||
[ -z "$(denied_since "$1")" ] || return 1
|
||||
echo "app running (pid $pid, release build: page load assumed, not verified)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
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
|
||||
@@ -82,19 +120,23 @@ page_loaded() {
|
||||
|
||||
launch() {
|
||||
ensure_awake || return 1
|
||||
local attempt
|
||||
local attempt started
|
||||
for attempt in $(seq 1 $ATTEMPTS); do
|
||||
started=$(device_now)
|
||||
"$ADB" shell am force-stop "$PKG"
|
||||
"$ADB" shell am start -W -n "$ACT" >/dev/null
|
||||
if page_loaded; then
|
||||
if page_loaded "$started"; then
|
||||
[ "$attempt" -gt 1 ] && echo "(took $attempt attempts - post-install renderer denial)"
|
||||
return 0
|
||||
fi
|
||||
echo "attempt $attempt: renderer denied, retrying" >&2
|
||||
echo "attempt $attempt: no page, 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
|
||||
# Bounded to this launch and to our package. Unfiltered, this printed other
|
||||
# apps' denials from minutes earlier and sent one debugging session chasing a
|
||||
# denial that had never happened to us.
|
||||
denied_since "$started" | tail -4 >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user