Bug 1131414 (part 2) - add the reading-list engine to Sync prefs. r=adw a=readinglist
authorMark Hammond <mhammond@skippinet.com.au>
Fri, 20 Mar 2015 11:08:51 -0700
changeset 258062 395fa1ecf377e8f736312f2d1961094e58534632
parent 258061 bf356118c79edd721906d013977d475bb6d01a5b
child 258063 b0e7f69c3590c883b733d0c6a0d4acd6dcfcd380
push id4610
push userjlund@mozilla.com
push dateMon, 30 Mar 2015 18:32:55 +0000
treeherdermozilla-beta@4df54044d9ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersadw, readinglist
bugs1131414
milestone38.0a2
Bug 1131414 (part 2) - add the reading-list engine to Sync prefs. r=adw a=readinglist
browser/app/profile/firefox.js
browser/base/content/sync/customize.js
browser/base/content/sync/customize.xul
browser/components/preferences/in-content/sync.js
browser/components/preferences/in-content/sync.xul
browser/components/preferences/sync.js
browser/components/preferences/sync.xul
browser/components/readinglist/Scheduler.jsm
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1882,10 +1882,12 @@ pref("dom.ipc.reportProcessHangs", false
 pref("dom.ipc.reportProcessHangs", true);
 #endif
 
 #ifndef NIGHTLY_BUILD
 // Disable reader mode by default.
 pref("reader.parse-on-load.enabled", false);
 #endif
 
-// Disable ReadingList by default.
+// Disable ReadingList browser UI by default.
 pref("browser.readinglist.enabled", false);
+// Enable the readinglist engine by default.
+pref("readinglist.scheduler.enabled", true);
--- a/browser/base/content/sync/customize.js
+++ b/browser/base/content/sync/customize.js
@@ -1,11 +1,34 @@
 /* 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";
 
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+addEventListener("load", function () {
+  // unhide the reading-list engine if readinglist is enabled (note this
+  // dialog is only used with FxA sync, so no special action is needed
+  // for legacy sync.)
+  if (Services.prefs.getBoolPref("browser.readinglist.enabled")) {
+    document.getElementById("readinglist-engine").removeAttribute("hidden");
+  }
+});
+
 addEventListener("dialogaccept", function () {
   let pane = document.getElementById("sync-customize-pane");
+  // First determine what the preference for the "global" sync enabled pref
+  // should be based on the engines selected.
+  let prefElts = pane.querySelectorAll("preferences > preference");
+  let syncEnabled = false;
+  for (let elt of prefElts) {
+    if (elt.name.startsWith("services.sync.") && elt.value) {
+      syncEnabled = true;
+      break;
+    }
+  }
+  Services.prefs.setBoolPref("services.sync.enabled", syncEnabled);
+  // and write the individual prefs.
   pane.writePreferences(true);
   window.arguments[0].accepted = true;
 });
--- a/browser/base/content/sync/customize.xul
+++ b/browser/base/content/sync/customize.xul
@@ -22,16 +22,18 @@
   <prefpane id="sync-customize-pane">
     <preferences>
       <preference id="engine.bookmarks" name="services.sync.engine.bookmarks" type="bool"/>
       <preference id="engine.history"   name="services.sync.engine.history"   type="bool"/>
       <preference id="engine.tabs"      name="services.sync.engine.tabs"      type="bool"/>
       <preference id="engine.passwords" name="services.sync.engine.passwords" type="bool"/>
       <preference id="engine.addons"    name="services.sync.engine.addons"    type="bool"/>
       <preference id="engine.prefs"     name="services.sync.engine.prefs"     type="bool"/>
+      <!-- non Sync-Engine engines -->
+      <preference id="engine.readinglist" name="readinglist.scheduler.enabled" type="bool"/>
     </preferences>
 
     <label id="sync-customize-title" value="&syncCustomize.title;"/>
     <description id="sync-customize-subtitle"
 #ifdef XP_UNIX
                  value="&syncCustomizeUnix.description;"
 #else
                  value="&syncCustomize.description;"
@@ -46,16 +48,21 @@
                 accesskey="&engine.bookmarks.accesskey;"
                 preference="engine.bookmarks"/>
       <checkbox label="&engine.passwords.label;"
                 accesskey="&engine.passwords.accesskey;"
                 preference="engine.passwords"/>
       <checkbox label="&engine.history.label;"
                 accesskey="&engine.history.accesskey;"
                 preference="engine.history"/>
+      <checkbox id="readinglist-engine"
+                label="&engine.readinglist.label;"
+                accesskey="&engine.readinglist.accesskey;"
+                preference="engine.readinglist"
+                hidden="true"/>
       <checkbox label="&engine.addons.label;"
                 accesskey="&engine.addons.accesskey;"
                 preference="engine.addons"/>
       <checkbox label="&engine.prefs.label;"
                 accesskey="&engine.prefs.accesskey;"
                 preference="engine.prefs"/>
   </vbox>
 
--- a/browser/components/preferences/in-content/sync.js
+++ b/browser/components/preferences/in-content/sync.js
@@ -232,16 +232,21 @@ let gSyncPane = {
     Services.obs.notifyObservers(null, "fxa-migration:state-request", null);
 
     let service = Components.classes["@mozilla.org/weave/service;1"]
                   .getService(Components.interfaces.nsISupports)
                   .wrappedJSObject;
     // service.fxAccountsEnabled is false iff sync is already configured for
     // the legacy provider.
     if (service.fxAccountsEnabled) {
+      // unhide the reading-list engine if readinglist is enabled (note we do
+      // it here as it must remain disabled for legacy sync users)
+      if (Services.prefs.getBoolPref("browser.readinglist.enabled")) {
+        document.getElementById("readinglist-engine").removeAttribute("hidden");
+      }
       // determine the fxa status...
       this.page = PAGE_PLEASE_WAIT;
       fxAccounts.getSignedInUser().then(data => {
         if (!data) {
           this.page = FXA_PAGE_LOGGED_OUT;
           return;
         }
         this.page = FXA_PAGE_LOGGED_IN;
@@ -367,16 +372,29 @@ let gSyncPane = {
         }
         document.getElementById("sync-migration").hidden = true;
         return;
     }
     document.getElementById("sync-migration").hidden = false;
     document.getElementById("sync-migration-deck").selectedIndex = selIndex;
   },
 
+  // Called whenever one of the sync engine preferences is changed.
+  onPreferenceChanged: function() {
+    let prefElts = document.querySelectorAll("#syncEnginePrefs > preference");
+    let syncEnabled = false;
+    for (let elt of prefElts) {
+      if (elt.name.startsWith("services.sync.") && elt.value) {
+        syncEnabled = true;
+        break;
+      }
+    }
+    Services.prefs.setBoolPref("services.sync.enabled", syncEnabled);
+  },
+
   startOver: function (showDialog) {
     if (showDialog) {
       let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING +
                   Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_CANCEL + 
                   Services.prompt.BUTTON_POS_1_DEFAULT;
       let buttonChoice =
         Services.prompt.confirmEx(window,
                                   this._stringBundle.GetStringFromName("syncUnlink.title"),
--- a/browser/components/preferences/in-content/sync.xul
+++ b/browser/components/preferences/in-content/sync.xul
@@ -1,15 +1,16 @@
 # 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/.
 
 <!-- Sync panel -->
 
-<preferences hidden="true" data-category="paneSync">
+<preferences id="syncEnginePrefs" hidden="true" data-category="paneSync"
+             onchange="gSyncPane.onPreferenceChanged();">
   <preference id="engine.addons"
               name="services.sync.engine.addons"
               type="bool"/>
   <preference id="engine.bookmarks"
               name="services.sync.engine.bookmarks"
               type="bool"/>
   <preference id="engine.history"
               name="services.sync.engine.history"
@@ -18,16 +19,20 @@
               name="services.sync.engine.tabs"
               type="bool"/>
   <preference id="engine.prefs"
               name="services.sync.engine.prefs"
               type="bool"/>
   <preference id="engine.passwords"
               name="services.sync.engine.passwords"
               type="bool"/>
+  <!-- non Sync-Engine engines -->
+  <preference id="engine.readinglist"
+              name="readinglist.scheduler.enabled"
+              type="bool"/>
 </preferences>
 
 <script type="application/javascript"
         src="chrome://browser/content/preferences/in-content/sync.js"/>
 <script type="application/javascript"
         src="chrome://browser/content/sync/utils.js"/>
 
 <hbox id="header-sync"
@@ -285,16 +290,21 @@
                     accesskey="&engine.bookmarks.accesskey;"
                     preference="engine.bookmarks"/>
           <checkbox label="&engine.passwords.label;"
                     accesskey="&engine.passwords.accesskey;"
                     preference="engine.passwords"/>
           <checkbox label="&engine.history.label;"
                     accesskey="&engine.history.accesskey;"
                     preference="engine.history"/>
+          <checkbox id="readinglist-engine"
+                    label="&engine.readinglist.label;"
+                    accesskey="&engine.readinglist.accesskey;"
+                    preference="engine.readinglist"
+                    hidden="true"/>
           <checkbox label="&engine.addons.label;"
                     accesskey="&engine.addons.accesskey;"
                     preference="engine.addons"/>
           <checkbox label="&engine.prefs.label;"
                     accesskey="&engine.prefs.accesskey;"
                     preference="engine.prefs"/>
         </vbox>
         <spacer/>
--- a/browser/components/preferences/sync.js
+++ b/browser/components/preferences/sync.js
@@ -49,16 +49,36 @@ let gSyncPane = {
   needsUpdate: function () {
     this.page = PAGE_NEEDS_UPDATE;
     let label = document.getElementById("loginError");
     label.value = Weave.Utils.getErrorString(Weave.Status.login);
     label.className = "error";
   },
 
   init: function () {
+    // We use a preference observer to notice changes to the Sync engines
+    // enabled state - other techniques are problematic due to the window
+    // being instant-apply on Mac etc but modal on Windows.
+    let prefObserver = () => {
+      // If all our Sync engines are disabled we flip the "master" Sync-enabled pref.
+      let prefElts = document.querySelectorAll("#syncEnginePrefs > preference");
+      let syncEnabled = false;
+      for (let elt of prefElts) {
+        if (elt.name.startsWith("services.sync.") && elt.value) {
+          syncEnabled = true;
+          break;
+        }
+      }
+      Services.prefs.setBoolPref("services.sync.enabled", syncEnabled);
+    }
+    Services.prefs.addObserver("services.sync.engine.", prefObserver, false);
+    window.addEventListener("unload", () => {
+      Services.prefs.removeObserver("services.sync.engine.", prefObserver);
+    }, false);
+
     // If the Service hasn't finished initializing, wait for it.
     let xps = Components.classes["@mozilla.org/weave/service;1"]
                                 .getService(Components.interfaces.nsISupports)
                                 .wrappedJSObject;
 
     if (xps.ready) {
       this._init();
       return;
@@ -131,16 +151,21 @@ let gSyncPane = {
     Services.obs.notifyObservers(null, "fxa-migration:state-request", null);
 
     let service = Components.classes["@mozilla.org/weave/service;1"]
                   .getService(Components.interfaces.nsISupports)
                   .wrappedJSObject;
     // service.fxAccountsEnabled is false iff sync is already configured for
     // the legacy provider.
     if (service.fxAccountsEnabled) {
+      // unhide the reading-list engine if readinglist is enabled (note we do
+      // it here as it must remain disabled for legacy sync users)
+      if (Services.prefs.getBoolPref("browser.readinglist.enabled")) {
+        document.getElementById("readinglist-engine").removeAttribute("hidden");
+      }
       // determine the fxa status...
       this.page = PAGE_PLEASE_WAIT;
       fxAccounts.getSignedInUser().then(data => {
         if (!data) {
           this.page = FXA_PAGE_LOGGED_OUT;
           return;
         }
         this.page = FXA_PAGE_LOGGED_IN;
--- a/browser/components/preferences/sync.xul
+++ b/browser/components/preferences/sync.xul
@@ -16,23 +16,25 @@
 <overlay id="SyncPaneOverlay"
          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
          xmlns:html="http://www.w3.org/1999/xhtml">
 
   <prefpane id="paneSync"
             helpTopic="prefs-weave"
             onpaneload="gSyncPane.init()">
 
-    <preferences>
+    <preferences id="syncEnginePrefs">
       <preference id="engine.addons"    name="services.sync.engine.addons"    type="bool"/>
       <preference id="engine.bookmarks" name="services.sync.engine.bookmarks" type="bool"/>
       <preference id="engine.history"   name="services.sync.engine.history"   type="bool"/>
       <preference id="engine.tabs"      name="services.sync.engine.tabs"      type="bool"/>
       <preference id="engine.prefs"     name="services.sync.engine.prefs"     type="bool"/>
       <preference id="engine.passwords" name="services.sync.engine.passwords" type="bool"/>
+      <!-- non Sync-Engine engines -->
+      <preference id="engine.readinglist" name="readinglist.scheduler.enabled" type="bool"/>
     </preferences>
 
 
     <script type="application/javascript"
             src="chrome://browser/content/preferences/sync.js"/>
     <script type="application/javascript"
             src="chrome://browser/content/sync/utils.js"/>
 
@@ -280,31 +282,43 @@
           </groupbox>
 
           <groupbox id="syncOptions">
             <caption label="&syncBrand.shortName.label;"/>
             <hbox id="fxaSyncEngines">
               <vbox>
                 <checkbox label="&engine.tabs.label;"
                           accesskey="&engine.tabs.accesskey;"
+                          onsynctopreference="gSyncPane.onPreferenceChanged();"
                           preference="engine.tabs"/>
                 <checkbox label="&engine.bookmarks.label;"
                           accesskey="&engine.bookmarks.accesskey;"
+                          onsynctopreference="gSyncPane.onPreferenceChanged();"
                           preference="engine.bookmarks"/>
                 <checkbox label="&engine.passwords.label;"
                           accesskey="&engine.passwords.accesskey;"
+                          onsynctopreference="gSyncPane.onPreferenceChanged();"
                           preference="engine.passwords"/>
                 <checkbox label="&engine.history.label;"
                           accesskey="&engine.history.accesskey;"
+                          onsynctopreference="gSyncPane.onPreferenceChanged(this);"
                           preference="engine.history"/>
+                <!-- onpreferencechanged not needed for the readinglist engine -->
+                <checkbox id="readinglist-engine"
+                          label="&engine.readinglist.label;"
+                          accesskey="&engine.readinglist.accesskey;"
+                          preference="engine.readinglist"
+                          hidden="true"/>
                 <checkbox label="&engine.addons.label;"
                           accesskey="&engine.addons.accesskey;"
+                          onsynctopreference="gSyncPane.onPreferenceChanged();"
                           preference="engine.addons"/>
                 <checkbox label="&engine.prefs.label;"
                           accesskey="&engine.prefs.accesskey;"
+                          onsynctopreference="gSyncPane.onPreferenceChanged();"
                           preference="engine.prefs"/>
               </vbox>
               <spacer/>
             </hbox>
           </groupbox>
           <hbox align="center">
             <label value="&syncDeviceName.label;"
                    accesskey="&syncDeviceName.accesskey;"
--- a/browser/components/readinglist/Scheduler.jsm
+++ b/browser/components/readinglist/Scheduler.jsm
@@ -167,16 +167,20 @@ InternalScheduler.prototype = {
   // Is the current error state such that we shouldn't schedule a new sync.
   _isBlockedOnError() {
     // this needs more thought...
     return this.state == this.STATE_ERROR_AUTHENTICATION;
   },
 
   // canSync indicates if we can currently sync.
   _canSync(ignoreBlockingErrors = false) {
+    if (!prefs.get("enabled")) {
+      this.log.info("canSync=false - syncing is disabled");
+      return false;
+    }
     if (Services.io.offline) {
       this.log.info("canSync=false - we are offline");
       return false;
     }
     if (!ignoreBlockingErrors && this._isBlockedOnError()) {
       this.log.info("canSync=false - we are in a blocked error state", this.state);
       return false;
     }