Skip to content

fix(android): make FOREGROUND_SERVICE_DATA_SYNC opt-in (fixes #725) - #726

Merged
ened merged 4 commits into
mainfrom
fix/android-fgs-optin
Aug 4, 2026
Merged

fix(android): make FOREGROUND_SERVICE_DATA_SYNC opt-in (fixes #725)#726
ened merged 4 commits into
mainfrom
fix/android-fgs-optin

Conversation

@ened

@ened ened commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Fixes #725 — the plugin always declared FOREGROUND_SERVICE_DATA_SYNC and merged the dataSync type onto SystemForegroundService, so Play Console demanded a dataSync foreground-service declaration + demonstration video from every app — even those that only run plain periodic background tasks.

Change

  • Default manifest now declares only FOREGROUND_SERVICE + FOREGROUND_SERVICE_SHORT_SERVICE (expedited work needs shortService; it is not a Play special type).
  • dataSync is opt-in: set workmanager.enableDataSyncForegroundService=true in gradle.properties (or -P on the CLI) and the build swaps in AndroidManifest.dataSync.xml (adds the permission + dataSync|shortService service type).
  • README documents the opt-in and when it's needed (ForegroundServiceConfig / long-running workers).

Verification (aapt2 dump permissions on the built APK)

Config Permissions in final APK
default FOREGROUND_SERVICE, FOREGROUND_SERVICE_SHORT_SERVICE — no DATA_SYNC
-Pworkmanager.enableDataSyncForegroundService=true + FOREGROUND_SERVICE_DATA_SYNC, service type 0x801 (dataSync|shortService)

Unit tests: 50/50 pass.

ened added 2 commits August 4, 2026 19:20
The plugin always declared FOREGROUND_SERVICE_DATA_SYNC and merged the
dataSync type onto SystemForegroundService, forcing Play Console to ask
every app for a dataSync foreground-service declaration + demonstration
video — even apps that only run plain periodic background tasks.

dataSync is now opt-in: the default manifest declares only
FOREGROUND_SERVICE + FOREGROUND_SERVICE_SHORT_SERVICE (expedited work,
not a Play special type). Apps running long-running workers with the
dataSync type enable it via the
workmanager.enableDataSyncForegroundService Gradle property, which swaps
in AndroidManifest.dataSync.xml (permission + dataSync|shortService
type).

Verified with aapt2 dump on the final APK: default has no DATA_SYNC
permission, opt-in has permission + type 0x801 (dataSync|shortService).
50 unit tests pass.
Runtime guard in resolveForegroundServiceType: when a worker requests the
dataSync foreground service type but FOREGROUND_SERVICE_DATA_SYNC is not
in the merged manifest (the app did not set
workmanager.enableDataSyncForegroundService=true), throw a descriptive
IllegalStateException instead of a cryptic SecurityException on Android
14+ when the service starts. shortService (always declared) is unaffected.

Adds ForegroundServicePermissionTest (Robolectric): dataSync without the
permission throws; shortService builds with the shortService type.
@ened

ened commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator Author

Added a runtime guard per your idea: if a worker requests foregroundServiceType=dataSync but the merged manifest lacks FOREGROUND_SERVICE_DATA_SYNC (the flag was missed), the plugin now throws a descriptive IllegalStateException at the first use — pointing at the gradle property and #725 — instead of a cryptic SecurityException on Android 14+ when the service starts. shortService (always declared) is unaffected. Two new Robolectric tests: dataSync-without-permission throws, shortService builds. 52/52 tests pass locally; CI re-running.

ened added 2 commits August 4, 2026 19:39
Expedited work runs as a shortService FGS on Android 14+, which needs
FOREGROUND_SERVICE_SHORT_SERVICE in the merged manifest. The plugin
declares it by default, but if an app strips it, fail at registration
with a descriptive error instead of a SecurityException at task time.

Shared requireForegroundServicePermission helper (also used by the
dataSync guard). Note: the SDK stubs expose no Manifest.permission
constant for SHORT_SERVICE — the manifest literal string is used.
@ened
ened merged commit 20c8829 into main Aug 4, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Android plugin always declares FOREGROUND_SERVICE_DATA_SYNC even when no foreground service task is used

1 participant