aboutsummaryrefslogtreecommitdiffstats
path: root/android/app/src/main/java/io/coinos
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-12 15:47:56 -0700
committerAdam Soltys <[email protected]>2026-09-12 15:47:56 -0700
commit85d7858a0ef4b4f3ee60eb2bd5621e4899195935 (patch)
treeffd283a14df52948461a1125c41bff976a4f47cc /android/app/src/main/java/io/coinos
parent9356684a78cddd106d82296a50a637406908cffd (diff)
downloadcoinosv3-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 'android/app/src/main/java/io/coinos')
-rw-r--r--android/app/src/main/java/io/coinos/app/PushReceiver.java20
1 files changed, 16 insertions, 4 deletions
diff --git a/android/app/src/main/java/io/coinos/app/PushReceiver.java b/android/app/src/main/java/io/coinos/app/PushReceiver.java
index faabfaf..508c331 100644
--- a/android/app/src/main/java/io/coinos/app/PushReceiver.java
+++ b/android/app/src/main/java/io/coinos/app/PushReceiver.java
@@ -45,10 +45,13 @@ public class PushReceiver extends BroadcastReceiver {
byte[] bytes = intent.getByteArrayExtra(Push.EXTRA_BYTES_MESSAGE);
String body = bytes != null ? new String(bytes) : intent.getStringExtra(Push.EXTRA_MESSAGE);
// On the WebView build the wallet lives in THIS app's storage, so it
- // can be woken and told to deal with whatever arrived — no tap. On
- // the TWA build the wallet is Chrome's and out of reach, so the
- // notification is the whole of what we can do.
- if (!Wake.start(context, body)) notify(context, body);
+ // can be woken and told to deal with whatever arrived. On the TWA
+ // build the wallet is Chrome's and out of reach, so the notification
+ // is the whole of what we can do.
+ boolean woke = Wake.start(context, body);
+ // A payment or a message is news whether or not we handled it; a
+ // wallet-connect request is not, unless nobody is going to answer it.
+ if (!woke || !isSilent(body)) notify(context, body);
Push.ack(context, intent.getStringExtra(Push.EXTRA_ID));
break;
}
@@ -57,6 +60,15 @@ public class PushReceiver extends BroadcastReceiver {
}
}
+ /** Requests the woken wallet answers by itself need no notification. */
+ private boolean isSilent(String payload) {
+ try {
+ JSONObject j = new JSONObject(payload == null ? "{}" : payload);
+ String reason = j.optString("reason", j.optString("type", ""));
+ return "nwc".equals(reason) || "request".equals(reason);
+ } catch (Exception e) { return false; }
+ }
+
/**
* The payload is the same JSON the web push path sends. We show what it
* describes; anything we don't recognise still gets a notification, because