From cbcc56bbba917af42cdc095895afcdbd5c93f617 Mon Sep 17 00:00:00 2001 From: Jonathan Almeida Date: Thu, 23 Jan 2020 18:03:04 -0500 Subject: [PATCH] For #373: Implement LeanPlum push messaging Also closes #6250, since we rely solely on the SDK itself to consume the messages straight from FCM. --- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 2 +- .../fenix/components/BackgroundServices.kt | 2 +- .../mozilla/fenix/components/FirebasePush.kt | 9 --- .../fenix/components/FirebasePushService.kt | 62 +++++++++++++++++++ buildSrc/src/main/java/Dependencies.kt | 3 +- 6 files changed, 69 insertions(+), 13 deletions(-) delete mode 100644 app/src/main/java/org/mozilla/fenix/components/FirebasePush.kt create mode 100644 app/src/main/java/org/mozilla/fenix/components/FirebasePushService.kt diff --git a/app/build.gradle b/app/build.gradle index 37d3c2da1d..9292470273 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -374,9 +374,11 @@ dependencies { implementation Deps.androidx_coordinatorlayout implementation Deps.sentry - implementation Deps.leanplum implementation Deps.osslicenses_library + implementation Deps.leanplum_core + implementation Deps.leanplum_fcm + implementation Deps.mozilla_concept_engine implementation Deps.mozilla_concept_push implementation Deps.mozilla_concept_storage diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2e2fe3ee69..98d84dc728 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -221,7 +221,7 @@ android:exported="false" /> diff --git a/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt b/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt index 2974693556..69aa9429cc 100644 --- a/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt +++ b/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt @@ -87,7 +87,7 @@ class BackgroundServices( syncPeriodInMinutes = 240L) // four hours } - val pushService by lazy { FirebasePush() } + val pushService by lazy { FirebasePushService() } val push by lazy { makePushConfig()?.let { makePush(it) } } diff --git a/app/src/main/java/org/mozilla/fenix/components/FirebasePush.kt b/app/src/main/java/org/mozilla/fenix/components/FirebasePush.kt deleted file mode 100644 index 4d20e52010..0000000000 --- a/app/src/main/java/org/mozilla/fenix/components/FirebasePush.kt +++ /dev/null @@ -1,9 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.fenix.components - -import mozilla.components.lib.push.firebase.AbstractFirebasePushService - -class FirebasePush : AbstractFirebasePushService() diff --git a/app/src/main/java/org/mozilla/fenix/components/FirebasePushService.kt b/app/src/main/java/org/mozilla/fenix/components/FirebasePushService.kt new file mode 100644 index 0000000000..ec3ad6c545 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/components/FirebasePushService.kt @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.components + +import android.annotation.SuppressLint +import com.google.firebase.messaging.RemoteMessage +import com.google.firebase.messaging.FirebaseMessagingService +import com.leanplum.LeanplumPushFirebaseMessagingService +import mozilla.components.concept.push.PushService +import mozilla.components.lib.push.firebase.AbstractFirebasePushService +import mozilla.components.feature.push.AutoPushFeature + +/** + * A wrapper class that only exists to delegate to [FirebaseMessagingService] instances. + * + * Implementation notes: + * + * This was a doozy... + * + * With Firebase Cloud Messaging, we've been given some tight constraints in order to get this to + * work: + * - We want to have multiple FCM message receivers for AutoPush and LeanPlum (for now), however + * there can only be one registered [FirebaseMessagingService] in the AndroidManifest. + * - The [LeanplumPushFirebaseMessagingService] does not function as expected unless it's the + * inherited service that receives the messages. + * - The [AutoPushService] is not strongly tied to being the inherited service, but the + * [AutoPushFeature] requires a reference to the push instance as a [PushService]. + * + * We tried creating an empty [FirebaseMessagingService] that can hold a list of the services + * for delegating, but the [LeanplumPushFirebaseMessagingService] tries to get a reference to the + * Application Context, however,since the FCM service runs in a background process that gives a + * nullptr. Within LeanPlum, this is something that is probably provided internally. + * + * We tried to pass in an instance of the [AbstractFirebasePushService] to [FirebasePushService] + * through the constructor and delegate the implementation of a [PushService] to that, but alas, + * the service requires you to have an empty default constructor in order for the OS to do the + * initialization. For this reason, we created a singleton instance of the AutoPush instance since + * that lets us easily delegate the implementation to that, as well as make invocations when FCM + * receives new messages. + */ +class FirebasePushService : LeanplumPushFirebaseMessagingService(), + PushService by AutoPushService { + + override fun onNewToken(newToken: String) { + AutoPushService.onNewToken(newToken) + super.onNewToken(newToken) + } + + override fun onMessageReceived(remoteMessage: RemoteMessage?) { + AutoPushService.onMessageReceived(remoteMessage) + super.onMessageReceived(remoteMessage) + } +} + +/** + * A singleton instance of the FirebasePushService needed for communicating between FCM and the + * [AutoPushFeature]. + */ +@SuppressLint("MissingFirebaseInstanceTokenRefresh") // Implemented internally. +object AutoPushService : AbstractFirebasePushService() diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index 768b8f8534..306035498d 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -154,7 +154,8 @@ object Deps { const val sentry = "io.sentry:sentry-android:${Versions.sentry}" const val leakcanary = "com.squareup.leakcanary:leakcanary-android:${Versions.leakcanary}" - const val leanplum = "com.leanplum:leanplum-core:${Versions.leanplum}" + const val leanplum_core = "com.leanplum:leanplum-core:${Versions.leanplum}" + const val leanplum_fcm = "com.leanplum:leanplum-fcm:${Versions.leanplum}" const val androidx_annotation = "androidx.annotation:annotation:${Versions.androidx_annotation}" const val androidx_biometric = "androidx.biometric:biometric:${Versions.androidx_biometric}"