feat(android): report full-screen intent availability in getNotificationSettings - #65
Open
KAMRONBEK wants to merge 1 commit into
Open
feat(android): report full-screen intent availability in getNotificationSettings#65KAMRONBEK wants to merge 1 commit into
KAMRONBEK wants to merge 1 commit into
Conversation
…ionSettings Android 14 / API 34 turned USE_FULL_SCREEN_INTENT into a user-revocable special app access: the Play Store revokes it on install for apps outside the calling and alarm categories, apps installed before the device upgraded keep it, and the user can toggle it at any time. A denial is silent. The notification still posts, the promise resolves and nothing throws — only the full screen presentation is dropped. Neither Build.VERSION.SDK_INT nor the manifest permission is a usable signal, so apps had no way to explain the behaviour or offer the fix. Expose it as android.fullScreenIntent on getNotificationSettings(), beside the existing android.alarm field and with the same semantics: ENABLED below API 34, and NotificationManager.canUseFullScreenIntent() at or above it. The check fails open when the NotificationManager is unavailable, so a state we cannot prove never has apps nag the user. Closes marcocrupi#64
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #64.
What
Adds
android.fullScreenIntenttogetNotificationSettings(), anAndroidNotificationSettingreporting whether a notification posted with afullScreenActionwill actually be shown full screen.Why
Android 14 / API 34 turned
USE_FULL_SCREEN_INTENTinto a user-revocable special app access: the Play Store revokes it on install for apps outside the calling and alarm categories, apps installed before the device upgraded keep it, and the user can toggle it at any time under Settings → Apps → Special app access.A denial is completely silent. The notification still posts, the promise resolves, nothing throws — only the full-screen presentation is dropped. None of the signals available to JS help:
Build.VERSION.SDK_INT— the state is per-app and per-user, not per-OS-version.dumpsys packagestill reportsgranted=truewhile the app-op denies it.getNotificationSettings()— reportsauthorizationStatusandandroid.alarm, both of which stay green.The only reliable signal is
NotificationManager.canUseFullScreenIntent(), which has no binding here and cannot be added from JS. A calling app is left ringing without ever taking the lock screen, unable to explain why or offer the one-tap fix.Shape
Deliberately modelled on the existing
alarm←AlarmManager.canScheduleExactAlarms()field — one boolean special-access check, oneAndroidNotificationSetting, no new method on the public API surface:ENABLED— granted at install, always honouredcanUseFullScreenIntent()trueENABLEDcanUseFullScreenIntent()falseDISABLEDENABLED— the same fallbackalarmalready usesFullScreenIntentUtils.canUseFullScreenIntent()fails open when theNotificationManageris unavailable: a state we cannot prove is not one apps should nag the user about.Scope
Detection only. I left out an
openFullScreenIntentSettings()companion toopenAlarmPermissionSettings()on purpose — launchingSettings.ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENTis already possible from JS with any intent launcher, so it isn't a gap. Detection is the part JS cannot do. Happy to add it in a follow-up if you'd like the pair symmetric.Why this touches the core
packages/react-native/android/.../Notifee.javais the only place the value can come from — it's behind a nativeNotificationManagercall, so the bridge layer can't reach it. PerCONTRIBUTING.md("Modifications to the core are therefore fully allowed when the bridge layer isn't the right place"), flagging explicitly since the issue template still says the core isn't modified. The change is 9 lines ingetNotificationSettings, immediately beside thealarmblock it mirrors, plus one new utility.Changes
utility/FullScreenIntentUtils.javaAlarmUtils.canScheduleExactAlarms()Notifee.javafullScreenIntentinto the android settings bundleutility/FullScreenIntentUtilsTest.javatypes/NotificationAndroid.tsNotifeeApiModule.tsrequestPermission×2,getNotificationSettings×2)jest-mock.jstestNotificationSettingsfixture__tests__/NotifeeApiModule.test.tsCHANGELOG.md[Unreleased] → AddedVerification
Run on Windows, Node 22.20.0, JDK 17:
yarn tests_rn:test— 654 passed, 38 suites, including the new case./gradlew :react-native-notify-kit:testDebugUnitTest— the new suite reportstests="5" skipped="0" failures="0" errors="0"yarn validate:all:ts— cleanOne thing to flag so it isn't mistaken for my change: in my Windows environment 14 of the 15 tests in
NotifeeAlarmManagerCurrentBehaviorTestfail withIllegalStateException: Illegal connection pointer(Room/SQLite under Robolectric), which turns the whole Gradle task red. I re-ran that suite on a cleandevcheckout with no changes applied and got the identical 14/15, so it is environmental and pre-existing rather than anything this PR touches. Every other suite is green.On device: not verified for this PR, and I want to be straight about that. The identical native logic has been shipping in a production Android calling app via
patch-package, which is where the problem was found and diagnosed (the tell was a missingfullscreenIntent=line indumpsys notificationwhiledumpsys packagestill showed the permission granted). But the full grant → revoke → re-read cycle on an API 34 device was not re-run against this branch — the coverage here is the Robolectric matrix pinning both sides of the API boundary. Glad to do a device pass if you'd like one before merging.One note: I did not regenerate
docs/react-native/reference/— typedoc output carries source line-number links, so it churns unrelated files. Say the word and I'll runyarn gen:referencehere instead of leaving it to the release.