Skip to content

Commit

Permalink
feat: redirect to app notification settings for PushPrimer (RMCCX-6711)
Browse files Browse the repository at this point in the history
  • Loading branch information
maureenorea-clores committed Jul 18, 2024
1 parent da74256 commit ffb5e2d
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 84 deletions.
14 changes: 13 additions & 1 deletion bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ workflows:
- _common-start
after_run:
- _common-end
- _publish-apk
steps:
- cache-pull@2: {}
- script@1:
Expand Down Expand Up @@ -118,7 +119,7 @@ workflows:
steps:
- set-java-version@1:
inputs:
- set_java_version: '11'
- set_java_version: '17'
- git-clone@6:
inputs:
- fetch_tags: 'yes'
Expand Down Expand Up @@ -255,6 +256,17 @@ workflows:
- username: "$GITHUB_BOT_USERNAME"
- api_token: "$GITHUB_BOT_API_TOKEN"
- name: "$BITRISE_GIT_TAG"
_publish-apk:
steps:
- script@1:
title: Generate test-debug.apk
inputs:
- content: "./gradlew :test:assembleDebug"
- deploy-to-bitrise-io@2:
is_always_run: false
inputs:
- is_enable_public_page: 'false'
- deploy_path: test/build/outputs/apk/debug/test-debug.apk
meta:
bitrise.io:
stack: linux-docker-android-20.04
Expand Down
1 change: 1 addition & 0 deletions inappmessaging/USERGUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ All the events "launch the app event, login event, purchase successful event, cu
* SDKCF-6327: Updated compile and target SDK to API 34 (Android 14).
* RMCCX-6695: Improved the userguide.
* RMCCX-6698: Supported Push Primer feature through CustomJson.
* RMCCX-6711: Supported redirecting to App Notification Settings on tapping PushPrimer button action.
* RMCCX-6706: Prevented showing Push Primer campaign for unsupported devices (Android 12 and below) and when push permission is granted.

#### 7.5.0 (2023-12-12)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import androidx.annotation.VisibleForTesting
import androidx.core.app.ActivityCompat
import com.rakuten.tech.mobile.inappmessaging.runtime.InAppMessaging
import com.rakuten.tech.mobile.inappmessaging.runtime.R
import com.rakuten.tech.mobile.inappmessaging.runtime.data.ui.UiMessage
Expand All @@ -22,12 +21,16 @@ import com.rakuten.tech.mobile.inappmessaging.runtime.data.repositories.HostAppI
import com.rakuten.tech.mobile.inappmessaging.runtime.data.responses.ping.OnClickBehavior
import com.rakuten.tech.mobile.inappmessaging.runtime.data.responses.ping.Trigger
import com.rakuten.tech.mobile.inappmessaging.runtime.data.responses.ping.TriggerAttribute
import com.rakuten.tech.mobile.inappmessaging.runtime.extensions.openAppNotifPermissionSettings
import com.rakuten.tech.mobile.inappmessaging.runtime.extensions.promptPushPermissionDialog
import com.rakuten.tech.mobile.inappmessaging.runtime.manager.EventsManager
import com.rakuten.tech.mobile.inappmessaging.runtime.manager.ImpressionManager
import com.rakuten.tech.mobile.inappmessaging.runtime.manager.MessageReadinessManager
import com.rakuten.tech.mobile.inappmessaging.runtime.manager.PushPrimerTrackerManager
import com.rakuten.tech.mobile.inappmessaging.runtime.utils.BuildVersionChecker
import com.rakuten.tech.mobile.inappmessaging.runtime.utils.CheckPermissionResult
import com.rakuten.tech.mobile.inappmessaging.runtime.utils.InAppLogger
import com.rakuten.tech.mobile.inappmessaging.runtime.utils.PermissionUtil
import java.util.Date
import kotlin.collections.ArrayList

Expand All @@ -38,6 +41,7 @@ import kotlin.collections.ArrayList
internal class MessageActionsCoroutine(
private val campaignRepo: CampaignRepository = CampaignRepository.instance(),
private val readinessManager: MessageReadinessManager = MessageReadinessManager.instance(),
private val hostAppRepo: HostAppInfoRepository = HostAppInfoRepository.instance(),
) {

fun executeTask(uiMessage: UiMessage?, viewResourceId: Int, optOut: Boolean): Boolean {
Expand Down Expand Up @@ -173,17 +177,21 @@ internal class MessageActionsCoroutine(
callback.invoke()
} else if (checker.isAndroidTAndAbove()) {
PushPrimerTrackerManager.campaignId = campaignId
requestPushPrimer()
requestPushNotifPermission()
}
}
}

@SuppressLint("InlinedApi")
private fun requestPushPrimer() {
HostAppInfoRepository.instance().getRegisteredActivity()?.let { act ->
ActivityCompat.requestPermissions(
act, arrayOf(Manifest.permission.POST_NOTIFICATIONS), InAppMessaging.PUSH_PRIMER_REQ_CODE,
)
@SuppressLint("NewApi")
private fun requestPushNotifPermission() {
val activity = hostAppRepo.getRegisteredActivity() ?: return

val permissionResult = PermissionUtil.checkPermission(activity, Manifest.permission.POST_NOTIFICATIONS)
when (permissionResult) {
CheckPermissionResult.CAN_ASK -> activity.promptPushPermissionDialog()
CheckPermissionResult.PREVIOUSLY_DENIED -> activity.promptPushPermissionDialog()
CheckPermissionResult.PERMANENTLY_DENIED -> activity.openAppNotifPermissionSettings()
CheckPermissionResult.GRANTED -> Unit
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.rakuten.tech.mobile.inappmessaging.runtime.extensions

import android.Manifest
import android.app.Activity
import android.content.Intent
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import com.rakuten.tech.mobile.inappmessaging.runtime.InAppMessaging

/**
* Prompts the push notification permission dialog if applicable.
*/
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
internal fun Activity.promptPushPermissionDialog(requestCode: Int = InAppMessaging.PUSH_PRIMER_REQ_CODE): Unit =
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), requestCode)

/**
* Redirects to app push notification Settings.
*/
internal fun Activity.openAppNotifPermissionSettings() {
val intent = Intent()
intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.putExtra("android.provider.extra.APP_PACKAGE", this.packageName)

this.startActivity(intent)
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,58 @@
package com.rakuten.tech.mobile.inappmessaging.runtime.utils

import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat

internal enum class CheckPermissionResult {
CAN_ASK,

/** Permission is denied once. */
PREVIOUSLY_DENIED,

/** Permission is permanently denied, which means native prompt won't show ever again. */
PERMANENTLY_DENIED,

GRANTED,
}

internal object PermissionUtil {

fun isPermissionGranted(context: Context, permission: String) =
context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED

@SuppressWarnings("ReturnCount")
@JvmStatic
fun checkPermission(activity: Activity, permission: String): CheckPermissionResult {
if (isPermissionGranted(activity, permission)) {
return CheckPermissionResult.GRANTED
}

// If permission denied previously
return if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
CheckPermissionResult.PREVIOUSLY_DENIED
} else {
// Permission denied or first time requested
val isFirstTime = isFirstTimeAskingPermission(activity, permission)
return if (isFirstTime) {
firstTimeAskingPermission(activity, permission, false)
CheckPermissionResult.CAN_ASK
} else {
// Handle the feature without permission or ask user to manually allow permission
CheckPermissionResult.PERMANENTLY_DENIED
}
}
}

private fun firstTimeAskingPermission(context: Context, permission: String, isFirstTime: Boolean) {
getPermissionCache(context).edit().putBoolean(permission, isFirstTime).apply()
}

private fun isFirstTimeAskingPermission(context: Context, permission: String): Boolean =
getPermissionCache(context).getBoolean(permission, true)

@SuppressWarnings("kotlin:S6291")
private fun getPermissionCache(context: Context) =
context.getSharedPreferences("iam_permission_prefs", Context.MODE_PRIVATE)
}
Loading

0 comments on commit ffb5e2d

Please sign in to comment.