Skip to content

Commit

Permalink
chore: add activity to handle push click (#249)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrehan27 authored Sep 26, 2023
1 parent 9f2deec commit f7665c1
Show file tree
Hide file tree
Showing 8 changed files with 300 additions and 54 deletions.
23 changes: 22 additions & 1 deletion messagingpush/api/messagingpush.api
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ public final class io/customer/messagingpush/CustomerIOFirebaseMessagingService$

public final class io/customer/messagingpush/MessagingPushModuleConfig : io/customer/sdk/module/CustomerIOModuleConfig {
public static final field Companion Lio/customer/messagingpush/MessagingPushModuleConfig$Companion;
public synthetic fun <init> (ZLio/customer/messagingpush/data/communication/CustomerIOPushNotificationCallback;ZLkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (ZLio/customer/messagingpush/data/communication/CustomerIOPushNotificationCallback;ZLio/customer/messagingpush/config/NotificationClickBehavior;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getAutoTrackPushEvents ()Z
public final fun getNotificationCallback ()Lio/customer/messagingpush/data/communication/CustomerIOPushNotificationCallback;
public final fun getNotificationOnClickBehavior ()Lio/customer/messagingpush/config/NotificationClickBehavior;
public final fun getRedirectDeepLinksToOtherApps ()Z
}

Expand All @@ -38,6 +39,7 @@ public final class io/customer/messagingpush/MessagingPushModuleConfig$Builder :
public synthetic fun build ()Lio/customer/sdk/module/CustomerIOModuleConfig;
public final fun setAutoTrackPushEvents (Z)Lio/customer/messagingpush/MessagingPushModuleConfig$Builder;
public final fun setNotificationCallback (Lio/customer/messagingpush/data/communication/CustomerIOPushNotificationCallback;)Lio/customer/messagingpush/MessagingPushModuleConfig$Builder;
public final fun setNotificationClickBehavior (Lio/customer/messagingpush/config/NotificationClickBehavior;)Lio/customer/messagingpush/MessagingPushModuleConfig$Builder;
public final fun setRedirectDeepLinksToOtherApps (Z)Lio/customer/messagingpush/MessagingPushModuleConfig$Builder;
}

Expand All @@ -58,6 +60,25 @@ public final class io/customer/messagingpush/ModuleMessagingPushFCM : io/custome
public final class io/customer/messagingpush/ModuleMessagingPushFCM$Companion {
}

public final class io/customer/messagingpush/activity/NotificationClickReceiverActivity : android/app/Activity, io/customer/sdk/tracking/TrackableScreen {
public static final field Companion Lio/customer/messagingpush/activity/NotificationClickReceiverActivity$Companion;
public static final field NOTIFICATION_PAYLOAD_EXTRA Ljava/lang/String;
public fun <init> ()V
public final fun getLogger ()Lio/customer/sdk/util/Logger;
public fun getScreenName ()Ljava/lang/String;
}

public final class io/customer/messagingpush/activity/NotificationClickReceiverActivity$Companion {
}

public final class io/customer/messagingpush/config/NotificationClickBehavior : java/lang/Enum {
public static final field ACTIVITY_NO_FLAGS Lio/customer/messagingpush/config/NotificationClickBehavior;
public static final field ACTIVITY_PREVENT_RESTART Lio/customer/messagingpush/config/NotificationClickBehavior;
public static final field RESET_TASK_STACK Lio/customer/messagingpush/config/NotificationClickBehavior;
public static fun valueOf (Ljava/lang/String;)Lio/customer/messagingpush/config/NotificationClickBehavior;
public static fun values ()[Lio/customer/messagingpush/config/NotificationClickBehavior;
}

public abstract interface class io/customer/messagingpush/data/communication/CustomerIOPushNotificationCallback {
public abstract fun createTaskStackFromPayload (Landroid/content/Context;Lio/customer/messagingpush/data/model/CustomerIOParsedPushPayload;)Landroidx/core/app/TaskStackBuilder;
public abstract fun onNotificationComposed (Lio/customer/messagingpush/data/model/CustomerIOParsedPushPayload;Landroidx/core/app/NotificationCompat$Builder;)V
Expand Down
9 changes: 9 additions & 0 deletions messagingpush/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@
<uses-permission android:name="android.permission.INTERNET" />

<application>
<!-- Transparent activity for push interactions -->
<activity
android:name=".activity.NotificationClickReceiverActivity"
android:excludeFromRecents="true"
android:exported="true"
android:noHistory="true"
android:taskAffinity=""
android:theme="@android:style/Theme.Translucent.NoTitleBar" />

<service
android:name=".CustomerIOFirebaseMessagingService"
android:exported="false">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.TaskStackBuilder
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import io.customer.messagingpush.activity.NotificationClickReceiverActivity
import io.customer.messagingpush.data.model.CustomerIOParsedPushPayload
import io.customer.messagingpush.di.deepLinkUtil
import io.customer.messagingpush.di.moduleConfig
Expand Down Expand Up @@ -210,11 +211,11 @@ internal class CustomerIOPushNotificationHandler(
payload = payload,
builder = notificationBuilder
)
createIntentFromLink(
createIntentForNotificationClick(

Check warning on line 214 in messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt#L214

Added line #L214 was not covered by tests
context,
requestCode,
payload
)?.let { pendingIntent ->
).let { pendingIntent ->

Check warning on line 218 in messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt#L218

Added line #L218 was not covered by tests
notificationBuilder.setContentIntent(pendingIntent)
}

Expand Down Expand Up @@ -267,6 +268,27 @@ internal class CustomerIOPushNotificationHandler(
}
}

private fun createIntentForNotificationClick(
context: Context,
requestCode: Int,
payload: CustomerIOParsedPushPayload
): PendingIntent {
val notifyIntent = Intent(context, NotificationClickReceiverActivity::class.java)
notifyIntent.putExtra(NotificationClickReceiverActivity.NOTIFICATION_PAYLOAD_EXTRA, payload)

Check warning on line 277 in messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt#L276-L277

Added lines #L276 - L277 were not covered by tests
// In Android M, you must specify the mutability of each PendingIntent
val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE

Check warning on line 280 in messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt#L280

Added line #L280 was not covered by tests
} else {
PendingIntent.FLAG_UPDATE_CURRENT

Check warning on line 282 in messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt#L282

Added line #L282 was not covered by tests
}
return PendingIntent.getActivity(
context,
requestCode,
notifyIntent,
flags

Check warning on line 288 in messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt#L284-L288

Added lines #L284 - L288 were not covered by tests
)
}

private fun addImage(
imageUrl: String,
builder: NotificationCompat.Builder,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.customer.messagingpush

import io.customer.messagingpush.config.NotificationClickBehavior
import io.customer.messagingpush.config.NotificationClickBehavior.ACTIVITY_NO_FLAGS
import io.customer.messagingpush.data.communication.CustomerIOPushNotificationCallback
import io.customer.sdk.module.CustomerIOModuleConfig

Expand All @@ -14,16 +16,20 @@ import io.customer.sdk.module.CustomerIOModuleConfig
* notifications
* @property redirectDeepLinksToOtherApps flag to support opening urls from
* notification to other native apps or browsers; default true
* @property notificationOnClickBehavior defines the behavior when a notification
* is clicked
*/
class MessagingPushModuleConfig private constructor(
val autoTrackPushEvents: Boolean,
val notificationCallback: CustomerIOPushNotificationCallback?,
val redirectDeepLinksToOtherApps: Boolean
val redirectDeepLinksToOtherApps: Boolean,
val notificationOnClickBehavior: NotificationClickBehavior
) : CustomerIOModuleConfig {
class Builder : CustomerIOModuleConfig.Builder<MessagingPushModuleConfig> {
private var autoTrackPushEvents: Boolean = true
private var notificationCallback: CustomerIOPushNotificationCallback? = null
private var redirectDeepLinksToOtherApps: Boolean = true
private var notificationOnClickBehavior: NotificationClickBehavior = ACTIVITY_NO_FLAGS

/**
* Allows to enable/disable automatic tracking of push events. Auto tracking will generate
Expand Down Expand Up @@ -62,11 +68,23 @@ class MessagingPushModuleConfig private constructor(
return this
}

/**
* Defines the behavior when a notification is clicked.
*
* @param notificationOnClickBehavior the behavior when a notification is clicked; default [NotificationClickBehavior.ACTIVITY_PREVENT_RESTART].
* @see NotificationClickBehavior for more details.
*/
fun setNotificationClickBehavior(notificationOnClickBehavior: NotificationClickBehavior): Builder {
this.notificationOnClickBehavior = notificationOnClickBehavior
return this

Check warning on line 79 in messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt#L78-L79

Added lines #L78 - L79 were not covered by tests
}

override fun build(): MessagingPushModuleConfig {
return MessagingPushModuleConfig(
autoTrackPushEvents = autoTrackPushEvents,
notificationCallback = notificationCallback,
redirectDeepLinksToOtherApps = redirectDeepLinksToOtherApps
redirectDeepLinksToOtherApps = redirectDeepLinksToOtherApps,
notificationOnClickBehavior = notificationOnClickBehavior
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package io.customer.messagingpush.activity

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.core.app.TaskStackBuilder
import io.customer.messagingpush.MessagingPushModuleConfig
import io.customer.messagingpush.config.NotificationClickBehavior
import io.customer.messagingpush.data.model.CustomerIOParsedPushPayload
import io.customer.messagingpush.di.deepLinkUtil
import io.customer.messagingpush.di.moduleConfig
import io.customer.messagingpush.extensions.parcelable
import io.customer.messagingpush.util.DeepLinkUtil
import io.customer.sdk.CustomerIO
import io.customer.sdk.CustomerIOShared
import io.customer.sdk.data.request.MetricEvent
import io.customer.sdk.extensions.takeIfNotBlank
import io.customer.sdk.tracking.TrackableScreen
import io.customer.sdk.util.Logger

/**
* Activity to handle notification click events.
*
* This activity is launched when a notification is clicked. It tracks opened
* metrics, handles the deep link and opens the desired activity in the host app.
*/
class NotificationClickReceiverActivity : Activity(), TrackableScreen {
val logger: Logger by lazy { CustomerIOShared.instance().diStaticGraph.logger }

Check warning on line 28 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L27-L28

Added lines #L27 - L28 were not covered by tests

override fun getScreenName(): String? {
// Return null to prevent this screen from being tracked
return null

Check warning on line 32 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L32

Added line #L32 was not covered by tests
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
handleIntent(data = intent)
}

Check warning on line 38 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L36-L38

Added lines #L36 - L38 were not covered by tests

override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
handleIntent(data = intent)
}

Check warning on line 43 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L41-L43

Added lines #L41 - L43 were not covered by tests

private fun handleIntent(data: Intent?) {
kotlin.runCatching {
val payload: CustomerIOParsedPushPayload? =

Check warning on line 47 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L46-L47

Added lines #L46 - L47 were not covered by tests
data?.extras?.parcelable(NOTIFICATION_PAYLOAD_EXTRA)
if (payload == null) {
logger.error("Payload is null, cannot handle notification intent")

Check warning on line 50 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L50

Added line #L50 was not covered by tests
} else {
processNotificationIntent(payload = payload)

Check warning on line 52 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L52

Added line #L52 was not covered by tests
}
}.onFailure { ex ->
logger.error("Failed to process notification intent: ${ex.message}")
}
finish()
}

Check warning on line 58 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L55-L58

Added lines #L55 - L58 were not covered by tests

private fun processNotificationIntent(payload: CustomerIOParsedPushPayload) {
val sdkInstance = CustomerIO.instanceOrNull(context = this)

Check warning on line 61 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L61

Added line #L61 was not covered by tests
if (sdkInstance == null) {
logger.error("SDK is not initialized, cannot handle notification intent")
return

Check warning on line 64 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L63-L64

Added lines #L63 - L64 were not covered by tests
}

val moduleConfig: MessagingPushModuleConfig = sdkInstance.diGraph.moduleConfig
trackMetrics(moduleConfig, payload)
handleDeepLink(moduleConfig, payload)
}

Check warning on line 70 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L67-L70

Added lines #L67 - L70 were not covered by tests

private fun trackMetrics(
moduleConfig: MessagingPushModuleConfig,
payload: CustomerIOParsedPushPayload
) {
if (moduleConfig.autoTrackPushEvents) {
CustomerIO.instance().trackMetric(
payload.cioDeliveryId,
MetricEvent.opened,
payload.cioDeliveryToken

Check warning on line 80 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L77-L80

Added lines #L77 - L80 were not covered by tests
)
}
}

Check warning on line 83 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L83

Added line #L83 was not covered by tests

private fun handleDeepLink(
moduleConfig: MessagingPushModuleConfig,
payload: CustomerIOParsedPushPayload
) {
val deepLinkUtil: DeepLinkUtil = CustomerIO.instance().diGraph.deepLinkUtil

Check warning on line 89 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L89

Added line #L89 was not covered by tests
val deepLink = payload.deepLink?.takeIfNotBlank()

// check if host app overrides the handling of deeplink
val notificationCallback = moduleConfig.notificationCallback

Check warning on line 93 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L93

Added line #L93 was not covered by tests
val taskStackFromPayload = notificationCallback?.createTaskStackFromPayload(this, payload)
if (taskStackFromPayload != null) {
logger.info("Notification target overridden by createTaskStackFromPayload, starting new stack for link $deepLink")
taskStackFromPayload.startActivities()
return

Check warning on line 98 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L96-L98

Added lines #L96 - L98 were not covered by tests
}

// Get the default intent for the host app
val defaultHostAppIntent = deepLinkUtil.createDefaultHostAppIntent(
context = this,
contentActionLink = null

Check warning on line 104 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L102-L104

Added lines #L102 - L104 were not covered by tests
)
// Check if the deep links are handled within the host app
val deepLinkHostAppIntent = deepLink?.let { link ->
deepLinkUtil.createDeepLinkHostAppIntent(context = this, link = link)

Check warning on line 108 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L108

Added line #L108 was not covered by tests
}
// Check if the deep links can be opened outside the host app
val deepLinkExternalIntent = deepLink?.let { link ->
deepLinkUtil.createDeepLinkExternalIntent(
context = this,
link = link,
startingFromService = true

Check warning on line 115 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L112-L115

Added lines #L112 - L115 were not covered by tests
)
}
val deepLinkIntent: Intent = deepLinkHostAppIntent
?: deepLinkExternalIntent
?: defaultHostAppIntent
?: return
deepLinkIntent.putExtra(NOTIFICATION_PAYLOAD_EXTRA, payload)
logger.info("Dispatching notification with link $deepLink to intent: $deepLinkIntent with behavior: ${moduleConfig.notificationOnClickBehavior}")

Check warning on line 123 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L121-L123

Added lines #L121 - L123 were not covered by tests

when (moduleConfig.notificationOnClickBehavior) {
NotificationClickBehavior.RESET_TASK_STACK -> {
val taskStackBuilder = TaskStackBuilder.create(this).apply {
addNextIntentWithParentStack(deepLinkIntent)
}
taskStackBuilder.startActivities()

Check warning on line 130 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L127-L130

Added lines #L127 - L130 were not covered by tests
}

NotificationClickBehavior.ACTIVITY_PREVENT_RESTART -> {
deepLinkIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or

Check warning on line 134 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L134

Added line #L134 was not covered by tests
Intent.FLAG_ACTIVITY_SINGLE_TOP
startActivity(deepLinkIntent)

Check warning on line 136 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L136

Added line #L136 was not covered by tests
}

NotificationClickBehavior.ACTIVITY_NO_FLAGS -> {
startActivity(deepLinkIntent)

Check warning on line 140 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L140

Added line #L140 was not covered by tests
}
}
}

Check warning on line 143 in messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt

View check run for this annotation

Codecov / codecov/patch

messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt#L143

Added line #L143 was not covered by tests

companion object {
const val NOTIFICATION_PAYLOAD_EXTRA = "CIO_NotificationPayloadExtras"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.customer.messagingpush.config

/**
* Defines the behaviors for what happens when a notification is clicked.
*/
enum class NotificationClickBehavior {

/**
* Resets the task stack to include the deep-linked activity 'D'.
* - Example 1: Stack (A -> B -> C) becomes (D) if D is the deep-linked activity.
* - Example 2: Stack (A -> B -> C) changes to (A -> D) if D is the deep-linked activity and A is the root of the task stack provided by callback.
*
* This is similar to Android's "Set up a regular activity PendingIntent."
* For more info, see [Android Documentation](https://developer.android.com/develop/ui/views/notifications/navigation#DirectEntry).
*/
RESET_TASK_STACK,

/**
* Adds the deep-linked activity 'D' to the existing stack only if it's not already there.
* - Example: Stack (A -> B) becomes (A -> B -> D) if D is the deep-linked activity and not already in the stack.
* - Example: Stack (A -> B -> D) stays as (A -> B -> D) if D is the deep-linked activity and is already in the stack.
*
* The same activity instance will be reused and receive the data in `onNewIntent` if already on top.
*
* This is similar to Android's "Set up a special activity PendingIntent."
* For more info, see [Android Documentation](https://developer.android.com/develop/ui/views/notifications/navigation#ExtendedNotification).
*/
ACTIVITY_PREVENT_RESTART,

/**
* Starts the deep-linked activity without adding any intent flags.
* - Example: Stack (A -> B) becomes (A -> B -> D) if D is the deep-linked target activity.
*
* This behavior relies on the launch mode or flags specified for the activity in the Android manifest.
* System default behaviors will take over if no flags are mentioned.
*/
ACTIVITY_NO_FLAGS
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.customer.messagingpush.extensions
import android.content.res.Resources
import android.os.Build
import android.os.Bundle
import android.os.Parcelable

private val RESOURCE_ID_NULL: Int =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Resources.ID_NULL else 0
Expand All @@ -14,3 +15,14 @@ internal fun Bundle.getMetaDataResource(name: String): Int? {
internal fun Bundle.getMetaDataString(name: String): String? {
return getString(name, null).takeUnless { value -> value.isNullOrBlank() }
}

inline fun <reified T : Parcelable> Bundle.parcelable(key: String): T? = when {
// There is a known bug on Android 13 which can throw NPE on newly added getParcelable method
// The issue is fixed for the next major Android release, but can't be back-ported to Android 13
// The recommended approach is to continue using the older APIs for Android 13 and below
// See following issue for more details
// https://issuetracker.google.com/issues/240585930#comment6
Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU -> getParcelable(key, T::class.java)
else -> @Suppress("DEPRECATION")
getParcelable(key) as? T
}
Loading

0 comments on commit f7665c1

Please sign in to comment.