Bug 1268154 - Port bug 1262880 to TB [Remove add-on compatibility check from application update]. r=mkmelin
authorRichard Marti <richard.marti@gmail.com>
Tue, 03 May 2016 17:48:54 +0200
changeset 19289 95b6c7ca61847f4cec5a8a7c4d2822104e7f2af8
parent 19288 067b77c50b68ea81623d4992dfff5531c54d94ee
child 19290 30e54571d31c70a3c9291babff2b7c416970c5c9
push id11857
push userrichard.marti@gmail.com
push dateWed, 04 May 2016 22:58:40 +0000
treeherdercomm-central@30e54571d31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1268154, 1262880
Bug 1268154 - Port bug 1262880 to TB [Remove add-on compatibility check from application update]. r=mkmelin
mail/app/profile/all-thunderbird.js
mail/base/content/aboutDialog.js
mail/base/content/aboutDialog.xul
mail/components/preferences/advanced.js
mail/components/preferences/advanced.xul
mail/locales/en-US/chrome/messenger/preferences/advanced.dtd
--- a/mail/app/profile/all-thunderbird.js
+++ b/mail/app/profile/all-thunderbird.js
@@ -82,32 +82,21 @@ pref("app.update.certs.1.issuerName", "C
 pref("app.update.certs.1.commonName", "aus5.mozilla.org");
 
 pref("app.update.certs.2.issuerName", "CN=thawte SSL CA - G2,O=\"thawte, Inc.\",C=US");
 pref("app.update.certs.2.commonName", "aus5.mozilla.org");
 
 // Whether or not app updates are enabled
 pref("app.update.enabled", true);
 
-// This preference turns on app.update.mode and allows automatic download and
-// install to take place. We use a separate boolean toggle for this to make
-// the UI easier to construct.
+// If set to true, the Update Service will automatically download updates when
+// app updates are enabled per the app.update.enabled preference and if the user
+// can apply updates.
 pref("app.update.auto", true);
 
-// Defines how the Application Update Service notifies the user about updates:
-//
-// AUM Set to:        Minor Releases:     Major Releases:
-// 0                  download no prompt  download no prompt
-// 1                  download no prompt  download no prompt if no incompatibilities
-// 2                  download no prompt  prompt
-//
-// See chart in nsUpdateService.js.in for more details
-//
-pref("app.update.mode", 1);
-
 // If set to true, the Update Service will present no UI for any event.
 pref("app.update.silent", false);
 
 // If set to true, the Update Service will apply updates in the background
 // when it finishes downloading them.
 pref("app.update.staging.enabled", true);
 
 // Update service URL:
@@ -800,17 +789,17 @@ pref("mail.taskbar.lists.tasks.enabled",
 #endif
 
 // Disable hardware accelerated layers
 pref("layers.acceleration.disabled", true);
 #ifdef XP_WIN
 // and direct2d support on Windows.
 pref("gfx.direct2d.disabled", true);
 #endif
- 
+
 // Account provisioner.
 pref("mail.provider.providerList", "https://broker-live.mozillamessaging.com/provider/list");
 pref("mail.provider.suggestFromName", "https://broker-live.mozillamessaging.com/provider/suggest");
 pref("mail.provider.enabled", true);
 
 // Pointer to the default engine name.
 pref("browser.search.defaultenginename", "chrome://messenger-region/locale/region.properties");
 
--- a/mail/base/content/aboutDialog.js
+++ b/mail/base/content/aboutDialog.js
@@ -1,17 +1,15 @@
 # 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/.
 
 // Services = object with smart getters for common XPCOM services
 Components.utils.import("resource://gre/modules/Services.jsm");
 
-var PREF_EM_HOTFIX_ID = "extensions.hotfix.id";
-
 function init(aEvent)
 {
   if (aEvent.target != document)
     return;
 
   try {
     var distroId = Services.prefs.getCharPref("distribution.id");
     if (distroId) {
@@ -96,17 +94,16 @@ function openUILink(url, event)
     m.launchExternalURL(url);
     event.preventDefault();
   }
 }
 
 #ifdef MOZ_UPDATER
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
-Components.utils.import("resource://gre/modules/AddonManager.jsm");
 
 var gAppUpdater;
 
 function onUnload(aEvent) {
   if (gAppUpdater.isChecking)
     gAppUpdater.checker.stopChecking(Components.interfaces.nsIUpdateChecker.CURRENT_CHECK);
   // Safe to call even when there isn't a download in progress.
   gAppUpdater.removeDownloadListener();
@@ -279,31 +276,16 @@ appUpdater.prototype =
   checkForUpdates: function() {
     this.selectPanel("checkingForUpdates");
     this.isChecking = true;
     this.checker.checkForUpdates(this.updateCheckListener, true);
     // after checking, onCheckComplete() is called
   },
 
   /**
-   * Check for addon compat, or start the download right away
-   */
-  doUpdate: function() {
-    // skip the compatibility check if the update doesn't provide appVersion,
-    // or the appVersion is unchanged, e.g. nightly update
-    if (!this.update.appVersion ||
-        Services.vc.compare(gAppUpdater.update.appVersion,
-                            Services.appinfo.version) == 0) {
-      this.startDownload();
-    } else {
-      this.checkAddonCompatibility();
-    }
-  },
-
-  /**
    * Handles oncommand for the "Restart to Update" button
    * which is presented after the download has been downloaded.
    */
   buttonRestartAfterDownload: function() {
     if (!this.isPending && !this.isApplied)
       return;
 
       // Notify all windows that an application quit has been requested.
@@ -380,17 +362,17 @@ appUpdater.prototype =
       // Thunderbird no longer displays a license for updates and the licenseURL
       // check is just in case a distibution does.
       if (gAppUpdater.update.billboardURL || gAppUpdater.update.licenseURL) {
         gAppUpdater.selectPanel("applyBillboard");
         return;
       }
 
       if (gAppUpdater.updateAuto) // automatically download and install
-        gAppUpdater.doUpdate();
+        gAppUpdater.startDownload();
       else // ask
         gAppUpdater.selectPanel("downloadAndInstall");
     },
 
     /**
      * See nsIUpdateService.idl
      */
     onError: function(aRequest, aUpdate) {
@@ -409,128 +391,16 @@ appUpdater.prototype =
       if (!aIID.equals(Components.interfaces.nsIUpdateCheckListener) &&
           !aIID.equals(Components.interfaces.nsISupports))
         throw Components.results.NS_ERROR_NO_INTERFACE;
       return this;
     }
   },
 
   /**
-   * Checks the compatibility of add-ons for the application update.
-   */
-  checkAddonCompatibility: function() {
-    try {
-      var hotfixID = Services.prefs.getCharPref(PREF_EM_HOTFIX_ID);
-    }
-    catch (e) { }
-
-    var self = this;
-    AddonManager.getAllAddons(function(aAddons) {
-      self.addons = [];
-      self.addonsCheckedCount = 0;
-      aAddons.forEach(function(aAddon) {
-        // Protect against code that overrides the add-ons manager and doesn't
-        // implement the isCompatibleWith or the findUpdates method.
-        if (!("isCompatibleWith" in aAddon) || !("findUpdates" in aAddon)) {
-          let errMsg = "Add-on doesn't implement either the isCompatibleWith " +
-                       "or the findUpdates method!";
-          if (aAddon.id)
-            errMsg += " Add-on ID: " + aAddon.id;
-          Components.utils.reportError(errMsg);
-          return;
-        }
-
-        // If an add-on isn't appDisabled and isn't userDisabled then it is
-        // either active now or the user expects it to be active after the
-        // restart. If that is the case and the add-on is not installed by the
-        // application and is not compatible with the new application version
-        // then the user should be warned that the add-on will become
-        // incompatible. If an addon's type equals plugin it is skipped since
-        // checking plugins compatibility information isn't supported and
-        // getting the scope property of a plugin breaks in some environments
-        // (see bug 566787). The hotfix add-on is also ignored as it shouldn't
-        // block the user from upgrading.
-        try {
-          if (aAddon.type != "plugin" && aAddon.id != hotfixID &&
-              !aAddon.appDisabled && !aAddon.userDisabled &&
-              aAddon.scope != AddonManager.SCOPE_APPLICATION &&
-              aAddon.isCompatible &&
-              !aAddon.isCompatibleWith(self.update.appVersion,
-                                       self.update.platformVersion))
-            self.addons.push(aAddon);
-        }
-        catch (e) {
-          Components.utils.reportError(e);
-        }
-      });
-      self.addonsTotalCount = self.addons.length;
-      if (self.addonsTotalCount == 0) {
-        self.startDownload();
-        return;
-      }
-
-      self.checkAddonsForUpdates();
-    });
-  },
-
-  /**
-   * Checks if there are updates for add-ons that are incompatible with the
-   * application update.
-   */
-  checkAddonsForUpdates: function() {
-    this.addons.forEach(function(aAddon) {
-      aAddon.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED,
-                         this.update.appVersion,
-                         this.update.platformVersion);
-    }, this);
-  },
-
-  /**
-   * See XPIProvider.jsm
-   */
-  onCompatibilityUpdateAvailable: function(aAddon) {
-    for (var i = 0; i < this.addons.length; ++i) {
-      if (this.addons[i].id == aAddon.id) {
-        this.addons.splice(i, 1);
-        break;
-      }
-    }
-  },
-
-  /**
-   * See XPIProvider.jsm
-   */
-  onUpdateAvailable: function(aAddon, aInstall) {
-    if (!Services.blocklist.isAddonBlocklisted(aAddon,
-                                               this.update.appVersion,
-                                               this.update.platformVersion)) {
-      // Compatibility or new version updates mean the same thing here.
-      this.onCompatibilityUpdateAvailable(aAddon);
-    }
-  },
-
-  /**
-   * See XPIProvider.jsm
-   */
-  onUpdateFinished: function(aAddon) {
-    ++this.addonsCheckedCount;
-
-    if (this.addonsCheckedCount < this.addonsTotalCount)
-      return;
-
-    if (this.addons.length == 0) {
-      // Compatibility updates or new version updates were found for all add-ons
-      this.startDownload();
-      return;
-    }
-
-    this.selectPanel("applyBillboard");
-  },
-
-  /**
    * Starts the download of an update mar.
    */
   startDownload: function() {
     if (!this.update)
       this.update = this.um.activeUpdate;
     this.update.QueryInterface(Components.interfaces.nsIWritablePropertyBag);
     this.update.setProperty("foregroundDownload", "true");
 
--- a/mail/base/content/aboutDialog.xul
+++ b/mail/base/content/aboutDialog.xul
@@ -53,17 +53,17 @@
                 <button id="checkForUpdatesButton" align="start"
                         label="&update.checkForUpdatesButton.label;"
                         accesskey="&update.checkForUpdatesButton.accesskey;"
                         oncommand="gAppUpdater.checkForUpdates();"/>
                 <spacer flex="1"/>
               </hbox>
               <hbox id="downloadAndInstall" align="center">
                 <button id="downloadAndInstallButton"
-                        oncommand="gAppUpdater.doUpdate();"/>
+                        oncommand="gAppUpdater.startDownload();"/>
                         <!-- label and accesskey will be filled by JS -->
                 <spacer flex="1"/>
               </hbox>
               <hbox id="apply" align="center">
                 <button id="updateButton"
                         label="&update.updateButton.label2;"
                         accesskey="&update.updateButton.accesskey;"
                         oncommand="gAppUpdater.buttonRestartAfterDownload();"/>
--- a/mail/components/preferences/advanced.js
+++ b/mail/components/preferences/advanced.js
@@ -186,41 +186,31 @@ var gAdvancedPane = {
     var preference = document.getElementById(aPreferenceID);
     // This is actually before the value changes, so the value is not as you expect.
     button.disabled = preference.value == true;
     return undefined;
   },
 
 #ifdef MOZ_UPDATER
 /**
- * Selects the item of the radiogroup, and sets the warnIncompatible checkbox
- * based on the pref values and locked states.
+ * Selects the item of the radiogroup based on the pref values and locked
+ * states.
  *
  * UI state matrix for update preference conditions
  *
  * UI Components:                              Preferences
  * Radiogroup                                  i   = app.update.enabled
- * Warn before disabling extensions checkbox   ii  = app.update.auto
- *                                             iii = app.update.mode
+ *                                             ii  = app.update.auto
  *
  * Disabled states:
  * Element           pref  value  locked  disabled
  * radiogroup        i     t/f    f       false
  *                   i     t/f    *t*     *true*
  *                   ii    t/f    f       false
  *                   ii    t/f    *t*     *true*
- *                   iii   0/1/2  t/f     false
- * warnIncompatible  i     t      f       false
- *                   i     t      *t*     *true*
- *                   i     *f*    t/f     *true*
- *                   ii    t      f       false
- *                   ii    t      *t*     *true*
- *                   ii    *f*    t/f     *true*
- *                   iii   0/1/2  f       false
- *                   iii   0/1/2  *t*     *true*
  */
 updateReadPrefs: function ()
 {
   var enabledPref = document.getElementById("app.update.enabled");
   var autoPref = document.getElementById("app.update.auto");
   var radiogroup = document.getElementById("updateRadioGroup");
 
   if (!enabledPref.value)   // Don't care for autoPref.value in this case.
@@ -234,23 +224,16 @@ updateReadPrefs: function ()
                    getService(Components.interfaces.nsIApplicationUpdateService).
                    canCheckForUpdates;
 
   // canCheck is false if the enabledPref is false and locked,
   // or the binary platform or OS version is not known.
   // A locked pref is sufficient to disable the radiogroup.
   radiogroup.disabled = !canCheck || enabledPref.locked || autoPref.locked;
 
-  var modePref = document.getElementById("app.update.mode");
-  var warnIncompatible = document.getElementById("warnIncompatible");
-
-  // the warnIncompatible checkbox value is set by readAddonWarn
-  warnIncompatible.disabled = radiogroup.disabled || modePref.locked ||
-                              !enabledPref.value || !autoPref.value;
-
 #ifdef MOZ_MAINTENANCE_SERVICE
   // Check to see if the maintenance service is installed.
   // If it is don't show the preference at all.
   var installed;
   try {
     let wrk = Components.classes["@mozilla.org/windows-registry-key;1"]
               .createInstance(Components.interfaces.nsIWindowsRegKey);
     wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
@@ -262,18 +245,17 @@ updateReadPrefs: function ()
   }
   if (installed != 1) {
     document.getElementById("useService").hidden = true;
   }
 #endif
 },
 
 /**
- * Sets the pref values based on the selected item of the radiogroup,
- * and sets the disabled state of the warnIncompatible checkbox accordingly.
+ * Sets the pref values based on the selected item of the radiogroup.
  */
 updateWritePrefs: function ()
 {
   var enabledPref = document.getElementById("app.update.enabled");
   var autoPref = document.getElementById("app.update.auto");
   var radiogroup = document.getElementById("updateRadioGroup");
   switch (radiogroup.value) {
     case "auto":      // 1. Automatically install updates
@@ -282,48 +264,16 @@ updateWritePrefs: function ()
       break;
     case "checkOnly": // 2. Check, but but let me choose
       enabledPref.value = true;
       autoPref.value = false;
       break;
     case "manual":    // 3. Never check for updates.
       enabledPref.value = false;
       autoPref.value = false;
-  }
-
-  var warnIncompatible = document.getElementById("warnIncompatible");
-  var modePref = document.getElementById("app.update.mode");
-  warnIncompatible.disabled = enabledPref.locked || !enabledPref.value ||
-                              autoPref.locked || !autoPref.value ||
-                              modePref.locked;
-},
-
-  /**
-   * app.update.mode is a three state integer preference, and we have to
-   * express all three values in a single checkbox:
-   * "Warn me if this will disable extensions or themes"
-   * Preference Value         Checkbox State    Meaning
-   * 0                        Unchecked         Do not warn
-   * 1                        Checked           Warn if there are incompatibilities
-   * 2                        Checked           Warn if there are incompatibilities,
-   *                                            or the update is major.
-   */
-  _modePreference: -1,
-  addonWarnSyncFrom: function ()
-  {
-    var preference = document.getElementById("app.update.mode");
-    var warn = preference.value != 0;
-    gAdvancedPane._modePreference = warn ? preference.value : 1;
-    return warn;
-  },
-
-  addonWarnSyncTo: function ()
-  {
-    var warnIncompatible = document.getElementById("warnIncompatible");
-    return !warnIncompatible.checked ? 0 : gAdvancedPane._modePreference;
   },
 
   showUpdates: function ()
   {
     var prompter = Components.classes["@mozilla.org/updates/update-prompt;1"]
                              .createInstance(Components.interfaces.nsIUpdatePrompt);
     prompter.showUpdateHistory(window);
   },
--- a/mail/components/preferences/advanced.xul
+++ b/mail/components/preferences/advanced.xul
@@ -92,18 +92,16 @@
       <preference id="browser.cache.disk.capacity"
                   name="browser.cache.disk.capacity" type="int"/>
 #ifdef MOZ_UPDATER
       <!-- Update tab -->
       <preference id="app.update.enabled" name="app.update.enabled"
 type="bool"/>
       <preference id="app.update.auto" name="app.update.auto"
 type="bool"/>
-      <preference id="app.update.mode" name="app.update.mode"
-type="int"/>
       <preference id="app.update.disable_button.showUpdateHistory"
                   name="app.update.disable_button.showUpdateHistory"
                   type="bool"/>
 
 #ifdef MOZ_MAINTENANCE_SERVICE
       <preference id="app.update.service.enabled"
                   name="app.update.service.enabled"
                   type="bool"/>
@@ -340,24 +338,16 @@ type="int"/>
         <tabpanel orient="vertical" align="start">
           <groupbox id="updateApp">
             <caption label="&updateApp.label;"/>
             <radiogroup id="updateRadioGroup"
                         oncommand="gAdvancedPane.updateWritePrefs();">
               <radio value="auto"
                      label="&updateAuto.label;"
                      accesskey="&updateAuto.accesskey;"/>
-              <hbox class="indent">
-                <checkbox id="warnIncompatible"
-                          label="&updateAutoAddonWarn.label;"
-                          accesskey="&updateAutoAddonWarn.accesskey;"
-                          preference="app.update.mode"
-                          onsyncfrompreference="return gAdvancedPane.addonWarnSyncFrom();"
-                          onsynctopreference="return gAdvancedPane.addonWarnSyncTo();"/>
-              </hbox>
               <hbox>
                 <radio value="checkOnly"
                        label="&updateCheck.label;"
                        accesskey="&updateCheck.accesskey;"/>
                 <spacer flex="1"/>
               </hbox>
               <hbox>
                 <radio value="manual"
--- a/mail/locales/en-US/chrome/messenger/preferences/advanced.dtd
+++ b/mail/locales/en-US/chrome/messenger/preferences/advanced.dtd
@@ -54,18 +54,16 @@
 <!-- Update -->
 <!ENTITY updateApp.label                 "&brandShortName; updates:">
 <!ENTITY updateAuto.label                "Automatically install updates (recommended: improved security)">
 <!ENTITY updateAuto.accesskey            "A">
 <!ENTITY updateCheck.label               "Check for updates, but let me choose whether to install them">
 <!ENTITY updateCheck.accesskey           "C">
 <!ENTITY updateManual.label              "Never check for updates (not recommended: security risk)">
 <!ENTITY updateManual.accesskey          "N">
-<!ENTITY updateAutoAddonWarn.label       "Warn me if this will disable any of my add-ons">
-<!ENTITY updateAutoAddonWarn.accesskey   "W">
 <!ENTITY updateHistory.label             "Show Update History">
 <!ENTITY updateHistory.accesskey         "p">
 
 <!ENTITY useService.label                "Use a background service to install updates">
 <!ENTITY useService.accesskey            "b">
 
 <!-- Networking and Disk Space -->
 <!ENTITY showSettings.label            "Settingsā€¦">