diff --git a/app/build.gradle b/app/build.gradle index f08ef3a49..468f18a25 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -362,6 +362,7 @@ dependencies { implementation Deps.sentry implementation Deps.leanplum + implementation Deps.leanplumMessaging implementation Deps.osslicenses_library implementation Deps.mozilla_concept_engine diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index db7b09edf..cd17dd394 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -54,6 +54,18 @@ -keep class org.mozilla.fenix.**ViewModel { *; } +#################################################################################################### +# Leanplum +#################################################################################################### + +-keepclassmembers class * { + @com.leanplum.annotations.* ; +} + +-keep class com.leanplum.** { *; } +-dontwarn com.leanplum.** + + #################################################################################################### # Adjust #################################################################################################### @@ -94,3 +106,4 @@ # Keep motionlayout internal methods # https://github.com/mozilla-mobile/fenix/issues/2094 -keep class androidx.constraintlayout.** { *; } + diff --git a/app/src/main/java/org/mozilla/fenix/components/FirebasePush.kt b/app/src/main/java/org/mozilla/fenix/components/FirebasePush.kt index 4d20e5201..39b5579aa 100644 --- a/app/src/main/java/org/mozilla/fenix/components/FirebasePush.kt +++ b/app/src/main/java/org/mozilla/fenix/components/FirebasePush.kt @@ -4,6 +4,40 @@ package org.mozilla.fenix.components +import com.google.firebase.messaging.RemoteMessage import mozilla.components.lib.push.firebase.AbstractFirebasePushService +import org.json.JSONObject +import org.mozilla.fenix.ext.components -class FirebasePush : AbstractFirebasePushService() +class FirebasePush : AbstractFirebasePushService() { + + // Helper function to help determine if the incoming message is from Leanplum + private fun RemoteMessage.isLeanplumChannel(): Boolean = + data[LEANPLUM_KEY] + ?.let { JSONObject(it) } + ?.getString(LEANPLUM_NAME_KEY) == LEANPLUM_CHANNEL_NAME + + /** + * Overrides onMessageReceived to handle incoming Leanplum messages. + */ + override fun onMessageReceived(remoteMessage: RemoteMessage?) { + if (remoteMessage?.isLeanplumChannel() == true) { + val message = remoteMessage.data?.get(LEANPLUM_MESSAGE_KEY) ?: return + sendLeanplumMessage(message) + return + } + + return super.onMessageReceived(remoteMessage) + } + + private fun sendLeanplumMessage(message: String) { + applicationContext.components.backgroundServices.notificationManager.showMessage(message) + } + + companion object { + private const val LEANPLUM_KEY = "lp_channel" + private const val LEANPLUM_NAME_KEY = "name" + private const val LEANPLUM_CHANNEL_NAME = "leanplum" + private const val LEANPLUM_MESSAGE_KEY = "lp_message" + } +} diff --git a/app/src/main/java/org/mozilla/fenix/components/NotificationManager.kt b/app/src/main/java/org/mozilla/fenix/components/NotificationManager.kt index 98b484c60..42763def3 100644 --- a/app/src/main/java/org/mozilla/fenix/components/NotificationManager.kt +++ b/app/src/main/java/org/mozilla/fenix/components/NotificationManager.kt @@ -19,6 +19,7 @@ import androidx.core.app.NotificationManagerCompat import androidx.core.content.getSystemService import mozilla.components.concept.sync.DeviceEvent import mozilla.components.concept.sync.TabData +import mozilla.components.support.base.ids.notify import mozilla.components.support.base.log.logger.Logger import org.mozilla.fenix.R @@ -29,6 +30,8 @@ class NotificationManager(private val context: Context) { companion object { const val RECEIVE_TABS_TAG = "ReceivedTabs" const val RECEIVE_TABS_CHANNEL_ID = "ReceivedTabsChannel" + const val DEFAULT_CHANNEL_TAG = "Default" + const val DEFAULT_CHANEL_ID = "DefaultChannel" } init { @@ -44,6 +47,13 @@ class NotificationManager(private val context: Context) { context.getString(R.string.fxa_received_tab_channel_name), context.getString(R.string.fxa_received_tab_channel_description) ) + + createNotificationChannel( + DEFAULT_CHANEL_ID, + NotificationManager.IMPORTANCE_DEFAULT, + context.getString(R.string.app_name), + "" + ) } } @@ -88,6 +98,21 @@ class NotificationManager(private val context: Context) { } } + fun showMessage(message: String) { + val builder = NotificationCompat.Builder(context, DEFAULT_CHANEL_ID) + .setSmallIcon(R.drawable.ic_status_logo) + .setContentTitle(context.getString(R.string.app_name)) + .setContentText(message) + .setWhen(System.currentTimeMillis()) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .setDefaults(Notification.DEFAULT_VIBRATE or Notification.DEFAULT_SOUND) + + val notification = builder.build() + with(NotificationManagerCompat.from(context)) { + notify(context, DEFAULT_CHANNEL_TAG, notification) + } + } + @TargetApi(Build.VERSION_CODES.O) private fun createNotificationChannel( channelId: String, diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index cf2d5fc3d..0c772b41a 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -159,6 +159,8 @@ object Deps { const val leakcanary_noop = "com.squareup.leakcanary:leakcanary-android-no-op:${Versions.leakcanary}" const val leanplum = "com.leanplum:leanplum-core:${Versions.leanplum}" + const val leanplumMessaging = "com.leanplum:leanplum-fcm:${Versions.leanplum}" + const val androidx_annotation = "androidx.annotation:annotation:${Versions.androidx_annotation}" const val androidx_fragment = "androidx.fragment:fragment-ktx:${Versions.androidx_fragment}"