Bug 1357027 - Should mark the Firefox Sync tour as completed if user sign-in a Firefox Account. r=mossop, florian draft
authorRex Lee <rexboy@mozilla.com>
Mon, 10 Jul 2017 14:10:03 +0800
changeset 612150 e888f9363d93a668cc82b15673ec7b3dc6e69abf
parent 612110 0985725c848ec0cfc6f2f3c3a5aa3d71321e7620
child 638325 466695d54235f9c7fa00283d63226358f354285e
push id69399
push userbmo:rexboy@mozilla.com
push dateThu, 20 Jul 2017 11:09:19 +0000
reviewersmossop, florian
bugs1357027
milestone56.0a1
Bug 1357027 - Should mark the Firefox Sync tour as completed if user sign-in a Firefox Account. r=mossop, florian 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"
 ];
@@ -64,16 +65,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);
@@ -82,33 +131,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();
 }