MOBILEWEBVIEW-133: Add push permission request for jsbridge#695
MOBILEWEBVIEW-133: Add push permission request for jsbridge#695enotniy merged 3 commits intomission/webview-inappfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the WebView JS bridge permission flow to specifically support requesting push notification permission (Android 13+), returning richer response metadata to the JS side, and removing the old generic runtime-permission request activity.
Changes:
- Refactors
WebViewPermissionRequesterto request only push notification permission via a newPushPermissionLauncherbacked byPushActivationActivity. - Extends the JS bridge response payload with
details(required,shouldShowRequestPermissionRationale) and updates serialization/unit tests accordingly. - Removes the obsolete
RuntimePermissionRequestActivityand its manifest entry.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| sdk/src/main/java/cloud/mindbox/mobile_sdk/inapp/presentation/view/WebViewPermissionRequester.kt | Refactors permission request logic to push-only; adds detailed response and new launcher implementation. |
| sdk/src/main/java/cloud/mindbox/mobile_sdk/inapp/presentation/actions/PushActivationActivity.kt | Adds request-id based result bridging via RuntimePermissionRequestBridge. |
| sdk/src/main/java/cloud/mindbox/mobile_sdk/inapp/presentation/actions/RuntimePermissionRequestActivity.kt | Deleted (previous generic permission request activity). |
| sdk/src/main/AndroidManifest.xml | Removes manifest declaration for the deleted activity. |
| sdk/src/test/java/cloud/mindbox/mobile_sdk/inapp/presentation/view/WebViewPermissionRequesterTest.kt | Updates unit tests to cover push permission request behavior and new response details. |
| sdk/src/test/java/cloud/mindbox/mobile_sdk/inapp/presentation/view/WebViewPermissionBridgeSerializationTest.kt | Updates serialization test to assert new details JSON fields. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| internal enum class PermissionType(val value: String) { | ||
| PUSH_NOTIFICATIONS("pushNotifications"), | ||
| LOCATION("location"), | ||
| CAMERA("camera"), | ||
| MICROPHONE("microphone"), | ||
| PHOTO_LIBRARY("photoLibrary") | ||
| PUSH_NOTIFICATIONS("pushNotifications") | ||
| } |
There was a problem hiding this comment.
PermissionType was reduced to only PUSH_NOTIFICATIONS. WebViewInappViewHolder.handlePermissionAction parses the incoming payload type into this enum and will now reject previously supported values (e.g., camera, location, microphone, photoLibrary) with "Unknown permission type". If the JS bridge still uses those types, this becomes a breaking behavior change; consider keeping the enum values (and their handling) or explicitly deprecating/removing support with coordinated client changes.
| val requestId: String = Mindbox.generateRandomUuid() | ||
| val deferredResult = RuntimePermissionRequestBridge.register(requestId) | ||
| withContext(Dispatchers.Main.immediate) { | ||
| activity.startActivity( | ||
| Intent(activity, RuntimePermissionRequestActivity::class.java).apply { | ||
| putExtra(RuntimePermissionRequestActivity.EXTRA_REQUEST_ID, requestId) | ||
| putExtra(RuntimePermissionRequestActivity.EXTRA_PERMISSIONS, permissions) | ||
| Intent(activity, PushActivationActivity::class.java).apply { | ||
| putExtra(PushActivationActivity.EXTRA_REQUEST_ID, requestId) | ||
| } | ||
| ) | ||
| } |
There was a problem hiding this comment.
PushPermissionLauncherImpl.requestPermission registers the request in RuntimePermissionRequestBridge before startActivity. If startActivity(...) throws (e.g., misconfigured manifest, ActivityNotFoundException), the pending request stays in the map and the caller may fail without cleanup. Consider wrapping the launch in try/catch and ensuring the bridge entry is removed/resolved (e.g., resolve with false) on failure/cancellation to avoid leaking pending requests.
| RuntimePermissionRequestBridge.resolve(requestId.orEmpty(), false) | ||
| } | ||
| super.onDestroy() | ||
| } | ||
|
|
||
| private fun finishWithResult(isGranted: Boolean) { | ||
| RuntimePermissionRequestBridge.resolve(requestId.orEmpty(), isGranted) |
There was a problem hiding this comment.
RuntimePermissionRequestBridge.resolve(requestId.orEmpty(), ...) is called even when requestId is null/blank (e.g., activity started without EXTRA_REQUEST_ID). Using orEmpty() can silently mask an invalid/missing request id; if a bridge-based request is ever launched with a missing extra, the awaiting coroutine for the real id would never be resolved. Consider guarding these calls with if (!requestId.isNullOrBlank()) and handling the missing-id case explicitly (log + finish) to avoid hard-to-debug hangs/leaks.
| RuntimePermissionRequestBridge.resolve(requestId.orEmpty(), false) | |
| } | |
| super.onDestroy() | |
| } | |
| private fun finishWithResult(isGranted: Boolean) { | |
| RuntimePermissionRequestBridge.resolve(requestId.orEmpty(), isGranted) | |
| if (!requestId.isNullOrBlank()) { | |
| RuntimePermissionRequestBridge.resolve(requestId!!, false) | |
| } else { | |
| mindboxLogI("PushActivationActivity.onDestroy: missing requestId, skip resolving permission request") | |
| } | |
| } | |
| super.onDestroy() | |
| } | |
| private fun finishWithResult(isGranted: Boolean) { | |
| if (!requestId.isNullOrBlank()) { | |
| RuntimePermissionRequestBridge.resolve(requestId!!, isGranted) | |
| } else { | |
| mindboxLogI("PushActivationActivity.finishWithResult: missing requestId, skip resolving permission request") | |
| } |
https://tracker.yandex.ru/MOBILEWEBVIEW-133