Update FxA integration to new APIs
parent
b8b677cbe4
commit
fe51bbcf7b
|
@ -325,7 +325,6 @@ dependencies {
|
||||||
implementation Deps.mozilla_feature_qr
|
implementation Deps.mozilla_feature_qr
|
||||||
implementation Deps.mozilla_feature_search
|
implementation Deps.mozilla_feature_search
|
||||||
implementation Deps.mozilla_feature_session
|
implementation Deps.mozilla_feature_session
|
||||||
implementation Deps.mozilla_feature_sync
|
|
||||||
implementation Deps.mozilla_feature_toolbar
|
implementation Deps.mozilla_feature_toolbar
|
||||||
implementation Deps.mozilla_feature_tabs
|
implementation Deps.mozilla_feature_tabs
|
||||||
implementation Deps.mozilla_feature_findinpage
|
implementation Deps.mozilla_feature_findinpage
|
||||||
|
|
|
@ -147,7 +147,7 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback
|
||||||
accountManager.initAsync().await()
|
accountManager.initAsync().await()
|
||||||
// If we're authenticated, kick-off a sync and a device state refresh.
|
// If we're authenticated, kick-off a sync and a device state refresh.
|
||||||
accountManager.authenticatedAccount()?.let {
|
accountManager.authenticatedAccount()?.let {
|
||||||
syncManager?.syncNow(startup = true)
|
accountManager.syncNowAsync(startup = true)
|
||||||
it.deviceConstellation().refreshDeviceStateAsync().await()
|
it.deviceConstellation().refreshDeviceStateAsync().await()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ package org.mozilla.fenix.components
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.lifecycle.ProcessLifecycleOwner
|
import androidx.lifecycle.ProcessLifecycleOwner
|
||||||
import androidx.work.WorkManager
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -17,11 +16,11 @@ import mozilla.components.concept.sync.DeviceCapability
|
||||||
import mozilla.components.concept.sync.DeviceEvent
|
import mozilla.components.concept.sync.DeviceEvent
|
||||||
import mozilla.components.concept.sync.DeviceEventsObserver
|
import mozilla.components.concept.sync.DeviceEventsObserver
|
||||||
import mozilla.components.concept.sync.DeviceType
|
import mozilla.components.concept.sync.DeviceType
|
||||||
import mozilla.components.feature.sync.BackgroundSyncManager
|
import mozilla.components.service.fxa.DeviceConfig
|
||||||
import mozilla.components.feature.sync.GlobalSyncableStoreProvider
|
import mozilla.components.service.fxa.ServerConfig
|
||||||
import mozilla.components.service.fxa.Config
|
import mozilla.components.service.fxa.SyncConfig
|
||||||
import mozilla.components.service.fxa.manager.DeviceTuple
|
|
||||||
import mozilla.components.service.fxa.manager.FxaAccountManager
|
import mozilla.components.service.fxa.manager.FxaAccountManager
|
||||||
|
import mozilla.components.service.fxa.sync.GlobalSyncableStoreProvider
|
||||||
import mozilla.components.support.base.log.logger.Logger
|
import mozilla.components.support.base.log.logger.Logger
|
||||||
import org.mozilla.fenix.BuildConfig
|
import org.mozilla.fenix.BuildConfig
|
||||||
import org.mozilla.fenix.Experiments
|
import org.mozilla.fenix.Experiments
|
||||||
|
@ -44,12 +43,26 @@ class BackgroundServices(
|
||||||
const val REDIRECT_URL = "https://accounts.firefox.com/oauth/success/$CLIENT_ID"
|
const val REDIRECT_URL = "https://accounts.firefox.com/oauth/success/$CLIENT_ID"
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is slightly messy - here we need to know the union of all "scopes"
|
private val serverConfig = ServerConfig.release(CLIENT_ID, REDIRECT_URL)
|
||||||
// needed by components which rely on FxA integration. If this list
|
private val deviceConfig = DeviceConfig(
|
||||||
// grows too far we probably want to find a way to determine the set
|
name = Build.MANUFACTURER + " " + Build.MODEL,
|
||||||
// at runtime.
|
type = DeviceType.MOBILE,
|
||||||
private val scopes: Array<String> = arrayOf("profile", "https://identity.mozilla.com/apps/oldsync")
|
|
||||||
private val config = Config.release(CLIENT_ID, REDIRECT_URL)
|
// NB: flipping this flag back and worth is currently not well supported and may need hand-holding.
|
||||||
|
// Consult with the android-components peers before changing.
|
||||||
|
// See https://github.com/mozilla/application-services/issues/1308
|
||||||
|
capabilities = if (BuildConfig.SEND_TAB_ENABLED) {
|
||||||
|
setOf(DeviceCapability.SEND_TAB)
|
||||||
|
} else {
|
||||||
|
emptySet()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// If sync has been turned off on the server then disable syncing.
|
||||||
|
private val syncConfig = if (context.isInExperiment(Experiments.asFeatureSyncDisabled)) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
SyncConfig(setOf("history", "bookmarks"), syncPeriodInMinutes = 240L) // four hours
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// Make the "history" and "bookmark" stores accessible to workers spawned by the sync manager.
|
// Make the "history" and "bookmark" stores accessible to workers spawned by the sync manager.
|
||||||
|
@ -57,17 +70,6 @@ class BackgroundServices(
|
||||||
GlobalSyncableStoreProvider.configureStore("bookmarks" to bookmarkStorage)
|
GlobalSyncableStoreProvider.configureStore("bookmarks" to bookmarkStorage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if sync has been turned off on the server then make `syncManager` null
|
|
||||||
val syncManager = if (context.isInExperiment(Experiments.asFeatureSyncDisabled)) {
|
|
||||||
WorkManager.getInstance().cancelUniqueWork("Periodic")
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
BackgroundSyncManager("https://identity.mozilla.com/apps/oldsync").also {
|
|
||||||
it.addStore("history")
|
|
||||||
it.addStore("bookmarks")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val deviceEventObserver = object : DeviceEventsObserver {
|
private val deviceEventObserver = object : DeviceEventsObserver {
|
||||||
private val logger = Logger("DeviceEventsObserver")
|
private val logger = Logger("DeviceEventsObserver")
|
||||||
override fun onEvents(events: List<DeviceEvent>) {
|
override fun onEvents(events: List<DeviceEvent>) {
|
||||||
|
@ -78,23 +80,17 @@ class BackgroundServices(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NB: flipping this flag back and worth is currently not well supported and may need hand-holding.
|
|
||||||
// Consult with the android-components peers before changing.
|
|
||||||
// See https://github.com/mozilla/application-services/issues/1308
|
|
||||||
private val deviceCapabilities = if (BuildConfig.SEND_TAB_ENABLED) {
|
|
||||||
listOf(DeviceCapability.SEND_TAB)
|
|
||||||
} else {
|
|
||||||
emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val defaultDeviceName = Build.MANUFACTURER + " " + Build.MODEL
|
|
||||||
|
|
||||||
val accountManager = FxaAccountManager(
|
val accountManager = FxaAccountManager(
|
||||||
context,
|
context,
|
||||||
config,
|
serverConfig,
|
||||||
scopes,
|
deviceConfig,
|
||||||
DeviceTuple(defaultDeviceName, DeviceType.MOBILE, deviceCapabilities),
|
syncConfig,
|
||||||
syncManager
|
// We don't need to specify this explicitly, but `syncConfig` may be disabled due to an 'experiments'
|
||||||
|
// flag. In that case, sync scope necessary for syncing won't be acquired during authentication
|
||||||
|
// unless we explicitly specify it below.
|
||||||
|
// This is a good example of an information leak at the API level.
|
||||||
|
// See https://github.com/mozilla-mobile/android-components/issues/3732
|
||||||
|
setOf("https://identity.mozilla.com/apps/oldsync")
|
||||||
).also {
|
).also {
|
||||||
it.registerForDeviceEvents(deviceEventObserver, ProcessLifecycleOwner.get(), true)
|
it.registerForDeviceEvents(deviceEventObserver, ProcessLifecycleOwner.get(), true)
|
||||||
CoroutineScope(Dispatchers.Main).launch { it.initAsync().await() }
|
CoroutineScope(Dispatchers.Main).launch { it.initAsync().await() }
|
||||||
|
|
|
@ -21,8 +21,6 @@ class AuthCustomTabActivity : CustomTabActivity() {
|
||||||
|
|
||||||
override fun onAuthenticationProblems() {}
|
override fun onAuthenticationProblems() {}
|
||||||
|
|
||||||
override fun onError(error: Exception) {}
|
|
||||||
|
|
||||||
override fun onLoggedOut() {}
|
override fun onLoggedOut() {}
|
||||||
|
|
||||||
override fun onProfileUpdated(profile: Profile) {}
|
override fun onProfileUpdated(profile: Profile) {}
|
||||||
|
|
|
@ -745,10 +745,6 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
emitAccountChanges()
|
emitAccountChanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(error: Exception) {
|
|
||||||
emitAccountChanges()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onLoggedOut() {
|
override fun onLoggedOut() {
|
||||||
emitAccountChanges()
|
emitAccountChanges()
|
||||||
}
|
}
|
||||||
|
|
|
@ -414,9 +414,6 @@ class BookmarkFragment : Fragment(), BackHandler, AccountObserver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(error: Exception) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onLoggedOut() {
|
override fun onLoggedOut() {
|
||||||
getManagedEmitter<SignInChange>().onNext(SignInChange.SignedOut)
|
getManagedEmitter<SignInChange>().onNext(SignInChange.SignedOut)
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,9 +154,6 @@ class SelectBookmarkFolderFragment : Fragment(), AccountObserver {
|
||||||
getManagedEmitter<SignInChange>().onNext(SignInChange.SignedIn)
|
getManagedEmitter<SignInChange>().onNext(SignInChange.SignedIn)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(error: Exception) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onLoggedOut() {
|
override fun onLoggedOut() {
|
||||||
getManagedEmitter<SignInChange>().onNext(SignInChange.SignedOut)
|
getManagedEmitter<SignInChange>().onNext(SignInChange.SignedOut)
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,8 +84,6 @@ class AccountProblemFragment : PreferenceFragmentCompat(), AccountObserver {
|
||||||
|
|
||||||
override fun onAuthenticationProblems() {}
|
override fun onAuthenticationProblems() {}
|
||||||
|
|
||||||
override fun onError(error: Exception) {}
|
|
||||||
|
|
||||||
// We're told there are no more auth problems since there is no more account; close this fragment.
|
// We're told there are no more auth problems since there is no more account; close this fragment.
|
||||||
override fun onLoggedOut() {
|
override fun onLoggedOut() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
|
|
|
@ -24,11 +24,11 @@ import mozilla.components.concept.sync.ConstellationState
|
||||||
import mozilla.components.concept.sync.DeviceConstellationObserver
|
import mozilla.components.concept.sync.DeviceConstellationObserver
|
||||||
import mozilla.components.concept.sync.OAuthAccount
|
import mozilla.components.concept.sync.OAuthAccount
|
||||||
import mozilla.components.concept.sync.Profile
|
import mozilla.components.concept.sync.Profile
|
||||||
import mozilla.components.concept.sync.SyncStatusObserver
|
|
||||||
import mozilla.components.feature.sync.getLastSynced
|
|
||||||
import mozilla.components.service.fxa.FxaException
|
import mozilla.components.service.fxa.FxaException
|
||||||
import mozilla.components.service.fxa.FxaPanicException
|
import mozilla.components.service.fxa.FxaPanicException
|
||||||
import mozilla.components.service.fxa.manager.FxaAccountManager
|
import mozilla.components.service.fxa.manager.FxaAccountManager
|
||||||
|
import mozilla.components.service.fxa.sync.SyncStatusObserver
|
||||||
|
import mozilla.components.service.fxa.sync.getLastSynced
|
||||||
import mozilla.components.support.base.log.logger.Logger
|
import mozilla.components.support.base.log.logger.Logger
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.FenixSnackbar
|
import org.mozilla.fenix.components.FenixSnackbar
|
||||||
|
@ -49,8 +49,6 @@ class AccountSettingsFragment : PreferenceFragmentCompat() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(error: Exception) {}
|
|
||||||
|
|
||||||
override fun onLoggedOut() {
|
override fun onLoggedOut() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
findNavController().popBackStack()
|
findNavController().popBackStack()
|
||||||
|
@ -97,18 +95,8 @@ class AccountSettingsFragment : PreferenceFragmentCompat() {
|
||||||
val syncNow = context!!.getPreferenceKey(R.string.pref_key_sync_now)
|
val syncNow = context!!.getPreferenceKey(R.string.pref_key_sync_now)
|
||||||
val preferenceSyncNow = findPreference<Preference>(syncNow)
|
val preferenceSyncNow = findPreference<Preference>(syncNow)
|
||||||
preferenceSyncNow?.let {
|
preferenceSyncNow?.let {
|
||||||
preferenceSyncNow.onPreferenceClickListener = getClickListenerForSyncNow()
|
it.onPreferenceClickListener = getClickListenerForSyncNow()
|
||||||
|
updateLastSyncedTimePref(context!!, it)
|
||||||
// Current sync state
|
|
||||||
updateLastSyncedTimePref(context!!, preferenceSyncNow)
|
|
||||||
requireComponents.backgroundServices.syncManager?.let {
|
|
||||||
if (it.isSyncRunning()) {
|
|
||||||
preferenceSyncNow.title = getString(R.string.sync_syncing_in_progress)
|
|
||||||
preferenceSyncNow.isEnabled = false
|
|
||||||
} else {
|
|
||||||
preferenceSyncNow.isEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Device Name
|
// Device Name
|
||||||
|
@ -129,7 +117,9 @@ class AccountSettingsFragment : PreferenceFragmentCompat() {
|
||||||
|
|
||||||
// NB: ObserverRegistry will take care of cleaning up internal references to 'observer' and
|
// NB: ObserverRegistry will take care of cleaning up internal references to 'observer' and
|
||||||
// 'owner' when appropriate.
|
// 'owner' when appropriate.
|
||||||
requireComponents.backgroundServices.syncManager?.register(syncStatusObserver, owner = this, autoPause = true)
|
requireComponents.backgroundServices.accountManager.registerForSyncEvents(
|
||||||
|
syncStatusObserver, owner = this, autoPause = true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getClickListenerForSignOut(): Preference.OnPreferenceClickListener {
|
private fun getClickListenerForSignOut(): Preference.OnPreferenceClickListener {
|
||||||
|
@ -144,11 +134,11 @@ class AccountSettingsFragment : PreferenceFragmentCompat() {
|
||||||
|
|
||||||
private fun getClickListenerForSyncNow(): Preference.OnPreferenceClickListener {
|
private fun getClickListenerForSyncNow(): Preference.OnPreferenceClickListener {
|
||||||
return Preference.OnPreferenceClickListener {
|
return Preference.OnPreferenceClickListener {
|
||||||
// Trigger a sync.
|
|
||||||
requireComponents.analytics.metrics.track(Event.SyncAccountSyncNow)
|
|
||||||
requireComponents.backgroundServices.syncManager?.syncNow()
|
|
||||||
// Poll for device events.
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
|
requireComponents.analytics.metrics.track(Event.SyncAccountSyncNow)
|
||||||
|
// Trigger a sync.
|
||||||
|
requireComponents.backgroundServices.accountManager.syncNowAsync().await()
|
||||||
|
// Poll for device events.
|
||||||
accountManager.authenticatedAccount()
|
accountManager.authenticatedAccount()
|
||||||
?.deviceConstellation()
|
?.deviceConstellation()
|
||||||
?.refreshDeviceStateAsync()
|
?.refreshDeviceStateAsync()
|
||||||
|
@ -175,9 +165,10 @@ class AccountSettingsFragment : PreferenceFragmentCompat() {
|
||||||
// This may fail, and we'll have a disparity in the UI until `updateDeviceName` is called.
|
// This may fail, and we'll have a disparity in the UI until `updateDeviceName` is called.
|
||||||
lifecycleScope.launch(IO) {
|
lifecycleScope.launch(IO) {
|
||||||
try {
|
try {
|
||||||
accountManager.authenticatedAccount()?.let {
|
accountManager.authenticatedAccount()
|
||||||
it.deviceConstellation().setDeviceNameAsync(newValue)
|
?.deviceConstellation()
|
||||||
}
|
?.setDeviceNameAsync(newValue)
|
||||||
|
?.await()
|
||||||
} catch (e: FxaPanicException) {
|
} catch (e: FxaPanicException) {
|
||||||
throw e
|
throw e
|
||||||
} catch (e: FxaException) {
|
} catch (e: FxaException) {
|
||||||
|
|
|
@ -350,8 +350,6 @@ class SettingsFragment : PreferenceFragmentCompat(), AccountObserver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(error: Exception) {}
|
|
||||||
|
|
||||||
override fun onLoggedOut() {
|
override fun onLoggedOut() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
context?.let {
|
context?.let {
|
||||||
|
|
|
@ -87,7 +87,6 @@ class TurnOnSyncFragment : Fragment(), AccountObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAuthenticationProblems() {}
|
override fun onAuthenticationProblems() {}
|
||||||
override fun onError(error: Exception) {}
|
|
||||||
override fun onLoggedOut() {}
|
override fun onLoggedOut() {}
|
||||||
override fun onProfileUpdated(profile: Profile) {}
|
override fun onProfileUpdated(profile: Profile) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,6 @@ object Deps {
|
||||||
const val mozilla_feature_qr = "org.mozilla.components:feature-qr:${Versions.mozilla_android_components}"
|
const val mozilla_feature_qr = "org.mozilla.components:feature-qr:${Versions.mozilla_android_components}"
|
||||||
const val mozilla_feature_search = "org.mozilla.components:feature-search:${Versions.mozilla_android_components}"
|
const val mozilla_feature_search = "org.mozilla.components:feature-search:${Versions.mozilla_android_components}"
|
||||||
const val mozilla_feature_session = "org.mozilla.components:feature-session:${Versions.mozilla_android_components}"
|
const val mozilla_feature_session = "org.mozilla.components:feature-session:${Versions.mozilla_android_components}"
|
||||||
const val mozilla_feature_sync = "org.mozilla.components:feature-sync:${Versions.mozilla_android_components}"
|
|
||||||
const val mozilla_feature_tabs = "org.mozilla.components:feature-tabs:${Versions.mozilla_android_components}"
|
const val mozilla_feature_tabs = "org.mozilla.components:feature-tabs:${Versions.mozilla_android_components}"
|
||||||
const val mozilla_feature_downloads = "org.mozilla.components:feature-downloads:${Versions.mozilla_android_components}"
|
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_storage = "org.mozilla.components:feature-storage:${Versions.mozilla_android_components}"
|
||||||
|
|
Loading…
Reference in New Issue