Commit 83befd90 authored by Grisha Kruglov's avatar Grisha Kruglov Committed by Grisha Kruglov
Browse files

Update component documentation and changelog

parent 7afec7d4
......@@ -4,17 +4,29 @@ A library for integrating with Firefox Accounts.
## Motivation
The **Firefox Accounts Android Component** provides a way for Android applications to do the following:
The **Firefox Accounts Android Component** provides both low and high level accounts functionality.
* Obtain OAuth tokens that can be used to access the user's data in Mozilla-hosted services like Firefox Sync
At a low level, there is direct interaction with the accounts system:
* Obtain scoped OAuth tokens that can be used to access the user's data in Mozilla-hosted services like Firefox Sync
* Fetch client-side scoped keys needed for end-to-end encryption of that data
* Fetch a user's profile to personalize the application
See also the [sample app](https://github.com/mozilla-mobile/android-components/tree/master/samples/firefox-accounts)
for help with integrating this component into your application.
At a high level, there is an Account Manager:
* Handles account state management and persistence
* Abstracts away OAuth details, handling scopes, token caching, recovery, etc. Application can still specify custom scopes if needed
* Integrates with FxA device management, automatically creating and destroying device records as appropriate
* (optionally) Provides Send Tab integration - allows sending and receiving tabs within the Firefox Account ecosystem
* (optionally) Provides Firefox Sync integration
## Usage
Sample applications:
* [accounts sample app](https://github.com/mozilla-mobile/android-components/tree/master/samples/firefox-accounts), demonstrates how to use low level APIs
* [sync app](https://github.com/mozilla-mobile/android-components/tree/master/samples/sync), demonstrates a high level accounts integration, complete with syncing multiple data stores
Useful companion components:
* [feature-accounts](https://github.com/mozilla-mobile/android-components/tree/master/components/feature/accounts), provides a `tabs` integration on top of `FxaAccountManager`, to handle display of web sign-in UI.
* [browser-storage-sync](https://github.com/mozilla-mobile/android-components/tree/master/components/browser/storage-sync), provides data storage layers compatible with Firefox Sync.
## Usage
### Setting up the dependency
Use Gradle to download the library from [maven.mozilla.org](https://maven.mozilla.org/) ([Setup repository](../../../README.md#maven-repository)):
......@@ -23,7 +35,134 @@ Use Gradle to download the library from [maven.mozilla.org](https://maven.mozill
implementation "org.mozilla.components:service-firefox-accounts:{latest-version}"
```
### Start coding
### High level APIs, recommended for most applications
Below is an example of how to integrate most of the common functionality exposed by `FxaAccountManager`.
Additionally, see `feature-accounts`
```kotlin
// Make the two "syncable" stores accessible to account manager's sync machinery.
GlobalSyncableStoreProvider.configureStore("history" to historyStorage)
GlobalSyncableStoreProvider.configureStore("bookmarks" to bookmarksStorage)
val accountManager = FxaAccountManager(
context = this,
serverConfig = ServerConfig.release(CLIENT_ID, REDIRECT_URL),
deviceConfig =DeviceConfig(
name = "Sample app",
type = DeviceType.MOBILE,
capabilities = setOf(DeviceCapability.SEND_TAB)
),
syncConfig = SyncConfig(setOf("history", "bookmarks"), syncPeriodInMinutes = 15L)
)
// Observe changes to the account and profile.
accountManager.register(accountObserver, owner = this, autoPause = true)
// Observe sync state changes.
accountManager.registerForSyncEvents(syncObserver, owner = this, autoPause = true)
// Observe incoming device events (e.g. SEND_TAB events from other devices).
accountManager.registerForDeviceEvents(deviceEventsObserver, owner = this, autoPause = true)
// Now that all of the observers we care about are registered, kick off the account manager.
// If we're already authenticated
launch { accountManager.initAsync().await() }
// 'Sync Now' button binding.
findViewById<View>(R.id.buttonSync).setOnClickListener {
accountManager.syncNowAsync()
}
// 'Sign-in' button binding.
findViewById<View>(R.id.buttonSignIn).setOnClickListener {
launch {
val authUrl = accountManager.beginAuthenticationAsync().await()
authUrl?.let { openWebView(it) }
}
}
// 'Sign-out' button binding
findViewById<View>(R.id.buttonLogout).setOnClickListener {
launch {
accountManager.logoutAsync().await()
}
}
// 'Disable periodic sync' button binding
findViewById<View>(R.id.disablePeriodicSync).setOnClickListener {
launch {
accountManager.setSyncConfigAsync(
SyncConfig(setOf("history", "bookmarks")
).await()
}
}
// 'Enable periodic sync' button binding
findViewById<View>(R.id.enablePeriodicSync).setOnClickListener {
launch {
accountManager.setSyncConfigAsync(
SyncConfig(setOf("history", "bookmarks"), syncPeriodInMinutes = 60L)
).await()
}
}
// This is expected to be called from the webview/geckoview integration, which intercepts page loads and gets
// 'code' and 'state' out of the 'successful sign-in redirect' url.
fun onLoginComplete(code: String, state: String) {
launch {
accountManager.finishAuthenticationAsync(code, state).await()
}
}
// Observe changes to account state.
val accountObserver = object : AccountObserver {
override fun onLoggedOut() = launch {
// handle logging-out in the UI
}
override fun onAuthenticationProblems() = launch {
// prompt user to re-authenticate
}
override fun onAuthenticated(account: OAuthAccount) = launch {
// logged-in successfully; display account details
}
override fun onProfileUpdated(profile: Profile) {
// display ${profile.displayName} and ${profile.email} if desired
}
}
// Observe changes to sync state.
val syncObserver = object : SyncStatusObserver {
override fun onStarted() = launch {
// sync started running; update some UI to indicate this
}
override fun onIdle() = launch {
// sync stopped running; update some UI to indicate this
}
override fun onError(error: Exception?) = launch {
// sync encountered an error; optionally indicate this in the UI
}
}
// Observe incoming device events.
val deviceEventsObserver = object : DeviceEventsObserver {
override fun onEvents(events: List<DeviceEvent>) {
// device received some events; for example, here's how you can process incoming Send Tab events:
events.filter { it is DeviceEvent.TabReceived }.forEach {
val tabReceivedEvent = it as DeviceEvent.TabReceived
val fromDeviceName = tabReceivedEvent.from?.displayName
showNotification("Tab ${tab.title}, received from: ${fromDisplayName}", tab.url)
}
}
}
```
### Low level APIs
First you need some OAuth information. Generate a `client_id`, `redirectUrl` and find out the scopes for your application.
See Firefox Account documentation for that.
......
......@@ -18,6 +18,13 @@ permalink: /changelog/
* **feature-downloads**
* Added custom notification icon for `FetchDownloadManager`.
* **feature-accounts**
* ⚠️ **This is a breaking change**: Public API for interacting with `FxaAccountManager` and sync changes
* `FxaAccountManager` now has a new, simplified public API.
* `BackgroundSyncManager` is longer exists; sync functionality exposed directly via `FxaAccountManager`.
* See component's [README](https://github.com/mozilla-mobile/android-components/blob/master/components/service/firefox-accounts/README.md) for detailed description of the new API.
* As part of these changes, token caching issue has been fixed. See [#3579](https://github.com/mozilla-mobile/android-components/pull/3579) for details.
# 3.0.0
* [Commits](https://github.com/mozilla-mobile/android-components/compare/v2.0.0...v3.0.0)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment