From 8432ab9673fba9a31b9c33143ad348705a536cd8 Mon Sep 17 00:00:00 2001 From: Grisha Kruglov Date: Sun, 26 Jul 2020 13:05:01 -0700 Subject: [PATCH] async -> suspend --- .../components/concept/sync/Devices.kt | 16 +- .../components/concept/sync/OAuthAccount.kt | 39 ++- .../accounts/push/FxaPushSupportFeature.kt | 21 +- .../feature/accounts/push/SendTabUseCases.kt | 8 +- .../accounts/push/AccountObserverTest.kt | 2 +- .../accounts/push/AutoPushObserverTest.kt | 14 +- .../accounts/push/OneTimeFxaPushResetTest.kt | 2 +- .../accounts/push/SendTabUseCasesTest.kt | 54 ++-- .../accounts/FirefoxAccountsAuthFeature.kt | 16 +- .../feature/accounts/FxaWebChannelFeature.kt | 16 +- .../FirefoxAccountsAuthFeatureTest.kt | 20 +- .../accounts/FxaWebChannelFeatureTest.kt | 4 +- .../controller/DefaultController.kt | 6 +- .../controller/DefaultControllerTest.kt | 6 +- .../components/service/fxa/FirefoxAccount.kt | 30 +- .../service/fxa/FxaDeviceConstellation.kt | 137 ++++----- .../service/fxa/manager/FxaAccountManager.kt | 155 ++++------ .../service/fxa/FxaAccountManagerTest.kt | 266 +++++++++--------- .../service/fxa/FxaDeviceConstellationTest.kt | 42 +-- .../support/migration/FennecFxaMigration.kt | 4 +- .../migration/FennecFxaMigrationTest.kt | 20 +- .../support/migration/FennecMigratorTest.kt | 12 +- .../org/mozilla/samples/fxa/MainActivity.kt | 14 +- .../samples/sync/logins/MainActivity.kt | 10 +- .../org/mozilla/samples/sync/MainActivity.kt | 30 +- 25 files changed, 447 insertions(+), 497 deletions(-) diff --git a/components/concept/sync/src/main/java/mozilla/components/concept/sync/Devices.kt b/components/concept/sync/src/main/java/mozilla/components/concept/sync/Devices.kt index 835fadd5c24..7f1c5e19ba4 100644 --- a/components/concept/sync/src/main/java/mozilla/components/concept/sync/Devices.kt +++ b/components/concept/sync/src/main/java/mozilla/components/concept/sync/Devices.kt @@ -19,7 +19,7 @@ interface DeviceConstellation : Observable { * @param config A [DeviceConfig] that describes current device. * @return A [Deferred] that will be resolved with a success flag once operation is complete. */ - fun finalizeDeviceAsync(authType: AuthType, config: DeviceConfig): Deferred + suspend fun finalizeDevice(authType: AuthType, config: DeviceConfig): Boolean /** * Current state of the constellation. May be missing if state was never queried. @@ -39,14 +39,14 @@ interface DeviceConstellation : Observable { * @param context An application context, used for updating internal caches. * @return A [Deferred] that will be resolved with a success flag once operation is complete. */ - fun setDeviceNameAsync(name: String, context: Context): Deferred + suspend fun setDeviceName(name: String, context: Context): Boolean /** * Set a [DevicePushSubscription] for the current device. * @param subscription A new [DevicePushSubscription]. * @return A [Deferred] that will be resolved with a success flag once operation is complete. */ - fun setDevicePushSubscriptionAsync(subscription: DevicePushSubscription): Deferred + suspend fun setDevicePushSubscription(subscription: DevicePushSubscription): Boolean /** * Send a command to a specified device. @@ -54,21 +54,21 @@ interface DeviceConstellation : Observable { * @param outgoingCommand An event to send. * @return A [Deferred] that will be resolved with a success flag once operation is complete. */ - fun sendCommandToDeviceAsync(targetDeviceId: String, outgoingCommand: DeviceCommandOutgoing): Deferred + suspend fun sendCommandToDevice(targetDeviceId: String, outgoingCommand: DeviceCommandOutgoing): Boolean /** * Process a raw event, obtained via a push message or some other out-of-band mechanism. * @param payload A raw, plaintext payload to be processed. * @return A [Deferred] that will be resolved with a success flag once operation is complete. */ - fun processRawEventAsync(payload: String): Deferred + suspend fun processRawEvent(payload: String): Boolean /** * Refreshes [ConstellationState]. Registered [DeviceConstellationObserver] observers will be notified. * * @return A [Deferred] that will be resolved with a success flag once operation is complete. */ - fun refreshDevicesAsync(): Deferred + suspend fun refreshDevices(): Boolean /** * Polls for any pending [DeviceCommandIncoming] commands. @@ -76,7 +76,7 @@ interface DeviceConstellation : Observable { * * @return A [Deferred] that will be resolved with a success flag once operation is complete. */ - fun pollForCommandsAsync(): Deferred + suspend fun pollForCommands(): Boolean } /** @@ -116,7 +116,7 @@ data class DevicePushSubscription( * Configuration for the current device. * * @property name An initial name to use for the device record which will be created during authentication. - * This can be changed later via [DeviceConstellation.setDeviceNameAsync]. + * This can be changed later via [DeviceConstellation.setDeviceName]. * @property type Type of a device - mobile, desktop - used for displaying identifying icons on other devices. * This cannot be changed once device record is created. * @property capabilities A set of device capabilities, such as SEND_TAB. diff --git a/components/concept/sync/src/main/java/mozilla/components/concept/sync/OAuthAccount.kt b/components/concept/sync/src/main/java/mozilla/components/concept/sync/OAuthAccount.kt index 2fd76a07e56..80ee92d375f 100644 --- a/components/concept/sync/src/main/java/mozilla/components/concept/sync/OAuthAccount.kt +++ b/components/concept/sync/src/main/java/mozilla/components/concept/sync/OAuthAccount.kt @@ -21,14 +21,14 @@ enum class AccessType(val msg: String) { /** * An object that represents a login flow initiated by [OAuthAccount]. * @property state OAuth state parameter, identifying a specific authentication flow. - * This string is randomly generated during [OAuthAccount.beginOAuthFlowAsync] and [OAuthAccount.beginPairingFlowAsync]. + * This string is randomly generated during [OAuthAccount.beginOAuthFlow] and [OAuthAccount.beginPairingFlow]. * @property url Url which needs to be loaded to go through the authentication flow identified by [state]. */ data class AuthFlowUrl(val state: String, val url: String) /** * Represents a specific type of an "in-flight" migration state that could result from intermittent - * issues during [OAuthAccount.migrateFromSessionTokenAsync] or [OAuthAccount.copyFromSessionTokenAsync]. + * issues during [OAuthAccount.migrateFromAccount]. */ enum class InFlightMigrationState { /** @@ -37,12 +37,12 @@ enum class InFlightMigrationState { NONE, /** - * "Copy" in-flight migration present. Can retry migration via [OAuthAccount.retryMigrateFromSessionTokenAsync]. + * "Copy" in-flight migration present. Can retry migration via [OAuthAccount.retryMigrateFromSessionToken]. */ COPY_SESSION_TOKEN, /** - * "Reuse" in-flight migration present. Can retry migration via [OAuthAccount.retryMigrateFromSessionTokenAsync]. + * "Reuse" in-flight migration present. Can retry migration via [OAuthAccount.retryMigrateFromSessionToken]. */ REUSE_SESSION_TOKEN } @@ -68,7 +68,7 @@ interface OAuthAccount : AutoCloseable { * @param scopes List of OAuth scopes for which the client wants access * @return Deferred AuthFlowUrl that resolves to the flow URL when complete */ - fun beginOAuthFlowAsync(scopes: Set): Deferred + suspend fun beginOAuthFlow(scopes: Set): AuthFlowUrl? /** * Constructs a URL used to begin the pairing flow for the requested scopes and pairingUrl. @@ -77,7 +77,7 @@ interface OAuthAccount : AutoCloseable { * @param scopes List of OAuth scopes for which the client wants access * @return Deferred AuthFlowUrl Optional that resolves to the flow URL when complete */ - fun beginPairingFlowAsync(pairingUrl: String, scopes: Set): Deferred + suspend fun beginPairingFlow(pairingUrl: String, scopes: Set): AuthFlowUrl? /** * Returns current FxA Device ID for an authenticated account. @@ -103,12 +103,12 @@ interface OAuthAccount : AutoCloseable { * the code can be exchanged for a refresh token to be used offline or not * @return Deferred authorized auth code string, or `null` in case of failure. */ - fun authorizeOAuthCodeAsync( + suspend fun authorizeOAuthCode( clientId: String, scopes: Array, state: String, accessType: AccessType = AccessType.ONLINE - ): Deferred + ): String? /** * Fetches the profile object for the current client either from the existing cached state @@ -117,18 +117,18 @@ interface OAuthAccount : AutoCloseable { * @param ignoreCache Fetch the profile information directly from the server * @return Profile (optional, if successfully retrieved) representing the user's basic profile info */ - fun getProfileAsync(ignoreCache: Boolean = false): Deferred + suspend fun getProfile(ignoreCache: Boolean = false): Profile? /** * Authenticates the current account using the [code] and [state] parameters obtained via the - * OAuth flow initiated by [beginOAuthFlowAsync]. + * OAuth flow initiated by [beginOAuthFlow]. * * Modifies the FirefoxAccount state. * @param code OAuth code string * @param state state token string * @return Deferred boolean representing success or failure */ - fun completeOAuthFlowAsync(code: String, state: String): Deferred + suspend fun completeOAuthFlow(code: String, state: String): Boolean /** * Tries to fetch an access token for the given scope. @@ -137,11 +137,11 @@ interface OAuthAccount : AutoCloseable { * @return [AccessTokenInfo] that stores the token, along with its scope, key and * expiration timestamp (in seconds) since epoch when complete */ - fun getAccessTokenAsync(singleScope: String): Deferred + suspend fun getAccessToken(singleScope: String): AccessTokenInfo? /** * Call this whenever an authentication error was encountered while using an access token - * issued by [getAccessTokenAsync]. + * issued by [getAccessToken]. */ fun authErrorDetected() @@ -156,7 +156,7 @@ interface OAuthAccount : AutoCloseable { * @return An optional [Boolean] flag indicating if we're connected, or need to go through * re-authentication. A null result means we were not able to determine state at this time. */ - fun checkAuthorizationStatusAsync(singleScope: String): Deferred + suspend fun checkAuthorizationStatus(singleScope: String): Boolean? /** * Fetches the token server endpoint, for authentication using the SAML bearer flow. @@ -189,13 +189,12 @@ interface OAuthAccount : AutoCloseable { * For up-to-date schema, see underlying implementation in https://github.com/mozilla/application-services/blob/v0.49.0/components/fxa-client/src/migrator.rs#L10 * At the moment, it's just "{total_duration: long}". */ - fun migrateFromAccountAsync(authInfo: AuthInfo, reuseSessionToken: Boolean): Deferred + suspend fun migrateFromAccount(authInfo: AuthInfo, reuseSessionToken: Boolean): JSONObject? /** * Checks if there's a migration in-flight. An in-flight migration means that we've tried to migrate - * via either [migrateFromSessionTokenAsync] or [copyFromSessionTokenAsync], and failed for intermittent - * (e.g. network) - * reasons. When an in-flight migration is present, we can retry using [retryMigrateFromSessionTokenAsync]. + * via [migrateFromAccount], and failed for intermittent (e.g. network) reasons. When an in-flight + * migration is present, we can retry using [retryMigrateFromSessionToken]. * @return InFlightMigrationState indicating specific migration state. */ fun isInMigrationState(): InFlightMigrationState @@ -206,7 +205,7 @@ interface OAuthAccount : AutoCloseable { * For up-to-date schema, see underlying implementation in https://github.com/mozilla/application-services/blob/v0.49.0/components/fxa-client/src/migrator.rs#L10 * At the moment, it's just "{total_duration: long}". */ - fun retryMigrateFromSessionTokenAsync(): Deferred + suspend fun retryMigrateFromSessionToken(): JSONObject? /** * Returns the device constellation for the current account @@ -224,7 +223,7 @@ interface OAuthAccount : AutoCloseable { * Failure indicates that we may have failed to destroy current device record. Nothing to do for * the consumer; device record will be cleaned up eventually via TTL. */ - fun disconnectAsync(): Deferred + suspend fun disconnect(): Boolean /** * Serializes the current account's authentication state as a JSON string, for persistence in diff --git a/components/feature/accounts-push/src/main/java/mozilla/components/feature/accounts/push/FxaPushSupportFeature.kt b/components/feature/accounts-push/src/main/java/mozilla/components/feature/accounts/push/FxaPushSupportFeature.kt index 81108c394d1..3bd8f81fa80 100644 --- a/components/feature/accounts-push/src/main/java/mozilla/components/feature/accounts/push/FxaPushSupportFeature.kt +++ b/components/feature/accounts-push/src/main/java/mozilla/components/feature/accounts/push/FxaPushSupportFeature.kt @@ -8,6 +8,9 @@ import android.content.Context import androidx.annotation.VisibleForTesting import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ProcessLifecycleOwner +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import mozilla.components.concept.push.PushProcessor import mozilla.components.concept.sync.AuthType import mozilla.components.concept.sync.ConstellationState @@ -122,7 +125,9 @@ internal class AccountObserver( logger.debug("Subscribing for FxaPushScope ($fxaPushScope) events.") push.subscribe(fxaPushScope) { subscription -> - account.deviceConstellation().setDevicePushSubscriptionAsync(subscription.into()) + CoroutineScope(Dispatchers.Main).launch { + account.deviceConstellation().setDevicePushSubscription(subscription.into()) + } } } @@ -190,9 +195,9 @@ internal class AutoPushObserver( // Ignore push messages that do not have data. val rawEvent = message ?: return - accountManager.withConstellation { - processRawEventAsync(String(rawEvent)) - } + accountManager.withConstellation { CoroutineScope(Dispatchers.Main).launch { + processRawEvent(String(rawEvent)) + } } } override fun onSubscriptionChanged(scope: PushScope) { @@ -210,7 +215,9 @@ internal class AutoPushObserver( return@subscribe } - account.deviceConstellation().setDevicePushSubscriptionAsync(subscription.into()) + CoroutineScope(Dispatchers.Main).launch { + account.deviceConstellation().setDevicePushSubscription(subscription.into()) + } } } } @@ -325,7 +332,9 @@ class OneTimeFxaPushReset( pushFeature.unsubscribe(pushScope) pushFeature.subscribe(newPushScope) { subscription -> - account.deviceConstellation().setDevicePushSubscriptionAsync(subscription.into()) + CoroutineScope(Dispatchers.Main).launch { + account.deviceConstellation().setDevicePushSubscription(subscription.into()) + } } preference(context).edit().putString(PREF_FXA_SCOPE, newPushScope).apply() diff --git a/components/feature/accounts-push/src/main/java/mozilla/components/feature/accounts/push/SendTabUseCases.kt b/components/feature/accounts-push/src/main/java/mozilla/components/feature/accounts/push/SendTabUseCases.kt index ea6d32065da..58ee124a629 100644 --- a/components/feature/accounts-push/src/main/java/mozilla/components/feature/accounts/push/SendTabUseCases.kt +++ b/components/feature/accounts-push/src/main/java/mozilla/components/feature/accounts/push/SendTabUseCases.kt @@ -75,10 +75,10 @@ class SendTabUseCases( it.id == deviceId } device?.let { - return constellation.sendCommandToDeviceAsync( + return constellation.sendCommandToDevice( device.id, SendTab(tab.title, tab.url) - ).await() + ) } } @@ -131,10 +131,10 @@ class SendTabUseCases( // Get a list of device-tab combinations that we want to send. return block(devices).map { (device, tab) -> // Send the tab! - constellation.sendCommandToDeviceAsync( + constellation.sendCommandToDevice( device.id, SendTab(tab.title, tab.url) - ).await() + ) }.fold(true) { acc, result -> // Collect the results and reduce them into one final result. acc and result diff --git a/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/AccountObserverTest.kt b/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/AccountObserverTest.kt index fa3d4717c6d..0303ab86aea 100644 --- a/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/AccountObserverTest.kt +++ b/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/AccountObserverTest.kt @@ -164,7 +164,7 @@ class AccountObserverTest { observer.onAuthenticated(account, AuthType.Signin) - verify(constellation).setDevicePushSubscriptionAsync(any()) + verify(constellation).setDevicePushSubscription(any()) } @Test diff --git a/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/AutoPushObserverTest.kt b/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/AutoPushObserverTest.kt index c94060cbe37..9635f1010c9 100644 --- a/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/AutoPushObserverTest.kt +++ b/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/AutoPushObserverTest.kt @@ -34,7 +34,7 @@ class AutoPushObserverTest { observer.onMessageReceived("test", "foobar".toByteArray()) - verify(constellation).processRawEventAsync("foobar") + verify(constellation).processRawEvent("foobar") } @Test @@ -43,8 +43,8 @@ class AutoPushObserverTest { observer.onMessageReceived("test", "foobar".toByteArray()) - verify(constellation, never()).setDevicePushSubscriptionAsync(any()) - verify(constellation, never()).processRawEventAsync("foobar") + verify(constellation, never()).setDevicePushSubscription(any()) + verify(constellation, never()).processRawEvent("foobar") } @Test @@ -53,7 +53,7 @@ class AutoPushObserverTest { observer.onMessageReceived("test", "foobar".toByteArray()) - verify(constellation, never()).processRawEventAsync(any()) + verify(constellation, never()).processRawEvent(any()) } @Test @@ -67,7 +67,7 @@ class AutoPushObserverTest { observer.onSubscriptionChanged("test") - verify(constellation).setDevicePushSubscriptionAsync(any()) + verify(constellation).setDevicePushSubscription(any()) } @Test @@ -78,7 +78,7 @@ class AutoPushObserverTest { observer.onSubscriptionChanged("test") - verify(constellation, never()).setDevicePushSubscriptionAsync(any()) + verify(constellation, never()).setDevicePushSubscription(any()) } @Test @@ -90,7 +90,7 @@ class AutoPushObserverTest { observer.onSubscriptionChanged("test") - verify(constellation, never()).setDevicePushSubscriptionAsync(any()) + verify(constellation, never()).setDevicePushSubscription(any()) verifyZeroInteractions(pushFeature) } diff --git a/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/OneTimeFxaPushResetTest.kt b/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/OneTimeFxaPushResetTest.kt index 5ea07c99dcd..8e3cf688234 100644 --- a/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/OneTimeFxaPushResetTest.kt +++ b/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/OneTimeFxaPushResetTest.kt @@ -92,7 +92,7 @@ class OneTimeFxaPushResetTest { verify(pushFeature).unsubscribe(eq("12345"), any(), any()) verify(pushFeature).subscribe(eq(validPushScope), nullable(), any(), any()) - verify(constellation).setDevicePushSubscriptionAsync(any()) + verify(constellation).setDevicePushSubscription(any()) assertEquals(validPushScope, preference(testContext).getString(PREF_FXA_SCOPE, null)) } } diff --git a/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/SendTabUseCasesTest.kt b/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/SendTabUseCasesTest.kt index 07c3468c4e9..0e960d6384c 100644 --- a/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/SendTabUseCasesTest.kt +++ b/components/feature/accounts-push/src/test/java/mozilla/components/feature/accounts/push/SendTabUseCasesTest.kt @@ -49,12 +49,12 @@ class SendTabUseCasesTest { val device: Device = generateDevice() `when`(state.otherDevices).thenReturn(listOf(device)) - `when`(constellation.sendCommandToDeviceAsync(any(), any())) + `when`(constellation.sendCommandToDevice(any(), any())) .thenReturn(CompletableDeferred(true)) useCases.sendToDeviceAsync(device.id, TabData("Title", "http://example.com")) - verify(constellation).sendCommandToDeviceAsync(any(), any()) + verify(constellation).sendCommandToDevice(any(), any()) } @Test @@ -64,12 +64,12 @@ class SendTabUseCasesTest { val tab = TabData("Title", "http://example.com") `when`(state.otherDevices).thenReturn(listOf(device)) - `when`(constellation.sendCommandToDeviceAsync(any(), any())) + `when`(constellation.sendCommandToDevice(any(), any())) .thenReturn(CompletableDeferred(true)) useCases.sendToDeviceAsync(device.id, listOf(tab, tab)) - verify(constellation, times(2)).sendCommandToDeviceAsync(any(), any()) + verify(constellation, times(2)).sendCommandToDevice(any(), any()) } @Test @@ -80,16 +80,16 @@ class SendTabUseCasesTest { useCases.sendToDeviceAsync("123", listOf(tab, tab)) - verify(constellation, never()).sendCommandToDeviceAsync(any(), any()) + verify(constellation, never()).sendCommandToDevice(any(), any()) `when`(device.id).thenReturn("123") `when`(state.otherDevices).thenReturn(listOf(device)) - `when`(constellation.sendCommandToDeviceAsync(any(), any())) + `when`(constellation.sendCommandToDevice(any(), any())) .thenReturn(CompletableDeferred(false)) useCases.sendToDeviceAsync("123", listOf(tab, tab)) - verify(constellation, never()).sendCommandToDeviceAsync(any(), any()) + verify(constellation, never()).sendCommandToDevice(any(), any()) } @Test @@ -100,19 +100,19 @@ class SendTabUseCasesTest { useCases.sendToDeviceAsync("123", tab) - verify(constellation, never()).sendCommandToDeviceAsync(any(), any()) + verify(constellation, never()).sendCommandToDevice(any(), any()) `when`(state.otherDevices).thenReturn(listOf(device)) - `when`(constellation.sendCommandToDeviceAsync(any(), any())) + `when`(constellation.sendCommandToDevice(any(), any())) .thenReturn(CompletableDeferred(false)) useCases.sendToDeviceAsync("456", tab) - verify(constellation, never()).sendCommandToDeviceAsync(any(), any()) + verify(constellation, never()).sendCommandToDevice(any(), any()) useCases.sendToDeviceAsync("123", tab) - verify(constellation).sendCommandToDeviceAsync(any(), any()) + verify(constellation).sendCommandToDevice(any(), any()) } @Test @@ -123,19 +123,19 @@ class SendTabUseCasesTest { useCases.sendToDeviceAsync("123", listOf(tab)) - verify(constellation, never()).sendCommandToDeviceAsync(any(), any()) + verify(constellation, never()).sendCommandToDevice(any(), any()) `when`(state.otherDevices).thenReturn(listOf(device)) - `when`(constellation.sendCommandToDeviceAsync(any(), any())) + `when`(constellation.sendCommandToDevice(any(), any())) .thenReturn(CompletableDeferred(false)) useCases.sendToDeviceAsync("456", listOf(tab)) - verify(constellation, never()).sendCommandToDeviceAsync(any(), any()) + verify(constellation, never()).sendCommandToDevice(any(), any()) useCases.sendToDeviceAsync("123", listOf(tab)) - verify(constellation).sendCommandToDeviceAsync(any(), any()) + verify(constellation).sendCommandToDevice(any(), any()) } @Test @@ -145,14 +145,14 @@ class SendTabUseCasesTest { val device2: Device = generateDevice() `when`(state.otherDevices).thenReturn(listOf(device, device2)) - `when`(constellation.sendCommandToDeviceAsync(any(), any())) + `when`(constellation.sendCommandToDevice(any(), any())) .thenReturn(CompletableDeferred(false)) val tab = TabData("Mozilla", "https://mozilla.org") useCases.sendToAllAsync(tab) - verify(constellation, times(2)).sendCommandToDeviceAsync(any(), any()) + verify(constellation, times(2)).sendCommandToDevice(any(), any()) } @Test @@ -162,7 +162,7 @@ class SendTabUseCasesTest { val device2: Device = generateDevice() `when`(state.otherDevices).thenReturn(listOf(device, device2)) - `when`(constellation.sendCommandToDeviceAsync(any(), any())) + `when`(constellation.sendCommandToDevice(any(), any())) .thenReturn(CompletableDeferred(false)) val tab = TabData("Mozilla", "https://mozilla.org") @@ -170,7 +170,7 @@ class SendTabUseCasesTest { useCases.sendToAllAsync(listOf(tab, tab2)) - verify(constellation, times(4)).sendCommandToDeviceAsync(any(), any()) + verify(constellation, times(4)).sendCommandToDevice(any(), any()) } @Test @@ -183,7 +183,7 @@ class SendTabUseCasesTest { runBlocking { useCases.sendToAllAsync(tab) - verify(constellation, never()).sendCommandToDeviceAsync(any(), any()) + verify(constellation, never()).sendCommandToDevice(any(), any()) `when`(device.id).thenReturn("123") `when`(device2.id).thenReturn("456") @@ -191,7 +191,7 @@ class SendTabUseCasesTest { useCases.sendToAllAsync(tab) - verify(constellation, never()).sendCommandToDeviceAsync(any(), any()) + verify(constellation, never()).sendCommandToDevice(any(), any()) } } @@ -206,7 +206,7 @@ class SendTabUseCasesTest { runBlocking { useCases.sendToAllAsync(tab) - verify(constellation, never()).sendCommandToDeviceAsync(any(), any()) + verify(constellation, never()).sendCommandToDevice(any(), any()) `when`(device.id).thenReturn("123") `when`(device2.id).thenReturn("456") @@ -214,8 +214,8 @@ class SendTabUseCasesTest { useCases.sendToAllAsync(listOf(tab, tab2)) - verify(constellation, never()).sendCommandToDeviceAsync(eq("123"), any()) - verify(constellation, never()).sendCommandToDeviceAsync(eq("456"), any()) + verify(constellation, never()).sendCommandToDevice(eq("123"), any()) + verify(constellation, never()).sendCommandToDevice(eq("456"), any()) } } @@ -227,17 +227,17 @@ class SendTabUseCasesTest { useCases.sendToDeviceAsync("123", listOf(tab, tab)) - verify(constellation, never()).sendCommandToDeviceAsync(any(), any()) + verify(constellation, never()).sendCommandToDevice(any(), any()) `when`(device.id).thenReturn("123") `when`(state.otherDevices).thenReturn(listOf(device)) - `when`(constellation.sendCommandToDeviceAsync(any(), any())) + `when`(constellation.sendCommandToDevice(any(), any())) .thenReturn(CompletableDeferred(true)) .thenReturn(CompletableDeferred(true)) val result = useCases.sendToDeviceAsync("123", listOf(tab, tab)) - verify(constellation, never()).sendCommandToDeviceAsync(any(), any()) + verify(constellation, never()).sendCommandToDevice(any(), any()) Assert.assertFalse(result.await()) } diff --git a/components/feature/accounts/src/main/java/mozilla/components/feature/accounts/FirefoxAccountsAuthFeature.kt b/components/feature/accounts/src/main/java/mozilla/components/feature/accounts/FirefoxAccountsAuthFeature.kt index 3b78f5ad58b..f762164574f 100644 --- a/components/feature/accounts/src/main/java/mozilla/components/feature/accounts/FirefoxAccountsAuthFeature.kt +++ b/components/feature/accounts/src/main/java/mozilla/components/feature/accounts/FirefoxAccountsAuthFeature.kt @@ -34,13 +34,13 @@ class FirefoxAccountsAuthFeature( ) { fun beginAuthentication(context: Context) { beginAuthenticationAsync(context) { - accountManager.beginAuthenticationAsync().await() + accountManager.beginAuthentication() } } fun beginPairingAuthentication(context: Context, pairingUrl: String) { beginAuthenticationAsync(context) { - accountManager.beginAuthenticationAsync(pairingUrl).await() + accountManager.beginAuthentication(pairingUrl) } } @@ -80,11 +80,13 @@ class FirefoxAccountsAuthFeature( val state = parsedUri.getQueryParameter("state") as String // Notify the state machine about our success. - accountManager.finishAuthenticationAsync(FxaAuthData( - authType = authType, - code = code, - state = state - )) + CoroutineScope(Dispatchers.Main).launch { + accountManager.finishAuthentication(FxaAuthData( + authType = authType, + code = code, + state = state + )) + } return RequestInterceptor.InterceptionResponse.Url(redirectUrl) } diff --git a/components/feature/accounts/src/main/java/mozilla/components/feature/accounts/FxaWebChannelFeature.kt b/components/feature/accounts/src/main/java/mozilla/components/feature/accounts/FxaWebChannelFeature.kt index dedf6c25128..a28220978db 100644 --- a/components/feature/accounts/src/main/java/mozilla/components/feature/accounts/FxaWebChannelFeature.kt +++ b/components/feature/accounts/src/main/java/mozilla/components/feature/accounts/FxaWebChannelFeature.kt @@ -7,9 +7,11 @@ package mozilla.components.feature.accounts import android.content.Context import androidx.annotation.VisibleForTesting import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.launch import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.EngineSession @@ -299,12 +301,14 @@ class FxaWebChannelFeature( return null } - accountManager.finishAuthenticationAsync(FxaAuthData( - authType = authType, - code = code, - state = state, - declinedEngines = declinedEngines?.toSyncEngines() - )) + CoroutineScope(Dispatchers.Main).launch { + accountManager.finishAuthentication(FxaAuthData( + authType = authType, + code = code, + state = state, + declinedEngines = declinedEngines?.toSyncEngines() + )) + } return null } diff --git a/components/feature/accounts/src/test/java/mozilla/components/feature/accounts/FirefoxAccountsAuthFeatureTest.kt b/components/feature/accounts/src/test/java/mozilla/components/feature/accounts/FirefoxAccountsAuthFeatureTest.kt index 6bf1a08b74a..3adbbf1801d 100644 --- a/components/feature/accounts/src/test/java/mozilla/components/feature/accounts/FirefoxAccountsAuthFeatureTest.kt +++ b/components/feature/accounts/src/test/java/mozilla/components/feature/accounts/FirefoxAccountsAuthFeatureTest.kt @@ -217,10 +217,10 @@ class FirefoxAccountsAuthFeatureTest { val mockAccount: OAuthAccount = mock() val profile = Profile(uid = "testUID", avatar = null, email = "test@example.com", displayName = "test profile") - `when`(mockAccount.getProfileAsync(anyBoolean())).thenReturn(CompletableDeferred(profile)) - `when`(mockAccount.beginOAuthFlowAsync(any())).thenReturn(CompletableDeferred(AuthFlowUrl("authState", "auth://url"))) - `when`(mockAccount.beginPairingFlowAsync(anyString(), any())).thenReturn(CompletableDeferred(AuthFlowUrl("authState", "auth://url"))) - `when`(mockAccount.completeOAuthFlowAsync(anyString(), anyString())).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.getProfile(anyBoolean())).thenReturn(CompletableDeferred(profile)) + `when`(mockAccount.beginOAuthFlow(any())).thenReturn(CompletableDeferred(AuthFlowUrl("authState", "auth://url"))) + `when`(mockAccount.beginPairingFlow(anyString(), any())).thenReturn(CompletableDeferred(AuthFlowUrl("authState", "auth://url"))) + `when`(mockAccount.completeOAuthFlow(anyString(), anyString())).thenReturn(CompletableDeferred(true)) val manager = TestableFxaAccountManager( testContext, @@ -231,7 +231,7 @@ class FirefoxAccountsAuthFeatureTest { } runBlocking { - manager.startAsync().await() + manager.start().await() } return manager @@ -242,11 +242,11 @@ class FirefoxAccountsAuthFeatureTest { val mockAccount: OAuthAccount = mock() val profile = Profile(uid = "testUID", avatar = null, email = "test@example.com", displayName = "test profile") - `when`(mockAccount.getProfileAsync(anyBoolean())).thenReturn(CompletableDeferred(profile)) + `when`(mockAccount.getProfile(anyBoolean())).thenReturn(CompletableDeferred(profile)) - `when`(mockAccount.beginOAuthFlowAsync(any())).thenReturn(CompletableDeferred(value = null)) - `when`(mockAccount.beginPairingFlowAsync(anyString(), any())).thenReturn(CompletableDeferred(value = null)) - `when`(mockAccount.completeOAuthFlowAsync(anyString(), anyString())).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.beginOAuthFlow(any())).thenReturn(CompletableDeferred(value = null)) + `when`(mockAccount.beginPairingFlow(anyString(), any())).thenReturn(CompletableDeferred(value = null)) + `when`(mockAccount.completeOAuthFlow(anyString(), anyString())).thenReturn(CompletableDeferred(true)) val manager = TestableFxaAccountManager( testContext, @@ -257,7 +257,7 @@ class FirefoxAccountsAuthFeatureTest { } runBlocking { - manager.startAsync().await() + manager.start().await() } return manager diff --git a/components/feature/accounts/src/test/java/mozilla/components/feature/accounts/FxaWebChannelFeatureTest.kt b/components/feature/accounts/src/test/java/mozilla/components/feature/accounts/FxaWebChannelFeatureTest.kt index 19b7d821395..a096a821d60 100644 --- a/components/feature/accounts/src/test/java/mozilla/components/feature/accounts/FxaWebChannelFeatureTest.kt +++ b/components/feature/accounts/src/test/java/mozilla/components/feature/accounts/FxaWebChannelFeatureTest.kt @@ -263,7 +263,7 @@ class FxaWebChannelFeatureTest { whenever(accountManager.accountProfile()).thenReturn(profile) whenever(accountManager.authenticatedAccount()).thenReturn(account) whenever(accountManager.supportedSyncEngines()).thenReturn(expectedEngines) - whenever(accountManager.logoutAsync()).thenReturn(logoutDeferred) + whenever(accountManager.logout()).thenReturn(logoutDeferred) val webchannelFeature = prepareFeatureForTest(ext, port, engineSession, expectedEngines, emptySet(), accountManager) webchannelFeature.start() @@ -317,7 +317,7 @@ class FxaWebChannelFeatureTest { whenever(accountManager.accountProfile()).thenReturn(null) whenever(accountManager.authenticatedAccount()).thenReturn(account) whenever(accountManager.supportedSyncEngines()).thenReturn(expectedEngines) - whenever(accountManager.logoutAsync()).thenReturn(logoutDeferred) + whenever(accountManager.logout()).thenReturn(logoutDeferred) val webchannelFeature = prepareFeatureForTest(ext, port, engineSession, expectedEngines, emptySet(), accountManager) webchannelFeature.start() diff --git a/components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/controller/DefaultController.kt b/components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/controller/DefaultController.kt index 4df77706fd5..6b1572449e6 100644 --- a/components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/controller/DefaultController.kt +++ b/components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/controller/DefaultController.kt @@ -57,10 +57,8 @@ internal class DefaultController( */ override fun syncAccount() { scope.launch { - accountManager.withConstellation { - refreshDevicesAsync().await() - } - accountManager.syncNowAsync(SyncReason.User) + accountManager.withConstellation { refreshDevices() } + accountManager.syncNow(SyncReason.User) } } } diff --git a/components/feature/syncedtabs/src/test/java/mozilla/components/feature/syncedtabs/controller/DefaultControllerTest.kt b/components/feature/syncedtabs/src/test/java/mozilla/components/feature/syncedtabs/controller/DefaultControllerTest.kt index 5c1b6ba48a4..15aec9c0331 100644 --- a/components/feature/syncedtabs/src/test/java/mozilla/components/feature/syncedtabs/controller/DefaultControllerTest.kt +++ b/components/feature/syncedtabs/src/test/java/mozilla/components/feature/syncedtabs/controller/DefaultControllerTest.kt @@ -160,11 +160,11 @@ class DefaultControllerTest { `when`(accountManager.authenticatedAccount()).thenReturn(account) `when`(account.deviceConstellation()).thenReturn(constellation) - `when`(constellation.refreshDevicesAsync()).thenReturn(CompletableDeferred(true)) + `when`(constellation.refreshDevices()).thenReturn(CompletableDeferred(true)) controller.syncAccount() - verify(constellation).refreshDevicesAsync() - verify(accountManager).syncNowAsync(SyncReason.User, false) + verify(constellation).refreshDevices() + verify(accountManager).syncNow(SyncReason.User, false) } } diff --git a/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/FirefoxAccount.kt b/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/FirefoxAccount.kt index 83bfd7d6091..51a012fecde 100644 --- a/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/FirefoxAccount.kt +++ b/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/FirefoxAccount.kt @@ -5,12 +5,11 @@ package mozilla.components.service.fxa import android.net.Uri -import kotlinx.coroutines.async import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Deferred import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.plus +import kotlinx.coroutines.withContext import mozilla.appservices.fxaclient.FirefoxAccount as InternalFxAcct import mozilla.components.concept.sync.AccessType import mozilla.components.concept.sync.AuthFlowUrl @@ -19,7 +18,6 @@ import mozilla.components.concept.sync.DeviceConstellation import mozilla.components.concept.sync.OAuthAccount import mozilla.components.concept.sync.StatePersistenceCallback import mozilla.components.support.base.log.logger.Logger -import org.json.JSONObject typealias PersistCallback = mozilla.appservices.fxaclient.FirefoxAccount.PersistCallback @@ -101,7 +99,7 @@ class FirefoxAccount internal constructor( persistCallback.setCallback(callback) } - override fun beginOAuthFlowAsync(scopes: Set) = scope.async { + override suspend fun beginOAuthFlow(scopes: Set) = withContext(scope.coroutineContext) { handleFxaExceptions(logger, "begin oauth flow", { null }) { val url = inner.beginOAuthFlow(scopes.toTypedArray()) val state = Uri.parse(url).getQueryParameter("state")!! @@ -109,7 +107,7 @@ class FirefoxAccount internal constructor( } } - override fun beginPairingFlowAsync(pairingUrl: String, scopes: Set) = scope.async { + override suspend fun beginPairingFlow(pairingUrl: String, scopes: Set) = withContext(scope.coroutineContext) { handleFxaExceptions(logger, "begin oauth pairing flow", { null }) { val url = inner.beginPairingFlow(pairingUrl, scopes.toTypedArray()) val state = Uri.parse(url).getQueryParameter("state")!! @@ -117,7 +115,7 @@ class FirefoxAccount internal constructor( } } - override fun getProfileAsync(ignoreCache: Boolean) = scope.async { + override suspend fun getProfile(ignoreCache: Boolean) = withContext(scope.coroutineContext) { handleFxaExceptions(logger, "getProfile", { null }) { inner.getProfile(ignoreCache).into() } @@ -135,21 +133,21 @@ class FirefoxAccount internal constructor( } } - override fun authorizeOAuthCodeAsync( + override suspend fun authorizeOAuthCode( clientId: String, scopes: Array, state: String, accessType: AccessType - ) = scope.async { + ) = withContext(scope.coroutineContext) { handleFxaExceptions(logger, "authorizeOAuthCode", { null }) { inner.authorizeOAuthCode(clientId, scopes, state, accessType.msg) } } override fun getSessionToken(): String? { - // This is awkward, yes. Underlying method simply reads some data from in-memory state, and yet it throws - // in case that data isn't there. See https://github.com/mozilla/application-services/issues/2202. return try { + // This is awkward, yes. Underlying method simply reads some data from in-memory state, and yet it throws + // in case that data isn't there. See https://github.com/mozilla/application-services/issues/2202. inner.getSessionToken() } catch (e: FxaPanicException) { throw e @@ -158,7 +156,7 @@ class FirefoxAccount internal constructor( } } - override fun migrateFromAccountAsync(authInfo: AuthInfo, reuseSessionToken: Boolean): Deferred = scope.async { + override suspend fun migrateFromAccount(authInfo: AuthInfo, reuseSessionToken: Boolean) = withContext(scope.coroutineContext) { if (reuseSessionToken) { handleFxaExceptions(logger, "migrateFromSessionToken", { null }) { inner.migrateFromSessionToken(authInfo.sessionToken, authInfo.kSync, authInfo.kXCS) @@ -172,7 +170,7 @@ class FirefoxAccount internal constructor( override fun isInMigrationState() = inner.isInMigrationState().into() - override fun retryMigrateFromSessionTokenAsync(): Deferred = scope.async { + override suspend fun retryMigrateFromSessionToken() = withContext(scope.coroutineContext) { handleFxaExceptions(logger, "retryMigrateFromSessionToken", { null }) { inner.retryMigrateFromSessionToken() } @@ -193,13 +191,13 @@ class FirefoxAccount internal constructor( return inner.getConnectionSuccessURL() } - override fun completeOAuthFlowAsync(code: String, state: String) = scope.async { + override suspend fun completeOAuthFlow(code: String, state: String) = withContext(scope.coroutineContext) { handleFxaExceptions(logger, "complete oauth flow") { inner.completeOAuthFlow(code, state) } } - override fun getAccessTokenAsync(singleScope: String) = scope.async { + override suspend fun getAccessToken(singleScope: String) = withContext(scope.coroutineContext) { handleFxaExceptions(logger, "get access token", { null }) { inner.getAccessToken(singleScope).into() } @@ -211,7 +209,7 @@ class FirefoxAccount internal constructor( inner.clearAccessTokenCache() } - override fun checkAuthorizationStatusAsync(singleScope: String) = scope.async { + override suspend fun checkAuthorizationStatus(singleScope: String) = withContext(scope.coroutineContext) { // Now that internal token caches are cleared, we can perform a connectivity check. // Do so by requesting a new access token using an internally-stored "refresh token". // Success here means that we're still able to connect - our cached access token simply expired. @@ -234,7 +232,7 @@ class FirefoxAccount internal constructor( // Re-throw all other exceptions. } - override fun disconnectAsync() = scope.async { + override suspend fun disconnect() = withContext(scope.coroutineContext) { // TODO can this ever throw FxaUnauthorizedException? would that even make sense? or is that a bug? handleFxaExceptions(logger, "disconnect", { false }) { inner.disconnect() diff --git a/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/FxaDeviceConstellation.kt b/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/FxaDeviceConstellation.kt index ab5046fd827..d621c97451c 100644 --- a/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/FxaDeviceConstellation.kt +++ b/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/FxaDeviceConstellation.kt @@ -6,12 +6,10 @@ package mozilla.components.service.fxa import android.content.Context import androidx.lifecycle.LifecycleOwner -import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Deferred import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import mozilla.appservices.fxaclient.FirefoxAccount import mozilla.components.concept.sync.ConstellationState import mozilla.components.concept.sync.Device @@ -50,7 +48,7 @@ class FxaDeviceConstellation( None } - override fun finalizeDeviceAsync(authType: AuthType, config: DeviceConfig): Deferred { + override suspend fun finalizeDevice(authType: AuthType, config: DeviceConfig) = withContext(scope.coroutineContext) { val finalizeAction = when (authType) { AuthType.Signin, AuthType.Signup, @@ -63,10 +61,8 @@ class FxaDeviceConstellation( } if (finalizeAction == DeviceFinalizeAction.None) { - return CompletableDeferred(true) - } - - return scope.async { + true + } else { val capabilities = config.capabilities.map { it.into() }.toSet() if (finalizeAction == DeviceFinalizeAction.Initialize) { handleFxaExceptions(logger, "initializing device") { @@ -80,11 +76,9 @@ class FxaDeviceConstellation( } } - override fun processRawEventAsync(payload: String): Deferred { - return scope.async { - handleFxaExceptions(logger, "processing raw commands") { - processEvents(account.handlePushMessage(payload).map { it.into() }) - } + override suspend fun processRawEvent(payload: String) = withContext(scope.coroutineContext) { + handleFxaExceptions(logger, "processing raw commands") { + processEvents(account.handlePushMessage(payload).map { it.into() }) } } @@ -96,59 +90,50 @@ class FxaDeviceConstellation( deviceObserverRegistry.register(observer, owner, autoPause) } - override fun setDeviceNameAsync(name: String, context: Context): Deferred { - return scope.async { - val rename = handleFxaExceptions(logger, "changing device name") { - account.setDeviceDisplayName(name) - } - FxaDeviceSettingsCache(context).updateCachedName(name) - // See the latest device (name) changes after changing it. - val refreshDevices = refreshDevicesAsync().await() - - rename && refreshDevices + override suspend fun setDeviceName(name: String, context: Context) = withContext(scope.coroutineContext) { + val rename = handleFxaExceptions(logger, "changing device name") { + account.setDeviceDisplayName(name) } + FxaDeviceSettingsCache(context).updateCachedName(name) + // See the latest device (name) changes after changing it. + + rename && refreshDevices() } - override fun setDevicePushSubscriptionAsync(subscription: DevicePushSubscription): Deferred { - return scope.async { - handleFxaExceptions(logger, "updating device push subscription") { - account.setDevicePushSubscription( - subscription.endpoint, subscription.publicKey, subscription.authKey - ) - } + override suspend fun setDevicePushSubscription(subscription: DevicePushSubscription) = withContext(scope.coroutineContext) { + handleFxaExceptions(logger, "updating device push subscription") { + account.setDevicePushSubscription( + subscription.endpoint, subscription.publicKey, subscription.authKey + ) } } - override fun sendCommandToDeviceAsync( + override suspend fun sendCommandToDevice( targetDeviceId: String, outgoingCommand: DeviceCommandOutgoing - ): Deferred { - return scope.async { - handleFxaExceptions(logger, "sending device command") { - when (outgoingCommand) { - is DeviceCommandOutgoing.SendTab -> { - account.sendSingleTab(targetDeviceId, outgoingCommand.title, outgoingCommand.url) - } - else -> logger.debug("Skipped sending unsupported command type: $outgoingCommand") + ) = withContext(scope.coroutineContext) { + handleFxaExceptions(logger, "sending device command") { + when (outgoingCommand) { + is DeviceCommandOutgoing.SendTab -> { + account.sendSingleTab(targetDeviceId, outgoingCommand.title, outgoingCommand.url) } + else -> logger.debug("Skipped sending unsupported command type: $outgoingCommand") } } } // Poll for missed commands. Commands are the only event-type that can be // polled for, although missed commands will be delivered as AccountEvents. - override fun pollForCommandsAsync(): Deferred { - return scope.async { - val events = handleFxaExceptions(logger, "polling for device commands", { null }) { - account.pollDeviceCommands().map { AccountEvent.DeviceCommandIncoming(command = it.into()) } - } + override suspend fun pollForCommands() = withContext(scope.coroutineContext) { + val events = handleFxaExceptions(logger, "polling for device commands", { null }) { + account.pollDeviceCommands().map { AccountEvent.DeviceCommandIncoming(command = it.into()) } + } - if (events == null) { - false - } else { - processEvents(events) - true - } + if (events == null) { + false + } else { + processEvents(events) + true } } @@ -156,46 +141,46 @@ class FxaDeviceConstellation( notifyObservers { onEvents(events) } } - override fun refreshDevicesAsync(): Deferred = scope.async { - logger.info("Refreshing device list...") + override suspend fun refreshDevices(): Boolean { + return withContext(scope.coroutineContext) { + logger.info("Refreshing device list...") - // Attempt to fetch devices, or bail out on failure. - val allDevices = fetchAllDevicesAsync().await() ?: return@async false + // Attempt to fetch devices, or bail out on failure. + val allDevices = fetchAllDevices() ?: return@withContext false - // Find the current device. - val currentDevice = allDevices.find { it.isCurrentDevice }?.also { - // Check if our current device's push subscription needs to be renewed. - if (it.subscriptionExpired) { - logger.info("Current device needs push endpoint registration") + // Find the current device. + val currentDevice = allDevices.find { it.isCurrentDevice }?.also { + // Check if our current device's push subscription needs to be renewed. + if (it.subscriptionExpired) { + logger.info("Current device needs push endpoint registration") + } } - } - // Filter out the current devices. - val otherDevices = allDevices.filter { !it.isCurrentDevice } + // Filter out the current devices. + val otherDevices = allDevices.filter { !it.isCurrentDevice } - val newState = ConstellationState(currentDevice, otherDevices) - constellationState = newState + val newState = ConstellationState(currentDevice, otherDevices) + constellationState = newState - logger.info("Refreshed device list; saw ${allDevices.size} device(s).") + logger.info("Refreshed device list; saw ${allDevices.size} device(s).") - CoroutineScope(Dispatchers.Main).launch { - // NB: at this point, 'constellationState' might have changed. - // Notify with an immutable, local 'newState' instead. - deviceObserverRegistry.notifyObservers { onDevicesUpdate(newState) } - } + CoroutineScope(Dispatchers.Main).launch { + // NB: at this point, 'constellationState' might have changed. + // Notify with an immutable, local 'newState' instead. + deviceObserverRegistry.notifyObservers { onDevicesUpdate(newState) } + } - true + true + } } /** * Get all devices in the constellation. * @return A list of all devices in the constellation, or `null` on failure. */ - private fun fetchAllDevicesAsync(): Deferred?> { - return scope.async { - handleFxaExceptions(logger, "fetching all devices", { null }) { - account.getDevices().map { it.into() } - } + private suspend fun fetchAllDevices(): List? { + return handleFxaExceptions(logger, "fetching all devices", { null }) { + account.getDevices().map { it.into() } } } } diff --git a/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/manager/FxaAccountManager.kt b/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/manager/FxaAccountManager.kt index 8181b87ef1a..3857c2bedd1 100644 --- a/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/manager/FxaAccountManager.kt +++ b/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/manager/FxaAccountManager.kt @@ -8,12 +8,9 @@ import android.content.Context import androidx.annotation.GuardedBy import androidx.annotation.VisibleForTesting import androidx.lifecycle.LifecycleOwner -import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Deferred import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.asCoroutineDispatcher -import kotlinx.coroutines.async import kotlinx.coroutines.launch import kotlinx.coroutines.cancel import kotlinx.coroutines.withContext @@ -83,7 +80,7 @@ const val AUTH_CHECK_CIRCUIT_BREAKER_COUNT = 10 const val MAX_NETWORK_RETRIES = 3 /** - * Describes a result of running [FxaAccountManager.migrateFromAccountAsync]. + * Describes a result of running [FxaAccountManager.migrateFromAccount]. */ enum class MigrationResult { /** @@ -155,21 +152,19 @@ open class FxaAccountManager( @Volatile private var latestAuthState: String? = null - // This is used during 'beginAuthenticationAsync' call, which returns a Deferred. + // This is used during 'beginAuthentication' call, which returns a Deferred. // 'deferredAuthUrl' is set on this observer and returned, and resolved once state machine goes // through its motions. This allows us to keep around only one observer in the registry. private val fxaOAuthObserver = FxaOAuthObserver() private class FxaOAuthObserver : OAuthObserver { @Volatile - lateinit var deferredAuthUrl: CompletableDeferred + var deferredAuthUrl: String? = null override fun onBeginOAuthFlow(authFlowUrl: AuthFlowUrl) { - deferredAuthUrl.complete(authFlowUrl.url) + deferredAuthUrl = authFlowUrl.url } - override fun onError() { - deferredAuthUrl.complete(null) - } + override fun onError() {} } private val oauthObservers = object : Observable by ObserverRegistry() {} init { @@ -232,7 +227,7 @@ open class FxaAccountManager( private val internalSyncStatusObserver = SyncToAccountsIntegration(this) init { - syncConfig?.let { setSyncConfigAsync(it) } + syncConfig?.let { setSyncConfig(it) } if (syncManager == null) { logger.info("Sync is disabled") @@ -244,7 +239,7 @@ open class FxaAccountManager( /** * Queries trusted FxA Auth providers available on the device, returning a list of [ShareableAccount] * in an order of preference. Any of the returned [ShareableAccount] may be used with - * [migrateFromAccountAsync] to sign-in into an FxA account without any required user input. + * [migrateFromAccount] to sign-in into an FxA account without any required user input. */ fun shareableAccounts(context: Context): List { return AccountSharing.queryShareableAccounts(context) @@ -258,27 +253,20 @@ open class FxaAccountManager( * @param reuseSessionToken Whether or not to reuse existing session token (which is part of the [ShareableAccount]. * @return A deferred boolean flag indicating success (if true) of the sign-in operation. */ - fun migrateFromAccountAsync( + suspend fun migrateFromAccount( fromAccount: ShareableAccount, reuseSessionToken: Boolean = false - ): Deferred { - val stateMachineTransition = processQueueAsync(Event.External.MigrateFromAccount(fromAccount, reuseSessionToken)) - val result = CompletableDeferred() - CoroutineScope(coroutineContext).launch { - stateMachineTransition.await() - - val migrationResult = when (val s = state) { - is SS.Idle -> when (s.accountState) { - AccountState.Authenticated -> MigrationResult.Success - AccountState.IncompleteMigration -> MigrationResult.WillRetry - else -> MigrationResult.Failure - } + ): MigrationResult = withContext(coroutineContext) { + processQueue(Event.External.MigrateFromAccount(fromAccount, reuseSessionToken)) + + when (val s = state) { + is SS.Idle -> when (s.accountState) { + AccountState.Authenticated -> MigrationResult.Success + AccountState.IncompleteMigration -> MigrationResult.WillRetry else -> MigrationResult.Failure } - - result.complete(migrationResult) + else -> MigrationResult.Failure } - return result } /** @@ -287,7 +275,7 @@ open class FxaAccountManager( * @param config Sync behaviour configuration, see [SyncConfig]. */ @VisibleForTesting - internal fun setSyncConfigAsync(config: SyncConfig): Deferred = synchronized(this) { + internal fun setSyncConfig(config: SyncConfig) = synchronized(this) { logger.info("Enabling/updating sync with a new SyncConfig: $config") syncConfig = config @@ -295,20 +283,18 @@ open class FxaAccountManager( syncManager?.stop() syncManagerIntegration = null - val result = CompletableDeferred() - // Initialize a new sync manager with the passed-in config. if (config.supportedEngines.isEmpty()) { throw IllegalArgumentException("Set of supported engines can't be empty") } - syncManager = createSyncManager(config).also { manager -> + syncManager = createSyncManager(config).also { sync -> // Observe account state changes. - syncManagerIntegration = AccountsToSyncIntegration(manager).also { accountToSync -> + syncManagerIntegration = AccountsToSyncIntegration(sync).also { accountToSync -> this@FxaAccountManager.register(accountToSync) } // Observe sync status changes. - manager.registerSyncStatusObserver(internalSyncStatusObserver) + sync.registerSyncStatusObserver(internalSyncStatusObserver) // If account is currently authenticated, 'enable' the sync manager. if (authenticatedAccount() != null) { CoroutineScope(coroutineContext).launch { @@ -326,15 +312,10 @@ open class FxaAccountManager( // - persist local choice, if we've signed for an account up locally and have CWTS // data from the user // - or fetch existing CWTS data from the server, if we don't have it locally. - manager.start(SyncReason.FirstSync) - result.complete(Unit) + sync.start(SyncReason.FirstSync) } - } else { - result.complete(Unit) } } - - return result } /** @@ -364,28 +345,21 @@ open class FxaAccountManager( * @param reason A [SyncReason] indicating why this sync is being requested. * @param debounce Boolean flag indicating if this sync may be debounced (in case another sync executed recently). */ - fun syncNowAsync( + suspend fun syncNow( reason: SyncReason, debounce: Boolean = false - ): Deferred = CoroutineScope(coroutineContext).async { - // We may be in a state where we're not quite authenticated yet - but can auto-retry our - // authentication, instead. - // This is one of our trigger points for retrying - when a user asks us to sync. - // Another trigger point is the initialization flow of the account manager itself. + ) = withContext(coroutineContext) { when (val s = state) { + // Can't sync while we're still doing stuff. + is SS.Active -> Unit is SS.Idle -> when (s.accountState) { + // If we're in an incomplete migration state, try to complete it. + // This is one of our trigger points for retrying - when a user asks us to sync. + // Another trigger point is the startup flow of the account manager itself. AccountState.IncompleteMigration -> { - // Only trigger a retry attempt if the sync request was caused by a direct user action. - // We don't attempt to retry migration on 'SyncReason.Startup' because a retry will happen during - // account manager initialization if necessary anyway. - // If the retry attempt succeeds, sync will run as a by-product of regular account authentication flow, - // which is why we don't check for the result of a retry attempt here. -// when (reason) { -// SyncReason.User, SyncReason.EngineChange -> processQueueAsync(Event.ExternalEvent.FinalizeMigration).await() -// } - // TODO i don't think it matters 'why', state machine should do the right thing here. - processQueueAsync(Event.External.RetryMigration).await() + processQueue(Event.External.RetryMigration) } + // All good, request a sync. AccountState.Authenticated -> { // Make sure auth cache is populated before we try to sync. maybeUpdateSyncAuthInfoCache() @@ -403,7 +377,6 @@ open class FxaAccountManager( else -> logger.info("Ignoring syncNow request, not in the right state: $s") } } - Unit } /** @@ -414,9 +387,9 @@ open class FxaAccountManager( /** * Call this after registering your observers, and before interacting with this class. */ - fun startAsync(): Deferred { - statePersistenceCallback = FxaStatePersistenceCallback(WeakReference(this)) - return processQueueAsync(Event.External.Start) + suspend fun start() = withContext(coroutineContext) { + statePersistenceCallback = FxaStatePersistenceCallback(WeakReference(this@FxaAccountManager)) + processQueue(Event.External.Start) } /** @@ -435,7 +408,7 @@ open class FxaAccountManager( } /** - * Indicates if account needs to be re-authenticated via [beginAuthenticationAsync]. + * Indicates if account needs to be re-authenticated via [beginAuthentication]. * Most common reason for an account to need re-authentication is a password change. * * TODO this may return a false-positive, if we're currently going through a recovery flow. @@ -461,7 +434,7 @@ open class FxaAccountManager( } private suspend fun refreshProfile(ignoreCache: Boolean) { - authenticatedAccount()?.getProfileAsync(ignoreCache = ignoreCache)?.await()?.let { newProfile -> + authenticatedAccount()?.getProfile(ignoreCache = ignoreCache)?.let { newProfile -> profile = newProfile notifyObservers { onProfileUpdated(newProfile) @@ -469,24 +442,19 @@ open class FxaAccountManager( } } - fun beginAuthenticationAsync(pairingUrl: String? = null): Deferred { - val deferredAuthUrl = CompletableDeferred() - - // Observer will 'complete' this deferred once state machine resolves its events. - fxaOAuthObserver.deferredAuthUrl = deferredAuthUrl - + suspend fun beginAuthentication(pairingUrl: String? = null): String? { val event = if (pairingUrl != null) { Event.External.BeginPairingFlow(pairingUrl) } else { Event.External.BeginEmailFlow } - processQueueAsync(event) - return deferredAuthUrl + processQueue(event) + return fxaOAuthObserver.deferredAuthUrl } /** - * Finalize authentication that was started via [beginAuthenticationAsync]. + * Finalize authentication that was started via [beginAuthentication]. * * If authentication wasn't started via this manager we won't accept this authentication attempt, * returning `false`. This may happen if [WebChannelFeature] is enabled, and user is manually @@ -498,33 +466,22 @@ open class FxaAccountManager( * * @return A deferred boolean flag indicating if authentication state was accepted. */ - fun finishAuthenticationAsync(authData: FxaAuthData): Deferred { - val result = CompletableDeferred() - + suspend fun finishAuthentication(authData: FxaAuthData) = withContext(coroutineContext) { when { latestAuthState == null -> { logger.warn("Trying to finish authentication that was never started.") - result.complete(false) } authData.state != latestAuthState -> { logger.warn("Trying to finish authentication for an invalid auth state; ignoring.") - result.complete(false) } authData.state == latestAuthState -> { - CoroutineScope(coroutineContext).launch { - processQueueAsync(Event.Internal.AuthData(authData)).await() - result.complete(true) - } + processQueue(Event.Internal.AuthData(authData)) } - else -> throw IllegalStateException("Unexpected finishAuthenticationAsync state") + else -> throw IllegalStateException("Unexpected finishAuthentication state") } - - return result } - fun logoutAsync(): Deferred { - return processQueueAsync(Event.External.Logout) - } + suspend fun logout() = withContext(coroutineContext) { processQueue(Event.External.Logout) } fun registerForAccountEvents(observer: AccountEventsObserver, owner: LifecycleOwner, autoPause: Boolean) { accountEventObserverRegistry.register(observer, owner, autoPause) @@ -544,15 +501,15 @@ open class FxaAccountManager( operation: String, errorCountWithinTheTimeWindow: Int = 1 ) = withContext(coroutineContext) { - processQueueAsync( + processQueue( Event.External.AuthenticationError(operation, errorCountWithinTheTimeWindow) - ).await() + ) } /** * Pumps the state machine until all events are processed and their side-effects resolve. */ - private fun processQueueAsync(event: Event): Deferred = CoroutineScope(coroutineContext).async { + private suspend fun processQueue(event: Event) = withContext(coroutineContext) { eventQueue.add(event) do { val toProcess: Event = eventQueue.poll()!! @@ -641,7 +598,7 @@ open class FxaAccountManager( InternalState.LoggingOut -> { // Clean up internal account state and destroy the current FxA device record. // This can fail (network issues, auth problems, etc), but nothing we can do at this point. - account.disconnectAsync().await() + account.disconnect() // Clean up resources. profile = null @@ -688,7 +645,7 @@ open class FxaAccountManager( is Event.Internal.AuthData -> { val completeAuth = suspend { withRetries(MAX_NETWORK_RETRIES) { - account.completeOAuthFlowAsync(via.authData.code, via.authData.state).await() + account.completeOAuthFlow(via.authData.code, via.authData.state) } } val finalize = suspend { @@ -726,7 +683,7 @@ open class FxaAccountManager( InFlightMigrationState.COPY_SESSION_TOKEN -> false InFlightMigrationState.NONE -> return Event.Internal.UnrecoverableErrorMigrating } - val json = account.retryMigrateFromSessionTokenAsync().await() + val json = account.retryMigrateFromSessionToken() if (json != null) { Event.Internal.Migrated(reusingSessionToken) } else { @@ -738,7 +695,7 @@ open class FxaAccountManager( } } is Event.External.MigrateFromAccount -> { - val json = account.migrateFromAccountAsync(via.account.authInfo, via.reuseSessionToken).await() + val json = account.migrateFromAccount(via.account.authInfo, via.reuseSessionToken) if (json != null) { Event.Internal.Migrated(via.reuseSessionToken) } else { @@ -786,7 +743,7 @@ open class FxaAccountManager( // We request an access token for a "profile" scope since that's the only // scope we're guaranteed to have at this point. That is, we don't rely on // passed-in application-specific scopes. - when (account.checkAuthorizationStatusAsync(SCOPE_PROFILE).await()) { + when (account.checkAuthorizationStatus(SCOPE_PROFILE)) { true -> { logger.info("Able to recover from an auth problem.") @@ -841,7 +798,7 @@ open class FxaAccountManager( } // NB: this call will inform authErrorRegistry in case an auth error is encountered. - account.getAccessTokenAsync(SCOPE_SYNC).await()?.let { + account.getAccessToken(SCOPE_SYNC)?.let { SyncAuthInfoCache(context).setToCache( it.asSyncAuthInfo(account.getTokenServerEndpointURL()) ) @@ -894,13 +851,13 @@ open class FxaAccountManager( private suspend fun String?.asAuthFlowUrl(): AuthFlowUrl? { return if (this != null) { - account.beginPairingFlowAsync(this, scopes).await() + account.beginPairingFlow(this, scopes) } else { - account.beginOAuthFlowAsync(scopes).await() + account.beginOAuthFlow(scopes) } } - private suspend fun finalizeDevice(authType: AuthType) = account.deviceConstellation().finalizeDeviceAsync(authType, deviceConfig).await() + private suspend fun finalizeDevice(authType: AuthType) = account.deviceConstellation().finalizeDevice(authType, deviceConfig) private suspend fun authenticationSideEffects(authType: AuthType) { // Make sure our SyncAuthInfo cache is hot, background sync worker needs it to function. @@ -916,7 +873,7 @@ open class FxaAccountManager( // If device supports SEND_TAB, and we're not recovering from an auth problem... if (deviceConfig.capabilities.contains(DeviceCapability.SEND_TAB) && authType != AuthType.Recovered) { // ... update constellation state (fetching info about other devices, our own device). - account.deviceConstellation().refreshDevicesAsync().await() + account.deviceConstellation().refreshDevices() } } diff --git a/components/service/firefox-accounts/src/test/java/mozilla/components/service/fxa/FxaAccountManagerTest.kt b/components/service/firefox-accounts/src/test/java/mozilla/components/service/fxa/FxaAccountManagerTest.kt index 83d6204e927..2f74f42f2f3 100644 --- a/components/service/firefox-accounts/src/test/java/mozilla/components/service/fxa/FxaAccountManagerTest.kt +++ b/components/service/firefox-accounts/src/test/java/mozilla/components/service/fxa/FxaAccountManagerTest.kt @@ -198,11 +198,11 @@ class FxaAccountManagerTest { } } - `when`(constellation.finalizeDeviceAsync(AuthType.Existing, any())).thenReturn(CompletableDeferred(true)) + `when`(constellation.finalizeDevice(AuthType.Existing, any())).thenReturn(CompletableDeferred(true)) // We have an account at the start. `when`(accountStorage.read()).thenReturn(account) - manager.startAsync().await() + manager.start().await() // Can check if sync is running (it's not!), even if we don't have sync configured. assertFalse(manager.isSyncActive()) @@ -219,7 +219,7 @@ class FxaAccountManagerTest { // Bad configuration: no stores. try { - manager.setSyncConfigAsync(SyncConfig(setOf())).await() + manager.setSyncConfig(SyncConfig(setOf())).await() fail() } catch (e: IllegalArgumentException) {} @@ -230,7 +230,7 @@ class FxaAccountManagerTest { assertEquals(0, syncStatusObserver.onErrorCount) // No periodic sync. - manager.setSyncConfigAsync(SyncConfig(setOf(SyncEngine.History))).await() + manager.setSyncConfig(SyncConfig(setOf(SyncEngine.History))).await() assertEquals(setOf(SyncEngine.History), manager.supportedSyncEngines()) assertNotNull(latestSyncManager) @@ -241,7 +241,7 @@ class FxaAccountManagerTest { verify(latestSyncManager!!.dispatcher.inner, times(1)).syncNow(eq(SyncReason.FirstSync), anyBoolean()) // With periodic sync. - manager.setSyncConfigAsync(SyncConfig(setOf(SyncEngine.History, SyncEngine.Passwords), 60 * 1000L)).await() + manager.setSyncConfig(SyncConfig(setOf(SyncEngine.History, SyncEngine.Passwords), 60 * 1000L)).await() assertEquals(setOf(SyncEngine.History, SyncEngine.Passwords), manager.supportedSyncEngines()) verify(latestSyncManager!!.dispatcher.inner, times(1)).startPeriodicSync(any(), anyLong()) @@ -302,7 +302,7 @@ class FxaAccountManagerTest { } } - `when`(constellation.finalizeDeviceAsync(AuthType.Existing, any())).thenReturn(CompletableDeferred(true)) + `when`(constellation.finalizeDevice(AuthType.Existing, any())).thenReturn(CompletableDeferred(true)) // We have an account at the start. `when`(accountStorage.read()).thenReturn(account) @@ -313,7 +313,7 @@ class FxaAccountManagerTest { `when`(lifecycleOwner.lifecycle).thenReturn(lifecycle) manager.registerForSyncEvents(syncStatusObserver, lifecycleOwner, true) - manager.startAsync().await() + manager.start().await() // Make sure that sync access token was cached correctly. assertFalse(SyncAuthInfoCache(testContext).expired()) @@ -334,11 +334,11 @@ class FxaAccountManagerTest { verify(latestSyncManager!!.dispatcher.inner, times(1)).syncNow(eq(SyncReason.Startup), anyBoolean()) // Can trigger syncs. - manager.syncNowAsync(SyncReason.User).await() + manager.syncNow(SyncReason.User).await() verify(latestSyncManager!!.dispatcher.inner, times(1)).syncNow(SyncReason.User, debounce = false) - manager.syncNowAsync(SyncReason.Startup).await() + manager.syncNow(SyncReason.Startup).await() verify(latestSyncManager!!.dispatcher.inner, times(2)).syncNow(SyncReason.Startup, debounce = false) - manager.syncNowAsync(SyncReason.EngineChange, debounce = true).await() + manager.syncNow(SyncReason.EngineChange, debounce = true).await() verify(latestSyncManager!!.dispatcher.inner, times(1)).syncNow(SyncReason.EngineChange, debounce = true) // TODO fix these tests @@ -356,16 +356,16 @@ class FxaAccountManagerTest { // assertEquals(1, syncStatusObserver.onErrorCount) // Turn off periodic syncing. - manager.setSyncConfigAsync(SyncConfig(setOf(SyncEngine.History))).await() + manager.setSyncConfig(SyncConfig(setOf(SyncEngine.History))).await() verify(latestSyncManager!!.dispatcher.inner, never()).startPeriodicSync(any(), anyLong()) verify(latestSyncManager!!.dispatcher.inner, never()).stopPeriodicSync() verify(latestSyncManager!!.dispatcher.inner, times(1)).syncNow(SyncReason.FirstSync, debounce = false) // Can trigger syncs. - manager.syncNowAsync(SyncReason.User).await() + manager.syncNow(SyncReason.User).await() verify(latestSyncManager!!.dispatcher.inner, times(1)).syncNow(SyncReason.User, debounce = false) - manager.syncNowAsync(SyncReason.Startup).await() + manager.syncNow(SyncReason.Startup).await() verify(latestSyncManager!!.dispatcher.inner, times(1)).syncNow(SyncReason.Startup, debounce = false) // Pretend sync is running. @@ -399,7 +399,7 @@ class FxaAccountManagerTest { // We don't have an account at the start. `when`(accountStorage.read()).thenReturn(null) - manager.startAsync().await() + manager.start().await() // Bad package name. var migratableAccount = ShareableAccount( @@ -415,7 +415,7 @@ class FxaAccountManagerTest { account.migrationResult = MigrationResult.Failure assertEquals( MigrationResult.Failure, - manager.migrateFromAccountAsync(migratableAccount).await() + manager.migrateFromAccount(migratableAccount).await() ) assertEquals("session", account.latestMigrateAuthInfo!!.sessionToken) @@ -425,7 +425,7 @@ class FxaAccountManagerTest { assertNull(manager.authenticatedAccount()) // Prepare for a successful migration. - `when`(constellation.finalizeDeviceAsync(AuthType.MigratedCopy, any())).thenReturn(CompletableDeferred(true)) + `when`(constellation.finalizeDevice(AuthType.MigratedCopy, any())).thenReturn(CompletableDeferred(true)) // Success. account.migrationResult = MigrationResult.Success @@ -435,7 +435,7 @@ class FxaAccountManagerTest { assertEquals( MigrationResult.Success, - manager.migrateFromAccountAsync(migratableAccount).await() + manager.migrateFromAccount(migratableAccount).await() ) assertEquals("session2", account.latestMigrateAuthInfo!!.sessionToken) @@ -445,7 +445,7 @@ class FxaAccountManagerTest { assertNotNull(manager.authenticatedAccount()) assertEquals(profile, manager.accountProfile()) - verify(constellation, times(1)).finalizeDeviceAsync(AuthType.MigratedCopy, any()) + verify(constellation, times(1)).finalizeDevice(AuthType.MigratedCopy, any()) verify(accountObserver, times(1)).onAuthenticated(account, AuthType.MigratedCopy) } @@ -471,7 +471,7 @@ class FxaAccountManagerTest { // We don't have an account at the start. `when`(accountStorage.read()).thenReturn(null) - manager.startAsync().await() + manager.start().await() // Bad package name. var migratableAccount = ShareableAccount( @@ -487,7 +487,7 @@ class FxaAccountManagerTest { account.migrationResult = MigrationResult.Failure assertEquals( MigrationResult.Failure, - manager.migrateFromAccountAsync(migratableAccount, reuseSessionToken = true).await() + manager.migrateFromAccount(migratableAccount, reuseSessionToken = true).await() ) assertEquals("session", account.latestMigrateAuthInfo!!.sessionToken) @@ -497,7 +497,7 @@ class FxaAccountManagerTest { assertNull(manager.authenticatedAccount()) // Prepare for a successful migration. - `when`(constellation.finalizeDeviceAsync(AuthType.MigratedReuse, any())).thenReturn(CompletableDeferred(true)) + `when`(constellation.finalizeDevice(AuthType.MigratedReuse, any())).thenReturn(CompletableDeferred(true)) // Success. account.migrationResult = MigrationResult.Success @@ -507,7 +507,7 @@ class FxaAccountManagerTest { assertEquals( MigrationResult.Success, - manager.migrateFromAccountAsync(migratableAccount, reuseSessionToken = true).await() + manager.migrateFromAccount(migratableAccount, reuseSessionToken = true).await() ) assertEquals("session2", account.latestMigrateAuthInfo!!.sessionToken) @@ -517,7 +517,7 @@ class FxaAccountManagerTest { assertNotNull(manager.authenticatedAccount()) assertEquals(profile, manager.accountProfile()) - verify(constellation, times(1)).finalizeDeviceAsync(AuthType.MigratedReuse, any()) + verify(constellation, times(1)).finalizeDevice(AuthType.MigratedReuse, any()) verify(accountObserver, times(1)).onAuthenticated(account, AuthType.MigratedReuse) } @@ -539,7 +539,7 @@ class FxaAccountManagerTest { // We don't have an account at the start. `when`(accountStorage.read()).thenReturn(null) - manager.startAsync().await() + manager.start().await() // Bad package name. val migratableAccount = ShareableAccount( @@ -555,7 +555,7 @@ class FxaAccountManagerTest { account.migrationResult = MigrationResult.WillRetry assertEquals( MigrationResult.WillRetry, - manager.migrateFromAccountAsync(migratableAccount, reuseSessionToken = true).await() + manager.migrateFromAccount(migratableAccount, reuseSessionToken = true).await() ) assertEquals("session", account.latestMigrateAuthInfo!!.sessionToken) @@ -566,17 +566,17 @@ class FxaAccountManagerTest { assertNull(manager.accountProfile()) // Prepare for a successful migration. - `when`(constellation.finalizeDeviceAsync(AuthType.MigratedReuse, any())).thenReturn(CompletableDeferred(true)) + `when`(constellation.finalizeDevice(AuthType.MigratedReuse, any())).thenReturn(CompletableDeferred(true)) account.migrationResult = MigrationResult.Success account.migrationRetrySuccess = true // 'sync now' user action will trigger a sign-in retry. - manager.syncNowAsync(SyncReason.User).await() + manager.syncNow(SyncReason.User).await() assertNotNull(manager.authenticatedAccount()) assertEquals(profile, manager.accountProfile()) - verify(constellation, times(1)).finalizeDeviceAsync(AuthType.MigratedReuse, any()) + verify(constellation, times(1)).finalizeDevice(AuthType.MigratedReuse, any()) verify(accountObserver, times(1)).onAuthenticated(account, AuthType.MigratedReuse) } @@ -594,7 +594,7 @@ class FxaAccountManagerTest { account } - `when`(constellation.finalizeDeviceAsync(AuthType.MigratedReuse, any())).thenReturn(CompletableDeferred(true)) + `when`(constellation.finalizeDevice(AuthType.MigratedReuse, any())).thenReturn(CompletableDeferred(true)) // We have an account at the start. `when`(accountStorage.read()).thenReturn(account) @@ -602,15 +602,15 @@ class FxaAccountManagerTest { account.migrationRetrySuccess = false assertNull(account.persistenceCallback) - manager.startAsync().await() + manager.start().await() // Make sure a persistence callback was registered while pumping the state machine. assertNotNull(account.persistenceCallback) // Assert that neither ensureCapabilities nor initialization fired. - verify(constellation, never()).finalizeDeviceAsync(any(), any()) + verify(constellation, never()).finalizeDevice(any(), any()) // Assert that we do not refresh device state. - verify(constellation, never()).refreshDevicesAsync() + verify(constellation, never()).refreshDevices() // Finally, assert that we see an account with an inflight migration. assertNotNull(manager.authenticatedAccount()) @@ -631,7 +631,7 @@ class FxaAccountManagerTest { account } - `when`(constellation.finalizeDeviceAsync(AuthType.MigratedReuse, any())).thenReturn(CompletableDeferred(true)) + `when`(constellation.finalizeDevice(AuthType.MigratedReuse, any())).thenReturn(CompletableDeferred(true)) // We have an account at the start. `when`(accountStorage.read()).thenReturn(account) @@ -639,11 +639,11 @@ class FxaAccountManagerTest { account.migrationRetrySuccess = true assertNull(account.persistenceCallback) - manager.startAsync().await() + manager.start().await() // Make sure a persistence callback was registered while pumping the state machine. assertNotNull(account.persistenceCallback) - verify(constellation).finalizeDeviceAsync(AuthType.MigratedReuse, any()) + verify(constellation).finalizeDevice(AuthType.MigratedReuse, any()) // Finally, assert that we see an account with an inflight migration. assertNotNull(manager.authenticatedAccount()) @@ -669,7 +669,7 @@ class FxaAccountManagerTest { `when`(accountStorage.read()).thenReturn(account) assertNull(account.persistenceCallback) - manager.startAsync().await() + manager.start().await() // Assert that persistence callback is set. assertNotNull(account.persistenceCallback) @@ -679,7 +679,7 @@ class FxaAccountManagerTest { verify(constellation, never()).initDeviceAsync(any(), any(), any()) // Assert that we refresh device state. - verify(constellation).refreshDevicesAsync() + verify(constellation).refreshDevices() // Assert that persistence callback is interacting with the storage layer. account.persistenceCallback!!.persist("test") @@ -705,7 +705,7 @@ class FxaAccountManagerTest { `when`(accountStorage.read()).thenReturn(account) assertNull(account.persistenceCallback) - manager.startAsync().await() + manager.start().await() // Assert that persistence callback is set. assertNotNull(account.persistenceCallback) @@ -752,7 +752,7 @@ class FxaAccountManagerTest { assertFalse(account.checkAuthorizationStatusCalled) verify(accountObserver, never()).onAuthenticationProblems() - manager.startAsync().await() + manager.start().await() toAwait.await() assertTrue(manager.accountNeedsReauth()) @@ -790,7 +790,7 @@ class FxaAccountManagerTest { assertFalse(manager.accountNeedsReauth()) verify(accountObserver, never()).onAuthenticationProblems() - manager.startAsync().await() + manager.start().await() } @Test @@ -819,13 +819,13 @@ class FxaAccountManagerTest { manager.register(accountObserver) // Kick it off, we'll get into a "NotAuthenticated" state. - manager.startAsync().await() + manager.start().await() assertNull(account.persistenceCallback) // Perform authentication. - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) assertTrue(manager.finishAuthenticationAsync(FxaAuthData(AuthType.Signin, "dummyCode", EXPECTED_AUTH_STATE)).await()) @@ -864,13 +864,13 @@ class FxaAccountManagerTest { manager.register(accountObserver) // Kick it off, we'll get into a "NotAuthenticated" state. - manager.startAsync().await() + manager.start().await() // Attempt to finish authentication without starting it first. assertFalse(manager.finishAuthenticationAsync(FxaAuthData(AuthType.Signin, "dummyCode", EXPECTED_AUTH_STATE)).await()) // Start authentication. StatePersistenceTestableAccount will produce state=EXPECTED_AUTH_STATE. - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) // Attempt to finish authentication with a wrong state. assertFalse(manager.finishAuthenticationAsync(FxaAuthData(AuthType.Signin, "dummyCode", UNEXPECTED_AUTH_STATE)).await()) @@ -898,19 +898,19 @@ class FxaAccountManagerTest { var authErrorDetectedCalled = false var latestMigrateAuthInfo: AuthInfo? = null - override fun beginOAuthFlowAsync(scopes: Set): Deferred { + override fun beginOAuthFlow(scopes: Set): Deferred { return CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url")) } - override fun beginPairingFlowAsync(pairingUrl: String, scopes: Set): Deferred { + override fun beginPairingFlow(pairingUrl: String, scopes: Set): Deferred { return CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url")) } - override fun getProfileAsync(ignoreCache: Boolean): Deferred { + override fun getProfile(ignoreCache: Boolean): Deferred { return CompletableDeferred(profile) } - override fun authorizeOAuthCodeAsync(clientId: String, scopes: Array, state: String, accessType: AccessType): Deferred { + override fun authorizeOAuthCode(clientId: String, scopes: Array, state: String, accessType: AccessType): Deferred { return CompletableDeferred("123abc") } @@ -922,11 +922,11 @@ class FxaAccountManagerTest { return null } - override fun completeOAuthFlowAsync(code: String, state: String): Deferred { + override fun completeOAuthFlow(code: String, state: String): Deferred { return CompletableDeferred(true) } - override fun migrateFromAccountAsync(authInfo: AuthInfo, reuseSessionToken: Boolean): Deferred { + override fun migrateFromAccount(authInfo: AuthInfo, reuseSessionToken: Boolean): Deferred { latestMigrateAuthInfo = authInfo return CompletableDeferred(when (migrationResult) { MigrationResult.Failure, MigrationResult.WillRetry -> null @@ -941,14 +941,14 @@ class FxaAccountManagerTest { } } - override fun retryMigrateFromSessionTokenAsync(): Deferred { + override fun retryMigrateFromSessionToken(): Deferred { return CompletableDeferred(when (migrationRetrySuccess) { true -> JSONObject() false -> null }) } - override fun getAccessTokenAsync(singleScope: String): Deferred { + override fun getAccessToken(singleScope: String): Deferred { val token = accessToken?.invoke() if (token != null) return CompletableDeferred(token) @@ -960,7 +960,7 @@ class FxaAccountManagerTest { authErrorDetectedCalled = true } - override fun checkAuthorizationStatusAsync(singleScope: String): Deferred { + override fun checkAuthorizationStatus(singleScope: String): Deferred { checkAuthorizationStatusCalled = true return CompletableDeferred(ableToRecoverFromAuthError) } @@ -984,7 +984,7 @@ class FxaAccountManagerTest { return constellation } - override fun disconnectAsync(): Deferred { + override fun disconnect(): Deferred { fail() return CompletableDeferred(false) } @@ -1033,7 +1033,7 @@ class FxaAccountManagerTest { } manager.register(accountObserver) - manager.startAsync().await() + manager.start().await() } @Test @@ -1051,7 +1051,7 @@ class FxaAccountManagerTest { val accountObserver: AccountObserver = mock() manager.register(accountObserver) - manager.startAsync().await() + manager.start().await() verify(accountObserver, never()).onAuthenticated(any(), any()) verify(accountObserver, never()).onProfileUpdated(any()) @@ -1072,7 +1072,7 @@ class FxaAccountManagerTest { val constellation: DeviceConstellation = mock() val profile = Profile( "testUid", "test@example.com", null, "Test Profile") - `when`(mockAccount.getProfileAsync(ignoreCache = false)).thenReturn(CompletableDeferred(profile)) + `when`(mockAccount.getProfile(ignoreCache = false)).thenReturn(CompletableDeferred(profile)) `when`(mockAccount.isInMigrationState()).thenReturn(InFlightMigrationState.NONE) // We have an account at the start. `when`(accountStorage.read()).thenReturn(mockAccount) @@ -1091,7 +1091,7 @@ class FxaAccountManagerTest { manager.register(accountObserver) - manager.startAsync().await() + manager.start().await() // Make sure that account and profile observers are fired exactly once. verify(accountObserver, times(1)).onAuthenticated(mockAccount, AuthType.Existing) @@ -1106,26 +1106,26 @@ class FxaAccountManagerTest { assertEquals(profile, manager.accountProfile()) // Assert that we don't refresh device state for non-SEND_TAB enabled devices. - verify(constellation, never()).refreshDevicesAsync() + verify(constellation, never()).refreshDevices() // Make sure 'logoutAsync' clears out state and fires correct observers. reset(accountObserver) reset(accountStorage) - `when`(mockAccount.disconnectAsync()).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.disconnect()).thenReturn(CompletableDeferred(true)) // Simulate SyncManager populating SyncEnginesStorage with some state. SyncEnginesStorage(testContext).setStatus(SyncEngine.History, true) SyncEnginesStorage(testContext).setStatus(SyncEngine.Passwords, false) assertTrue(SyncEnginesStorage(testContext).getStatus().isNotEmpty()) - verify(mockAccount, never()).disconnectAsync() - manager.logoutAsync().await() + verify(mockAccount, never()).disconnect() + manager.logout().await() assertTrue(SyncEnginesStorage(testContext).getStatus().isEmpty()) verify(accountObserver, never()).onAuthenticated(any(), any()) verify(accountObserver, never()).onProfileUpdated(any()) verify(accountObserver, times(1)).onLoggedOut() - verify(mockAccount, times(1)).disconnectAsync() + verify(mockAccount, times(1)).disconnect() verify(accountStorage, never()).read() verify(accountStorage, never()).write(any()) @@ -1149,7 +1149,7 @@ class FxaAccountManagerTest { verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1184,7 +1184,7 @@ class FxaAccountManagerTest { verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1201,13 +1201,13 @@ class FxaAccountManagerTest { val mockAccount: OAuthAccount = mock() val profile = Profile(uid = "testUID", avatar = null, email = "test@example.com", displayName = "test profile") val accountStorage = mock() - `when`(mockAccount.getProfileAsync(ignoreCache = false)).thenReturn(CompletableDeferred(profile)) + `when`(mockAccount.getProfile(ignoreCache = false)).thenReturn(CompletableDeferred(profile)) val fxaPanic = CompletableDeferred() fxaPanic.completeExceptionally(FxaPanicException("panic!")) - `when`(mockAccount.beginPairingFlowAsync(any(), any())).thenReturn(fxaPanic) - `when`(mockAccount.completeOAuthFlowAsync(anyString(), anyString())).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.beginPairingFlow(any(), any())).thenReturn(fxaPanic) + `when`(mockAccount.completeOAuthFlow(anyString(), anyString())).thenReturn(CompletableDeferred(true)) // There's no account at the start. `when`(accountStorage.read()).thenReturn(null) @@ -1219,8 +1219,8 @@ class FxaAccountManagerTest { mockAccount } - manager.startAsync().await() - manager.beginAuthenticationAsync("http://pairing.com").await() + manager.start().await() + manager.beginAuthentication("http://pairing.com").await() fail() } @@ -1238,7 +1238,7 @@ class FxaAccountManagerTest { verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals("auth://url", manager.beginAuthenticationAsync(pairingUrl = "auth://pairing").await()) + assertEquals("auth://url", manager.beginAuthentication(pairingUrl = "auth://pairing").await()) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1277,17 +1277,17 @@ class FxaAccountManagerTest { reset(accountObserver) - assertNull(manager.beginAuthenticationAsync().await()) + assertNull(manager.beginAuthentication().await()) // Confirm that account state observable doesn't receive authentication errors. assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) // Try again, without any network problems this time. - `when`(mockAccount.beginOAuthFlowAsync(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) + `when`(mockAccount.beginOAuthFlow(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) `when`(constellation.initDeviceAsync(any(), any(), any())).thenReturn(CompletableDeferred(true)) - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1323,17 +1323,17 @@ class FxaAccountManagerTest { reset(accountObserver) - assertNull(manager.beginAuthenticationAsync(pairingUrl = "auth://pairing").await()) + assertNull(manager.beginAuthentication(pairingUrl = "auth://pairing").await()) // Confirm that account state observable doesn't receive authentication errors. assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) // Try again, without any network problems this time. - `when`(mockAccount.beginPairingFlowAsync(anyString(), any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) + `when`(mockAccount.beginPairingFlow(anyString(), any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) `when`(constellation.initDeviceAsync(any(), any(), any())).thenReturn(CompletableDeferred(true)) - assertEquals("auth://url", manager.beginAuthenticationAsync(pairingUrl = "auth://pairing").await()) + assertEquals("auth://url", manager.beginAuthentication(pairingUrl = "auth://pairing").await()) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1365,7 +1365,7 @@ class FxaAccountManagerTest { verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1379,7 +1379,7 @@ class FxaAccountManagerTest { assertFalse(manager.accountNeedsReauth()) // Our recovery flow should attempt to hit this API. Model the "can't recover" condition by returning 'false'. - `when`(mockAccount.checkAuthorizationStatusAsync(eq("profile"))).thenReturn(CompletableDeferred(false)) + `when`(mockAccount.checkAuthorizationStatus(eq("profile"))).thenReturn(CompletableDeferred(false)) // At this point, we're logged in. Trigger a 401. manager.encounteredAuthError("a test") @@ -1393,7 +1393,7 @@ class FxaAccountManagerTest { // Able to re-authenticate. reset(accountObserver) - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) assertEquals(mockAccount, manager.authenticatedAccount()) assertTrue(manager.finishAuthenticationAsync(FxaAuthData(AuthType.Pairing, "dummyCode", EXPECTED_AUTH_STATE)).await()) @@ -1427,14 +1427,14 @@ class FxaAccountManagerTest { verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) `when`(mockAccount.getCurrentDeviceId()).thenReturn("testDeviceId") `when`(mockAccount.deviceConstellation()).thenReturn(constellation) `when`(constellation.initDeviceAsync(any(), any(), any())).thenReturn(CompletableDeferred(true)) - `when`(constellation.refreshDevicesAsync()).thenReturn(CompletableDeferred(true)) + `when`(constellation.refreshDevices()).thenReturn(CompletableDeferred(true)) assertTrue(manager.finishAuthenticationAsync(FxaAuthData(AuthType.Signin, "dummyCode", EXPECTED_AUTH_STATE)).await()) @@ -1442,7 +1442,7 @@ class FxaAccountManagerTest { assertFalse(manager.accountNeedsReauth()) // Recovery flow will hit this API, and will recover if it returns 'true'. - `when`(mockAccount.checkAuthorizationStatusAsync(eq("profile"))).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.checkAuthorizationStatus(eq("profile"))).thenReturn(CompletableDeferred(true)) // At this point, we're logged in. Trigger a 401. manager.encounteredAuthError("a test") @@ -1473,14 +1473,14 @@ class FxaAccountManagerTest { verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) `when`(mockAccount.getCurrentDeviceId()).thenReturn("testDeviceId") `when`(mockAccount.deviceConstellation()).thenReturn(constellation) `when`(constellation.initDeviceAsync(any(), any(), any())).thenReturn(CompletableDeferred(true)) - `when`(constellation.refreshDevicesAsync()).thenReturn(CompletableDeferred(true)) + `when`(constellation.refreshDevices()).thenReturn(CompletableDeferred(true)) assertTrue(manager.finishAuthenticationAsync(FxaAuthData(AuthType.Signin, "dummyCode", EXPECTED_AUTH_STATE)).await()) @@ -1488,7 +1488,7 @@ class FxaAccountManagerTest { assertFalse(manager.accountNeedsReauth()) // Recovery flow will hit this API, and will recover if it returns 'true'. - `when`(mockAccount.checkAuthorizationStatusAsync(eq("profile"))).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.checkAuthorizationStatus(eq("profile"))).thenReturn(CompletableDeferred(true)) // At this point, we're logged in. Trigger a 401 for the first time. manager.encounteredAuthError("a test") @@ -1516,7 +1516,7 @@ class FxaAccountManagerTest { ) { // During recovery, neither `init` nor `refresh` nor `ensure` calls should not have been made. verify(constellation, times(1)).initDeviceAsync(any(), any(), any()) - verify(constellation, times(1)).refreshDevicesAsync() + verify(constellation, times(1)).refreshDevices() verify(constellation, never()).ensureCapabilitiesAsync(any()) assertEquals(mockAccount, manager.authenticatedAccount()) @@ -1547,9 +1547,9 @@ class FxaAccountManagerTest { `when`(mockAccount.deviceConstellation()).thenReturn(constellation) `when`(mockAccount.getCurrentDeviceId()).thenReturn("testDeviceId") `when`(constellation.initDeviceAsync(any(), any(), any())).thenReturn(CompletableDeferred(true)) - `when`(mockAccount.getProfileAsync(ignoreCache = false)).thenReturn(CompletableDeferred(value = null)) - `when`(mockAccount.beginOAuthFlowAsync(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) - `when`(mockAccount.completeOAuthFlowAsync(anyString(), anyString())).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.getProfile(ignoreCache = false)).thenReturn(CompletableDeferred(value = null)) + `when`(mockAccount.beginOAuthFlow(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) + `when`(mockAccount.completeOAuthFlow(anyString(), anyString())).thenReturn(CompletableDeferred(true)) // There's no account at the start. `when`(accountStorage.read()).thenReturn(null) @@ -1564,14 +1564,14 @@ class FxaAccountManagerTest { val accountObserver: AccountObserver = mock() manager.register(accountObserver) - manager.startAsync().await() + manager.start().await() // We start off as logged-out, but the event won't be called (initial default state is assumed). verify(accountObserver, never()).onLoggedOut() verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1592,7 +1592,7 @@ class FxaAccountManagerTest { val profile = Profile( uid = "testUID", avatar = null, email = "test@example.com", displayName = "test profile") - `when`(mockAccount.getProfileAsync(ignoreCache = false)).thenReturn(CompletableDeferred(profile)) + `when`(mockAccount.getProfile(ignoreCache = false)).thenReturn(CompletableDeferred(profile)) manager.updateProfileAsync().await() @@ -1613,10 +1613,10 @@ class FxaAccountManagerTest { `when`(constellation.initDeviceAsync(any(), any(), any())).thenReturn(CompletableDeferred(true)) // Our recovery flow should attempt to hit this API. Model the "can't recover" condition by returning false. - `when`(mockAccount.checkAuthorizationStatusAsync(eq("profile"))).thenReturn(CompletableDeferred(false)) + `when`(mockAccount.checkAuthorizationStatus(eq("profile"))).thenReturn(CompletableDeferred(false)) - `when`(mockAccount.beginOAuthFlowAsync(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) - `when`(mockAccount.completeOAuthFlowAsync(anyString(), anyString())).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.beginOAuthFlow(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) + `when`(mockAccount.completeOAuthFlow(anyString(), anyString())).thenReturn(CompletableDeferred(true)) // There's no account at the start. `when`(accountStorage.read()).thenReturn(null) @@ -1628,7 +1628,7 @@ class FxaAccountManagerTest { mockAccount } - `when`(mockAccount.getProfileAsync(ignoreCache = false)).then { + `when`(mockAccount.getProfile(ignoreCache = false)).then { // Hit an auth error. CoroutineScope(coroutineContext).launch { manager.encounteredAuthError("a test") } CompletableDeferred(value = null) @@ -1637,17 +1637,17 @@ class FxaAccountManagerTest { val accountObserver: AccountObserver = mock() manager.register(accountObserver) - manager.startAsync().await() + manager.start().await() // We start off as logged-out, but the event won't be called (initial default state is assumed). verify(accountObserver, never()).onLoggedOut() verify(accountObserver, never()).onAuthenticated(any(), any()) verify(accountObserver, never()).onAuthenticationProblems() - verify(mockAccount, never()).checkAuthorizationStatusAsync(any()) + verify(mockAccount, never()).checkAuthorizationStatus(any()) assertFalse(manager.accountNeedsReauth()) reset(accountObserver) - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1655,7 +1655,7 @@ class FxaAccountManagerTest { assertTrue(manager.accountNeedsReauth()) verify(accountObserver, times(1)).onAuthenticationProblems() - verify(mockAccount, times(1)).checkAuthorizationStatusAsync(eq("profile")) + verify(mockAccount, times(1)).checkAuthorizationStatus(eq("profile")) Unit } @@ -1670,10 +1670,10 @@ class FxaAccountManagerTest { `when`(constellation.initDeviceAsync(any(), any(), any())).thenReturn(CompletableDeferred(true)) // Our recovery flow should attempt to hit this API. Model the "don't know what's up" condition by returning null. - `when`(mockAccount.checkAuthorizationStatusAsync(eq("profile"))).thenReturn(CompletableDeferred(value = null)) + `when`(mockAccount.checkAuthorizationStatus(eq("profile"))).thenReturn(CompletableDeferred(value = null)) - `when`(mockAccount.beginOAuthFlowAsync(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) - `when`(mockAccount.completeOAuthFlowAsync(anyString(), anyString())).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.beginOAuthFlow(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) + `when`(mockAccount.completeOAuthFlow(anyString(), anyString())).thenReturn(CompletableDeferred(true)) // There's no account at the start. `when`(accountStorage.read()).thenReturn(null) @@ -1685,7 +1685,7 @@ class FxaAccountManagerTest { mockAccount } - `when`(mockAccount.getProfileAsync(ignoreCache = false)).then { + `when`(mockAccount.getProfile(ignoreCache = false)).then { // Hit an auth error. CoroutineScope(coroutineContext).launch { manager.encounteredAuthError("a test") } CompletableDeferred(value = null) @@ -1694,17 +1694,17 @@ class FxaAccountManagerTest { val accountObserver: AccountObserver = mock() manager.register(accountObserver) - manager.startAsync().await() + manager.start().await() // We start off as logged-out, but the event won't be called (initial default state is assumed). verify(accountObserver, never()).onLoggedOut() verify(accountObserver, never()).onAuthenticated(any(), any()) verify(accountObserver, never()).onAuthenticationProblems() - verify(mockAccount, never()).checkAuthorizationStatusAsync(any()) + verify(mockAccount, never()).checkAuthorizationStatus(any()) assertFalse(manager.accountNeedsReauth()) reset(accountObserver) - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1712,7 +1712,7 @@ class FxaAccountManagerTest { assertTrue(manager.accountNeedsReauth()) verify(accountObserver, times(1)).onAuthenticationProblems() - verify(mockAccount, times(1)).checkAuthorizationStatusAsync(eq("profile")) + verify(mockAccount, times(1)).checkAuthorizationStatus(eq("profile")) Unit } @@ -1731,10 +1731,10 @@ class FxaAccountManagerTest { uid = "testUID", avatar = null, email = "test@example.com", displayName = "test profile") // Recovery flow will hit this API, return a success. - `when`(mockAccount.checkAuthorizationStatusAsync(eq("profile"))).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.checkAuthorizationStatus(eq("profile"))).thenReturn(CompletableDeferred(true)) - `when`(mockAccount.beginOAuthFlowAsync(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) - `when`(mockAccount.completeOAuthFlowAsync(anyString(), anyString())).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.beginOAuthFlow(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) + `when`(mockAccount.completeOAuthFlow(anyString(), anyString())).thenReturn(CompletableDeferred(true)) // There's no account at the start. `when`(accountStorage.read()).thenReturn(null) @@ -1747,7 +1747,7 @@ class FxaAccountManagerTest { } var didFailProfileFetch = false - `when`(mockAccount.getProfileAsync(ignoreCache = false)).then { + `when`(mockAccount.getProfile(ignoreCache = false)).then { // Hit an auth error, but only once. As we recover from it, we'll attempt to fetch a profile // again. At that point, we'd like to succeed. if (!didFailProfileFetch) { @@ -1762,17 +1762,17 @@ class FxaAccountManagerTest { val accountObserver: AccountObserver = mock() manager.register(accountObserver) - manager.startAsync().await() + manager.start().await() // We start off as logged-out, but the event won't be called (initial default state is assumed). verify(accountObserver, never()).onLoggedOut() verify(accountObserver, never()).onAuthenticated(any(), any()) verify(accountObserver, never()).onAuthenticationProblems() - verify(mockAccount, never()).checkAuthorizationStatusAsync(any()) + verify(mockAccount, never()).checkAuthorizationStatus(any()) assertFalse(manager.accountNeedsReauth()) reset(accountObserver) - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1787,7 +1787,7 @@ class FxaAccountManagerTest { assertEquals(AuthType.Signup, captor.allValues[0]) assertEquals(AuthType.Recovered, captor.allValues[1]) // Verify that we went through the recovery flow. - verify(mockAccount, times(1)).checkAuthorizationStatusAsync(eq("profile")) + verify(mockAccount, times(1)).checkAuthorizationStatus(eq("profile")) Unit } @@ -1804,9 +1804,9 @@ class FxaAccountManagerTest { `when`(mockAccount.getCurrentDeviceId()).thenReturn("testDeviceId") `when`(mockAccount.deviceConstellation()).thenReturn(constellation) `when`(constellation.initDeviceAsync(any(), any(), any())).thenReturn(CompletableDeferred(true)) - `when`(mockAccount.getProfileAsync(ignoreCache = false)).thenReturn(exceptionalProfile) - `when`(mockAccount.beginOAuthFlowAsync(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) - `when`(mockAccount.completeOAuthFlowAsync(anyString(), anyString())).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.getProfile(ignoreCache = false)).thenReturn(exceptionalProfile) + `when`(mockAccount.beginOAuthFlow(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) + `when`(mockAccount.completeOAuthFlow(anyString(), anyString())).thenReturn(CompletableDeferred(true)) // There's no account at the start. `when`(accountStorage.read()).thenReturn(null) @@ -1821,7 +1821,7 @@ class FxaAccountManagerTest { val accountObserver: AccountObserver = mock() manager.register(accountObserver) - manager.startAsync().await() + manager.start().await() // We start off as logged-out, but the event won't be called (initial default state is assumed). verify(accountObserver, never()).onLoggedOut() @@ -1830,7 +1830,7 @@ class FxaAccountManagerTest { assertFalse(manager.accountNeedsReauth()) reset(accountObserver) - assertEquals("auth://url", manager.beginAuthenticationAsync().await()) + assertEquals("auth://url", manager.beginAuthentication().await()) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1884,10 +1884,10 @@ class FxaAccountManagerTest { crashReporter: CrashReporting? = null ): FxaAccountManager { - `when`(mockAccount.getProfileAsync(ignoreCache = false)).thenReturn(CompletableDeferred(profile)) - `when`(mockAccount.beginOAuthFlowAsync(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) - `when`(mockAccount.beginPairingFlowAsync(anyString(), any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) - `when`(mockAccount.completeOAuthFlowAsync(anyString(), anyString())).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.getProfile(ignoreCache = false)).thenReturn(CompletableDeferred(profile)) + `when`(mockAccount.beginOAuthFlow(any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) + `when`(mockAccount.beginPairingFlow(anyString(), any())).thenReturn(CompletableDeferred(AuthFlowUrl(EXPECTED_AUTH_STATE, "auth://url"))) + `when`(mockAccount.completeOAuthFlow(anyString(), anyString())).thenReturn(CompletableDeferred(true)) // There's no account at the start. `when`(accountStorage.read()).thenReturn(null) @@ -1902,7 +1902,7 @@ class FxaAccountManagerTest { manager.register(accountObserver) runBlocking(coroutineContext) { - manager.startAsync().await() + manager.start().await() } return manager @@ -1915,11 +1915,11 @@ class FxaAccountManagerTest { accountObserver: AccountObserver, coroutineContext: CoroutineContext ): FxaAccountManager { - `when`(mockAccount.getProfileAsync(ignoreCache = false)).thenReturn(CompletableDeferred(profile)) + `when`(mockAccount.getProfile(ignoreCache = false)).thenReturn(CompletableDeferred(profile)) - `when`(mockAccount.beginOAuthFlowAsync(any())).thenReturn(CompletableDeferred(value = null)) - `when`(mockAccount.beginPairingFlowAsync(anyString(), any())).thenReturn(CompletableDeferred(value = null)) - `when`(mockAccount.completeOAuthFlowAsync(anyString(), anyString())).thenReturn(CompletableDeferred(true)) + `when`(mockAccount.beginOAuthFlow(any())).thenReturn(CompletableDeferred(value = null)) + `when`(mockAccount.beginPairingFlow(anyString(), any())).thenReturn(CompletableDeferred(value = null)) + `when`(mockAccount.completeOAuthFlow(anyString(), anyString())).thenReturn(CompletableDeferred(true)) // There's no account at the start. `when`(accountStorage.read()).thenReturn(null) @@ -1934,7 +1934,7 @@ class FxaAccountManagerTest { manager.register(accountObserver) runBlocking(coroutineContext) { - manager.startAsync().await() + manager.start().await() } return manager @@ -1942,7 +1942,7 @@ class FxaAccountManagerTest { private fun mockDeviceConstellation(): DeviceConstellation { val c: DeviceConstellation = mock() - `when`(c.refreshDevicesAsync()).thenReturn(CompletableDeferred(true)) + `when`(c.refreshDevices()).thenReturn(CompletableDeferred(true)) return c } } diff --git a/components/service/firefox-accounts/src/test/java/mozilla/components/service/fxa/FxaDeviceConstellationTest.kt b/components/service/firefox-accounts/src/test/java/mozilla/components/service/fxa/FxaDeviceConstellationTest.kt index b3634f09c74..33b92a81f43 100644 --- a/components/service/firefox-accounts/src/test/java/mozilla/components/service/fxa/FxaDeviceConstellationTest.kt +++ b/components/service/firefox-accounts/src/test/java/mozilla/components/service/fxa/FxaDeviceConstellationTest.kt @@ -86,7 +86,7 @@ class FxaDeviceConstellationTest { // Can't update cached value in an empty cache try { - constellation.setDeviceNameAsync("new name", testContext).await() + constellation.setDeviceName("new name", testContext).await() fail() } catch (e: IllegalStateException) {} @@ -94,7 +94,7 @@ class FxaDeviceConstellationTest { cache.setToCache(DeviceSettings("someId", "test name", RustDeviceType.MOBILE)) // No device state observer. - assertTrue(constellation.setDeviceNameAsync("new name", testContext).await()) + assertTrue(constellation.setDeviceName("new name", testContext).await()) verify(account, times(2)).setDeviceDisplayName("new name") assertEquals(DeviceSettings("someId", "new name", RustDeviceType.MOBILE), cache.getCached()) @@ -109,7 +109,7 @@ class FxaDeviceConstellationTest { } constellation.registerDeviceObserver(observer, startedLifecycleOwner(), false) - assertTrue(constellation.setDeviceNameAsync("another name", testContext).await()) + assertTrue(constellation.setDeviceName("another name", testContext).await()) verify(account).setDeviceDisplayName("another name") assertEquals(DeviceSettings("someId", "another name", RustDeviceType.MOBILE), cache.getCached()) @@ -123,7 +123,7 @@ class FxaDeviceConstellationTest { @ExperimentalCoroutinesApi fun `set device push subscription`() = runBlocking(coroutinesTestRule.testDispatcher) { val subscription = DevicePushSubscription("http://endpoint.com", "pk", "auth key") - constellation.setDevicePushSubscriptionAsync(subscription).await() + constellation.setDevicePushSubscription(subscription).await() verify(account).setDevicePushSubscription("http://endpoint.com", "pk", "auth key") } @@ -133,7 +133,7 @@ class FxaDeviceConstellationTest { fun `process raw device command`() = runBlocking(coroutinesTestRule.testDispatcher) { // No commands, no observer. `when`(account.handlePushMessage("raw events payload")).thenReturn(emptyArray()) - assertTrue(constellation.processRawEventAsync("raw events payload").await()) + assertTrue(constellation.processRawEvent("raw events payload").await()) // No commands, with observer. val eventsObserver = object : AccountEventsObserver { @@ -146,7 +146,7 @@ class FxaDeviceConstellationTest { // No commands, with an observer. constellation.register(eventsObserver) - assertTrue(constellation.processRawEventAsync("raw events payload").await()) + assertTrue(constellation.processRawEvent("raw events payload").await()) assertEquals(listOf(), eventsObserver.latestEvents) // Some commands, with an observer. More detailed command handling tests below. @@ -157,7 +157,7 @@ class FxaDeviceConstellationTest { command = IncomingDeviceCommand.TabReceived(testDevice1, arrayOf(testTab1)) ) )) - assertTrue(constellation.processRawEventAsync("raw events payload").await()) + assertTrue(constellation.processRawEvent("raw events payload").await()) val events = eventsObserver.latestEvents!! val command = (events[0] as AccountEvent.DeviceCommandIncoming).command @@ -167,7 +167,7 @@ class FxaDeviceConstellationTest { @Test fun `send command to device`() = runBlocking(coroutinesTestRule.testDispatcher) { - assertTrue(constellation.sendCommandToDeviceAsync( + assertTrue(constellation.sendCommandToDevice( "targetID", DeviceCommandOutgoing.SendTab("Mozilla", "https://www.mozilla.org") ).await()) @@ -180,7 +180,7 @@ class FxaDeviceConstellationTest { // No devices, no observers. `when`(account.getDevices()).thenReturn(emptyArray()) - constellation.refreshDevicesAsync().await() + constellation.refreshDevices().await() val observer = object : DeviceConstellationObserver { var state: ConstellationState? = null @@ -192,7 +192,7 @@ class FxaDeviceConstellationTest { constellation.registerDeviceObserver(observer, startedLifecycleOwner(), false) // No devices, with an observer. - constellation.refreshDevicesAsync().await() + constellation.refreshDevices().await() assertEquals(ConstellationState(null, listOf()), observer.state) val testDevice1 = testDevice("test1", false) @@ -201,14 +201,14 @@ class FxaDeviceConstellationTest { // Single device, no current device. `when`(account.getDevices()).thenReturn(arrayOf(testDevice1)) - constellation.refreshDevicesAsync().await() + constellation.refreshDevices().await() assertEquals(ConstellationState(null, listOf(testDevice1.into())), observer.state) assertEquals(ConstellationState(null, listOf(testDevice1.into())), constellation.state()) // Current device, no other devices. `when`(account.getDevices()).thenReturn(arrayOf(currentDevice)) - constellation.refreshDevicesAsync().await() + constellation.refreshDevices().await() assertEquals(ConstellationState(currentDevice.into(), listOf()), observer.state) assertEquals(ConstellationState(currentDevice.into(), listOf()), constellation.state()) @@ -216,7 +216,7 @@ class FxaDeviceConstellationTest { `when`(account.getDevices()).thenReturn(arrayOf( currentDevice, testDevice1, testDevice2 )) - constellation.refreshDevicesAsync().await() + constellation.refreshDevices().await() assertEquals(ConstellationState(currentDevice.into(), listOf(testDevice1.into(), testDevice2.into())), observer.state) assertEquals(ConstellationState(currentDevice.into(), listOf(testDevice1.into(), testDevice2.into())), constellation.state()) @@ -226,7 +226,7 @@ class FxaDeviceConstellationTest { `when`(account.getDevices()).thenReturn(arrayOf( currentDeviceExpired, testDevice2 )) - constellation.refreshDevicesAsync().await() + constellation.refreshDevices().await() assertEquals(ConstellationState(currentDeviceExpired.into(), listOf(testDevice2.into())), observer.state) assertEquals(ConstellationState(currentDeviceExpired.into(), listOf(testDevice2.into())), constellation.state()) @@ -237,7 +237,7 @@ class FxaDeviceConstellationTest { fun `polling for commands triggers observers`() = runBlocking(coroutinesTestRule.testDispatcher) { // No commands, no observers. `when`(account.pollDeviceCommands()).thenReturn(emptyArray()) - assertTrue(constellation.pollForCommandsAsync().await()) + assertTrue(constellation.pollForCommands().await()) val eventsObserver = object : AccountEventsObserver { var latestEvents: List? = null @@ -249,14 +249,14 @@ class FxaDeviceConstellationTest { // No commands, with an observer. constellation.register(eventsObserver) - assertTrue(constellation.pollForCommandsAsync().await()) + assertTrue(constellation.pollForCommands().await()) assertEquals(listOf(), eventsObserver.latestEvents) // Some commands. `when`(account.pollDeviceCommands()).thenReturn(arrayOf( IncomingDeviceCommand.TabReceived(null, emptyArray()) )) - assertTrue(constellation.pollForCommandsAsync().await()) + assertTrue(constellation.pollForCommands().await()) var command = (eventsObserver.latestEvents!![0] as AccountEvent.DeviceCommandIncoming).command assertEquals(null, (command as DeviceCommandIncoming.TabReceived).from) @@ -272,7 +272,7 @@ class FxaDeviceConstellationTest { `when`(account.pollDeviceCommands()).thenReturn(arrayOf( IncomingDeviceCommand.TabReceived(testDevice1, emptyArray()) )) - assertTrue(constellation.pollForCommandsAsync().await()) + assertTrue(constellation.pollForCommands().await()) Assert.assertNotNull(eventsObserver.latestEvents) assertEquals(1, eventsObserver.latestEvents!!.size) @@ -284,7 +284,7 @@ class FxaDeviceConstellationTest { `when`(account.pollDeviceCommands()).thenReturn(arrayOf( IncomingDeviceCommand.TabReceived(testDevice2, arrayOf(testTab1)) )) - assertTrue(constellation.pollForCommandsAsync().await()) + assertTrue(constellation.pollForCommands().await()) command = (eventsObserver.latestEvents!![0] as AccountEvent.DeviceCommandIncoming).command assertEquals(testDevice2.into(), (command as DeviceCommandIncoming.TabReceived).from) @@ -294,7 +294,7 @@ class FxaDeviceConstellationTest { `when`(account.pollDeviceCommands()).thenReturn(arrayOf( IncomingDeviceCommand.TabReceived(testDevice2, arrayOf(testTab1, testTab3)) )) - assertTrue(constellation.pollForCommandsAsync().await()) + assertTrue(constellation.pollForCommands().await()) command = (eventsObserver.latestEvents!![0] as AccountEvent.DeviceCommandIncoming).command assertEquals(testDevice2.into(), (command as DeviceCommandIncoming.TabReceived).from) @@ -305,7 +305,7 @@ class FxaDeviceConstellationTest { IncomingDeviceCommand.TabReceived(testDevice2, arrayOf(testTab1, testTab2)), IncomingDeviceCommand.TabReceived(testDevice1, arrayOf(testTab3)) )) - assertTrue(constellation.pollForCommandsAsync().await()) + assertTrue(constellation.pollForCommands().await()) command = (eventsObserver.latestEvents!![0] as AccountEvent.DeviceCommandIncoming).command assertEquals(testDevice2.into(), (command as DeviceCommandIncoming.TabReceived).from) diff --git a/components/support/migration/src/main/java/mozilla/components/support/migration/FennecFxaMigration.kt b/components/support/migration/src/main/java/mozilla/components/support/migration/FennecFxaMigration.kt index 14a922d0152..44328096ecb 100644 --- a/components/support/migration/src/main/java/mozilla/components/support/migration/FennecFxaMigration.kt +++ b/components/support/migration/src/main/java/mozilla/components/support/migration/FennecFxaMigration.kt @@ -158,10 +158,10 @@ private object AuthenticatedAccountProcessor { authInfo = fennecAuthInfo ) - val signInResult = accountManager.migrateFromAccountAsync( + val signInResult = accountManager.migrateFromAccount( shareableAccount, reuseSessionToken = true - ).await() + ) return when (signInResult) { MigrationResult.Failure -> { diff --git a/components/support/migration/src/test/java/mozilla/components/support/migration/FennecFxaMigrationTest.kt b/components/support/migration/src/test/java/mozilla/components/support/migration/FennecFxaMigrationTest.kt index 86362077b49..6962f4399d2 100644 --- a/components/support/migration/src/test/java/mozilla/components/support/migration/FennecFxaMigrationTest.kt +++ b/components/support/migration/src/test/java/mozilla/components/support/migration/FennecFxaMigrationTest.kt @@ -82,7 +82,7 @@ class FennecFxaMigrationTest { val fxaPath = File(getTestPath("fxa"), "married-v4.json") val accountManager: FxaAccountManager = mock() - `when`(accountManager.migrateFromAccountAsync(any(), eq(true))).thenReturn( + `when`(accountManager.migrateFromAccount(any(), eq(true))).thenReturn( CompletableDeferred(MigrationResult.Success) ) @@ -92,7 +92,7 @@ class FennecFxaMigrationTest { assertEquals("Married", (this.value as FxaMigrationResult.Success.SignedInIntoAuthenticatedAccount).stateLabel) val captor = argumentCaptor() - verify(accountManager).migrateFromAccountAsync(captor.capture(), eq(true)) + verify(accountManager).migrateFromAccount(captor.capture(), eq(true)) assertEquals("test@example.com", captor.value.email) assertEquals("252fsvj8932vj32movj97325hjfksdhfjstrg23yurt267r23", captor.value.authInfo.kSync) @@ -106,7 +106,7 @@ class FennecFxaMigrationTest { val fxaPath = File(getTestPath("fxa"), "cohabiting-v4.json") val accountManager: FxaAccountManager = mock() - `when`(accountManager.migrateFromAccountAsync(any(), eq(true))).thenReturn( + `when`(accountManager.migrateFromAccount(any(), eq(true))).thenReturn( CompletableDeferred(MigrationResult.Success) ) @@ -116,7 +116,7 @@ class FennecFxaMigrationTest { assertEquals("Cohabiting", (this.value as FxaMigrationResult.Success.SignedInIntoAuthenticatedAccount).stateLabel) val captor = argumentCaptor() - verify(accountManager).migrateFromAccountAsync(captor.capture(), eq(true)) + verify(accountManager).migrateFromAccount(captor.capture(), eq(true)) assertEquals("test@example.com", captor.value.email) assertEquals("252bc4ccc3a239fsdfsdf32fg32wf3w4e3472d41d1a204890", captor.value.authInfo.kSync) @@ -130,7 +130,7 @@ class FennecFxaMigrationTest { val fxaPath = File(getTestPath("fxa"), "cohabiting-v4.json") val accountManager: FxaAccountManager = mock() - `when`(accountManager.migrateFromAccountAsync(any(), eq(true))).thenReturn( + `when`(accountManager.migrateFromAccount(any(), eq(true))).thenReturn( CompletableDeferred(MigrationResult.WillRetry) ) @@ -140,7 +140,7 @@ class FennecFxaMigrationTest { assertEquals("Cohabiting", (this.value as FxaMigrationResult.Success.WillAutoRetrySignInLater).stateLabel) val captor = argumentCaptor() - verify(accountManager).migrateFromAccountAsync(captor.capture(), eq(true)) + verify(accountManager).migrateFromAccount(captor.capture(), eq(true)) assertEquals("test@example.com", captor.value.email) assertEquals("252bc4ccc3a239fsdfsdf32fg32wf3w4e3472d41d1a204890", captor.value.authInfo.kSync) @@ -154,7 +154,7 @@ class FennecFxaMigrationTest { val fxaPath = File(getTestPath("fxa"), "married-v4.json") val accountManager: FxaAccountManager = mock() - `when`(accountManager.migrateFromAccountAsync(any(), eq(true))).thenReturn( + `when`(accountManager.migrateFromAccount(any(), eq(true))).thenReturn( CompletableDeferred(MigrationResult.Failure) ) @@ -166,7 +166,7 @@ class FennecFxaMigrationTest { assertEquals("Married", (unwrapped.failure as FxaMigrationResult.Failure.FailedToSignIntoAuthenticatedAccount).stateLabel) val captor = argumentCaptor() - verify(accountManager).migrateFromAccountAsync(captor.capture(), eq(true)) + verify(accountManager).migrateFromAccount(captor.capture(), eq(true)) assertEquals("test@example.com", captor.value.email) assertEquals("252fsvj8932vj32movj97325hjfksdhfjstrg23yurt267r23", captor.value.authInfo.kSync) @@ -222,7 +222,7 @@ class FennecFxaMigrationTest { val fxaPath = File(getTestPath("fxa"), "cohabiting-v4.json") val accountManager: FxaAccountManager = mock() - `when`(accountManager.migrateFromAccountAsync(any(), eq(true))).thenReturn( + `when`(accountManager.migrateFromAccount(any(), eq(true))).thenReturn( CompletableDeferred(MigrationResult.Failure) ) @@ -234,7 +234,7 @@ class FennecFxaMigrationTest { assertEquals("Cohabiting", unwrappedFailure.stateLabel) val captor = argumentCaptor() - verify(accountManager).migrateFromAccountAsync(captor.capture(), eq(true)) + verify(accountManager).migrateFromAccount(captor.capture(), eq(true)) assertEquals("test@example.com", captor.value.email) assertEquals("252bc4ccc3a239fsdfsdf32fg32wf3w4e3472d41d1a204890", captor.value.authInfo.kSync) diff --git a/components/support/migration/src/test/java/mozilla/components/support/migration/FennecMigratorTest.kt b/components/support/migration/src/test/java/mozilla/components/support/migration/FennecMigratorTest.kt index 10691f765f2..fee3c3c0763 100644 --- a/components/support/migration/src/test/java/mozilla/components/support/migration/FennecMigratorTest.kt +++ b/components/support/migration/src/test/java/mozilla/components/support/migration/FennecMigratorTest.kt @@ -573,7 +573,7 @@ class FennecMigratorTest { .setBrowserDbPath(File(getTestPath("combined"), "basic/browser.db").absolutePath) .build() - `when`(accountManager.migrateFromAccountAsync(any(), eq(true))).thenReturn( + `when`(accountManager.migrateFromAccount(any(), eq(true))).thenReturn( CompletableDeferred(MigrationResult.Success) ) @@ -584,7 +584,7 @@ class FennecMigratorTest { } val captor = argumentCaptor() - verify(accountManager).migrateFromAccountAsync(captor.capture(), eq(true)) + verify(accountManager).migrateFromAccount(captor.capture(), eq(true)) assertEquals("test@example.com", captor.value.email) // This is going to be package name (org.mozilla.firefox) in actual builds. @@ -612,7 +612,7 @@ class FennecMigratorTest { .setBrowserDbPath(File(getTestPath("combined"), "basic/browser.db").absolutePath) .build() - `when`(accountManager.migrateFromAccountAsync(any(), eq(true))).thenReturn( + `when`(accountManager.migrateFromAccount(any(), eq(true))).thenReturn( CompletableDeferred(MigrationResult.WillRetry) ) @@ -623,7 +623,7 @@ class FennecMigratorTest { } val captor = argumentCaptor() - verify(accountManager).migrateFromAccountAsync(captor.capture(), eq(true)) + verify(accountManager).migrateFromAccount(captor.capture(), eq(true)) assertEquals("test@example.com", captor.value.email) // This is going to be package name (org.mozilla.firefox) in actual builds. @@ -652,7 +652,7 @@ class FennecMigratorTest { .build() // For now, we don't treat sign-in failure any different from success. E.g. it's a one-shot attempt. - `when`(accountManager.migrateFromAccountAsync(any(), eq(true))).thenReturn( + `when`(accountManager.migrateFromAccount(any(), eq(true))).thenReturn( CompletableDeferred(MigrationResult.Failure) ) @@ -663,7 +663,7 @@ class FennecMigratorTest { } val captor = argumentCaptor() - verify(accountManager).migrateFromAccountAsync(captor.capture(), eq(true)) + verify(accountManager).migrateFromAccount(captor.capture(), eq(true)) assertEquals("test@example.com", captor.value.email) // This is going to be package name (org.mozilla.firefox) in actual builds. diff --git a/samples/firefox-accounts/src/main/java/org/mozilla/samples/fxa/MainActivity.kt b/samples/firefox-accounts/src/main/java/org/mozilla/samples/fxa/MainActivity.kt index 5389320bbff..ed297c070ee 100644 --- a/samples/firefox-accounts/src/main/java/org/mozilla/samples/fxa/MainActivity.kt +++ b/samples/firefox-accounts/src/main/java/org/mozilla/samples/fxa/MainActivity.kt @@ -72,7 +72,7 @@ open class MainActivity : AppCompatActivity(), LoginFragment.OnLoginCompleteList }, onScanResult = { pairingUrl -> launch { - val url = account.beginPairingFlowAsync(pairingUrl, scopes).await() + val url = account.beginPairingFlow(pairingUrl, scopes) if (url == null) { Log.log( Log.Priority.ERROR, @@ -91,7 +91,7 @@ open class MainActivity : AppCompatActivity(), LoginFragment.OnLoginCompleteList findViewById(R.id.buttonCustomTabs).setOnClickListener { launch { - account.beginOAuthFlowAsync(scopes).await()?.let { + account.beginOAuthFlow(scopes)?.let { openTab(it.url) } } @@ -99,7 +99,7 @@ open class MainActivity : AppCompatActivity(), LoginFragment.OnLoginCompleteList findViewById(R.id.buttonWebView).setOnClickListener { launch { - account.beginOAuthFlowAsync(scopes).await()?.let { + account.beginOAuthFlow(scopes)?.let { openWebView(it.url) } } @@ -123,8 +123,8 @@ open class MainActivity : AppCompatActivity(), LoginFragment.OnLoginCompleteList private fun initAccount(): FirefoxAccount { getAuthenticatedAccount()?.let { launch { - it.getProfileAsync(true).await()?.let { - displayProfile(it) + it.getProfile(true)?.let { profile -> + displayProfile(profile) } } return it @@ -189,8 +189,8 @@ open class MainActivity : AppCompatActivity(), LoginFragment.OnLoginCompleteList private fun displayAndPersistProfile(code: String, state: String) { launch { - account.completeOAuthFlowAsync(code, state).await() - account.getProfileAsync().await()?.let { + account.completeOAuthFlow(code, state) + account.getProfile()?.let { displayProfile(it) } account.toJSONString().let { diff --git a/samples/sync-logins/src/main/java/org/mozilla/samples/sync/logins/MainActivity.kt b/samples/sync-logins/src/main/java/org/mozilla/samples/sync/logins/MainActivity.kt index 6b001db370b..b148057a381 100644 --- a/samples/sync-logins/src/main/java/org/mozilla/samples/sync/logins/MainActivity.kt +++ b/samples/sync-logins/src/main/java/org/mozilla/samples/sync/logins/MainActivity.kt @@ -98,12 +98,12 @@ class MainActivity : AppCompatActivity(), LoginFragment.OnLoginCompleteListener, // kicking off the accountManager. GlobalSyncableStoreProvider.configureStore(SyncEngine.Passwords to loginsStorage) - accountManager.startAsync().await() + accountManager.start() } findViewById(R.id.buttonWebView).setOnClickListener { launch { - val authUrl = accountManager.beginAuthenticationAsync().await() + val authUrl = accountManager.beginAuthentication() if (authUrl == null) { Toast.makeText(this@MainActivity, "Account auth error", Toast.LENGTH_LONG).show() return@launch @@ -119,7 +119,7 @@ class MainActivity : AppCompatActivity(), LoginFragment.OnLoginCompleteListener, override fun onLoggedOut() {} override fun onAuthenticated(account: OAuthAccount, authType: AuthType) { - accountManager.syncNowAsync(SyncReason.User) + launch { accountManager.syncNow(SyncReason.User) } } @Suppress("EmptyFunctionBlock") @@ -148,9 +148,9 @@ class MainActivity : AppCompatActivity(), LoginFragment.OnLoginCompleteListener, override fun onLoginComplete(code: String, state: String, action: String, fragment: LoginFragment) { launch { - accountManager.finishAuthenticationAsync( + accountManager.finishAuthentication( FxaAuthData(action.toAuthType(), code = code, state = state) - ).await() + ) supportFragmentManager.popBackStack() } } diff --git a/samples/sync/src/main/java/org/mozilla/samples/sync/MainActivity.kt b/samples/sync/src/main/java/org/mozilla/samples/sync/MainActivity.kt index 073a3152ea9..2e557639b24 100644 --- a/samples/sync/src/main/java/org/mozilla/samples/sync/MainActivity.kt +++ b/samples/sync/src/main/java/org/mozilla/samples/sync/MainActivity.kt @@ -119,7 +119,7 @@ class MainActivity : findViewById(R.id.buttonSignIn).setOnClickListener { launch { - val authUrl = accountManager.beginAuthenticationAsync().await() + val authUrl = accountManager.beginAuthentication() if (authUrl == null) { val txtView: TextView = findViewById(R.id.fxaStatusView) txtView.text = getString(R.string.account_error, null) @@ -130,13 +130,11 @@ class MainActivity : } findViewById(R.id.buttonLogout).setOnClickListener { - launch { - accountManager.logoutAsync().await() - } + launch { accountManager.logout() } } findViewById(R.id.refreshDevice).setOnClickListener { - launch { accountManager.authenticatedAccount()?.deviceConstellation()?.refreshDevicesAsync()?.await() } + launch { accountManager.authenticatedAccount()?.deviceConstellation()?.refreshDevices() } } findViewById(R.id.sendTab).setOnClickListener { @@ -148,9 +146,9 @@ class MainActivity : } targets?.forEach { - constellation.sendCommandToDeviceAsync( + constellation.sendCommandToDevice( it.id, DeviceCommandOutgoing.SendTab("Sample tab", "https://www.mozilla.org") - ).await() + ) } Toast.makeText( @@ -171,19 +169,19 @@ class MainActivity : // Observe incoming device commands. accountManager.registerForAccountEvents(accountEventsObserver, owner = this, autoPause = true) - launch { - GlobalSyncableStoreProvider.configureStore(SyncEngine.History to historyStorage) - GlobalSyncableStoreProvider.configureStore(SyncEngine.Bookmarks to bookmarksStorage) - GlobalSyncableStoreProvider.configureStore(SyncEngine.Passwords to passwordsStorage) + GlobalSyncableStoreProvider.configureStore(SyncEngine.History to historyStorage) + GlobalSyncableStoreProvider.configureStore(SyncEngine.Bookmarks to bookmarksStorage) + GlobalSyncableStoreProvider.configureStore(SyncEngine.Passwords to passwordsStorage) + launch { // Now that our account state observer is registered, we can kick off the account manager. - accountManager.startAsync().await() + accountManager.start() } findViewById(R.id.buttonSync).setOnClickListener { launch { - accountManager.syncNowAsync(SyncReason.User).await() - accountManager.authenticatedAccount()?.deviceConstellation()?.pollForCommandsAsync()?.await() + accountManager.syncNow(SyncReason.User) + accountManager.authenticatedAccount()?.deviceConstellation()?.pollForCommands() } } } @@ -197,9 +195,9 @@ class MainActivity : override fun onLoginComplete(code: String, state: String, action: String, fragment: LoginFragment) { launch { supportFragmentManager.popBackStack() - accountManager.finishAuthenticationAsync( + accountManager.finishAuthentication( FxaAuthData(action.toAuthType(), code = code, state = state) - ).await() + ) } }