Bug 1361286 - add in-page messages support for Automigration module; r=Gijs
authorgasolin <gasolin@gmail.com>
Wed, 24 May 2017 16:56:00 +0800
changeset 409619 169bd90857808c38bd675e612a6c2a35ffd6522a
parent 409618 283ed0ad8bf47dff3bc1e62caedb37dd2a91c0a5
child 409620 8f2b4efc5f0d3191a7e80d9324933621e111b44a
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs
bugs1361286
milestone55.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 1361286 - add in-page messages support for Automigration module; r=Gijs MozReview-Commit-ID: I4xK2PkuHp3
browser/app/profile/firefox.js
browser/base/content/newtab/page.js
browser/base/content/tab-content.js
browser/components/migration/AutoMigrate.jsm
browser/components/migration/MigrationUtils.jsm
browser/components/nsBrowserGlue.js
browser/locales/en-US/chrome/browser/migration/migration.properties
browser/modules/AboutHome.jsm
browser/modules/AboutNewTab.jsm
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1599,16 +1599,17 @@ pref("dom.ipc.processPrelaunch.enabled",
 pref("browser.migrate.automigrate.enabled", true);
 #else
 pref("browser.migrate.automigrate.enabled", false);
 #endif
 // 4 here means the suggestion notification will be automatically
 // hidden the 4th day, so it will actually be shown on 3 different days.
 pref("browser.migrate.automigrate.daysToOfferUndo", 4);
 pref("browser.migrate.automigrate.ui.enabled", true);
+pref("browser.migrate.automigrate.inpage.ui.enabled", false);
 
 // See comments in bug 1340115 on how we got to these numbers.
 pref("browser.migrate.chrome.history.limit", 2000);
 pref("browser.migrate.chrome.history.maxAgeInDays", 180);
 
 // Enable browser frames for use on desktop.  Only exposed to chrome callers.
 pref("dom.mozBrowserFramesEnabled", true);
 
--- a/browser/base/content/newtab/page.js
+++ b/browser/base/content/newtab/page.js
@@ -246,15 +246,11 @@ var gPage = {
       this.onPageVisibleAndLoaded();
     } else {
       addEventListener("load", this);
     }
   },
 
   onPageVisibleAndLoaded() {
     // Maybe tell the user they can undo an initial automigration
-    this.maybeShowAutoMigrationUndoNotification();
-  },
-
-  maybeShowAutoMigrationUndoNotification() {
-    sendAsyncMessage("NewTab:MaybeShowAutoMigrationUndoNotification");
+    sendAsyncMessage("NewTab:MaybeShowMigrateMessage");
   },
 };
--- a/browser/base/content/tab-content.js
+++ b/browser/base/content/tab-content.js
@@ -155,17 +155,17 @@ var AboutHomeListener = {
     docElt.setAttribute("snippetsVersion", aData.snippetsVersion);
   },
 
   onPageLoad() {
     addMessageListener("AboutHome:Update", this);
     addEventListener("click", this, true);
     addEventListener("pagehide", this, true);
 
-    sendAsyncMessage("AboutHome:MaybeShowAutoMigrationUndoNotification");
+    sendAsyncMessage("AboutHome:MaybeShowMigrateMessage");
     sendAsyncMessage("AboutHome:RequestUpdate");
   },
 
   onClick(aEvent) {
     if (!aEvent.isTrusted || // Don't trust synthetic events
         aEvent.button == 2 || aEvent.target.localName != "button") {
       return;
     }
--- a/browser/components/migration/AutoMigrate.jsm
+++ b/browser/components/migration/AutoMigrate.jsm
@@ -6,31 +6,34 @@
 
 this.EXPORTED_SYMBOLS = ["AutoMigrate"];
 
 const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
 
 const kAutoMigrateEnabledPref = "browser.migrate.automigrate.enabled";
 const kUndoUIEnabledPref = "browser.migrate.automigrate.ui.enabled";
 
+const kInPageUIEnabledPref = "browser.migrate.automigrate.inpage.ui.enabled";
+
 const kAutoMigrateBrowserPref = "browser.migrate.automigrate.browser";
 const kAutoMigrateImportedItemIds = "browser.migrate.automigrate.imported-items";
 
 const kAutoMigrateLastUndoPromptDateMsPref = "browser.migrate.automigrate.lastUndoPromptDateMs";
 const kAutoMigrateDaysToOfferUndoPref = "browser.migrate.automigrate.daysToOfferUndo";
 
 const kAutoMigrateUndoSurveyPref = "browser.migrate.automigrate.undo-survey";
 const kAutoMigrateUndoSurveyLocalePref = "browser.migrate.automigrate.undo-survey-locales";
 
 const kNotificationId = "automigration-undo";
 
 Cu.import("resource:///modules/MigrationUtils.jsm");
 Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
 XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown",
                                   "resource://gre/modules/AsyncShutdown.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",
                                   "resource://gre/modules/LoginHelper.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils",
                                   "resource://gre/modules/NewTabUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OS",
                                   "resource://gre/modules/osfile.jsm");
@@ -309,102 +312,125 @@ const AutoMigrate = {
     let browserId = Services.prefs.getCharPref(kAutoMigrateBrowserPref);
     if (browserId) {
       return MigrationUtils.getBrowserName(browserId);
     }
     return null;
   },
 
   /**
-   * Show the user a notification bar indicating we automatically imported
-   * their data and offering them the possibility of removing it.
+   * Decide if we need to show [the user] a prompt indicating we automatically
+   * imported their data.
    * @param target (xul:browser)
    *        The browser in which we should show the notification.
+   * @returns {Boolean} return true when need to show the prompt.
    */
-  async maybeShowUndoNotification(target) {
+  async shouldShowMigratePrompt(target) {
     if (!(await this.canUndo())) {
-      return;
+      return false;
     }
 
     // The tab might have navigated since we requested the undo state:
     let canUndoFromThisPage = ["about:home", "about:newtab"].includes(target.currentURI.spec);
     if (!canUndoFromThisPage ||
         !Preferences.get(kUndoUIEnabledPref, false)) {
-      return;
-    }
-
-    let win = target.ownerGlobal;
-    let notificationBox = win.gBrowser.getNotificationBox(target);
-    if (!notificationBox || notificationBox.getNotificationWithValue(kNotificationId)) {
-      return;
+      return false;
     }
 
     // At this stage we're committed to show the prompt - unless we shouldn't,
     // in which case we remove the undo prefs (which will cause canUndo() to
     // return false from now on.):
-    if (!this.shouldStillShowUndoPrompt()) {
+    if (this.isMigratePromptExpired()) {
       this._purgeUndoState(this.UNDO_REMOVED_REASON_OFFER_EXPIRED);
       this._removeNotificationBars();
-      return;
+      return false;
     }
 
+    let remainingDays = Preferences.get(kAutoMigrateDaysToOfferUndoPref, 0);
+    Services.telemetry.getHistogramById("FX_STARTUP_MIGRATION_UNDO_OFFERED").add(4 - remainingDays);
+
+    return true;
+  },
+
+  /**
+   * Return the message that denotes the user data is migrated from the other browser.
+   * @returns {String} imported message with the brand and the browser name
+   */
+  getUndoMigrationMessage() {
     let browserName = this.getBrowserUsedForMigration();
     if (!browserName) {
       browserName = MigrationUtils.getLocalizedString("automigration.undo.unknownbrowser");
     }
-    const kMessageId = "automigration.undo.message." +
+    const kMessageId = "automigration.undo.message2." +
                       Preferences.get(kAutoMigrateImportedItemIds, "all");
     const kBrandShortName = gBrandBundle.GetStringFromName("brandShortName");
-    let message = MigrationUtils.getLocalizedString(kMessageId,
-                                                    [browserName, kBrandShortName]);
+    return MigrationUtils.getLocalizedString(kMessageId,
+                                             [kBrandShortName, browserName]);
+  },
 
+  /**
+   * Show the user a notification bar indicating we automatically imported
+   * their data and offering them the possibility of removing it.
+   * @param target (xul:browser)
+   *        The browser in which we should show the notification.
+   */
+  showUndoNotificationBar(target) {
+    let isInPage = Preferences.get(kInPageUIEnabledPref, false);
+    let win = target.ownerGlobal;
+    let notificationBox = win.gBrowser.getNotificationBox(target);
+    if (isInPage || !notificationBox || notificationBox.getNotificationWithValue(kNotificationId)) {
+      return;
+    }
+    let message = this.getUndoMigrationMessage();
     let buttons = [
       {
         label: MigrationUtils.getLocalizedString("automigration.undo.keep2.label"),
         accessKey: MigrationUtils.getLocalizedString("automigration.undo.keep2.accesskey"),
         callback: () => {
-          this._purgeUndoState(this.UNDO_REMOVED_REASON_OFFER_REJECTED);
+          this.keepAutoMigration();
           this._removeNotificationBars();
         },
       },
       {
         label: MigrationUtils.getLocalizedString("automigration.undo.dontkeep2.label"),
         accessKey: MigrationUtils.getLocalizedString("automigration.undo.dontkeep2.accesskey"),
         callback: () => {
-          this._maybeOpenUndoSurveyTab(win);
-          this.undo();
+          this.undoAutoMigration(win);
         },
       },
     ];
     notificationBox.appendNotification(
       message, kNotificationId, null, notificationBox.PRIORITY_INFO_HIGH, buttons
     );
-    let remainingDays = Preferences.get(kAutoMigrateDaysToOfferUndoPref, 0);
-    Services.telemetry.getHistogramById("FX_STARTUP_MIGRATION_UNDO_OFFERED").add(4 - remainingDays);
   },
 
-  shouldStillShowUndoPrompt() {
+
+  /**
+   * Return true if we have shown the prompt to user several days.
+   * (defined in kAutoMigrateDaysToOfferUndoPref)
+   */
+  isMigratePromptExpired() {
     let today = new Date();
     // Round down to midnight:
     today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
     // We store the unix timestamp corresponding to midnight on the last day
     // on which we prompted. Fetch that and compare it to today's date.
     // (NB: stored as a string because int prefs are too small for unix
     // timestamps.)
     let previousPromptDateMsStr = Preferences.get(kAutoMigrateLastUndoPromptDateMsPref, "0");
     let previousPromptDate = new Date(parseInt(previousPromptDateMsStr, 10));
     if (previousPromptDate < today) {
       let remainingDays = Preferences.get(kAutoMigrateDaysToOfferUndoPref, 4) - 1;
       Preferences.set(kAutoMigrateDaysToOfferUndoPref, remainingDays);
       Preferences.set(kAutoMigrateLastUndoPromptDateMsPref, today.valueOf().toString());
       if (remainingDays <= 0) {
-        return false;
+        return true;
       }
     }
-    return true;
+    return false;
   },
 
   UNDO_REMOVED_REASON_UNDO_USED: 0,
   UNDO_REMOVED_REASON_SYNC_SIGNIN: 1,
   UNDO_REMOVED_REASON_PASSWORD_CHANGE: 2,
   UNDO_REMOVED_REASON_BOOKMARK_CHANGE: 3,
   UNDO_REMOVED_REASON_OFFER_EXPIRED: 4,
   UNDO_REMOVED_REASON_OFFER_REJECTED: 5,
@@ -651,11 +677,27 @@ const AutoMigrate = {
     let url = Services.urlFormatter.formatURL(rawURL);
     url = url.replace("%IMPORTEDBROWSER%", encodeURIComponent(migrationBrowser));
     chromeWindow.openUILinkIn(url, "tab");
   },
 
   QueryInterface: XPCOMUtils.generateQI(
     [Ci.nsIObserver, Ci.nsINavBookmarkObserver, Ci.nsISupportsWeakReference]
   ),
+
+  /**
+   * Undo action called by the UndoNotification or by the newtab
+   * @param chromeWindow A reference to the window in which to open a link.
+   */
+  undoAutoMigration(chromeWindow) {
+    this._maybeOpenUndoSurveyTab(chromeWindow);
+    this.undo();
+  },
+
+  /**
+   * Keep the automigration result and not prompt anymore
+   */
+  keepAutoMigration() {
+    this._purgeUndoState(this.UNDO_REMOVED_REASON_OFFER_REJECTED);
+  },
 };
 
 AutoMigrate.init();
--- a/browser/components/migration/MigrationUtils.jsm
+++ b/browser/components/migration/MigrationUtils.jsm
@@ -1105,16 +1105,17 @@ this.MigrationUtils = Object.freeze({
 
   gAvailableMigratorKeys,
 
   MIGRATION_ENTRYPOINT_UNKNOWN: 0,
   MIGRATION_ENTRYPOINT_FIRSTRUN: 1,
   MIGRATION_ENTRYPOINT_FXREFRESH: 2,
   MIGRATION_ENTRYPOINT_PLACES: 3,
   MIGRATION_ENTRYPOINT_PASSWORDS: 4,
+  MIGRATION_ENTRYPOINT_NEWTAB: 5,
 
   _sourceNameToIdMapping: {
     "nothing":    1,
     "firefox":    2,
     "edge":       3,
     "ie":         4,
     "chrome":     5,
     "chromium":   6,
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -144,17 +144,17 @@ const listeners = {
     // PLEASE KEEP THIS LIST IN SYNC WITH THE LISTENERS ADDED IN ContentPrefServiceParent.init
     "FeedConverter:addLiveBookmark": ["Feeds"],
     "WCCR:setAutoHandler": ["Feeds"],
     "webrtc:UpdateGlobalIndicators": ["webrtcUI"],
     "webrtc:UpdatingIndicators": ["webrtcUI"],
   },
 
   mm: {
-    "AboutHome:MaybeShowAutoMigrationUndoNotification": ["AboutHome"],
+    "AboutHome:MaybeShowMigrateMessage": ["AboutHome"],
     "AboutHome:RequestUpdate": ["AboutHome"],
     "Content:Click": ["ContentClick"],
     "ContentSearch": ["ContentSearch"],
     "FormValidation:ShowPopup": ["FormValidationHandler"],
     "FormValidation:HidePopup": ["FormValidationHandler"],
     "Prompt:Open": ["RemotePrompt"],
     "Reader:ArticleGet": ["ReaderParent"],
     "Reader:FaviconRequest": ["ReaderParent"],
--- a/browser/locales/en-US/chrome/browser/migration/migration.properties
+++ b/browser/locales/en-US/chrome/browser/migration/migration.properties
@@ -67,21 +67,21 @@ 64_edge=Other Data
 64_safari=Other Data
 64_chrome=Other Data
 64_firefox_other=Other Data
 64_360se=Other Data
 
 128_firefox=Windows and Tabs
 
 # Automigration undo notification.
-# %1$S will be replaced with the name of the browser we imported from, %2$S will be replaced with brandShortName
-automigration.undo.message.all              = Pick up where you left off. We’ve imported these sites and your bookmarks, history and passwords from %1$S into %2$S.
-automigration.undo.message.bookmarks        = Pick up where you left off. We’ve imported these sites and your bookmarks from %1$S into %2$S.
-automigration.undo.message.bookmarks.logins = Pick up where you left off. We’ve imported these sites and your bookmarks and passwords from %1$S into %2$S.
-automigration.undo.message.bookmarks.visits = Pick up where you left off. We’ve imported these sites and your bookmarks and history from %1$S into %2$S.
-automigration.undo.message.logins           = Pick up where you left off. We’ve imported your passwords from %1$S into %2$S.
-automigration.undo.message.logins.visits    = Pick up where you left off. We’ve imported these sites and your history and passwords from %1$S into %2$S.
-automigration.undo.message.visits           = Pick up where you left off. We’ve imported these sites and your history from %1$S into %2$S.
+# %1$S will be replaced with brandShortName, %2$S will be replaced with the name of the browser we imported from
+automigration.undo.message2.all              = Dive right into %1$S! Import your favorite sites, bookmarks, history and passwords from %2$S.
+automigration.undo.message2.bookmarks        = Dive right into %1$S! Import your favorite sites and bookmarks from %2$S.
+automigration.undo.message2.bookmarks.logins = Dive right into %1$S! Import your favorite sites, bookmarks and passwords from %2$S.
+automigration.undo.message2.bookmarks.visits = Dive right into %1$S! Import your favorite sites, bookmarks and history from %2$S.
+automigration.undo.message2.logins           = Dive right into %1$S! Import your passwords from %2$S.
+automigration.undo.message2.logins.visits    = Dive right into %1$S! Import your favorite sites, history and passwords from %2$S.
+automigration.undo.message2.visits           = Dive right into %1$S! Import your favorite sites and history from %2$S.
 automigration.undo.keep2.label            = OK, Got it
 automigration.undo.keep2.accesskey        = O
 automigration.undo.dontkeep2.label        = No Thanks
 automigration.undo.dontkeep2.accesskey    = N
 automigration.undo.unknownbrowser         = Unknown Browser
--- a/browser/modules/AboutHome.jsm
+++ b/browser/modules/AboutHome.jsm
@@ -5,18 +5,18 @@
 "use strict";
 
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 var Cu = Components.utils;
 
 this.EXPORTED_SYMBOLS = [ "AboutHomeUtils", "AboutHome" ];
 
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
   "resource://gre/modules/AppConstants.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AutoMigrate",
   "resource:///modules/AutoMigrate.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
   "resource://gre/modules/FxAccounts.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
@@ -144,18 +144,22 @@ var AboutHome = {
       case "AboutHome:Settings":
         window.openPreferences(undefined, {origin: "aboutHome"} );
         break;
 
       case "AboutHome:RequestUpdate":
         this.sendAboutHomeData(aMessage.target);
         break;
 
-      case "AboutHome:MaybeShowAutoMigrationUndoNotification":
-        AutoMigrate.maybeShowUndoNotification(aMessage.target);
+      case "AboutHome:MaybeShowMigrateMessage":
+        AutoMigrate.shouldShowMigratePrompt(aMessage.target).then((prompt) => {
+          if (prompt) {
+            AutoMigrate.showUndoNotificationBar(aMessage.target);
+          }
+        });
         break;
     }
   },
 
   // Send all the chrome-privileged data needed by about:home. This
   // gets re-sent when the search engine changes.
   sendAboutHomeData(target) {
     let wrapper = {};
--- a/browser/modules/AboutNewTab.jsm
+++ b/browser/modules/AboutNewTab.jsm
@@ -27,18 +27,26 @@ var AboutNewTab = {
   isOverridden: false,
 
   init() {
     if (this.isOverridden) {
       return;
     }
     this.pageListener = new RemotePages("about:newtab");
     this.pageListener.addMessageListener("NewTab:Customize", this.customize.bind(this));
-    this.pageListener.addMessageListener("NewTab:MaybeShowAutoMigrationUndoNotification",
-      (msg) => AutoMigrate.maybeShowUndoNotification(msg.target.browser));
+    this.pageListener.addMessageListener("NewTab:MaybeShowMigrateMessage",
+      this.maybeShowMigrateMessage.bind(this));
+  },
+
+  maybeShowMigrateMessage({ target }) {
+    AutoMigrate.shouldShowMigratePrompt(target.browser).then((prompt) => {
+      if (prompt) {
+        AutoMigrate.showUndoNotificationBar(target.browser);
+      }
+    });
   },
 
   customize(message) {
     NewTabUtils.allPages.enabled = message.data.enabled;
     NewTabUtils.allPages.enhanced = message.data.enhanced;
   },
 
   uninit() {