Skip to content

Commit

Permalink
Reworked most of the Kotlin FxA wrapper
Browse files Browse the repository at this point in the history
Renamed the class from `PersistedFirefoxAccount` to `FxaClient` because
class is now adding more functionality than just persistance.
The main reason I chose `FxaClient` was that it doesn't conflict with
any of the other class names.

Added a state machine, similar to the android-components one but more
lightweight. Applications send FxaActions the client sends them back
FxaEvents.  Everything happens in a single async task that reads actions
from a channel and processing things serially.  Well, that was the goal
at least, there's a few places where we need break this model to make
things work with the existing firefox-android code.  See StateTypes.kt
for details.

Most getter functions are now async, using `withContext` plus a
application-supplied `CoroutineContext`. Some getter functions are
advertised as blocking because they don't make network requests.  I
don't think this is completely accurate (#5819), but I made this sync
functions since that's what the application expects.

Implemented a simple form of network retry / automatic auth checking.
I'm not sure if this is the correct logic, but it should be simple to
modify.  Added functions to manually test this, the plan is to hook them
up to the secret debug menu an Android.

Updated sync_local_device_info to accept a None value for display name.
This updates the device type/commands, then returns a LocalDevice record
with the display name filled in from the server response.  This is what
we firefox-android needs for its startup.

Switched to using FxaConfig and FxaServer directly.

Don't persist the state on startup with a Config.  This doesn't work on
firefox-android since the state persistence callback is not setup on the
layer above us.  It also doesn't make much sense to save the state
before any action has been taken -- you can always reproduce that state
by starting with a new config.
  • Loading branch information
bendk committed Oct 3, 2023
1 parent 2ccdd08 commit 0ef0a96
Show file tree
Hide file tree
Showing 15 changed files with 2,210 additions and 499 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

[Full Changelog](In progress)

## FxA Client

### What's changed

- Major changes to the Kotlin wrappers. They now present a higher-level action/event system. The
goal here is to allow new consumers to use this directly, without a lot of extra code like
android-components needed.

## Rust log forwarder

### 🦊 What's Changed 🦊
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ buildscript {
ktlint_version = '0.50.0'
gradle_download_task_version = '5.2.1'
junit_version = '4.13.2'
mockk_version = '1.13.8'
mockito_core_version = '5.5.0'
robolectric_core_version = '4.10.3'
rust_android_gradle_version = '0.9.3'
Expand Down
4 changes: 4 additions & 0 deletions components/fxa-client/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ apply from: "$rootDir/publish.gradle"

dependencies {
api project(':sync15')
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"

testImplementation("io.mockk:mockk:${mockk_version}")
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlin_coroutines_version"
}

ext.configureUniFFIBindgen("../src/fxa_client.udl")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,13 @@

package mozilla.appservices.fxaclient

/**
* Config represents the server endpoint configurations needed for the
* authentication flow.
*/
class Config constructor(
val server: FxaServer,
val clientId: String,
val redirectUri: String,
val tokenServerUrlOverride: String? = null,
) {
enum class Server(val rustServer: FxaServer) {
RELEASE(FxaServer.Release),
STABLE(FxaServer.Stable),
STAGE(FxaServer.Stage),
CHINA(FxaServer.China),
LOCALDEV(FxaServer.LocalDev),
;

val contentUrl get() = this.rustServer.contentUrl
}

constructor(
server: Server,
clientId: String,
redirectUri: String,
tokenServerUrlOverride: String? = null,
) : this(server.rustServer, clientId, redirectUri, tokenServerUrlOverride)

constructor(
contentUrl: String,
clientId: String,
redirectUri: String,
tokenServerUrlOverride: String? = null,
) : this(FxaServer.Custom(contentUrl), clientId, redirectUri, tokenServerUrlOverride)

val contentUrl get() = this.server.contentUrl

// Rust defines a config and server class that's virtually identically to these. We should
// remove the wrapper soon, but let's wait until we have a batch of breaking changes and do them
// all at once.
fun intoRustConfig() = FxaConfig(server, clientId, redirectUri, tokenServerUrlOverride)
fun FxaServer.isCustom() = this is FxaServer.Custom

fun FxaServer.contentUrl() = when(this) {
is FxaServer.Release -> "https://accounts.firefox.com"
is FxaServer.Stable -> "https://stable.dev.lcip.org"
is FxaServer.Stage -> "https://accounts.stage.mozaws.net"
is FxaServer.China -> "https://accounts.firefox.com.cn"
is FxaServer.LocalDev -> "http://127.0.0.1:3030"
is FxaServer.Custom -> this.url
}

val FxaServer.contentUrl: String
get() = when (this) {
is FxaServer.Release -> "https://accounts.firefox.com"
is FxaServer.Stable -> "https://stable.dev.lcip.org"
is FxaServer.Stage -> "https://accounts.stage.mozaws.net"
is FxaServer.China -> "https://accounts.firefox.com.cn"
is FxaServer.LocalDev -> "http://127.0.0.1:3030"
is FxaServer.Custom -> this.url
}
Loading

0 comments on commit 0ef0a96

Please sign in to comment.