Backed out changeset 2af514f1a7bc (bug 1559195)for failures at browser_startup_mainthreadio.js
authorGurzau Raul <rgurzau@mozilla.com>
Tue, 09 Jul 2019 18:10:38 +0300
changeset 481917 06d4b70144ff6e923f61b06d4164b9eda977c8cb
parent 481916 9ba600ae3c02a21a273596f2c98a2c47b0ee7c6e
child 481918 450801fafd10d18e6fce669408c551593b2028a7
push id113647
push useraciure@mozilla.com
push dateWed, 10 Jul 2019 09:46:39 +0000
treeherdermozilla-inbound@f3a387c13e2c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1559195
milestone70.0a1
backs out2af514f1a7bc1034f3c730d65fdfcb796b64fc10
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
Backed out changeset 2af514f1a7bc (bug 1559195)for failures at browser_startup_mainthreadio.js
browser/components/BrowserGlue.jsm
browser/extensions/pdfjs/content/PdfJs.jsm
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -1021,17 +1021,17 @@ BrowserGlue.prototype = {
       case "handlersvc-store-initialized":
         // Initialize PdfJs when running in-process and remote. This only
         // happens once since PdfJs registers global hooks. If the PdfJs
         // extension is installed the init method below will be overridden
         // leaving initialization to the extension.
         // parent only: configure default prefs, set up pref observers, register
         // pdf content handler, and initializes parent side message manager
         // shim for privileged api access.
-        PdfJs.init();
+        PdfJs.init(true);
         break;
       case "shield-init-complete":
         this._shieldInitComplete = true;
         this._sendMainPingCentrePing();
         break;
     }
   },
 
--- a/browser/extensions/pdfjs/content/PdfJs.jsm
+++ b/browser/extensions/pdfjs/content/PdfJs.jsm
@@ -18,43 +18,80 @@
 var EXPORTED_SYMBOLS = ["PdfJs"];
 
 const PREF_PREFIX = "pdfjs";
 const PREF_DISABLED = PREF_PREFIX + ".disabled";
 const PREF_MIGRATION_VERSION = PREF_PREFIX + ".migrationVersion";
 const PREF_PREVIOUS_ACTION = PREF_PREFIX + ".previousHandler.preferredAction";
 const PREF_PREVIOUS_ASK =
   PREF_PREFIX + ".previousHandler.alwaysAskBeforeHandling";
+const PREF_DISABLED_PLUGIN_TYPES = "plugin.disable_full_page_plugin_for_types";
 const PREF_ENABLED_CACHE_STATE = PREF_PREFIX + ".enabledCache.state";
+const PREF_ENABLED_CACHE_INITIALIZED =
+  PREF_PREFIX + ".enabledCache.initialized";
+const PREF_APP_UPDATE_POSTUPDATE = "app.update.postupdate";
 const TOPIC_PDFJS_HANDLER_CHANGED = "pdfjs:handlerChanged";
+const TOPIC_PLUGINS_LIST_UPDATED = "plugins-list-updated";
+const TOPIC_PLUGIN_INFO_UPDATED = "plugin-info-updated";
 const PDF_CONTENT_TYPE = "application/pdf";
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var Svc = {};
 XPCOMUtils.defineLazyServiceGetter(
   Svc,
   "mime",
   "@mozilla.org/mime;1",
   "nsIMIMEService"
 );
+XPCOMUtils.defineLazyServiceGetter(
+  Svc,
+  "pluginHost",
+  "@mozilla.org/plugin/host;1",
+  "nsIPluginHost"
+);
 ChromeUtils.defineModuleGetter(
   this,
   "PdfjsChromeUtils",
   "resource://pdf.js/PdfjsChromeUtils.jsm"
 );
 ChromeUtils.defineModuleGetter(
   this,
   "PdfJsDefaultPreferences",
   "resource://pdf.js/PdfJsDefaultPreferences.jsm"
 );
 
+function getBoolPref(aPref, aDefaultValue) {
+  try {
+    return Services.prefs.getBoolPref(aPref);
+  } catch (ex) {
+    return aDefaultValue;
+  }
+}
+
+function getIntPref(aPref, aDefaultValue) {
+  try {
+    return Services.prefs.getIntPref(aPref);
+  } catch (ex) {
+    return aDefaultValue;
+  }
+}
+
+function isDefaultHandler() {
+  if (Services.appinfo.processType !== Services.appinfo.PROCESS_TYPE_DEFAULT) {
+    throw new Error(
+      "isDefaultHandler should only get called in the parent process."
+    );
+  }
+  return PdfjsChromeUtils.isDefaultHandlerApp();
+}
+
 function initializeDefaultPreferences() {
   var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + ".");
   var defaultValue;
   for (var key in PdfJsDefaultPreferences) {
     defaultValue = PdfJsDefaultPreferences[key];
     switch (typeof defaultValue) {
       case "boolean":
         defaultBranch.setBoolPref(key, defaultValue);
@@ -68,17 +105,17 @@ function initializeDefaultPreferences() 
     }
   }
 }
 
 var PdfJs = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
   _initialized: false,
 
-  init: function init() {
+  init: function init(remote) {
     if (
       Services.appinfo.processType !== Services.appinfo.PROCESS_TYPE_DEFAULT
     ) {
       throw new Error(
         "PdfJs.init should only get called in the parent process."
       );
     }
     PdfjsChromeUtils.init();
@@ -94,39 +131,45 @@ var PdfJs = {
   },
 
   initPrefs: function initPrefs() {
     if (this._initialized) {
       return;
     }
     this._initialized = true;
 
-    if (!Services.prefs.getBoolPref(PREF_DISABLED, true)) {
+    if (!getBoolPref(PREF_DISABLED, true)) {
       this._migrate();
     }
 
     // Listen for when pdf.js is completely disabled or a different pdf handler
     // is chosen.
     Services.prefs.addObserver(PREF_DISABLED, this);
+    Services.prefs.addObserver(PREF_DISABLED_PLUGIN_TYPES, this);
     Services.obs.addObserver(this, TOPIC_PDFJS_HANDLER_CHANGED);
+    Services.obs.addObserver(this, TOPIC_PLUGINS_LIST_UPDATED);
+    Services.obs.addObserver(this, TOPIC_PLUGIN_INFO_UPDATED);
 
     initializeDefaultPreferences();
   },
 
   uninit: function uninit() {
     if (this._initialized) {
       Services.prefs.removeObserver(PREF_DISABLED, this);
+      Services.prefs.removeObserver(PREF_DISABLED_PLUGIN_TYPES, this);
       Services.obs.removeObserver(this, TOPIC_PDFJS_HANDLER_CHANGED);
+      Services.obs.removeObserver(this, TOPIC_PLUGINS_LIST_UPDATED);
+      Services.obs.removeObserver(this, TOPIC_PLUGIN_INFO_UPDATED);
       this._initialized = false;
     }
   },
 
   _migrate: function migrate() {
     const VERSION = 2;
-    var currentVersion = Services.prefs.getIntPref(PREF_MIGRATION_VERSION, 0);
+    var currentVersion = getIntPref(PREF_MIGRATION_VERSION, 0);
     if (currentVersion >= VERSION) {
       return;
     }
     // Make pdf.js the default pdf viewer on the first migration.
     if (currentVersion < 1) {
       this._becomeHandler();
     }
     if (currentVersion < 2) {
@@ -153,32 +196,79 @@ var PdfJs = {
     let handlerService = Cc[
       "@mozilla.org/uriloader/handler-service;1"
     ].getService(Ci.nsIHandlerService);
 
     // Change and save mime handler settings.
     handlerInfo.alwaysAskBeforeHandling = false;
     handlerInfo.preferredAction = Ci.nsIHandlerInfo.handleInternally;
     handlerService.store(handlerInfo);
+
+    // Also disable any plugins for pdfs.
+    var stringTypes = "";
+    var types = [];
+    if (prefs.prefHasUserValue(PREF_DISABLED_PLUGIN_TYPES)) {
+      stringTypes = prefs.getCharPref(PREF_DISABLED_PLUGIN_TYPES);
+    }
+    if (stringTypes !== "") {
+      types = stringTypes.split(",");
+    }
+
+    if (!types.includes(PDF_CONTENT_TYPE)) {
+      types.push(PDF_CONTENT_TYPE);
+    }
+    prefs.setCharPref(PREF_DISABLED_PLUGIN_TYPES, types.join(","));
+
+    // Update the category manager in case the plugins are already loaded.
+    Services.catMan.deleteCategoryEntry(
+      "Gecko-Content-Viewers",
+      PDF_CONTENT_TYPE,
+      false
+    );
   },
 
   _isEnabled: function _isEnabled() {
-    let { processType, PROCESS_TYPE_DEFAULT } = Services.appinfo;
-    if (processType !== PROCESS_TYPE_DEFAULT) {
-      throw new Error(
-        "isEnabled should only get called in the parent process."
-      );
-    }
-
-    if (Services.prefs.getBoolPref(PREF_DISABLED, true)) {
+    var disabled = getBoolPref(PREF_DISABLED, true);
+    if (disabled) {
       return false;
     }
 
     // Check if the 'application/pdf' preview handler is configured properly.
-    return PdfjsChromeUtils.isDefaultHandlerApp();
+    if (!isDefaultHandler()) {
+      return false;
+    }
+
+    // Check if we have disabled plugin handling of 'application/pdf' in prefs
+    if (Services.prefs.prefHasUserValue(PREF_DISABLED_PLUGIN_TYPES)) {
+      let disabledPluginTypes = Services.prefs
+        .getCharPref(PREF_DISABLED_PLUGIN_TYPES)
+        .split(",");
+      if (disabledPluginTypes.includes(PDF_CONTENT_TYPE)) {
+        return true;
+      }
+    }
+
+    // Check if there is an enabled pdf plugin.
+    // Note: this check is performed last because getPluginTags() triggers
+    // costly plugin list initialization (bug 881575)
+    let tags = Cc["@mozilla.org/plugin/host;1"]
+      .getService(Ci.nsIPluginHost)
+      .getPluginTags();
+    let enabledPluginFound = tags.some(function(tag) {
+      if (tag.disabled) {
+        return false;
+      }
+      let mimeTypes = tag.getMimeTypes();
+      return mimeTypes.some(function(mimeType) {
+        return mimeType === PDF_CONTENT_TYPE;
+      });
+    });
+
+    // Use pdf.js if pdf plugin is not present or disabled
+    return !enabledPluginFound;
   },
 
   checkEnabled: function checkEnabled() {
     let isEnabled = this._isEnabled();
     // This will be updated any time we observe a dependency changing, since
     // updateRegistration internally calls enabled.
     Services.prefs.setBoolPref(PREF_ENABLED_CACHE_STATE, isEnabled);
     return isEnabled;
@@ -191,9 +281,28 @@ var PdfJs = {
     ) {
       throw new Error(
         "Only the parent process should be observing PDF handler changes."
       );
     }
 
     Services.ppmm.sharedData.set("pdfjs.enabled", this.checkEnabled());
   },
+
+  /**
+   * pdf.js is only enabled if it is both selected as the pdf viewer and if the
+   * global switch enabling it is true.
+   * @return {boolean} Whether or not it's enabled.
+   */
+  get enabled() {
+    if (!Services.prefs.getBoolPref(PREF_ENABLED_CACHE_INITIALIZED, false)) {
+      // If we just updated, and the cache hasn't been initialized, then we
+      // can't assume a default state, and need to synchronously initialize
+      // PdfJs
+      if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_POSTUPDATE)) {
+        this.checkEnabled();
+      }
+
+      Services.prefs.setBoolPref(PREF_ENABLED_CACHE_INITIALIZED, true);
+    }
+    return Services.prefs.getBoolPref(PREF_ENABLED_CACHE_STATE, true);
+  },
 };