User:Anaaktgeboren/NativeSync

From MozillaWiki
Jump to: navigation, search

Android Sync behavior with multiple Firefox versions installed

User Support

  • Mozilla only supports one installation of Firefox for Android at a time, and a single Firefox Sync account. Attempting to set up Firefox Sync with multiple Firefox installations (e.g., Firefox and Firefox Beta) may result in a failure to set up an account. Forcing multiple Firefox versions to sync will fail.
  • In order to resolve Firefox Sync setup and syncing failures, please choose one Firefox installation to keep, and uninstall the others by going to Settings → Apps → All, selecting each unwanted Firefox installation, and clicking "Uninstall."
  • You can have both a "Native" Firefox and a "XUL" Firefox installed at the same time without problems.

Technical Examination

Firefox for Android includes an Android-native implementation of Firefox Sync: a background data synchronization component termed "Android Sync".

We currently only support a single Firefox installation per device if Sync is used. This is due to a number of technical constraints, best summed up as "Android expects only a single application to control each account, but we ship the code that manages the account with each version of Firefox".

We will be addressing these constraints in future releases.

User Experience

  • If two versions of Firefox are installed, the behavior of the system during Sync setup is undefined. Setup might complete if the user starts setup from the 'correct' version (which appears to be arbitrary). Installing a second version of Firefox after setting up Sync is likely to be safe, but it will not sync. Switching between versions of Firefox, but keeping only one permanently installed, is likely to be successful.
  • Precise behavior seems to depend on order of installation and Sync setup, as well as Android version.

Developer Overview

Android Sync exposes an Android SyncAdapter and account setup activities, and Firefox uses Android Sync to sync history, bookmarks, passwords, forms, tabs, etc.

Firefox Sync account credentials are only accessible to Sync and Firefox: the authenticator service is not exported. Android Sync functionality is bundled with the Firefox browser in a single APK.

Android associates an account type (e.g., org.mozilla.firefox_sync) with an account authenticator, and implicitly with the system uid of the authenticator.

In the following sections, we detail the behavior of multiple Firefox installations.

Setup

If you have a Firefox version (e.g., Nightly) installed, and you install a second, different version of Firefox (e.g., Aurora), then there will be two applications which each claim to 'own' the Firefox Sync account type. Attempting to set up a Firefox Sync account for the Aurora installation will fail if Android has decided that Nightly owns the account type, or vice versa; the Nightly Sync setup activity doesn't share Aurora's Android uid, and thus isn't permitted to create the account. The only way to get Sync setup working with the new installation is to uninstall the previous version(s) of Firefox.

Syncing

In the Firefox Sync account settings, under Settings → Accounts → (your Firefox Account), all Firefox installations will show up as sync-able options. Only the Firefox version that provided the Sync setup activity will be checked. Attempting to sync any of the other Firefox versions will fail, because only the original Firefox's Sync AccountAuthenticator will be permitted to access necessary metadata. (If this were to succeed, Sync would not behave correctly when tracking changes in each profile.) In order to sync an account with a particular Firefox installation, uninstall all other Firefox versions. In the Firefox Account settings, under Settings → Accounts → (your Firefox Account), make sure the Firefox version is checked (it should be the only option).

Possible improvements

We would like to support simultaneous syncing of multiple versions of Firefox, and multiple profiles, in a future release. Some avenues to explore are:

  • Providing distinct account types for each version of Firefox. (That is, you might have a "Firefox Sync", a "Firefox Sync for Aurora", and a "Firefox Sync for Nightly" account.)
    • Undesirable because it limits the ability to switch between channels, besides presenting a confusing user experience.
    • The only approach that's 100% likely to work.
  • Exporting the Sync authenticator, accessing it by reference, and allowing Android to determine which authenticator code runs.
    • Risk here in allowing significant version mismatch: you might get Firefox 14's setup or authentication code running when testing Firefox 16. Account types will need to change as significant differences are implemented.
    • Requires code signing protections (which hampers testing of custom builds against release builds) to avoid access to credentials by other Android applications.
    • Might not work at all if Android does not permit more than one application to export an authenticator in this way.
  • Shipping Sync as a separate system component.
    • Introduces packaging, deployment, and Fennec integration difficulties.

Regardless, we will also need to address:

  • UX issues — how to configure an account that will sync to three different Firefox profiles, or how to sanely present multiple Firefox applications in different accounts.
  • Internal data storage — correct storage of prefs and timestamps in a per-profile, per-application, per-account way.
  • Consistency — preventing an application's profile from syncing to more than one Sync account.

Engineering Notes

Triage

Bugzilla descriptions

General whiteboard flags

  • [not code] - this bug deals with something that is not actionable in code, such as documentation
  • [not started] - work has not started
  • [work started] - coding has begun
  • [decision needed] - work cannot proceed until a decision is made

Sync-specific whiteboard flags

Since the Sync team works in GitHub, Bugzilla does not reflect the review state of in-progress work. These whiteboard flags indicate when work has reached the review stage. Usually a pull request URL is added to the bug as work gets underway.

  • [needs review :<nick>] - code is waiting for review from <nick>
  • [in testing] - prior to landing, our code is QAed, this may be different from other groups who land and then QA

Landing state

  • Work lands on mozilla-inbound. Per inbound rules, we don't use a whiteboard flag for this; instead, 'target-milestone' is set to the next release (currently 15). Also ensure that the bug is ASSIGNED.
  • When mozilla-inbound is merged to mozilla-central, the bug is RESOLVED FIXED.
  • When QA has verified the fix, the bug is VERIFIED FIXED.

That is: work proceeds from [not started] → [work started] → [needs review] → TM=15 → TM=15 + RESOLVED → TM=15 + VERIFIED.

When work is uplifted to Aurora, its 'status-firefox14' flag is set to 'fixed'.

Having the resolution, target-milestone, and status-firefoxN flags visible in Bugzilla search results will give an at-a-glance view of the landing state of a bug.

Testing

  • android sync jenkins instance
  • waiting on a tegra board hookup for the services build machine (located in sf between :ally's & :gps' desk)
    •  :mconnor is looking into it

Cases that Android Sync does not handle: blank and corrupted servers

There are three significant cases that Android Sync encounters when performing a sync. The first and most likely case is that the server is correctly configured, meaning that it has both a valid meta/global record and a crypto/keys record. We expect this case for almost all syncs. This discussion does not concern this correctly configured case at all.

The remaining two exceptional cases are when the server is blank, meaning it has no meta/global record at all, and when the server is corrupt, meaning that it has an invalid meta/global and/or an invalid crypto/keys record. Of these two cases, we anticipate that the blank case will happen for almost all exceptional syncs.

Only the blank case is expected to occur during normal sync operation; an account that is node re-assigned will see a blank server on next sync, which we anticipate will happen only a small number of times for any individual account. The corrupt case will only occur if there is a server failure, a network connectivity error, or a bug in client code.

To recap: we expect a correctly configured server almost all the time, and in the exceptional cases, we expect a blank server almost all of the time.

Current behaviour when Android Sync sees a blank server

In the blank case, a bug in Android Sync manifests itself in the following client behaviour:

  1. a sync is started on the Android device;
  2. the blank server is correctly recognized;
  3. an HTTP request is sent to wipe the server in preparation for uploading valid meta/global and crypto/keys records;
  4. the client fails to upload the new meta/global record;
  5. Android spins the "sync" icon for 5 minutes before killing the sync.

A new sync will be started in 5 minutes, which will repeat the process, including spawning a new HTTP request to wipe the server. This process will repeat until Android stops Android Sync entirely or another (Desktop) client correctly configures the server.

Current behaviour when Android Sync sees a corrupted server

Android Sync does not recognize a corrupted server at all. During normal sync operation, there are two corrupted cases that Android Sync could see. The first is a missing crypto/keys record, and the second is an invalid meta/global record.

If Android Sync sees a (valid or invalid) meta/global record but a missing crypto/keys record, it will try to upload a new crypto/keys record without first wiping the server. If there is data on the server, this will cause data loss. However, we do not expect this to ever be the case: is highly likely that a client wiped the server, uploaded a fresh meta/global record, and then failed to upload a fresh crypto/keys record.

If Android Sync sees an invalid meta/global record, it will try to sync normally. Since we expect every client to wipe the server entirely before uploading a meta/global record, it is unlikely that this sync will fail outright due to data on the server being encrypted with the wrong keys. However any problems (the most likely being an engine version mismatch) will be ignored, almost certainly corrupting server data.

Suggested compromise for beta release

We propose to:

  1. abort immediately when Android Sync recognizes a blank server.
    This is the simplest way to ensure we do not appear to be syncing to the Android OS and that we do not spawn expensive HTTP wipe server requests. This will handle the vast majority of the exceptional cases, at the expense of temporarily not syncing Android data until a Desktop sync occurs.
  2. abort immediately when Android Sync recognizes that there is a corrupt server without a crypto/keys record.
    This is the simplest way to ensure that we do not cause data loss. This will handle the majority of corrupt server cases, again at the expense of temporarily not syncing Android data until a Desktop sync occurs.