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

Commit

Permalink
Account manager state machine refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Grisha Kruglov committed Sep 16, 2020
1 parent 8f40c02 commit 9f892e0
Show file tree
Hide file tree
Showing 38 changed files with 1,791 additions and 2,103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ typealias OuterDeviceCommandIncoming = DeviceCommandIncoming
*/
sealed class AccountEvent {
/** An incoming command from another device */
class DeviceCommandIncoming(val command: OuterDeviceCommandIncoming) : AccountEvent()
data class DeviceCommandIncoming(val command: OuterDeviceCommandIncoming) : AccountEvent()
/** The account's profile was updated */
class ProfileUpdated : AccountEvent()
object ProfileUpdated : AccountEvent()
/** The authentication state of the account changed - eg, the password changed */
class AccountAuthStateChanged : AccountEvent()
object AccountAuthStateChanged : AccountEvent()
/** The account itself was destroyed */
class AccountDestroyed : AccountEvent()
object AccountDestroyed : AccountEvent()
/** Another device connected to the account */
class DeviceConnected(val deviceName: String) : AccountEvent()
data class DeviceConnected(val deviceName: String) : AccountEvent()
/** A device (possibly this one) disconnected from the account */
class DeviceDisconnected(val deviceId: String, val isLocalDevice: Boolean) : AccountEvent()
data class DeviceDisconnected(val deviceId: String, val isLocalDevice: Boolean) : AccountEvent()
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,39 @@ package mozilla.components.concept.sync

import android.content.Context
import androidx.lifecycle.LifecycleOwner
import kotlinx.coroutines.Deferred
import mozilla.components.support.base.observer.Observable

/**
* Describes available interactions with the current device and other devices associated with an [OAuthAccount].
* Represents a result of interacting with a backend service which may return an authentication error.
*/
interface DeviceConstellation : Observable<AccountEventsObserver> {
sealed class ServiceResult {
/**
* Register current device in the associated [DeviceConstellation].
*
* @param name An initial name for the current device. This may be changed via [setDeviceNameAsync].
* @param type Type of the current device. This can't be changed.
* @param capabilities A list of capabilities that the current device claims to have.
* @return A [Deferred] that will be resolved with a success flag once operation is complete.
* All good.
*/
object Ok : ServiceResult()

/**
* Auth error.
*/
object AuthError : ServiceResult()

/**
* Error that isn't auth.
*/
fun initDeviceAsync(
name: String,
type: DeviceType = DeviceType.MOBILE,
capabilities: Set<DeviceCapability>
): Deferred<Boolean>
object OtherError : ServiceResult()
}

/**
* Describes available interactions with the current device and other devices associated with an [OAuthAccount].
*/
interface DeviceConstellation : Observable<AccountEventsObserver> {
/**
* Ensure that all passed in [capabilities] are configured.
* This may involve backend service registration, or other work involving network/disc access.
* @param capabilities A list of capabilities to configure. This is expected to be the same or
* longer list than what was passed into [initDeviceAsync]. Removing capabilities is currently
* not supported.
* @return A [Deferred] that will be resolved with a success flag once operation is complete.
* Perform actions necessary to finalize device initialization based on [authType].
* @param authType Type of an authentication event we're experiencing.
* @param config A [DeviceConfig] that describes current device.
* @return A boolean success flag.
*/
fun ensureCapabilitiesAsync(capabilities: Set<DeviceCapability>): Deferred<Boolean>
suspend fun finalizeDevice(authType: AuthType, config: DeviceConfig): ServiceResult

/**
* Current state of the constellation. May be missing if state was never queried.
Expand All @@ -53,46 +56,46 @@ interface DeviceConstellation : Observable<AccountEventsObserver> {
* Set name of the current device.
* @param name New device name.
* @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.
* @return A boolean success flag.
*/
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.
* @return A boolean success flag.
*/
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.
* @return A boolean success flag.
*/
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.
* @return A boolean success flag.
*/
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.
* @return A boolean success flag.
*/
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.
* @return A boolean success flag.
*/
fun pollForCommandsAsync(): Deferred<Boolean>
suspend fun pollForCommands(): Boolean
}

/**
Expand Down Expand Up @@ -128,6 +131,24 @@ data class DevicePushSubscription(
val authKey: String
)

/**
* 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.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.
* @property secureStateAtRest A flag indicating whether or not to use encrypted storage for the persisted account
* state.
*/
data class DeviceConfig(
val name: String,
val type: DeviceType,
val capabilities: Set<DeviceCapability>,
val secureStateAtRest: Boolean = false
)

/**
* Capabilities that a [Device] may have.
*/
Expand Down
Loading

1 comment on commit 9f892e0

@firefoxci-taskcluster
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh oh! Looks like an error! Details

Failed to get your artifact.

Please sign in to comment.