Bug 1357027 - Should mark the Firefox Sync tour as completed if user sign-in a Firefox Account. r=florian,mossop
authorRex Lee <rexboy@mozilla.com>
Mon, 10 Jul 2017 14:10:03 +0800
changeset 418625 aeb68364f85ee9ecdc28e57cdda0d9a87c94c535
parent 418624 6b2a40d10b494067c8eb11dfe94c913d6327ff78
child 418626 e9b1c60ebd4fa7689e2f4439d32e47bd9e804fc8
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflorian, mossop
bugs1357027
milestone56.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 1357027 - Should mark the Firefox Sync tour as completed if user sign-in a Firefox Account. r=florian,mossop MozReview-Commit-ID: 3giuXdqjJc3
browser/extensions/onboarding/bootstrap.js
--- a/browser/extensions/onboarding/bootstrap.js
+++ b/browser/extensions/onboarding/bootstrap.js
@@ -8,20 +8,21 @@
 const {utils: Cu} = Components;
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OnboardingTourType",
   "resource://onboarding/modules/OnboardingTourType.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
   "resource://gre/modules/Preferences.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
   "resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "setTimeout",
-  "resource://gre/modules/Timer.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
+  "resource://gre/modules/FxAccounts.jsm");
 
-const BROWSER_READY_NOTIFICATION = "final-ui-startup";
+const BROWSER_READY_NOTIFICATION = "browser-delayed-startup-finished";
+const BROWSER_SESSION_STORE_NOTIFICATION = "sessionstore-windows-restored";
 const PREF_WHITELIST = [
   "browser.onboarding.enabled",
   "browser.onboarding.hidden",
   "browser.onboarding.notification.finished",
   "browser.onboarding.notification.prompt-count",
   "browser.onboarding.notification.last-time-of-changing-tour-sec",
   "browser.onboarding.notification.tour-ids-queue"
 ];
@@ -66,16 +67,64 @@ function initContentMessageListener() {
     switch (msg.data.action) {
       case "set-prefs":
         setPrefs(msg.data.params);
         break;
     }
   });
 }
 
+let syncTourChecker = {
+  registered: false,
+
+  observe() {
+    this.setComplete();
+  },
+
+  init() {
+    if (Services.prefs.getBoolPref("browser.onboarding.tour.onboarding-tour-sync.completed", false)) {
+      return;
+    }
+    // Check if we've already logged in at startup.
+    fxAccounts.getSignedInUser().then(user => {
+      if (user) {
+        this.setComplete();
+        return;
+      }
+      // Observe for login action if we haven't logged in yet.
+      this.register();
+    });
+  },
+
+  register() {
+    if (this.registered) {
+      return;
+    }
+    Services.obs.addObserver(this, "fxaccounts:onverified");
+    this.registered = true;
+  },
+
+  setComplete() {
+    Services.prefs.setBoolPref("browser.onboarding.tour.onboarding-tour-sync.completed", true);
+    this.unregister();
+  },
+
+  unregister() {
+    if (!this.registered) {
+      return;
+    }
+    Services.obs.removeObserver(this, "fxaccounts:onverified");
+    this.registered = false;
+  },
+
+  uninit() {
+    this.unregister();
+  },
+}
+
 /**
  * onBrowserReady - Continues startup of the add-on after browser is ready.
  */
 function onBrowserReady() {
   waitingForBrowserReady = false;
 
   OnboardingTourType.check();
   Services.mm.loadFrameScript("resource://onboarding/onboarding.js", true);
@@ -84,33 +133,43 @@ function onBrowserReady() {
 
 /**
  * observe - nsIObserver callback to handle various browser notifications.
  */
 function observe(subject, topic, data) {
   switch (topic) {
     case BROWSER_READY_NOTIFICATION:
       Services.obs.removeObserver(observe, BROWSER_READY_NOTIFICATION);
-      // Avoid running synchronously during this event that's used for timing
-      setTimeout(() => onBrowserReady());
+      onBrowserReady();
+      break;
+    case BROWSER_SESSION_STORE_NOTIFICATION:
+      Services.obs.removeObserver(observe, BROWSER_SESSION_STORE_NOTIFICATION);
+      // Postpone Firefox account checking until "before handling user events"
+      // phase to meet performance criteria. The reason we don't postpone the
+      // whole onBrowserReady here is because in that way we will miss onload
+      // events for onboarding.js.
+      Services.tm.idleDispatchToMainThread(() => syncTourChecker.init());
       break;
   }
 }
 
 function install(aData, aReason) {}
 
 function uninstall(aData, aReason) {}
 
 function startup(aData, aReason) {
   // Only start Onboarding when the browser UI is ready
   if (aReason === APP_STARTUP || aReason === ADDON_INSTALL) {
     Services.obs.addObserver(observe, BROWSER_READY_NOTIFICATION);
+    Services.obs.addObserver(observe, BROWSER_SESSION_STORE_NOTIFICATION);
   } else {
     onBrowserReady();
+    syncTourChecker.init();
   }
 }
 
 function shutdown(aData, aReason) {
   // Stop waiting for browser to be ready
   if (waitingForBrowserReady) {
     Services.obs.removeObserver(observe, BROWSER_READY_NOTIFICATION);
   }
+  syncTourChecker.uninit();
 }