diff options
| author | Adam Soltys <[email protected]> | 2026-09-12 15:47:56 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-12 15:47:56 -0700 |
| commit | 85d7858a0ef4b4f3ee60eb2bd5621e4899195935 (patch) | |
| tree | ffd283a14df52948461a1125c41bff976a4f47cc /src/features/nwc.js | |
| parent | 9356684a78cddd106d82296a50a637406908cffd (diff) | |
| download | coinosv3-85d7858a0ef4b4f3ee60eb2bd5621e4899195935.tar.gz coinosv3-85d7858a0ef4b4f3ee60eb2bd5621e4899195935.zip | |
The wake had to be a job, not a foreground service — Android says so.
Tested on a real phone, and the first attempt didn't work at all:
Background started FGS: Disallowed [... code:DENIED ...]
startForegroundService() not allowed due to mAllowStartForeground false
Android 12 forbids starting a foreground service from a broadcast receiver.
An expedited job is the sanctioned replacement — it runs promptly from the
background and needs no notification of its own to apologise for existing —
so WakeService is now WakeJob, and the notification is decided by what
arrived rather than by whether we could wake: a payment or a message is news
either way, a wallet-connect request the wallet answers by itself is not.
Two more things the phone found. A job with a connectivity constraint needs
ACCESS_NETWORK_STATE, or schedule() throws and nothing runs at all. And a
wake with nothing to answer used to hold a WebView open for the full thirty
seconds — a locked wallet, no wallet on the device, or no NWC connections all
end the job immediately now.
Also a bug worth naming: ctx carried `wakeDone` by shorthand, which captured
the binding while it was still undefined (ctx is built before it's defined).
The page could never say it had finished, so every wake ran its full timeout.
It reads through a closure now, like its neighbour.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_019mrt228Upn9nNCwGixzSLx
Diffstat (limited to 'src/features/nwc.js')
| -rw-r--r-- | src/features/nwc.js | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/src/features/nwc.js b/src/features/nwc.js index cefeb31..2cb9d81 100644 --- a/src/features/nwc.js +++ b/src/features/nwc.js @@ -803,16 +803,17 @@ export function nwcFeature(ctx) { // service can stop rather than sit there costing battery. A cap, because // "finished" is not always reachable: the relay may have nothing for us. function serveWake() { - let payload = null; - try { payload = new URLSearchParams(location.search).get('wake'); } catch {} + const payload = ctx.wakePayload ? ctx.wakePayload() : null; if (payload == null) return; - try { history.replaceState(null, '', location.pathname || '/'); } catch {} - const host = typeof window !== 'undefined' && window.CoinosHost; + if (!ctx.wakeDone) return; + let settled = false; + const finish = () => { if (settled) return; settled = true; ctx.wakeDone(); }; + // No connections means nothing here could have been asked of us: end the + // job now rather than hold a WebView open for half a minute on the + // strength of a payload we can't act on. + if (!conns().length) { finish(); return; } listen(); // the request is on a relay; this is what hears it reconcileBg(); // and make sure the pouch behind it is current - if (!host || typeof host.done !== 'function') return; - let settled = false; - const finish = () => { if (settled) return; settled = true; try { host.done(); } catch {} }; // an answer published is the signal we were woken for const stop = onAnswered(() => setTimeout(finish, 1500)); setTimeout(() => { try { stop(); } catch {} finish(); }, 25_000); |
