Bug 1113493 - maintain engine state and offer engine customization during migration. r=rnewman/adw
authorMark Hammond <mhammond@skippinet.com.au>
Wed, 07 Jan 2015 13:57:38 +1100
changeset 248229 336ead0f496546d23dd5bad6bd1da08190a3f169
parent 248228 227dc63febd94321122c0bba29b07bd1d625e5df
child 248230 7a472c24f6aa62de58b54cb7db904709add4e62c
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrnewman, adw
bugs1113493
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1113493 - maintain engine state and offer engine customization during migration. r=rnewman/adw
services/sync/modules/FxaMigrator.jsm
services/sync/tests/unit/test_fxa_migration.js
--- a/services/sync/modules/FxaMigrator.jsm
+++ b/services/sync/modules/FxaMigrator.jsm
@@ -196,24 +196,42 @@ Migrator.prototype = {
       // our observers will kick us further along when complete.
       this.log.info("waiting for sync to complete")
       return null;
     }
 
     // Write the migration sentinel if necessary.
     yield this._setMigrationSentinelIfNecessary();
 
+    // Get the list of enabled engines to we can restore that state.
+    let enginePrefs = this._getEngineEnabledPrefs();
+
     // Must be ready to perform the actual migration.
     this.log.info("Performing final sync migration steps");
     // Do the actual migration.
     let startOverComplete = new Promise((resolve, reject) => {
       let observe;
       Services.obs.addObserver(observe = () => {
         this.log.info("observed that startOver is complete");
         Services.obs.removeObserver(observe, "weave:service:start-over:finish");
+        // We've now reset all sync prefs - set the engine related prefs back to
+        // what they were.
+        for (let [prefName, prefType, prefVal] of enginePrefs) {
+          switch (prefType) {
+            case Services.prefs.PREF_BOOL:
+              Services.prefs.setBoolPref(prefName, prefVal);
+              break;
+            case Services.prefs.PREF_STRING:
+              Services.prefs.setCharPref(prefName, prefVal);
+              break;
+            default:
+              // _getEngineEnabledPrefs doesn't return any other type...
+              Cu.reportError("unknown engine pref type for " + prefName + ": " + prefType);
+          }
+        }
         resolve();
       }, "weave:service:start-over:finish", false);
     });
 
     Weave.Service.startOver();
     // need to wait for an observer.
     yield startOverComplete;
     // observer fired, now kick things off with the FxA user.
@@ -306,16 +324,43 @@ Migrator.prototype = {
   _blockSync() {
     Weave.Service.scheduler.blockSync();
   },
 
   _unblockSync() {
     Weave.Service.scheduler.unblockSync();
   },
 
+  /* Return a list of [prefName, prefType, prefVal] for all engine related
+     preferences.
+  */
+  _getEngineEnabledPrefs() {
+    let result = [];
+    for (let engine of Weave.Service.engineManager.getAll()) {
+      let prefName = "services.sync.engine." + engine.prefName;
+      let prefVal;
+      try {
+        prefVal = Services.prefs.getBoolPref(prefName);
+        result.push([prefName, Services.prefs.PREF_BOOL, prefVal]);
+      } catch (ex) {} /* just skip this pref */
+    }
+    // and the declined list.
+    try {
+      let prefName = "services.sync.declinedEngines";
+      let prefVal = Services.prefs.getCharPref(prefName);
+      result.push([prefName, Services.prefs.PREF_STRING, prefVal]);
+    } catch (ex) {}
+    return result;
+  },
+
+  /* return true if all engines are enabled, false otherwise. */
+  _allEnginesEnabled() {
+    return Weave.Service.engineManager.getAll().every(e => e.enabled);
+  },
+
   /*
    * Some helpers for the UI to try and move to the next state.
    */
 
   // Open a UI for the user to create a Firefox Account.  This should only be
   // called while we are in the STATE_USER_FXA state.  When the user completes
   // the creation we'll see an ONLOGIN_NOTIFICATION notification from FxA and
   // we'll move to either the STATE_USER_FXA_VERIFIED state or we'll just
@@ -333,16 +378,21 @@ Migrator.prototype = {
       this._applySentinelPrefs(sentinel.prefs);
     }
     // If we already have a sentinel then we assume the user has previously
     // created the specified account, so just ask to sign-in.
     let action = sentinel ? "signin" : "signup";
     // See if we can find a default account name to use.
     let email = yield this._getDefaultAccountName(sentinel);
     let tail = email ? "&email=" + encodeURIComponent(email) : "";
+    // We want to ask FxA to offer a "Customize Sync" checkbox iff any engines
+    // are disabled.
+    let customize = !this._allEnginesEnabled();
+    tail += "&customizeSync=" + customize;
+
     win.switchToTabHavingURI("about:accounts?" + action + tail, true,
                              {ignoreFragment: true, replaceQueryString: true});
     // An FxA observer will fire when the user completes this, which will
     // cause us to move to the next "user blocked" state and notify via our
     // observer notification.
   }),
 
   // Ask the FxA servers to re-send a verification mail for the currently
--- a/services/sync/tests/unit/test_fxa_migration.js
+++ b/services/sync/tests/unit/test_fxa_migration.js
@@ -85,27 +85,38 @@ function configureFxa() {
 }
 
 add_task(function *testMigration() {
   configureFxa();
 
   // when we do a .startOver we want the new provider.
   let oldValue = Services.prefs.getBoolPref("services.sync-testing.startOverKeepIdentity");
   Services.prefs.setBoolPref("services.sync-testing.startOverKeepIdentity", false);
+
+  // disable the addons engine - this engine choice is arbitrary, but we
+  // want to check it remains disabled after migration.
+  Services.prefs.setBoolPref("services.sync.engine.addons", false);
+
   do_register_cleanup(() => {
     Services.prefs.setBoolPref("services.sync-testing.startOverKeepIdentity", oldValue)
+    Services.prefs.setBoolPref("services.sync.engine.addons", true);
   });
 
   // No sync user - that should report no user-action necessary.
   Assert.deepEqual((yield fxaMigrator._queueCurrentUserState()), null,
                    "no user state when complete");
 
   // Arrange for a legacy sync user and manually bump the migrator
   let [engine, server] = configureLegacySync();
 
+  // Check our disabling of the "addons" engine worked, and for good measure,
+  // that the "passwords" engine is enabled.
+  Assert.ok(!Service.engineManager.get("addons").enabled, "addons is disabled");
+  Assert.ok(Service.engineManager.get("passwords").enabled, "passwords is enabled");
+
   // monkey-patch the migration sentinel code so we know it was called.
   let haveStartedSentinel = false;
   let origSetFxAMigrationSentinel = Service.setFxAMigrationSentinel;
   let promiseSentinelWritten = new Promise((resolve, reject) => {
     Service.setFxAMigrationSentinel = function(arg) {
       haveStartedSentinel = true;
       return origSetFxAMigrationSentinel.call(Service, arg).then(result => {
         Service.setFxAMigrationSentinel = origSetFxAMigrationSentinel;
@@ -244,16 +255,19 @@ add_task(function *testMigration() {
   Assert.ok(Service.identity instanceof BrowserIDManager,
             "sync is configured with the browserid_identity provider.");
   Assert.equal(Service.identity.username, config.username, "correct user configured")
   Assert.ok(!Service.scheduler.isBlocked, "sync is not blocked.")
   // and the user state should remain null.
   Assert.deepEqual((yield fxaMigrator._queueCurrentUserState()),
                    null,
                    "still no user action necessary");
+  // and our engines should be in the same enabled/disabled state as before.
+  Assert.ok(!Service.engineManager.get("addons").enabled, "addons is still disabled");
+  Assert.ok(Service.engineManager.get("passwords").enabled, "passwords is still enabled");
 
   // aaaand, we are done - clean up.
   yield promiseStopServer(server);
 });
 
 
 function run_test() {
   initTestLogging();