Bug 1296767 part 10 - Remove FxA Migration code. r?markh draft
authorEdouard Oger <eoger@fastmail.com>
Thu, 19 Jan 2017 13:03:38 -0500
changeset 467370 227eebd073abf6031570cffca234bc5b6536e5cc
parent 467369 54b01340514852b94662bb9b567bd5ff611e34ad
child 467371 4e3485eb0d831b3f43a04f955dc082a513b3dfb7
push id43155
push userbmo:eoger@fastmail.com
push dateFri, 27 Jan 2017 18:31:15 +0000
reviewersmarkh
bugs1296767
milestone54.0a1
Bug 1296767 part 10 - Remove FxA Migration code. r?markh MozReview-Commit-ID: DamrbblcMmZ
browser/base/content/browser-fxaccounts.js
browser/base/content/test/general/browser.ini
browser/base/content/test/general/browser_fxa_migrate.js
browser/base/content/test/general/browser_fxaccounts.js
browser/components/uitour/test/browser.ini
browser/components/uitour/test/browser_fxa.js
browser/locales/en-US/chrome/browser/accounts.properties
browser/themes/shared/customizableui/panelUI.inc.css
services/sync/Weave.js
services/sync/locales/en-US/sync.properties
services/sync/modules/FxaMigrator.jsm
services/sync/modules/service.js
services/sync/moz.build
tools/lint/eslint/modules.json
--- a/browser/base/content/browser-fxaccounts.js
+++ b/browser/base/content/browser-fxaccounts.js
@@ -1,16 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var gFxAccounts = {
 
-  SYNC_MIGRATION_NOTIFICATION_TITLE: "fxa-migration",
-
   _initialized: false,
   _inCustomizationMode: false,
 
   get weave() {
     delete this.weave;
     return this.weave = Cc["@mozilla.org/weave/service;1"]
                           .getService(Ci.nsISupports)
                           .wrappedJSObject;
@@ -20,17 +18,16 @@ var gFxAccounts = {
     // Do all this dance to lazy-load FxAccountsCommon.
     delete this.topics;
     return this.topics = [
       "weave:service:ready",
       "weave:service:login:change",
       "weave:service:setup-complete",
       "weave:service:sync:error",
       "weave:ui:login:error",
-      "fxa-migration:state-changed",
       this.FxAccountsCommon.ONLOGIN_NOTIFICATION,
       this.FxAccountsCommon.ONLOGOUT_NOTIFICATION,
       this.FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION,
     ];
   },
 
   get panelUIFooter() {
     delete this.panelUIFooter;
@@ -138,90 +135,32 @@ var gFxAccounts = {
       Services.obs.removeObserver(this, topic);
     }
 
     this._initialized = false;
   },
 
   observe(subject, topic, data) {
     switch (topic) {
-      case "fxa-migration:state-changed":
-        this.onMigrationStateChanged(data, subject);
-        break;
       case this.FxAccountsCommon.ONPROFILE_IMAGE_CHANGE_NOTIFICATION:
         this.updateUI();
         break;
       default:
         this.updateUI();
         break;
     }
   },
 
-  onMigrationStateChanged() {
-    // Since we nuked most of the migration code, this notification will fire
-    // once after legacy Sync has been disconnected (and should never fire
-    // again)
-    let nb = window.document.getElementById("global-notificationbox");
-
-    let msg = this.strings.GetStringFromName("autoDisconnectDescription")
-    let signInLabel = this.strings.GetStringFromName("autoDisconnectSignIn.label");
-    let signInAccessKey = this.strings.GetStringFromName("autoDisconnectSignIn.accessKey");
-    let learnMoreLink = this.fxaMigrator.learnMoreLink;
-
-    let buttons = [
-      {
-        label: signInLabel,
-        accessKey: signInAccessKey,
-        callback: () => {
-          this.openPreferences();
-        }
-      }
-    ];
-
-    let fragment = document.createDocumentFragment();
-    let msgNode = document.createTextNode(msg);
-    fragment.appendChild(msgNode);
-    if (learnMoreLink) {
-      let link = document.createElement("label");
-      link.className = "text-link";
-      link.setAttribute("value", learnMoreLink.text);
-      link.href = learnMoreLink.href;
-      fragment.appendChild(link);
-    }
-
-    nb.appendNotification(fragment,
-                          this.SYNC_MIGRATION_NOTIFICATION_TITLE,
-                          undefined,
-                          nb.PRIORITY_WARNING_LOW,
-                          buttons);
-
-    // ensure the hamburger menu reflects the newly disconnected state.
-    this.updateAppMenuItem();
+  handleEvent(event) {
+    this._inCustomizationMode = event.type == "customizationstarting";
+    this.updateUI();
   },
 
-  handleEvent(event) {
-    this._inCustomizationMode = event.type == "customizationstarting";
-    this.updateAppMenuItem();
-  },
-
+  // Note that updateUI() returns a Promise that's only used by tests.
   updateUI() {
-    // It's possible someone signed in to FxA after seeing our notification
-    // about "Legacy Sync migration" (which now is actually "Legacy Sync
-    // auto-disconnect") so kill that notification if it still exists.
-    let nb = window.document.getElementById("global-notificationbox");
-    let n = nb.getNotificationWithValue(this.SYNC_MIGRATION_NOTIFICATION_TITLE);
-    if (n) {
-      nb.removeNotification(n, true);
-    }
-
-    this.updateAppMenuItem();
-  },
-
-  // Note that updateAppMenuItem() returns a Promise that's only used by tests.
-  updateAppMenuItem() {
     let profileInfoEnabled = false;
     try {
       profileInfoEnabled = Services.prefs.getBoolPref("identity.fxaccounts.profile_image.enabled");
     } catch (e) { }
 
     // Bail out if FxA is disabled.
     if (!this.weave.fxAccountsEnabled) {
       return Promise.resolve();
@@ -472,13 +411,10 @@ var gFxAccounts = {
     .forEach(id => contextMenu.showItem(id, showSendLink));
   }
 };
 
 XPCOMUtils.defineLazyGetter(gFxAccounts, "FxAccountsCommon", function() {
   return Cu.import("resource://gre/modules/FxAccountsCommon.js", {});
 });
 
-XPCOMUtils.defineLazyModuleGetter(gFxAccounts, "fxaMigrator",
-  "resource://services-sync/FxaMigrator.jsm");
-
 XPCOMUtils.defineLazyModuleGetter(this, "EnsureFxAccountsWebChannel",
   "resource://gre/modules/FxAccountsWebChannel.jsm");
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -313,17 +313,16 @@ skip-if = true # browser_drag.js is disa
 [browser_favicon_change_not_in_document.js]
 [browser_findbarClose.js]
 [browser_focusonkeydown.js]
 [browser_fullscreen-window-open.js]
 tags = fullscreen
 skip-if = os == "linux" # Linux: Intermittent failures - bug 941575.
 [browser_fxaccounts.js]
 support-files = fxa_profile_handler.sjs
-[browser_fxa_migrate.js]
 [browser_fxa_web_channel.js]
 [browser_gestureSupport.js]
 skip-if = e10s # Bug 863514 - no gesture support.
 [browser_getshortcutoruri.js]
 [browser_hide_removing.js]
 [browser_homeDrop.js]
 [browser_identity_UI.js]
 [browser_insecureLoginForms.js]
deleted file mode 100644
--- a/browser/base/content/test/general/browser_fxa_migrate.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const STATE_CHANGED_TOPIC = "fxa-migration:state-changed";
-const NOTIFICATION_TITLE = "fxa-migration";
-
-var imports = {};
-Cu.import("resource://services-sync/FxaMigrator.jsm", imports);
-
-add_task(function* test() {
-  // Fake the state where we saw an EOL notification.
-  Services.obs.notifyObservers(null, STATE_CHANGED_TOPIC, null);
-
-  let notificationBox = document.getElementById("global-notificationbox");
-  Assert.ok(notificationBox.allNotifications.some(n => {
-    return n.getAttribute("value") == NOTIFICATION_TITLE;
-  }), "Disconnect notification should be present");
-});
--- a/browser/base/content/test/general/browser_fxaccounts.js
+++ b/browser/base/content/test/general/browser_fxaccounts.js
@@ -11,19 +11,19 @@ const TEST_ROOT = "http://example.com/br
 
 // instrument gFxAccounts to send observer notifications when it's done
 // what it does.
 (function() {
   let unstubs = {}; // The original functions we stub out.
 
   // The stub functions.
   let stubs = {
-    updateAppMenuItem() {
-      return unstubs["updateAppMenuItem"].call(gFxAccounts).then(() => {
-        Services.obs.notifyObservers(null, "test:browser_fxaccounts:updateAppMenuItem", null);
+    updateUI() {
+      return unstubs["updateUI"].call(gFxAccounts).then(() => {
+        Services.obs.notifyObservers(null, "test:browser_fxaccounts:updateUI", null);
       });
     },
     // Opening preferences is trickier than it should be as leaks are reported
     // due to the promises it fires off at load time  and there's no clear way to
     // know when they are done.
     // So just ensure openPreferences is called rather than whether it opens.
     openPreferences() {
       Services.obs.notifyObservers(null, "test:browser_fxaccounts:openPreferences", null);
@@ -67,17 +67,17 @@ add_task(function* initialize() {
 var panelUILabel = document.getElementById("PanelUI-fxa-label");
 var panelUIStatus = document.getElementById("PanelUI-fxa-status");
 var panelUIFooter = document.getElementById("PanelUI-footer-fxa");
 
 // The tests
 add_task(function* test_nouser() {
   let user = yield fxAccounts.getSignedInUser();
   Assert.strictEqual(user, null, "start with no user signed in");
-  let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateAppMenuItem");
+  let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateUI");
   Services.obs.notifyObservers(null, this.FxAccountsCommon.ONLOGOUT_NOTIFICATION, null);
   yield promiseUpdateDone;
 
   // Check the world - the FxA footer area is visible as it is offering a signin.
   Assert.ok(isFooterVisible())
 
   Assert.equal(panelUILabel.getAttribute("label"), panelUIStatus.getAttribute("defaultlabel"));
   Assert.equal(panelUIStatus.getAttribute("tooltiptext"), panelUIStatus.getAttribute("signedinTooltiptext"));
@@ -88,17 +88,17 @@ add_task(function* test_nouser() {
   panelUIStatus.click();
   yield promisePreferencesOpened;
 });
 
 /*
 XXX - Bug 1191162 - need a better hawk mock story or this will leak in debug builds.
 
 add_task(function* test_unverifiedUser() {
-  let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateAppMenuItem");
+  let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateUI");
   yield setSignedInUser(false); // this will fire the observer that does the update.
   yield promiseUpdateDone;
 
   // Check the world.
   Assert.ok(isFooterVisible())
 
   Assert.equal(panelUILabel.getAttribute("label"), "foo@example.com");
   Assert.equal(panelUIStatus.getAttribute("tooltiptext"),
@@ -107,20 +107,20 @@ add_task(function* test_unverifiedUser()
   let promisePreferencesOpened = promiseObserver("test:browser_fxaccounts:openPreferences");
   panelUIStatus.click();
   yield promisePreferencesOpened
   yield signOut();
 });
 */
 
 add_task(function* test_verifiedUserEmptyProfile() {
-  // We see 2 updateAppMenuItem() calls - one for the signedInUser and one after
+  // We see 2 updateUI() calls - one for the signedInUser and one after
   // we first fetch the profile. We want them both to fire or we aren't testing
   // the state we think we are testing.
-  let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateAppMenuItem", 2);
+  let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateUI", 2);
   configureProfileURL({}); // successful but empty profile.
   yield setSignedInUser(true); // this will fire the observer that does the update.
   yield promiseUpdateDone;
 
   // Check the world.
   Assert.ok(isFooterVisible())
   Assert.equal(panelUILabel.getAttribute("label"), "foo@example.com");
   Assert.equal(panelUIStatus.getAttribute("tooltiptext"),
@@ -129,32 +129,32 @@ add_task(function* test_verifiedUserEmpt
 
   let promisePreferencesOpened = promiseObserver("test:browser_fxaccounts:openPreferences");
   panelUIStatus.click();
   yield promisePreferencesOpened;
   yield signOut();
 });
 
 add_task(function* test_verifiedUserDisplayName() {
-  let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateAppMenuItem", 2);
+  let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateUI", 2);
   configureProfileURL({ displayName: "Test User Display Name" });
   yield setSignedInUser(true); // this will fire the observer that does the update.
   yield promiseUpdateDone;
 
   Assert.ok(isFooterVisible())
   Assert.equal(panelUILabel.getAttribute("label"), "Test User Display Name");
   Assert.equal(panelUIStatus.getAttribute("tooltiptext"),
                panelUIStatus.getAttribute("signedinTooltiptext"));
   Assert.equal(panelUIFooter.getAttribute("fxastatus"), "signedin");
   yield signOut();
 });
 
 add_task(function* test_verifiedUserProfileFailure() {
   // profile failure means only one observer fires.
-  let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateAppMenuItem", 1);
+  let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateUI", 1);
   configureProfileURL(null, 500);
   yield setSignedInUser(true); // this will fire the observer that does the update.
   yield promiseUpdateDone;
 
   Assert.ok(isFooterVisible())
   Assert.equal(panelUILabel.getAttribute("label"), "foo@example.com");
   Assert.equal(panelUIStatus.getAttribute("tooltiptext"),
                panelUIStatus.getAttribute("signedinTooltiptext"));
@@ -245,13 +245,13 @@ function setSignedInUser(verified) {
   }
   return fxAccounts.setSignedInUser(data);
 }
 
 var signOut = Task.async(function* () {
   // This test needs to make sure that any updates for the logout have
   // completed before starting the next test, or we see the observer
   // notifications get out of sync.
-  let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateAppMenuItem");
+  let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateUI");
   // we always want a "localOnly" signout here...
   yield fxAccounts.signOut(true);
   yield promiseUpdateDone;
 });
--- a/browser/components/uitour/test/browser.ini
+++ b/browser/components/uitour/test/browser.ini
@@ -3,17 +3,17 @@ support-files =
   head.js
   image.png
   uitour.html
   ../UITour-lib.js
 
 [browser_backgroundTab.js]
 [browser_closeTab.js]
 [browser_fxa.js]
-skip-if = debug || asan # updateAppMenuItem leaks
+skip-if = debug || asan # updateUI leaks
 [browser_no_tabs.js]
 [browser_openPreferences.js]
 [browser_openSearchPanel.js]
 skip-if = true # Bug 1113038 - Intermittent "Popup was opened"
 [browser_trackingProtection.js]
 skip-if = os == "linux" # Intermittent NS_ERROR_NOT_AVAILABLE [nsIUrlClassifierDBService.beginUpdate]
 tag = trackingprotection
 support-files =
--- a/browser/components/uitour/test/browser_fxa.js
+++ b/browser/components/uitour/test/browser_fxa.js
@@ -13,34 +13,34 @@ var gContentAPI;
 var gContentWindow;
 
 function test() {
   UITourTest();
 }
 
 registerCleanupFunction(function*() {
   yield signOut();
-  gFxAccounts.updateAppMenuItem();
+  gFxAccounts.updateUI();
 });
 
 var tests = [
   taskify(function* test_highlight_accountStatus_loggedOut() {
     let userData = yield fxAccounts.getSignedInUser();
     is(userData, null, "Not logged in initially");
     yield showMenuPromise("appMenu");
     yield showHighlightPromise("accountStatus");
     let highlight = document.getElementById("UITourHighlightContainer");
     is(highlight.getAttribute("targetName"), "accountStatus", "Correct highlight target");
   }),
 
   taskify(function* test_highlight_accountStatus_loggedIn() {
     yield setSignedInUser();
     let userData = yield fxAccounts.getSignedInUser();
     isnot(userData, null, "Logged in now");
-    gFxAccounts.updateAppMenuItem(); // Causes a leak
+    gFxAccounts.updateUI(); // Causes a leak (see bug 1332985)
     yield showMenuPromise("appMenu");
     yield showHighlightPromise("accountStatus");
     let highlight = document.getElementById("UITourHighlightContainer");
     is(highlight.popupBoxObject.anchorNode.id, "PanelUI-fxa-avatar", "Anchored on avatar");
     is(highlight.getAttribute("targetName"), "accountStatus", "Correct highlight target");
   }),
 ];
 
--- a/browser/locales/en-US/chrome/browser/accounts.properties
+++ b/browser/locales/en-US/chrome/browser/accounts.properties
@@ -1,20 +1,12 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-# autoDisconnectDescription is shown in an info bar when we detect an old
-# Sync is being used.
-autoDisconnectDescription = We’ve rebuilt Sync to make it easier for everyone.
-
-# autoDisconnectSignIn.label and .accessKey are for buttons when we auto-disconnect
-autoDisconnectSignIn.label = Sign in to Sync
-autoDisconnectSignIn.accessKey = S
-
 # LOCALIZATION NOTE (reconnectDescription) - %S = Email address of user's Firefox Account
 reconnectDescription = Reconnect %S
 
 # LOCALIZATION NOTE (verifyDescription) - %S = Email address of user's Firefox Account
 verifyDescription = Verify %S
 
 # These strings are shown in a desktop notification after the
 # user requests we resend a verification email.
--- a/browser/themes/shared/customizableui/panelUI.inc.css
+++ b/browser/themes/shared/customizableui/panelUI.inc.css
@@ -837,22 +837,16 @@ toolbarpaletteitem[place="palette"] > to
 #PanelUI-remotetabs-main[devices-status="single"] > #PanelUI-remotetabs-buttons {
   display: none;
 }
 
 #PanelUI-fxa-icon[syncstatus="active"]:not([disabled]) {
   list-style-image: url(chrome://browser/skin/syncProgress-horizontalbar.png);
 }
 
-#PanelUI-footer-fxa[fxastatus="migrate-signup"] > #PanelUI-fxa-status > #PanelUI-fxa-label,
-#PanelUI-footer-fxa[fxastatus="migrate-verify"] > #PanelUI-fxa-status > #PanelUI-fxa-label {
-  list-style-image: url(chrome://browser/skin/warning.svg);
-  -moz-image-region: auto;
-}
-
 #PanelUI-customize {
   list-style-image: url(chrome://browser/skin/menuPanel-customize.png);
 }
 
 #customization-panelHolder #PanelUI-customize {
   list-style-image: url(chrome://browser/skin/customizableui/menuPanel-customizeFinish.png);
 }
 
--- a/services/sync/Weave.js
+++ b/services/sync/Weave.js
@@ -67,21 +67,16 @@ function WeaveService() {
 }
 WeaveService.prototype = {
   classID: Components.ID("{74b89fb0-f200-4ae8-a3ec-dd164117f6de}"),
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                          Ci.nsISupportsWeakReference]),
 
   ensureLoaded() {
-    // If we are loaded and not using FxA, load the migration module.
-    if (!this.fxAccountsEnabled) {
-      Cu.import("resource://services-sync/FxaMigrator.jsm");
-    }
-
     Components.utils.import("resource://services-sync/main.js");
 
     // Side-effect of accessing the service is that it is instantiated.
     Weave.Service;
   },
 
   whenLoaded() {
     if (this.ready) {
--- a/services/sync/locales/en-US/sync.properties
+++ b/services/sync/locales/en-US/sync.properties
@@ -7,21 +7,10 @@ client.name2 = %1$S’s %2$S on %3$S
 
 # %S is the date and time at which the last sync successfully completed
 lastSync2.label = Last sync: %S
 
 # signInToSync.description is the tooltip for the Sync buttons when Sync is
 # not configured.
 signInToSync.description = Sign In To Sync
 
-error.sync.title = Error While Syncing
-error.sync.description = Sync encountered an error while syncing: %1$S.  Sync will automatically retry this action.
-warning.sync.eol.label = Service Shutting Down
-# %1: the app name (Firefox)
-warning.sync.eol.description = Your Firefox Sync service is shutting down soon. Upgrade %1$S to keep syncing.
-error.sync.eol.label = Service Unavailable
-# %1: the app name (Firefox)
-error.sync.eol.description = Your Firefox Sync service is no longer available. You need to upgrade %1$S to keep syncing.
-sync.eol.learnMore.label = Learn more
-sync.eol.learnMore.accesskey = L
-
 syncnow.label = Sync Now
 syncing2.label = Syncing…
deleted file mode 100644
--- a/services/sync/modules/FxaMigrator.jsm
+++ /dev/null
@@ -1,99 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict;"
-
-// Note that this module used to supervise the step-by-step migration from
-// a legacy Sync account to a FxA-based Sync account. In bug 1205928, this
-// changed to automatically disconnect the legacy Sync account.
-
-const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Log.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "WeaveService", function() {
-  return Cc["@mozilla.org/weave/service;1"]
-         .getService(Components.interfaces.nsISupports)
-         .wrappedJSObject;
-});
-
-XPCOMUtils.defineLazyModuleGetter(this, "Weave",
-  "resource://services-sync/main.js");
-
-// We send this notification when we perform the disconnection. The browser
-// window will show a one-off notification bar.
-const OBSERVER_STATE_CHANGE_TOPIC = "fxa-migration:state-changed";
-
-const OBSERVER_TOPICS = [
-  "xpcom-shutdown",
-  "weave:eol",
-];
-
-function Migrator() {
-  // Leave the log-level as Debug - Sync will setup log appenders such that
-  // these messages generally will not be seen unless other log related
-  // prefs are set.
-  this.log.level = Log.Level.Debug;
-
-  for (let topic of OBSERVER_TOPICS) {
-    Services.obs.addObserver(this, topic, false);
-  }
-}
-
-Migrator.prototype = {
-  log: Log.repository.getLogger("Sync.SyncMigration"),
-
-  finalize() {
-    for (let topic of OBSERVER_TOPICS) {
-      Services.obs.removeObserver(this, topic);
-    }
-  },
-
-  observe(subject, topic, data) {
-    this.log.debug("observed " + topic);
-    switch (topic) {
-      case "xpcom-shutdown":
-        this.finalize();
-        break;
-
-      default:
-        // this notification when configured with legacy Sync means we want to
-        // disconnect
-        if (!WeaveService.fxAccountsEnabled) {
-          this.log.info("Disconnecting from legacy Sync");
-          // Set up an observer for when the disconnection is complete.
-          let observe;
-          Services.obs.addObserver(observe = () => {
-            this.log.info("observed that startOver is complete");
-            Services.obs.removeObserver(observe, "weave:service:start-over:finish");
-            // Send the notification for the UI.
-            Services.obs.notifyObservers(null, OBSERVER_STATE_CHANGE_TOPIC, null);
-          }, "weave:service:start-over:finish", false);
-
-          // Do the disconnection.
-          Weave.Service.startOver();
-        }
-    }
-  },
-
-  get learnMoreLink() {
-    try {
-      var url = Services.prefs.getCharPref("app.support.baseURL");
-    } catch (err) {
-      return null;
-    }
-    url += "sync-upgrade";
-    let sb = Services.strings.createBundle("chrome://weave/locale/services/sync.properties");
-    return {
-      text: sb.GetStringFromName("sync.eol.learnMore.label"),
-      href: Services.urlFormatter.formatURL(url),
-    };
-  },
-};
-
-// We expose a singleton
-this.EXPORTED_SYMBOLS = ["fxaMigrator"];
-var fxaMigrator = new Migrator();
--- a/services/sync/modules/service.js
+++ b/services/sync/modules/service.js
@@ -828,19 +828,16 @@ Sync11Service.prototype = {
     this.clusterURL = null;
 
     Svc.Prefs.set("lastversion", WEAVE_VERSION);
 
     this.identity.deleteSyncCredentials();
 
     try {
       this.identity.finalize();
-      // an observer so the FxA migration code can take some action before
-      // the new identity is created.
-      Svc.Obs.notify("weave:service:start-over:init-identity");
       this.status.__authManager = null;
       this.identity = Status._authManager;
       this._clusterManager = this.identity.createClusterManager(this);
       Svc.Obs.notify("weave:service:start-over:finish");
     } catch (err) {
       this._log.error("startOver failed to re-initialize the identity manager: " + err);
       // Still send the observer notification so the current state is
       // reflected in the UI.
@@ -1191,102 +1188,16 @@ Sync11Service.prototype = {
     let res = this.resource(this.metaURL);
     let response = res.put(meta);
     if (!response.success) {
       throw response;
     }
     this.recordManager.set(this.metaURL, meta);
   },
 
-  /**
-   * Get a migration sentinel for the Firefox Accounts migration.
-   * Returns a JSON blob - it is up to callers of this to make sense of the
-   * data.
-   *
-   * Returns a promise that resolves with the sentinel, or null.
-   */
-  getFxAMigrationSentinel() {
-    if (this._shouldLogin()) {
-      this._log.debug("In getFxAMigrationSentinel: should login.");
-      if (!this.login()) {
-        this._log.debug("Can't get migration sentinel: login returned false.");
-        return Promise.resolve(null);
-      }
-    }
-    if (!this.identity.syncKeyBundle) {
-      this._log.error("Can't get migration sentinel: no syncKeyBundle.");
-      return Promise.resolve(null);
-    }
-    try {
-      let collectionURL = this.storageURL + "meta/fxa_credentials";
-      let cryptoWrapper = this.recordManager.get(collectionURL);
-      if (!cryptoWrapper || !cryptoWrapper.payload) {
-        // nothing to decrypt - .decrypt is noisy in that case, so just bail
-        // now.
-        return Promise.resolve(null);
-      }
-      // If the payload has a sentinel it means we must have put back the
-      // decrypted version last time we were called.
-      if (cryptoWrapper.payload.sentinel) {
-        return Promise.resolve(cryptoWrapper.payload.sentinel);
-      }
-      // If decryption fails it almost certainly means the key is wrong - but
-      // it's not clear if we need to take special action for that case?
-      let payload = cryptoWrapper.decrypt(this.identity.syncKeyBundle);
-      // After decrypting the ciphertext is lost, so we just stash the
-      // decrypted payload back into the wrapper.
-      cryptoWrapper.payload = payload;
-      return Promise.resolve(payload.sentinel);
-    } catch (ex) {
-      this._log.error("Failed to fetch the migration sentinel: ${}", ex);
-      return Promise.resolve(null);
-    }
-  },
-
-  /**
-   * Set a migration sentinel for the Firefox Accounts migration.
-   * Accepts a JSON blob - it is up to callers of this to make sense of the
-   * data.
-   *
-   * Returns a promise that resolves with a boolean which indicates if the
-   * sentinel was successfully written.
-   */
-  setFxAMigrationSentinel(sentinel) {
-    if (this._shouldLogin()) {
-      this._log.debug("In setFxAMigrationSentinel: should login.");
-      if (!this.login()) {
-        this._log.debug("Can't set migration sentinel: login returned false.");
-        return Promise.resolve(false);
-      }
-    }
-    if (!this.identity.syncKeyBundle) {
-      this._log.error("Can't set migration sentinel: no syncKeyBundle.");
-      return Promise.resolve(false);
-    }
-    try {
-      let collectionURL = this.storageURL + "meta/fxa_credentials";
-      let cryptoWrapper = new CryptoWrapper("meta", "fxa_credentials");
-      cryptoWrapper.cleartext.sentinel = sentinel;
-
-      cryptoWrapper.encrypt(this.identity.syncKeyBundle);
-
-      let res = this.resource(collectionURL);
-      let response = res.put(cryptoWrapper.toJSON());
-
-      if (!response.success) {
-        throw response;
-      }
-      this.recordManager.set(collectionURL, cryptoWrapper);
-    } catch (ex) {
-      this._log.error("Failed to set the migration sentinel: ${}", ex);
-      return Promise.resolve(false);
-    }
-    return Promise.resolve(true);
-  },
-
   _freshStart: function _freshStart() {
     this._log.info("Fresh start. Resetting client.");
     this.resetClient();
     this.collectionKeys.clear();
 
     // Wipe the server.
     this.wipeServer();
 
--- a/services/sync/moz.build
+++ b/services/sync/moz.build
@@ -18,17 +18,16 @@ EXTRA_COMPONENTS += [
 
 EXTRA_JS_MODULES['services-sync'] += [
     'modules/addonsreconciler.js',
     'modules/addonutils.js',
     'modules/bookmark_validator.js',
     'modules/browserid_identity.js',
     'modules/collection_validator.js',
     'modules/engines.js',
-    'modules/FxaMigrator.jsm',
     'modules/keys.js',
     'modules/main.js',
     'modules/policies.js',
     'modules/record.js',
     'modules/resource.js',
     'modules/rest.js',
     'modules/service.js',
     'modules/status.js',
--- a/tools/lint/eslint/modules.json
+++ b/tools/lint/eslint/modules.json
@@ -84,17 +84,16 @@
   "fxa_utils.js": ["initializeIdentityWithTokenServerResponse"],
   "fxaccounts.jsm": ["Authentication"],
   "FxAccounts.jsm": ["fxAccounts", "FxAccounts"],
   "FxAccountsOAuthGrantClient.jsm": ["FxAccountsOAuthGrantClient", "FxAccountsOAuthGrantClientError"],
   "FxAccountsProfileClient.jsm": ["FxAccountsProfileClient", "FxAccountsProfileClientError"],
   "FxAccountsPush.js": ["FxAccountsPushService"],
   "FxAccountsStorage.jsm": ["FxAccountsStorageManagerCanStoreField", "FxAccountsStorageManager"],
   "FxAccountsWebChannel.jsm": ["EnsureFxAccountsWebChannel"],
-  "FxaMigrator.jsm": ["fxaMigrator"],
   "gDevTools.jsm": ["gDevTools", "gDevToolsBrowser"],
   "gDevTools.jsm": ["gDevTools", "gDevToolsBrowser"],
   "Geometry.jsm": ["Point", "Rect"],
   "Gestures.jsm": ["GestureSettings", "GestureTracker"],
   "GMPInstallManager.jsm": ["GMPInstallManager", "GMPExtractor", "GMPDownloader", "GMPAddon"],
   "GMPProvider.jsm": [],
   "GMPUtils.jsm": ["GMP_PLUGIN_IDS", "GMPPrefs", "GMPUtils", "OPEN_H264_ID", "WIDEVINE_ID"],
   "hawkclient.js": ["HawkClient"],