Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Commit

Permalink
async -> suspend
Browse files Browse the repository at this point in the history
  • Loading branch information
Grisha Kruglov committed Jul 27, 2020
1 parent e63138f commit 8432ab9
Show file tree
Hide file tree
Showing 25 changed files with 447 additions and 497 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ interface DeviceConstellation : Observable<AccountEventsObserver> {
* @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<Boolean>
suspend fun finalizeDevice(authType: AuthType, config: DeviceConfig): Boolean

/**
* Current state of the constellation. May be missing if state was never queried.
Expand All @@ -39,44 +39,44 @@ interface DeviceConstellation : Observable<AccountEventsObserver> {
* @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<Boolean>
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<Boolean>
suspend fun setDevicePushSubscription(subscription: DevicePushSubscription): Boolean

/**
* Send a command to a specified device.
* @param targetDeviceId A device ID of the recipient.
* @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<Boolean>
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<Boolean>
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<Boolean>
suspend fun refreshDevices(): Boolean

/**
* Polls for any pending [DeviceCommandIncoming] commands.
* In case of new commands, registered [AccountEventsObserver] observers will be notified.
*
* @return A [Deferred] that will be resolved with a success flag once operation is complete.
*/
fun pollForCommandsAsync(): Deferred<Boolean>
suspend fun pollForCommands(): Boolean
}

/**
Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
/**
Expand All @@ -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
}
Expand All @@ -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<String>): Deferred<AuthFlowUrl?>
suspend fun beginOAuthFlow(scopes: Set<String>): AuthFlowUrl?

/**
* Constructs a URL used to begin the pairing flow for the requested scopes and pairingUrl.
Expand All @@ -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<String>): Deferred<AuthFlowUrl?>
suspend fun beginPairingFlow(pairingUrl: String, scopes: Set<String>): AuthFlowUrl?

/**
* Returns current FxA Device ID for an authenticated account.
Expand All @@ -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<String>,
state: String,
accessType: AccessType = AccessType.ONLINE
): Deferred<String?>
): String?

/**
* Fetches the profile object for the current client either from the existing cached state
Expand All @@ -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<Profile?>
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<Boolean>
suspend fun completeOAuthFlow(code: String, state: String): Boolean

/**
* Tries to fetch an access token for the given scope.
Expand All @@ -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<AccessTokenInfo?>
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()

Expand All @@ -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<Boolean?>
suspend fun checkAuthorizationStatus(singleScope: String): Boolean?

/**
* Fetches the token server endpoint, for authentication using the SAML bearer flow.
Expand Down Expand Up @@ -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<JSONObject?>
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
Expand All @@ -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<JSONObject?>
suspend fun retryMigrateFromSessionToken(): JSONObject?

/**
* Returns the device constellation for the current account
Expand All @@ -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<Boolean>
suspend fun disconnect(): Boolean

/**
* Serializes the current account's authentication state as a JSON string, for persistence in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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())
}
}
}

Expand Down Expand Up @@ -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) {
Expand All @@ -210,7 +215,9 @@ internal class AutoPushObserver(
return@subscribe
}

account.deviceConstellation().setDevicePushSubscriptionAsync(subscription.into())
CoroutineScope(Dispatchers.Main).launch {
account.deviceConstellation().setDevicePushSubscription(subscription.into())
}
}
}
}
Expand Down Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
)
}
}

Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class AccountObserverTest {

observer.onAuthenticated(account, AuthType.Signin)

verify(constellation).setDevicePushSubscriptionAsync(any())
verify(constellation).setDevicePushSubscription(any())
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class AutoPushObserverTest {

observer.onMessageReceived("test", "foobar".toByteArray())

verify(constellation).processRawEventAsync("foobar")
verify(constellation).processRawEvent("foobar")
}

@Test
Expand All @@ -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
Expand All @@ -53,7 +53,7 @@ class AutoPushObserverTest {

observer.onMessageReceived("test", "foobar".toByteArray())

verify(constellation, never()).processRawEventAsync(any())
verify(constellation, never()).processRawEvent(any())
}

@Test
Expand All @@ -67,7 +67,7 @@ class AutoPushObserverTest {

observer.onSubscriptionChanged("test")

verify(constellation).setDevicePushSubscriptionAsync(any())
verify(constellation).setDevicePushSubscription(any())
}

@Test
Expand All @@ -78,7 +78,7 @@ class AutoPushObserverTest {

observer.onSubscriptionChanged("test")

verify(constellation, never()).setDevicePushSubscriptionAsync(any())
verify(constellation, never()).setDevicePushSubscription(any())
}

@Test
Expand All @@ -90,7 +90,7 @@ class AutoPushObserverTest {

observer.onSubscriptionChanged("test")

verify(constellation, never()).setDevicePushSubscriptionAsync(any())
verify(constellation, never()).setDevicePushSubscription(any())
verifyZeroInteractions(pushFeature)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
}
Loading

0 comments on commit 8432ab9

Please sign in to comment.