From e348a4627bc55b0479f3c6db57645f7a4eb0db00 Mon Sep 17 00:00:00 2001 From: Rehan Date: Mon, 4 Sep 2023 13:11:11 +0500 Subject: [PATCH 01/26] parcelable extension --- .../extensions/ApplicationInfoExtensions.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/extensions/ApplicationInfoExtensions.kt b/messagingpush/src/main/java/io/customer/messagingpush/extensions/ApplicationInfoExtensions.kt index 6ff1cb703..07a7181b1 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/extensions/ApplicationInfoExtensions.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/extensions/ApplicationInfoExtensions.kt @@ -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 @@ -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 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 +} From d1b7749e637535a42607682cedb6ac85246d47eb Mon Sep 17 00:00:00 2001 From: Rehan Date: Mon, 4 Sep 2023 17:01:21 +0500 Subject: [PATCH 02/26] added push activity --- messagingpush/api/messagingpush.api | 10 ++ messagingpush/src/main/AndroidManifest.xml | 8 ++ .../NotificationClickReceiverActivity.kt | 98 +++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt diff --git a/messagingpush/api/messagingpush.api b/messagingpush/api/messagingpush.api index 528131b7f..9239194f6 100644 --- a/messagingpush/api/messagingpush.api +++ b/messagingpush/api/messagingpush.api @@ -58,6 +58,16 @@ 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 { + public static final field Companion Lio/customer/messagingpush/activity/NotificationClickReceiverActivity$Companion; + public static final field NOTIFICATION_PAYLOAD_EXTRA Ljava/lang/String; + public fun ()V + public final fun getLogger ()Lio/customer/sdk/util/Logger; +} + +public final class io/customer/messagingpush/activity/NotificationClickReceiverActivity$Companion { +} + 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 diff --git a/messagingpush/src/main/AndroidManifest.xml b/messagingpush/src/main/AndroidManifest.xml index 2f4af990f..6efdfa528 100644 --- a/messagingpush/src/main/AndroidManifest.xml +++ b/messagingpush/src/main/AndroidManifest.xml @@ -6,6 +6,14 @@ + + diff --git a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt new file mode 100644 index 000000000..98f2ab813 --- /dev/null +++ b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt @@ -0,0 +1,98 @@ +package io.customer.messagingpush.activity + +import android.app.Activity +import android.content.ActivityNotFoundException +import android.content.Intent +import android.os.Bundle +import io.customer.messagingpush.MessagingPushModuleConfig +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.util.Logger + +class NotificationClickReceiverActivity : Activity() { + val logger: Logger by lazy { CustomerIOShared.instance().diStaticGraph.logger } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + handleIntent(data = intent) + } + + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + handleIntent(data = intent) + } + + private fun handleIntent(data: Intent?) { + val payload: CustomerIOParsedPushPayload? = + data?.extras?.parcelable(NOTIFICATION_PAYLOAD_EXTRA) + if (payload == null) { + logger.error("Payload is null, cannot handle notification intent") + } else { + processNotificationIntent(payload = payload) + } + finish() + } + + private fun processNotificationIntent(payload: CustomerIOParsedPushPayload) { + val sdkInstance = CustomerIO.instanceOrNull(context = this) + if (sdkInstance == null) { + logger.error("SDK is not initialized, cannot handle notification intent") + return + } + + val diGraph = sdkInstance.diGraph + val deepLinkUtil: DeepLinkUtil = diGraph.deepLinkUtil + val moduleConfig: MessagingPushModuleConfig = diGraph.moduleConfig + + val deliveryId = payload.cioDeliveryId + val deliveryToken = payload.cioDeliveryToken + + if (moduleConfig.autoTrackPushEvents) { + sdkInstance.trackMetric(deliveryId, MetricEvent.opened, deliveryToken) + } + + // check if host app overrides the handling of deeplink + val notificationCallback = moduleConfig.notificationCallback + val taskStackBuilder = notificationCallback?.createTaskStackFromPayload(this, payload) + if (taskStackBuilder != null) { + taskStackBuilder.startActivities() + return + } + + val deepLinkIntent = deepLinkUtil.createDeepLinkHostAppIntent( + // check if the deep links are handled within the host app + this, + payload.deepLink + ) ?: payload.deepLink?.let { link -> + // check if the deep links can be opened outside the host app + deepLinkUtil.createDeepLinkExternalIntent( + context = this, + link = link, + startingFromService = true + ) + } ?: deepLinkUtil.createDefaultHostAppIntent( + context = this, + contentActionLink = null + ) + + deepLinkIntent?.let { intent -> + try { + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or + Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED + startActivity(intent) + } catch (ex: ActivityNotFoundException) { + logger.error("Unable to start activity for notification action $payload; ${ex.message}") + } + } + } + + companion object { + const val NOTIFICATION_PAYLOAD_EXTRA = "CIO-Notification-Payload" + } +} From 0626e7d8a01026cf9c1de8581ab136da065729d5 Mon Sep 17 00:00:00 2001 From: Rehan Date: Mon, 4 Sep 2023 17:11:43 +0500 Subject: [PATCH 03/26] updated handler --- .../CustomerIOPushNotificationHandler.kt | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt b/messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt index 6b5fc374a..b9faccff5 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt @@ -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 @@ -210,11 +211,11 @@ internal class CustomerIOPushNotificationHandler( payload = payload, builder = notificationBuilder ) - createIntentFromLink( + createIntentForNotificationClick( context, requestCode, payload - )?.let { pendingIntent -> + ).let { pendingIntent -> notificationBuilder.setContentIntent(pendingIntent) } @@ -267,6 +268,22 @@ 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) + notifyIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP) + return PendingIntent.getActivity( + context, + requestCode, + notifyIntent, + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE + ) + } + private fun addImage( imageUrl: String, builder: NotificationCompat.Builder, From 8773541418697bfa8fd7a01237d3c8fd719225c2 Mon Sep 17 00:00:00 2001 From: Rehan Date: Mon, 4 Sep 2023 17:42:32 +0500 Subject: [PATCH 04/26] added config --- messagingpush/api/messagingpush.api | 11 +++++++- .../MessagingPushModuleConfig.kt | 26 +++++++++++++++++-- .../config/NotificationClickBehavior.kt | 21 +++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt diff --git a/messagingpush/api/messagingpush.api b/messagingpush/api/messagingpush.api index 9239194f6..8cc8c6eef 100644 --- a/messagingpush/api/messagingpush.api +++ b/messagingpush/api/messagingpush.api @@ -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 (ZLio/customer/messagingpush/data/communication/CustomerIOPushNotificationCallback;ZLkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (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 } @@ -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; } @@ -68,6 +70,13 @@ public final class io/customer/messagingpush/activity/NotificationClickReceiverA public final class io/customer/messagingpush/activity/NotificationClickReceiverActivity$Companion { } +public final class io/customer/messagingpush/config/NotificationClickBehavior : java/lang/Enum { + public static final field ALWAYS_RESTART_ACTIVITY Lio/customer/messagingpush/config/NotificationClickBehavior; + public static final field RESTART_ACTIVITY_IF_NEEDED 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 diff --git a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt index 759713e0b..6bc4ac70f 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt @@ -1,5 +1,6 @@ package io.customer.messagingpush +import io.customer.messagingpush.config.NotificationClickBehavior import io.customer.messagingpush.data.communication.CustomerIOPushNotificationCallback import io.customer.sdk.module.CustomerIOModuleConfig @@ -14,16 +15,21 @@ 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 { private var autoTrackPushEvents: Boolean = true private var notificationCallback: CustomerIOPushNotificationCallback? = null private var redirectDeepLinksToOtherApps: Boolean = true + private var notificationOnClickBehavior: NotificationClickBehavior = + NotificationClickBehavior.ALWAYS_RESTART_ACTIVITY /** * Allows to enable/disable automatic tracking of push events. Auto tracking will generate @@ -62,11 +68,27 @@ class MessagingPushModuleConfig private constructor( return this } + /** + * Defines the behavior when a notification is clicked. + *

+ * ALWAYS_RESTART_ACTIVITY: Always restart the activity and create a new task stack. + * RESTART_ACTIVITY_IF_NEEDED: Restart the activity only if needed, and avoid creating a new task stack otherwise. + *

+ * + * @param notificationOnClickBehavior the behavior when a notification is clicked; default ALWAYS_RESTART_ACTIVITY. + * @see NotificationClickBehavior for more details. + */ + fun setNotificationClickBehavior(notificationOnClickBehavior: NotificationClickBehavior): Builder { + this.notificationOnClickBehavior = notificationOnClickBehavior + return this + } + override fun build(): MessagingPushModuleConfig { return MessagingPushModuleConfig( autoTrackPushEvents = autoTrackPushEvents, notificationCallback = notificationCallback, - redirectDeepLinksToOtherApps = redirectDeepLinksToOtherApps + redirectDeepLinksToOtherApps = redirectDeepLinksToOtherApps, + notificationOnClickBehavior = notificationOnClickBehavior ) } } diff --git a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt new file mode 100644 index 000000000..efd30d30c --- /dev/null +++ b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt @@ -0,0 +1,21 @@ +package io.customer.messagingpush.config + +/** + * Defines the behaviors for what happens when a notification is clicked. + */ +enum class NotificationClickBehavior { + + /** + * Always restarts the activity and creates a new task stack upon clicking the notification. + * Corresponds 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). + */ + ALWAYS_RESTART_ACTIVITY, + + /** + * Restarts the activity only if it's necessary when the notification is clicked. + * Corresponds 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). + */ + RESTART_ACTIVITY_IF_NEEDED +} From 75042fd3d2af857994aef70f152c95083a806751 Mon Sep 17 00:00:00 2001 From: Rehan Date: Mon, 4 Sep 2023 18:37:57 +0500 Subject: [PATCH 05/26] config updates --- messagingpush/api/messagingpush.api | 1 + .../messagingpush/MessagingPushModuleConfig.kt | 2 +- .../config/NotificationClickBehavior.kt | 17 ++++++++++++----- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/messagingpush/api/messagingpush.api b/messagingpush/api/messagingpush.api index 8cc8c6eef..d9938017d 100644 --- a/messagingpush/api/messagingpush.api +++ b/messagingpush/api/messagingpush.api @@ -72,6 +72,7 @@ public final class io/customer/messagingpush/activity/NotificationClickReceiverA public final class io/customer/messagingpush/config/NotificationClickBehavior : java/lang/Enum { public static final field ALWAYS_RESTART_ACTIVITY Lio/customer/messagingpush/config/NotificationClickBehavior; + public static final field RESET_TASK_STACK Lio/customer/messagingpush/config/NotificationClickBehavior; public static final field RESTART_ACTIVITY_IF_NEEDED 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; diff --git a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt index 6bc4ac70f..e7b639903 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt @@ -29,7 +29,7 @@ class MessagingPushModuleConfig private constructor( private var notificationCallback: CustomerIOPushNotificationCallback? = null private var redirectDeepLinksToOtherApps: Boolean = true private var notificationOnClickBehavior: NotificationClickBehavior = - NotificationClickBehavior.ALWAYS_RESTART_ACTIVITY + NotificationClickBehavior.RESET_TASK_STACK /** * Allows to enable/disable automatic tracking of push events. Auto tracking will generate diff --git a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt index efd30d30c..7654900ad 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt @@ -6,16 +6,23 @@ package io.customer.messagingpush.config enum class NotificationClickBehavior { /** - * Always restarts the activity and creates a new task stack upon clicking the notification. - * Corresponds to Android's "Set up a regular activity PendingIntent". + * Creates a new task stack, clearing any existing one upon clicking the notification. + * 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). */ - ALWAYS_RESTART_ACTIVITY, + RESET_TASK_STACK, /** * Restarts the activity only if it's necessary when the notification is clicked. - * Corresponds to Android's "Set up a special activity PendingIntent". + * Similar to Android's "Set up a special activity PendingIntent" but without forced restart. * For more info, see [Android Documentation](https://developer.android.com/develop/ui/views/notifications/navigation#ExtendedNotification). */ - RESTART_ACTIVITY_IF_NEEDED + RESTART_ACTIVITY_IF_NEEDED, + + /** + * Always restarts the activity upon clicking the notification. + * Will force restart the activity if it already exists. + * Similar to RESTART_ACTIVITY_IF_NEEDED, but with forced restart. + */ + ALWAYS_RESTART_ACTIVITY } From ef9fc9c74e48eedba4f32965b62a14a82d08ff75 Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 5 Sep 2023 13:07:33 +0500 Subject: [PATCH 06/26] config updates --- messagingpush/api/messagingpush.api | 6 +++--- .../messagingpush/MessagingPushModuleConfig.kt | 2 +- .../messagingpush/config/NotificationClickBehavior.kt | 11 +++++------ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/messagingpush/api/messagingpush.api b/messagingpush/api/messagingpush.api index d9938017d..fa1850cfb 100644 --- a/messagingpush/api/messagingpush.api +++ b/messagingpush/api/messagingpush.api @@ -71,9 +71,9 @@ public final class io/customer/messagingpush/activity/NotificationClickReceiverA } public final class io/customer/messagingpush/config/NotificationClickBehavior : java/lang/Enum { - public static final field ALWAYS_RESTART_ACTIVITY Lio/customer/messagingpush/config/NotificationClickBehavior; - public static final field RESET_TASK_STACK Lio/customer/messagingpush/config/NotificationClickBehavior; - public static final field RESTART_ACTIVITY_IF_NEEDED Lio/customer/messagingpush/config/NotificationClickBehavior; + public static final field ACTIVITY_RESTART_ALWAYS Lio/customer/messagingpush/config/NotificationClickBehavior; + public static final field ACTIVITY_RESTART_IF_NEEDED Lio/customer/messagingpush/config/NotificationClickBehavior; + public static final field TASK_RESET_ALWAYS 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; } diff --git a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt index e7b639903..be9d90c7d 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt @@ -29,7 +29,7 @@ class MessagingPushModuleConfig private constructor( private var notificationCallback: CustomerIOPushNotificationCallback? = null private var redirectDeepLinksToOtherApps: Boolean = true private var notificationOnClickBehavior: NotificationClickBehavior = - NotificationClickBehavior.RESET_TASK_STACK + NotificationClickBehavior.TASK_RESET_ALWAYS /** * Allows to enable/disable automatic tracking of push events. Auto tracking will generate diff --git a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt index 7654900ad..d2efc2b88 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt @@ -10,19 +10,18 @@ enum class NotificationClickBehavior { * 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, + TASK_RESET_ALWAYS, /** * Restarts the activity only if it's necessary when the notification is clicked. - * Similar to Android's "Set up a special activity PendingIntent" but without forced restart. + * 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). */ - RESTART_ACTIVITY_IF_NEEDED, + ACTIVITY_RESTART_IF_NEEDED, /** * Always restarts the activity upon clicking the notification. - * Will force restart the activity if it already exists. - * Similar to RESTART_ACTIVITY_IF_NEEDED, but with forced restart. + * Similar to ACTIVITY_RESTART_IF_NEEDED, but with forced restart (if it is already on top). */ - ALWAYS_RESTART_ACTIVITY + ACTIVITY_RESTART_ALWAYS } From fece5d2e5d93331939e584ad1d84c92a7af160ba Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 5 Sep 2023 13:33:41 +0500 Subject: [PATCH 07/26] doc updates --- .../config/NotificationClickBehavior.kt | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt index d2efc2b88..9d62628d0 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt @@ -6,22 +6,31 @@ package io.customer.messagingpush.config enum class NotificationClickBehavior { /** - * Creates a new task stack, clearing any existing one upon clicking the notification. - * Similar to Android's "Set up a regular activity PendingIntent". + * Always creates a new task stack and clears any existing one upon clicking the notification. + * - Example 1: Stack (A -> B -> C) becomes (D) if D is the target activity. + * - Example 2: Stack (A -> B -> C) changes to (A -> D) if D is the target activity and A is the root of the task stack provided by callback. + * + * 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). */ TASK_RESET_ALWAYS, /** - * Restarts the activity only if it's necessary when the notification is clicked. - * Similar to Android's "Set up a special activity PendingIntent". + * Restarts the target activity only if necessary when the notification is clicked. + * - Example 1: Stack (A -> B) becomes (A -> B -> D) if D is the target activity and not in the stack. + * - Example 2: Stack (A -> B -> D) remains (A -> B -> D) if D is the target activity and is already in the stack. D will not be restarted. + * + * 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_RESTART_IF_NEEDED, /** - * Always restarts the activity upon clicking the notification. - * Similar to ACTIVITY_RESTART_IF_NEEDED, but with forced restart (if it is already on top). + * Always restarts the target activity upon clicking the notification. + * - Example 1: Stack (A -> B) becomes (A -> B -> D) if D is the target activity and not in the stack. + * - Example 2: Stack (A -> B -> D) remains (A -> B -> D) if D is the target activity and is already in the stack. D will be restarted. + * + * This behavior is similar to ACTIVITY_RESTART_IF_NEEDED, but it forces a restart of the activity if it is already on top of the stack. */ ACTIVITY_RESTART_ALWAYS } From 76f0191f74c70fc202aefbb3911c744e257581a4 Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 5 Sep 2023 14:54:35 +0500 Subject: [PATCH 08/26] deep link util updates --- .../messagingpush/util/DeepLinkUtil.kt | 61 +++++++------------ 1 file changed, 21 insertions(+), 40 deletions(-) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/util/DeepLinkUtil.kt b/messagingpush/src/main/java/io/customer/messagingpush/util/DeepLinkUtil.kt index a0816b5de..bcf57291a 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/util/DeepLinkUtil.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/util/DeepLinkUtil.kt @@ -6,7 +6,6 @@ import android.content.pm.PackageManager import android.net.Uri import android.os.Build import io.customer.messagingpush.MessagingPushModuleConfig -import io.customer.messagingpush.lifecycle.MessagingPushLifecycleCallback import io.customer.sdk.util.Logger interface DeepLinkUtil { @@ -54,32 +53,18 @@ class DeepLinkUtilImpl( private val logger: Logger, private val moduleConfig: MessagingPushModuleConfig ) : DeepLinkUtil { - private val notificationIntentFlags: Int = Intent.FLAG_ACTIVITY_NEW_TASK or - Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP - override fun createDefaultHostAppIntent(context: Context, contentActionLink: String?): Intent? { - return context.packageManager.getLaunchIntentForPackage(context.packageName)?.apply { - // Add pending link to open outside host app so open tracking metrics are not affected - putExtra(MessagingPushLifecycleCallback.PENDING_CONTENT_ACTION_LINK, contentActionLink) - } + return context.packageManager.getLaunchIntentForPackage(context.packageName) } override fun createDeepLinkHostAppIntent(context: Context, link: String?): Intent? { - if (link.isNullOrBlank()) { - logger.debug("No link received in push notification content") - return null - } - val intent: Intent? = queryDeepLinksForHostApp(context, Uri.parse(link)) - return if (intent != null) { - intent - } else { + if (intent == null) { logger.info( - "No supporting activity found in host app for link received in" + - " push notification $link" + "No supporting activity found in host app for link received in push notification $link" ) - null } + return intent } override fun createDeepLinkExternalIntent( @@ -88,14 +73,10 @@ class DeepLinkUtilImpl( startingFromService: Boolean ): Intent? { val linkUri = Uri.parse(link) - var intent: Intent? = null + val intent: Intent? if (moduleConfig.redirectDeepLinksToOtherApps) { - intent = queryDeepLinksForThirdPartyApps( - context = context, - uri = linkUri, - startingFromService = startingFromService - ) + intent = queryDeepLinksForThirdPartyApps(context = context, uri = linkUri) if (intent == null) { logger.info( @@ -103,6 +84,8 @@ class DeepLinkUtilImpl( "push notification: $link" ) } + } else { + intent = null } return intent @@ -118,33 +101,31 @@ class DeepLinkUtilImpl( // check if the deep link is handled within the host app val hostAppIntent = Intent(Intent.ACTION_VIEW, uri) hostAppIntent.setPackage(context.packageName) - - hostAppIntent.flags = - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { - notificationIntentFlags - } else { - notificationIntentFlags or Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER - } - return hostAppIntent.takeIfResolvable(context.packageManager) } private fun queryDeepLinksForThirdPartyApps( context: Context, - uri: Uri, - startingFromService: Boolean + uri: Uri ): Intent? { // check if the deep link can be opened by any other app val browsableIntent = Intent(Intent.ACTION_VIEW, uri) - if (startingFromService) { - browsableIntent.flags = notificationIntentFlags - } + val packageManager = context.packageManager + val resolveInfoFlag = PackageManager.MATCH_DEFAULT_ONLY - val resolveInfo = context.packageManager.queryIntentActivities(browsableIntent, 0) + val resolveInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + packageManager.queryIntentActivities( + browsableIntent, + PackageManager.ResolveInfoFlags.of(resolveInfoFlag.toLong()) + ) + } else { + @Suppress("DEPRECATION") + packageManager.queryIntentActivities(browsableIntent, resolveInfoFlag) + } if (resolveInfo.isNotEmpty()) { browsableIntent.setPackage(resolveInfo.first().activityInfo.packageName) } - return browsableIntent.takeIfResolvable(context.packageManager) + return browsableIntent.takeIfResolvable(packageManager) } } From 2b03bf5ee0b8d23998aef50899cfe6ad49cee352 Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 5 Sep 2023 15:05:08 +0500 Subject: [PATCH 09/26] activity updates --- .../NotificationClickReceiverActivity.kt | 90 ++++++++++++++----- 1 file changed, 66 insertions(+), 24 deletions(-) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt index 98f2ab813..b8eccfb74 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt @@ -4,7 +4,9 @@ import android.app.Activity import android.content.ActivityNotFoundException 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 @@ -13,6 +15,7 @@ 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.util.Logger class NotificationClickReceiverActivity : Activity() { @@ -29,12 +32,16 @@ class NotificationClickReceiverActivity : Activity() { } private fun handleIntent(data: Intent?) { - val payload: CustomerIOParsedPushPayload? = - data?.extras?.parcelable(NOTIFICATION_PAYLOAD_EXTRA) - if (payload == null) { - logger.error("Payload is null, cannot handle notification intent") - } else { - processNotificationIntent(payload = payload) + kotlin.runCatching { + val payload: CustomerIOParsedPushPayload? = + data?.extras?.parcelable(NOTIFICATION_PAYLOAD_EXTRA) + if (payload == null) { + logger.error("Payload is null, cannot handle notification intent") + } else { + processNotificationIntent(payload = payload) + } + }.onFailure { ex -> + logger.error("Failed to process notification intent: ${ex.message}") } finish() } @@ -65,34 +72,69 @@ class NotificationClickReceiverActivity : Activity() { return } - val deepLinkIntent = deepLinkUtil.createDeepLinkHostAppIntent( - // check if the deep links are handled within the host app - this, - payload.deepLink - ) ?: payload.deepLink?.let { link -> - // check if the deep links can be opened outside the host app + val deepLink = payload.deepLink?.takeIfNotBlank() + if (deepLink == null) { + logger.debug("No deep link received in push notification content") + } + + // Get the default intent for the host app + val defaultHostAppIntent = deepLinkUtil.createDefaultHostAppIntent( + context = this, + contentActionLink = null + ) + // Check if the deep links are handled within the host app + val deepLinkHostAppIntent = deepLink?.let { link -> + deepLinkUtil.createDeepLinkHostAppIntent(context = this, link = link) + } + // 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 ) - } ?: deepLinkUtil.createDefaultHostAppIntent( - context = this, - contentActionLink = null - ) + } + val deepLinkIntent: Intent = deepLinkHostAppIntent + ?: deepLinkExternalIntent + ?: defaultHostAppIntent + ?: return + deepLinkIntent.putExtra(NOTIFICATION_PAYLOAD_EXTRA, payload) + + try { + when (moduleConfig.notificationOnClickBehavior) { + NotificationClickBehavior.TASK_RESET_ALWAYS -> { + val taskStackBuilder = + moduleConfig.notificationCallback?.createTaskStackFromPayload( + this, + payload + ) ?: kotlin.run { + return@run TaskStackBuilder.create(this).run { + addNextIntentWithParentStack(deepLinkIntent) + } + } + if (taskStackBuilder.intentCount > 0) { + taskStackBuilder.startActivities() + } + } + + NotificationClickBehavior.ACTIVITY_RESTART_IF_NEEDED -> { + deepLinkIntent.flags = + Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP + startActivity(deepLinkIntent) + } - deepLinkIntent?.let { intent -> - try { - intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or - Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED - startActivity(intent) - } catch (ex: ActivityNotFoundException) { - logger.error("Unable to start activity for notification action $payload; ${ex.message}") + NotificationClickBehavior.ACTIVITY_RESTART_ALWAYS -> { + deepLinkIntent.flags = + Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK + startActivity(deepLinkIntent) + } } + } catch (ex: ActivityNotFoundException) { + logger.error("Unable to start activity for notification action $payload; ${ex.message}") } } companion object { - const val NOTIFICATION_PAYLOAD_EXTRA = "CIO-Notification-Payload" + const val NOTIFICATION_PAYLOAD_EXTRA = "CIO_NotificationPayloadExtras" } } From 5da2dffad4bc3f94c902dd71cdb262e6b561f285 Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 5 Sep 2023 15:13:03 +0500 Subject: [PATCH 10/26] fixed config docs --- .../io/customer/messagingpush/MessagingPushModuleConfig.kt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt index be9d90c7d..516630537 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt @@ -70,12 +70,8 @@ class MessagingPushModuleConfig private constructor( /** * Defines the behavior when a notification is clicked. - *

- * ALWAYS_RESTART_ACTIVITY: Always restart the activity and create a new task stack. - * RESTART_ACTIVITY_IF_NEEDED: Restart the activity only if needed, and avoid creating a new task stack otherwise. - *

* - * @param notificationOnClickBehavior the behavior when a notification is clicked; default ALWAYS_RESTART_ACTIVITY. + * @param notificationOnClickBehavior the behavior when a notification is clicked; default [NotificationClickBehavior.TASK_RESET_ALWAYS]. * @see NotificationClickBehavior for more details. */ fun setNotificationClickBehavior(notificationOnClickBehavior: NotificationClickBehavior): Builder { From 8c69c58582b87221cac9f207991dbe0a3bd1f20c Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 5 Sep 2023 15:17:31 +0500 Subject: [PATCH 11/26] removed intent flags --- .../customer/messagingpush/CustomerIOPushNotificationHandler.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt b/messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt index b9faccff5..5fc24108d 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushNotificationHandler.kt @@ -275,7 +275,6 @@ internal class CustomerIOPushNotificationHandler( ): PendingIntent { val notifyIntent = Intent(context, NotificationClickReceiverActivity::class.java) notifyIntent.putExtra(NotificationClickReceiverActivity.NOTIFICATION_PAYLOAD_EXTRA, payload) - notifyIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP) return PendingIntent.getActivity( context, requestCode, From 957557d86a3dd1feadf0ad71e6d486f619cae47d Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 5 Sep 2023 17:43:52 +0500 Subject: [PATCH 12/26] added TrackableScreen to deep links screen --- messagingpush/api/messagingpush.api | 3 ++- .../activity/NotificationClickReceiverActivity.kt | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/messagingpush/api/messagingpush.api b/messagingpush/api/messagingpush.api index fa1850cfb..816bcfb08 100644 --- a/messagingpush/api/messagingpush.api +++ b/messagingpush/api/messagingpush.api @@ -60,11 +60,12 @@ 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 { +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 ()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 { diff --git a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt index b8eccfb74..b9f837643 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt @@ -16,11 +16,17 @@ 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 -class NotificationClickReceiverActivity : Activity() { +class NotificationClickReceiverActivity : Activity(), TrackableScreen { val logger: Logger by lazy { CustomerIOShared.instance().diStaticGraph.logger } + override fun getScreenName(): String? { + // Return null to prevent this screen from being tracked + return null + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) handleIntent(data = intent) From 93ce193365c7fb3c82ca7db5c26dfd69a41ec99c Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 5 Sep 2023 18:04:36 +0500 Subject: [PATCH 13/26] fixed flags --- .../messagingpush/activity/NotificationClickReceiverActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt index b9f837643..51527089f 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt @@ -125,7 +125,7 @@ class NotificationClickReceiverActivity : Activity(), TrackableScreen { NotificationClickBehavior.ACTIVITY_RESTART_IF_NEEDED -> { deepLinkIntent.flags = - Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED startActivity(deepLinkIntent) } From 4785dc1c7ccb3a4f1dbda84b22be3044becbfcf5 Mon Sep 17 00:00:00 2001 From: Rehan Date: Wed, 6 Sep 2023 13:15:51 +0500 Subject: [PATCH 14/26] update default value --- .../java/io/customer/messagingpush/MessagingPushModuleConfig.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt index 516630537..93d800f92 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt @@ -29,7 +29,7 @@ class MessagingPushModuleConfig private constructor( private var notificationCallback: CustomerIOPushNotificationCallback? = null private var redirectDeepLinksToOtherApps: Boolean = true private var notificationOnClickBehavior: NotificationClickBehavior = - NotificationClickBehavior.TASK_RESET_ALWAYS + NotificationClickBehavior.ACTIVITY_RESTART_IF_NEEDED /** * Allows to enable/disable automatic tracking of push events. Auto tracking will generate From 092e2e472ec381eb32fd3ec7906bae524b6d6aa2 Mon Sep 17 00:00:00 2001 From: Rehan Date: Wed, 6 Sep 2023 14:23:14 +0500 Subject: [PATCH 15/26] config updates --- messagingpush/api/messagingpush.api | 6 ++-- .../MessagingPushModuleConfig.kt | 2 +- .../config/NotificationClickBehavior.kt | 34 +++++++++++-------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/messagingpush/api/messagingpush.api b/messagingpush/api/messagingpush.api index 816bcfb08..1720d1ef1 100644 --- a/messagingpush/api/messagingpush.api +++ b/messagingpush/api/messagingpush.api @@ -72,9 +72,9 @@ public final class io/customer/messagingpush/activity/NotificationClickReceiverA } public final class io/customer/messagingpush/config/NotificationClickBehavior : java/lang/Enum { - public static final field ACTIVITY_RESTART_ALWAYS Lio/customer/messagingpush/config/NotificationClickBehavior; - public static final field ACTIVITY_RESTART_IF_NEEDED Lio/customer/messagingpush/config/NotificationClickBehavior; - public static final field TASK_RESET_ALWAYS Lio/customer/messagingpush/config/NotificationClickBehavior; + public static final field ACTIVITY_ATTEMPT_RESTART 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; } diff --git a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt index 93d800f92..c9e7e0371 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt @@ -29,7 +29,7 @@ class MessagingPushModuleConfig private constructor( private var notificationCallback: CustomerIOPushNotificationCallback? = null private var redirectDeepLinksToOtherApps: Boolean = true private var notificationOnClickBehavior: NotificationClickBehavior = - NotificationClickBehavior.ACTIVITY_RESTART_IF_NEEDED + NotificationClickBehavior.ACTIVITY_PREVENT_RESTART /** * Allows to enable/disable automatic tracking of push events. Auto tracking will generate diff --git a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt index 9d62628d0..776e22655 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt @@ -6,31 +6,35 @@ package io.customer.messagingpush.config enum class NotificationClickBehavior { /** - * Always creates a new task stack and clears any existing one upon clicking the notification. - * - Example 1: Stack (A -> B -> C) becomes (D) if D is the target activity. - * - Example 2: Stack (A -> B -> C) changes to (A -> D) if D is the target activity and A is the root of the task stack provided by callback. + * 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. * - * Similar to Android's "Set up a regular activity PendingIntent." + * 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). */ - TASK_RESET_ALWAYS, + RESET_TASK_STACK, /** - * Restarts the target activity only if necessary when the notification is clicked. - * - Example 1: Stack (A -> B) becomes (A -> B -> D) if D is the target activity and not in the stack. - * - Example 2: Stack (A -> B -> D) remains (A -> B -> D) if D is the target activity and is already in the stack. D will not be restarted. + * 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. * - * Similar to Android's "Set up a special activity PendingIntent." + * Works well for activities with launch modes other than `standard`. The same activity instance will be reused and receive the data in `onNewIntent`. + * + * 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_RESTART_IF_NEEDED, + ACTIVITY_PREVENT_RESTART, /** - * Always restarts the target activity upon clicking the notification. - * - Example 1: Stack (A -> B) becomes (A -> B -> D) if D is the target activity and not in the stack. - * - Example 2: Stack (A -> B -> D) remains (A -> B -> D) if D is the target activity and is already in the stack. D will be restarted. + * Forces the restart of the deep-linked activity 'D' even if it's already at the top of the stack. + * - Example: Stack (A -> B) becomes (A -> B -> D) if D is the deep-linked activity and not in the stack. + * - Example: Stack (A -> B -> D) stays as (A -> B -> D) but D gets restarted if D is the deep-linked activity and is already at the top. + * + * Works well for activities with `standard` launch mode. The activity will be recreated and receive the data in `onCreate`. * - * This behavior is similar to ACTIVITY_RESTART_IF_NEEDED, but it forces a restart of the activity if it is already on top of the stack. + * This behavior is an extension of [ACTIVITY_PREVENT_RESTART], forcing the deep-linked activity to restart if it's already on top of the stack. */ - ACTIVITY_RESTART_ALWAYS + ACTIVITY_ATTEMPT_RESTART } From 8a50e8566e30a660a7715ca6ec3023da6d500344 Mon Sep 17 00:00:00 2001 From: Rehan Date: Wed, 6 Sep 2023 14:23:42 +0500 Subject: [PATCH 16/26] activity updates --- .../activity/NotificationClickReceiverActivity.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt index 51527089f..0bd3c5b7e 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt @@ -108,7 +108,7 @@ class NotificationClickReceiverActivity : Activity(), TrackableScreen { try { when (moduleConfig.notificationOnClickBehavior) { - NotificationClickBehavior.TASK_RESET_ALWAYS -> { + NotificationClickBehavior.RESET_TASK_STACK -> { val taskStackBuilder = moduleConfig.notificationCallback?.createTaskStackFromPayload( this, @@ -123,13 +123,13 @@ class NotificationClickReceiverActivity : Activity(), TrackableScreen { } } - NotificationClickBehavior.ACTIVITY_RESTART_IF_NEEDED -> { + NotificationClickBehavior.ACTIVITY_PREVENT_RESTART -> { deepLinkIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED startActivity(deepLinkIntent) } - NotificationClickBehavior.ACTIVITY_RESTART_ALWAYS -> { + NotificationClickBehavior.ACTIVITY_ATTEMPT_RESTART -> { deepLinkIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK startActivity(deepLinkIntent) From 9d701bbec24f402580f9686cf7805431ca22779e Mon Sep 17 00:00:00 2001 From: Rehan Date: Wed, 6 Sep 2023 15:26:09 +0500 Subject: [PATCH 17/26] more behavior for testing --- messagingpush/api/messagingpush.api | 1 + .../NotificationClickReceiverActivity.kt | 54 +++++++++---------- .../config/NotificationClickBehavior.kt | 10 +++- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/messagingpush/api/messagingpush.api b/messagingpush/api/messagingpush.api index 1720d1ef1..4a4464bc3 100644 --- a/messagingpush/api/messagingpush.api +++ b/messagingpush/api/messagingpush.api @@ -73,6 +73,7 @@ public final class io/customer/messagingpush/activity/NotificationClickReceiverA public final class io/customer/messagingpush/config/NotificationClickBehavior : java/lang/Enum { public static final field ACTIVITY_ATTEMPT_RESTART Lio/customer/messagingpush/config/NotificationClickBehavior; + 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; diff --git a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt index 0bd3c5b7e..bfa346f5b 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt @@ -1,7 +1,6 @@ package io.customer.messagingpush.activity import android.app.Activity -import android.content.ActivityNotFoundException import android.content.Intent import android.os.Bundle import androidx.core.app.TaskStackBuilder @@ -105,38 +104,39 @@ class NotificationClickReceiverActivity : Activity(), TrackableScreen { ?: defaultHostAppIntent ?: return deepLinkIntent.putExtra(NOTIFICATION_PAYLOAD_EXTRA, payload) - - try { - when (moduleConfig.notificationOnClickBehavior) { - NotificationClickBehavior.RESET_TASK_STACK -> { - val taskStackBuilder = - moduleConfig.notificationCallback?.createTaskStackFromPayload( - this, - payload - ) ?: kotlin.run { - return@run TaskStackBuilder.create(this).run { - addNextIntentWithParentStack(deepLinkIntent) - } + logger.debug("[DEV] Dispatching deep link intent: $deepLinkIntent with behavior: ${moduleConfig.notificationOnClickBehavior}") + + when (moduleConfig.notificationOnClickBehavior) { + NotificationClickBehavior.RESET_TASK_STACK -> { + val taskStackBuilder = + moduleConfig.notificationCallback?.createTaskStackFromPayload( + this, + payload + ) ?: kotlin.run { + return@run TaskStackBuilder.create(this).run { + addNextIntentWithParentStack(deepLinkIntent) } - if (taskStackBuilder.intentCount > 0) { - taskStackBuilder.startActivities() } + if (taskStackBuilder.intentCount > 0) { + taskStackBuilder.startActivities() } + } - NotificationClickBehavior.ACTIVITY_PREVENT_RESTART -> { - deepLinkIntent.flags = - Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED - startActivity(deepLinkIntent) - } + NotificationClickBehavior.ACTIVITY_PREVENT_RESTART -> { + deepLinkIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or + Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED + startActivity(deepLinkIntent) + } - NotificationClickBehavior.ACTIVITY_ATTEMPT_RESTART -> { - deepLinkIntent.flags = - Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK - startActivity(deepLinkIntent) - } + NotificationClickBehavior.ACTIVITY_ATTEMPT_RESTART -> { + deepLinkIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or + Intent.FLAG_ACTIVITY_NEW_TASK + startActivity(deepLinkIntent) + } + + NotificationClickBehavior.ACTIVITY_NO_FLAGS -> { + startActivity(deepLinkIntent) } - } catch (ex: ActivityNotFoundException) { - logger.error("Unable to start activity for notification action $payload; ${ex.message}") } } diff --git a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt index 776e22655..9a280e6b1 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt @@ -36,5 +36,13 @@ enum class NotificationClickBehavior { * * This behavior is an extension of [ACTIVITY_PREVENT_RESTART], forcing the deep-linked activity to restart if it's already on top of the stack. */ - ACTIVITY_ATTEMPT_RESTART + ACTIVITY_ATTEMPT_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. + */ + ACTIVITY_NO_FLAGS } From 73784ff026d0c55c079564316b651e1cfc45e3dc Mon Sep 17 00:00:00 2001 From: Rehan Date: Wed, 6 Sep 2023 16:10:51 +0500 Subject: [PATCH 18/26] removed ACTIVITY_ATTEMPT_RESTART --- messagingpush/api/messagingpush.api | 1 - .../activity/NotificationClickReceiverActivity.kt | 8 +------- .../messagingpush/config/NotificationClickBehavior.kt | 11 ----------- 3 files changed, 1 insertion(+), 19 deletions(-) diff --git a/messagingpush/api/messagingpush.api b/messagingpush/api/messagingpush.api index 4a4464bc3..48c9ac0cf 100644 --- a/messagingpush/api/messagingpush.api +++ b/messagingpush/api/messagingpush.api @@ -72,7 +72,6 @@ public final class io/customer/messagingpush/activity/NotificationClickReceiverA } public final class io/customer/messagingpush/config/NotificationClickBehavior : java/lang/Enum { - public static final field ACTIVITY_ATTEMPT_RESTART Lio/customer/messagingpush/config/NotificationClickBehavior; 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; diff --git a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt index bfa346f5b..4e265cbc2 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt @@ -124,13 +124,7 @@ class NotificationClickReceiverActivity : Activity(), TrackableScreen { NotificationClickBehavior.ACTIVITY_PREVENT_RESTART -> { deepLinkIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or - Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED - startActivity(deepLinkIntent) - } - - NotificationClickBehavior.ACTIVITY_ATTEMPT_RESTART -> { - deepLinkIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or - Intent.FLAG_ACTIVITY_NEW_TASK + Intent.FLAG_ACTIVITY_SINGLE_TOP startActivity(deepLinkIntent) } diff --git a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt index 9a280e6b1..ce6b8e135 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt @@ -27,17 +27,6 @@ enum class NotificationClickBehavior { */ ACTIVITY_PREVENT_RESTART, - /** - * Forces the restart of the deep-linked activity 'D' even if it's already at the top of the stack. - * - Example: Stack (A -> B) becomes (A -> B -> D) if D is the deep-linked activity and not in the stack. - * - Example: Stack (A -> B -> D) stays as (A -> B -> D) but D gets restarted if D is the deep-linked activity and is already at the top. - * - * Works well for activities with `standard` launch mode. The activity will be recreated and receive the data in `onCreate`. - * - * This behavior is an extension of [ACTIVITY_PREVENT_RESTART], forcing the deep-linked activity to restart if it's already on top of the stack. - */ - ACTIVITY_ATTEMPT_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. From a4837c311386d2d3894c82e6259fa5a52806d408 Mon Sep 17 00:00:00 2001 From: Rehan Date: Wed, 6 Sep 2023 16:12:55 +0500 Subject: [PATCH 19/26] fixed docs --- .../customer/messagingpush/config/NotificationClickBehavior.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt index ce6b8e135..33d8572e5 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/config/NotificationClickBehavior.kt @@ -20,7 +20,7 @@ enum class NotificationClickBehavior { * - 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. * - * Works well for activities with launch modes other than `standard`. The same activity instance will be reused and receive the data in `onNewIntent`. + * 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). From 99b64b327f6232677e97ab2da9d2fa96e578ed0b Mon Sep 17 00:00:00 2001 From: Rehan Date: Wed, 6 Sep 2023 16:16:53 +0500 Subject: [PATCH 20/26] fixed typo --- .../java/io/customer/messagingpush/MessagingPushModuleConfig.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt index c9e7e0371..2ab16a0f1 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt @@ -71,7 +71,7 @@ class MessagingPushModuleConfig private constructor( /** * Defines the behavior when a notification is clicked. * - * @param notificationOnClickBehavior the behavior when a notification is clicked; default [NotificationClickBehavior.TASK_RESET_ALWAYS]. + * @param notificationOnClickBehavior the behavior when a notification is clicked; default [NotificationClickBehavior.ACTIVITY_PREVENT_RESTART]. * @see NotificationClickBehavior for more details. */ fun setNotificationClickBehavior(notificationOnClickBehavior: NotificationClickBehavior): Builder { From 858cb8174f0f4c8db1e63121072a996e004012b6 Mon Sep 17 00:00:00 2001 From: Rehan Date: Wed, 6 Sep 2023 16:21:34 +0500 Subject: [PATCH 21/26] added docs --- .../activity/NotificationClickReceiverActivity.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt index 4e265cbc2..5a3ee3a7e 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt @@ -18,6 +18,12 @@ 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 } From 8bfb8b80c3c09dbaa6c3336ad24d5154b1d652bc Mon Sep 17 00:00:00 2001 From: Rehan Date: Thu, 7 Sep 2023 13:06:10 +0500 Subject: [PATCH 22/26] fixes and improvements --- messagingpush/src/main/AndroidManifest.xml | 1 + .../NotificationClickReceiverActivity.kt | 2 +- .../messagingpush/util/DeepLinkUtil.kt | 25 ++++++++----------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/messagingpush/src/main/AndroidManifest.xml b/messagingpush/src/main/AndroidManifest.xml index 6efdfa528..e1884a7ad 100644 --- a/messagingpush/src/main/AndroidManifest.xml +++ b/messagingpush/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + { diff --git a/messagingpush/src/main/java/io/customer/messagingpush/util/DeepLinkUtil.kt b/messagingpush/src/main/java/io/customer/messagingpush/util/DeepLinkUtil.kt index bcf57291a..c8365742c 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/util/DeepLinkUtil.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/util/DeepLinkUtil.kt @@ -72,22 +72,19 @@ class DeepLinkUtilImpl( link: String, startingFromService: Boolean ): Intent? { - val linkUri = Uri.parse(link) - val intent: Intent? - - if (moduleConfig.redirectDeepLinksToOtherApps) { - intent = queryDeepLinksForThirdPartyApps(context = context, uri = linkUri) - - if (intent == null) { - logger.info( - "No supporting application found for link received in " + - "push notification: $link" - ) - } - } else { - intent = null + // check config if the deep link should be opened by any other app or not + if (!moduleConfig.redirectDeepLinksToOtherApps) { + return null } + val linkUri = Uri.parse(link) + val intent = queryDeepLinksForThirdPartyApps(context = context, uri = linkUri) + if (intent == null) { + logger.info( + "No supporting application found for link received in " + + "push notification: $link" + ) + } return intent } From 3e146fbcb2b108408297c3dd804b2a2aafa367c9 Mon Sep 17 00:00:00 2001 From: Rehan Date: Thu, 7 Sep 2023 13:11:59 +0500 Subject: [PATCH 23/26] task stack fixes --- .../NotificationClickReceiverActivity.kt | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt index f95f0e3de..d38a56fec 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/activity/NotificationClickReceiverActivity.kt @@ -70,6 +70,7 @@ class NotificationClickReceiverActivity : Activity(), TrackableScreen { val deliveryId = payload.cioDeliveryId val deliveryToken = payload.cioDeliveryToken + val deepLink = payload.deepLink?.takeIfNotBlank() if (moduleConfig.autoTrackPushEvents) { sdkInstance.trackMetric(deliveryId, MetricEvent.opened, deliveryToken) @@ -77,17 +78,13 @@ class NotificationClickReceiverActivity : Activity(), TrackableScreen { // check if host app overrides the handling of deeplink val notificationCallback = moduleConfig.notificationCallback - val taskStackBuilder = notificationCallback?.createTaskStackFromPayload(this, payload) - if (taskStackBuilder != null) { - taskStackBuilder.startActivities() + 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 } - val deepLink = payload.deepLink?.takeIfNotBlank() - if (deepLink == null) { - logger.debug("No deep link received in push notification content") - } - // Get the default intent for the host app val defaultHostAppIntent = deepLinkUtil.createDefaultHostAppIntent( context = this, @@ -110,22 +107,14 @@ class NotificationClickReceiverActivity : Activity(), TrackableScreen { ?: defaultHostAppIntent ?: return deepLinkIntent.putExtra(NOTIFICATION_PAYLOAD_EXTRA, payload) - logger.debug("Dispatching deep link intent: $deepLinkIntent with behavior: ${moduleConfig.notificationOnClickBehavior}") + logger.info("Dispatching notification with link $deepLink to intent: $deepLinkIntent with behavior: ${moduleConfig.notificationOnClickBehavior}") when (moduleConfig.notificationOnClickBehavior) { NotificationClickBehavior.RESET_TASK_STACK -> { - val taskStackBuilder = - moduleConfig.notificationCallback?.createTaskStackFromPayload( - this, - payload - ) ?: kotlin.run { - return@run TaskStackBuilder.create(this).run { - addNextIntentWithParentStack(deepLinkIntent) - } - } - if (taskStackBuilder.intentCount > 0) { - taskStackBuilder.startActivities() + val taskStackBuilder = TaskStackBuilder.create(this).apply { + addNextIntentWithParentStack(deepLinkIntent) } + taskStackBuilder.startActivities() } NotificationClickBehavior.ACTIVITY_PREVENT_RESTART -> { From 523af2cc527a451124257758e45a9767829cea2e Mon Sep 17 00:00:00 2001 From: Rehan Date: Thu, 7 Sep 2023 13:13:13 +0500 Subject: [PATCH 24/26] updated default value --- .../io/customer/messagingpush/MessagingPushModuleConfig.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt index 2ab16a0f1..a16cf7029 100644 --- a/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt +++ b/messagingpush/src/main/java/io/customer/messagingpush/MessagingPushModuleConfig.kt @@ -1,6 +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 @@ -28,8 +29,7 @@ class MessagingPushModuleConfig private constructor( private var autoTrackPushEvents: Boolean = true private var notificationCallback: CustomerIOPushNotificationCallback? = null private var redirectDeepLinksToOtherApps: Boolean = true - private var notificationOnClickBehavior: NotificationClickBehavior = - NotificationClickBehavior.ACTIVITY_PREVENT_RESTART + private var notificationOnClickBehavior: NotificationClickBehavior = ACTIVITY_NO_FLAGS /** * Allows to enable/disable automatic tracking of push events. Auto tracking will generate From b38506c5095ef1b48b82bb024f6739de5a65e07e Mon Sep 17 00:00:00 2001 From: Rehan Date: Thu, 7 Sep 2023 13:17:28 +0500 Subject: [PATCH 25/26] chore: remove CustomerIOPushReceiver --- messagingpush/src/main/AndroidManifest.xml | 8 -- .../CustomerIOPushNotificationHandler.kt | 51 ---------- .../messagingpush/CustomerIOPushReceiver.kt | 94 ------------------- 3 files changed, 153 deletions(-) delete mode 100644 messagingpush/src/main/java/io/customer/messagingpush/CustomerIOPushReceiver.kt diff --git a/messagingpush/src/main/AndroidManifest.xml b/messagingpush/src/main/AndroidManifest.xml index e1884a7ad..a079c73b0 100644 --- a/messagingpush/src/main/AndroidManifest.xml +++ b/messagingpush/src/main/AndroidManifest.xml @@ -23,14 +23,6 @@ - - - - - -