fix(push): hold the ntfy connection as specialUse and restart it on boot
All checks were successful
PR Checks / android-build (pull_request) Successful in 24m52s
All checks were successful
PR Checks / android-build (pull_request) Successful in 24m52s
PushService was a dataSync foreground service. Android 15 stops dataSync after six hours a day and expects the service to stop itself on onTimeout; it never did, so with target 36 the app would crash. A held-open push connection is not a transfer either, which is what Play reserves dataSync for. - The service is now specialUse, with the PROPERTY_SPECIAL_USE_FGS_SUBTYPE reason Play reviews (ntfy does the same on Play). No daily limit. - PushBootReceiver restarts it after BOOT_COMPLETED and MY_PACKAGE_REPLACED when push was on and a registration is saved (a sign-out clears it). It starts the service from the saved topic instead of re-registering, since the network is often not up at boot. PLAN.md M8, decided by the org lead 2026-10-29. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -8,10 +8,14 @@
|
||||
|
||||
<!-- Opt-in push notifications (M7): the runtime notification permission (API 33+)
|
||||
and a foreground service that holds the persistent ntfy connection open — the
|
||||
embedded UnifiedPush distributor, so no separate app is needed (PLAN.md §11). -->
|
||||
embedded UnifiedPush distributor, so no separate app is needed (PLAN.md §11).
|
||||
specialUse, not dataSync (PLAN.md M8, 2026-10-29): a held-open connection is not a
|
||||
transfer, and Android 15 stops dataSync after six hours a day. RECEIVE_BOOT_COMPLETED
|
||||
restarts it after a reboot or an update. -->
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
<application
|
||||
android:name=".RunicGatewayApp"
|
||||
@@ -70,11 +74,28 @@
|
||||
</activity>
|
||||
|
||||
<!-- The embedded distributor's persistent ntfy connection (M7, PLAN.md §11).
|
||||
dataSync foreground type; not exported — started only by PushManager. -->
|
||||
specialUse foreground type, with the reason Play reviews in the property below;
|
||||
not exported — started only by PushManager and PushBootReceiver. -->
|
||||
<service
|
||||
android:name=".core.push.PushService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="dataSync" />
|
||||
android:foregroundServiceType="specialUse">
|
||||
<property
|
||||
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
|
||||
android:value="Instant push notifications without Google services. When the user turns notifications on, this service holds one connection open to the push relay their community's server names, and shows a notification for each message from it. The ongoing notification shows the service is running; turning notifications off or signing out stops it." />
|
||||
</service>
|
||||
|
||||
<!-- Restarts push after a reboot or an app update, if the member had it on and was
|
||||
signed in when the phone went down (PLAN.md M8). Not exported: only the system
|
||||
delivers these broadcasts. -->
|
||||
<receiver
|
||||
android:name=".core.push.PushBootReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
Reference in New Issue
Block a user