From cf9ae87d5050495f3dee64d954e2f14ac013b28b Mon Sep 17 00:00:00 2001 From: Jonathan Almeida Date: Fri, 12 Jul 2019 18:21:02 -0400 Subject: [PATCH] For #3015: Add push support for send tab --- app/build.gradle | 5 +- app/src/main/AndroidManifest.xml | 15 ++++ .../fenix/components/BackgroundServices.kt | 73 +++++++++++++++++++ .../mozilla/fenix/components/FirebasePush.kt | 9 +++ app/src/main/res/values/preference_keys.xml | 1 + buildSrc/src/main/java/Dependencies.kt | 4 + 6 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/org/mozilla/fenix/components/FirebasePush.kt diff --git a/app/build.gradle b/app/build.gradle index c49f1a21e..e14e047fd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -298,9 +298,10 @@ dependencies { implementation Deps.leanplum implementation Deps.mozilla_concept_engine + implementation Deps.mozilla_concept_push implementation Deps.mozilla_concept_storage - implementation Deps.mozilla_concept_toolbar implementation Deps.mozilla_concept_sync + implementation Deps.mozilla_concept_toolbar implementation Deps.mozilla_browser_awesomebar implementation Deps.mozilla_feature_downloads @@ -322,6 +323,7 @@ dependencies { implementation Deps.mozilla_feature_intent implementation Deps.mozilla_feature_media implementation Deps.mozilla_feature_prompts + implementation Deps.mozilla_feature_push implementation Deps.mozilla_feature_qr implementation Deps.mozilla_feature_search implementation Deps.mozilla_feature_session @@ -345,6 +347,7 @@ dependencies { implementation Deps.mozilla_ui_publicsuffixlist implementation Deps.mozilla_lib_crash + implementation Deps.mozilla_lib_push_firebase debugImplementation Deps.leakcanary releaseImplementation Deps.leakcanary_noop diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 74b281b0e..d8b114f04 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -107,6 +107,21 @@ + + + + + + + + + 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 f22e825e2..388454c49 100644 --- a/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt +++ b/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt @@ -12,18 +12,30 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import mozilla.components.browser.storage.sync.PlacesBookmarksStorage import mozilla.components.browser.storage.sync.PlacesHistoryStorage +import mozilla.components.concept.push.Bus +import mozilla.components.concept.push.PushProcessor +import mozilla.components.concept.sync.AccountObserver import mozilla.components.concept.sync.DeviceCapability import mozilla.components.concept.sync.DeviceEvent import mozilla.components.concept.sync.DeviceEventsObserver +import mozilla.components.concept.sync.DevicePushSubscription import mozilla.components.concept.sync.DeviceType import mozilla.components.service.fxa.DeviceConfig import mozilla.components.service.fxa.ServerConfig import mozilla.components.service.fxa.SyncConfig +import mozilla.components.concept.sync.OAuthAccount +import mozilla.components.concept.sync.Profile +import mozilla.components.feature.push.AutoPushFeature +import mozilla.components.feature.push.AutoPushSubscription +import mozilla.components.feature.push.PushConfig +import mozilla.components.feature.push.PushSubscriptionObserver +import mozilla.components.feature.push.PushType import mozilla.components.service.fxa.manager.FxaAccountManager import mozilla.components.service.fxa.sync.GlobalSyncableStoreProvider import mozilla.components.support.base.log.logger.Logger import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.Experiments +import org.mozilla.fenix.R import org.mozilla.fenix.isInExperiment import org.mozilla.fenix.test.Mockable @@ -64,10 +76,53 @@ class BackgroundServices( SyncConfig(setOf("history", "bookmarks"), syncPeriodInMinutes = 240L) // four hours } + private val pushConfig by lazy { + val projectIdKey = context.getString(R.string.pref_key_push_project_id) + val resId = context.resources.getIdentifier(projectIdKey, "string", context.packageName) + if (resId == 0) { + return@lazy null + } + val projectId = context.resources.getString(resId) + PushConfig(projectId) + } + + val pushService by lazy { FirebasePush() } + + private val push by lazy { + AutoPushFeature(context = context, service = pushService, config = pushConfig!!).also { + // Notify observers for Services' messages. + it.registerForPushMessages(PushType.Services, object : Bus.Observer { + override fun onEvent(type: PushType, message: String) { + accountManager.authenticatedAccount()?.deviceConstellation() + ?.processRawEventAsync(message) + } + }, ProcessLifecycleOwner.get(), false) + + // Notify observers for subscription changes. + it.registerForSubscriptions(object : PushSubscriptionObserver { + override fun onSubscriptionAvailable(subscription: AutoPushSubscription) { + accountManager.authenticatedAccount()?.deviceConstellation() + ?.setDevicePushSubscriptionAsync( + DevicePushSubscription( + endpoint = subscription.endpoint, + publicKey = subscription.publicKey, + authKey = subscription.authKey + ) + ) + } + }, ProcessLifecycleOwner.get(), false) + } + } + init { // Make the "history" and "bookmark" stores accessible to workers spawned by the sync manager. GlobalSyncableStoreProvider.configureStore("history" to historyStorage) GlobalSyncableStoreProvider.configureStore("bookmarks" to bookmarkStorage) + + // Sets the PushFeature as the singleton instance for push messages to go to. + if (BuildConfig.SEND_TAB_ENABLED && pushConfig != null) { + PushProcessor.install(push) + } } private val deviceEventObserver = object : DeviceEventsObserver { @@ -80,6 +135,20 @@ class BackgroundServices( } } + private val accountObserver = object : AccountObserver { + override fun onAuthenticationProblems() {} + + override fun onProfileUpdated(profile: Profile) {} + + override fun onLoggedOut() { + pushService.stop() + } + + override fun onAuthenticated(account: OAuthAccount) { + pushService.start(context) + } + } + val accountManager = FxaAccountManager( context, serverConfig, @@ -93,6 +162,10 @@ class BackgroundServices( setOf("https://identity.mozilla.com/apps/oldsync") ).also { it.registerForDeviceEvents(deviceEventObserver, ProcessLifecycleOwner.get(), true) + + if (BuildConfig.SEND_TAB_ENABLED && pushConfig != null) { + it.register(accountObserver) + } CoroutineScope(Dispatchers.Main).launch { it.initAsync().await() } } } diff --git a/app/src/main/java/org/mozilla/fenix/components/FirebasePush.kt b/app/src/main/java/org/mozilla/fenix/components/FirebasePush.kt new file mode 100644 index 000000000..4d20e5201 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/components/FirebasePush.kt @@ -0,0 +1,9 @@ +/* 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/res/values/preference_keys.xml b/app/src/main/res/values/preference_keys.xml index a4d10f0e1..3fabc832d 100644 --- a/app/src/main/res/values/preference_keys.xml +++ b/app/src/main/res/values/preference_keys.xml @@ -46,6 +46,7 @@ pref_key_sync_sign_in pref_key_sync_create_account pref_key_sync_problem + project_id pref_key_show_search_suggestions diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index 7a59e399f..8837d9403 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -83,6 +83,7 @@ object Deps { const val anko_constraintlayout = "org.jetbrains.anko:anko-constraint-layout:${Versions.anko}" const val mozilla_concept_engine = "org.mozilla.components:concept-engine:${Versions.mozilla_android_components}" + const val mozilla_concept_push = "org.mozilla.components:concept-push:${Versions.mozilla_android_components}" const val mozilla_concept_tabstray = "org.mozilla.components:concept-tabstray:${Versions.mozilla_android_components}" const val mozilla_concept_toolbar = "org.mozilla.components:concept-toolbar:${Versions.mozilla_android_components}" const val mozilla_concept_storage = "org.mozilla.components:concept-storage:${Versions.mozilla_android_components}" @@ -116,6 +117,7 @@ object Deps { const val mozilla_feature_downloads = "org.mozilla.components:feature-downloads:${Versions.mozilla_android_components}" const val mozilla_feature_storage = "org.mozilla.components:feature-storage:${Versions.mozilla_android_components}" const val mozilla_feature_prompts = "org.mozilla.components:feature-prompts:${Versions.mozilla_android_components}" + const val mozilla_feature_push = "org.mozilla.components:feature-push:${Versions.mozilla_android_components}" const val mozilla_feature_toolbar = "org.mozilla.components:feature-toolbar:${Versions.mozilla_android_components}" const val mozilla_feature_findinpage = "org.mozilla.components:feature-findinpage:${Versions.mozilla_android_components}" const val mozilla_feature_site_permissions = "org.mozilla.components:feature-sitepermissions:${Versions.mozilla_android_components}" @@ -131,6 +133,8 @@ object Deps { const val mozilla_lib_crash = "org.mozilla.components:lib-crash:${Versions.mozilla_android_components}" const val mozilla_lib_fetch_httpurlconnection = "org.mozilla.components:lib-fetch-httpurlconnection:${Versions.mozilla_android_components}" + const val mozilla_lib_push_firebase = "org.mozilla.components:lib-push-firebase:${Versions.mozilla_android_components}" + const val mozilla_ui_publicsuffixlist = "org.mozilla.components:lib-publicsuffixlist:${Versions.mozilla_android_components}" const val mozilla_support_base = "org.mozilla.components:support-base:${Versions.mozilla_android_components}"