Bug 1257565 - Refactor to (pre)load multiple files draft
authorMathieu Leplatre <mathieu@mozilla.com>
Thu, 21 Apr 2016 11:17:14 +0200
changeset 354576 8fda57ddb8126b6ee7f75700fca9e3bed90c5976
parent 354226 f05a1242fb29023bd7ebc492897ed3d6907733c7
child 354577 15813d7959c7ff309b77c69c843b94bf32c05467
child 354760 09dbf896992392afa1ac961dbaeb065a6f6d57e6
child 354846 639ec17db7dca2221bb8a03f9f2f2c2e5651dfe7
push id16129
push usermleplatre@mozilla.com
push dateThu, 21 Apr 2016 10:12:40 +0000
bugs1257565
milestone48.0a1
Bug 1257565 - Refactor to (pre)load multiple files MozReview-Commit-ID: 5LDzxA0mc5b
toolkit/mozapps/extensions/nsBlocklistService.js
--- a/toolkit/mozapps/extensions/nsBlocklistService.js
+++ b/toolkit/mozapps/extensions/nsBlocklistService.js
@@ -324,16 +324,17 @@ Blocklist.prototype = {
    *                 has the following properties:
    *                   "minVersion"  The minimum version in a version range
    *                                 (default = 0)
    *                   "maxVersion"  The maximum version in a version range
    *                                 (default = *)
    */
   _addonEntries: null,
   _pluginEntries: null,
+  _preloadedBlocklistContent: {},
 
   shutdown: function() {
     Services.obs.removeObserver(this, "xpcom-shutdown");
     Services.ppmm.removeMessageListener("Blocklist:getPluginBlocklistState", this);
     Services.ppmm.removeMessageListener("Blocklist:content-blocklist-updated", this);
     gPref.removeObserver("extensions.blocklist.", this);
     gPref.removeObserver(PREF_EM_LOGGING_ENABLED, this);
   },
@@ -654,20 +655,18 @@ Blocklist.prototype = {
     if (!responseXML || responseXML.documentElement.namespaceURI == XMLURI_PARSE_ERROR ||
         (request.status != 200 && request.status != 0)) {
       LOG("Blocklist::onXMLLoad: there was an error during load");
       return;
     }
 
     var oldAddonEntries = this._addonEntries;
     var oldPluginEntries = this._pluginEntries;
-    this._addonEntries = [];
-    this._pluginEntries = [];
 
-    this._loadBlocklistFromString(request.responseText);
+    this._loadBlocklistFromXMLString(request.responseText);
     this._blocklistUpdated(oldAddonEntries, oldPluginEntries);
 
     try {
       let path = OS.Path.join(OS.Constants.Path.profileDir, FILE_BLOCKLIST);
       yield OS.File.writeAtomic(path, request.responseText, {tmpPath: path + ".tmp"});
     } catch (e) {
       LOG("Blocklist::onXMLLoad: " + e);
     }
@@ -695,30 +694,130 @@ Blocklist.prototype = {
         statusText);
   },
 
   /**
    * Finds the newest blocklist file from the application and the profile and
    * load it or does nothing if neither exist.
    */
   _loadBlocklist: function() {
-    this._addonEntries = [];
-    this._pluginEntries = [];
-    var profFile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_BLOCKLIST]);
-    if (profFile.exists()) {
-      this._loadBlocklistFromFile(profFile);
+    if (!gBlocklistEnabled) {
+      LOG("Blocklist::_loadBlocklistFromFile: blocklist is disabled");
+      return;
+    }
+    const content = this._loadBlocklistFromFile(FILE_BLOCKLIST);
+    this._loadBlocklistFromXMLString(content);
+  },
+
+  _loadBlocklistFromFile: function(filename) {
+    let file = FileUtils.getFile(KEY_PROFILEDIR, [filename]);
+    if (!file.exists()) {
+      let appFile = FileUtils.getFile(KEY_APPDIR, [filename]);
+      if (appFile.exists()) {
+        file = appFile;
+      }
+    }
+
+    let telemetry = Services.telemetry;
+
+    // Check if preloaded content exists for this file.
+    if (this._preloadedBlocklistContent.hasOwnProperty(file.path)) {
+      telemetry.getHistogramById("BLOCKLIST_SYNC_FILE_LOAD").add(false);
+      const text = this._preloadedBlocklistContent[file.path];
+      delete this._preloadedBlocklistContent[file.path];
+      return text;
+    }
+
+    if (!file.exists()) {
+      LOG("Blocklist::_loadBlocklistFromFile: File does not exist " + file.path);
       return;
     }
-    var appFile = FileUtils.getFile(KEY_APPDIR, [FILE_BLOCKLIST]);
-    if (appFile.exists()) {
-      this._loadBlocklistFromFile(appFile);
+
+    telemetry.getHistogramById("BLOCKLIST_SYNC_FILE_LOAD").add(true);
+
+    let text = "";
+    let fstream = null;
+    let cstream = null;
+
+    try {
+      fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
+                          .createInstance(Components.interfaces.nsIFileInputStream);
+      cstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
+                          .createInstance(Components.interfaces.nsIConverterInputStream);
+
+      fstream.init(file, FileUtils.MODE_RDONLY, FileUtils.PERMS_FILE, 0);
+      cstream.init(fstream, "UTF-8", 0, 0);
+
+      let str = {};
+      let read = 0;
+
+      do {
+        read = cstream.readString(0xffffffff, str); // read as much as we can and put it in str.value
+        text += str.value;
+      } while (read != 0);
+    } catch (e) {
+      LOG("Blocklist::_loadBlocklistFromFile: Failed to load file " + e);
+    } finally {
+      if (cstream)
+        cstream.close();
+      if (fstream)
+        fstream.close();
+    }
+
+    return text;
+  },
+
+  _isBlocklistLoaded: function() {
+    return this._addonEntries != null && this._pluginEntries != null;
+  },
+
+  /* Used for testing */
+  _clear: function() {
+    this._addonEntries = null;
+    this._pluginEntries = null;
+    this._preloadedBlocklistContent = {};
+  },
+
+  _preloadBlocklist: Task.async(function*() {
+    if (!gBlocklistEnabled) {
+      LOG("Blocklist::_preloadBlocklistFile: blocklist is disabled");
       return;
     }
-    LOG("Blocklist::_loadBlocklist: no XML File found");
-  },
+
+    yield this._preloadBlocklistFile(FILE_BLOCKLIST);
+  }),
+
+  _preloadBlocklistFile: Task.async(function*(filename){
+    let file = FileUtils.getFile(KEY_PROFILEDIR, [filename]);
+    if (!file.exists()) {
+      let appFile = FileUtils.getFile(KEY_APPDIR, [filename]);
+      if (appFile.exists()) {
+        file = appFile;
+      } else {
+        LOG(`Blocklist::_preloadBlocklist: no ${filename} file found`);
+        return;
+      }
+    }
+    const path = file.path;
+    if (this._preloadedBlocklistContent.hasOwnProperty(path)) {
+      // The file has been already loaded.
+      return;
+    }
+
+    try {
+      let content = yield OS.File.read(path, { encoding: "utf-8" });
+
+      if (!this._preloadedBlocklistContent.hasOwnProperty(path)) {
+        // Store the content only if a sync load has not been performed in the meantime.
+        this._preloadedBlocklistContent[path] = content;
+      }
+    } catch (e) {
+      LOG(`Blocklist::_preloadBlocklist: Failed to load ${path} file : ${e}`);
+    }
+  }),
 
   /**
 #    The blocklist XML file looks something like this:
 #
 #    <blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
 #      <emItems>
 #        <emItem id="item_1@domain" blockID="i1">
 #          <prefs>
@@ -775,127 +874,20 @@ Blocklist.prototype = {
 #          <serialNumber>AkHVNA==</serialNumber>
 #        </certItem>
 #        <!-- subject is the DER subject name data base64 encoded... -->
 #        <certItem subject="MA0xCzAJBgNVBAMMAmNh" pubKeyHash="/xeHA5s+i9/z9d8qy6JEuE1xGoRYIwgJuTE/lmaGJ7M=">
 #        </certItem>
 #      </certItems>
 #    </blocklist>
    */
-
-  _loadBlocklistFromFile: function(file) {
-    if (!gBlocklistEnabled) {
-      LOG("Blocklist::_loadBlocklistFromFile: blocklist is disabled");
-      return;
-    }
-
-    let telemetry = Services.telemetry;
-
-    if (this._isBlocklistPreloaded()) {
-      telemetry.getHistogramById("BLOCKLIST_SYNC_FILE_LOAD").add(false);
-      this._loadBlocklistFromString(this._preloadedBlocklistContent);
-      delete this._preloadedBlocklistContent;
-      return;
-    }
-
-    if (!file.exists()) {
-      LOG("Blocklist::_loadBlocklistFromFile: XML File does not exist " + file.path);
-      return;
-    }
-
-    telemetry.getHistogramById("BLOCKLIST_SYNC_FILE_LOAD").add(true);
-
-    let text = "";
-    let fstream = null;
-    let cstream = null;
-
-    try {
-      fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
-                          .createInstance(Components.interfaces.nsIFileInputStream);
-      cstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
-                          .createInstance(Components.interfaces.nsIConverterInputStream);
-
-      fstream.init(file, FileUtils.MODE_RDONLY, FileUtils.PERMS_FILE, 0);
-      cstream.init(fstream, "UTF-8", 0, 0);
-
-      let str = {};
-      let read = 0;
-
-      do {
-        read = cstream.readString(0xffffffff, str); // read as much as we can and put it in str.value
-        text += str.value;
-      } while (read != 0);
-    } catch (e) {
-      LOG("Blocklist::_loadBlocklistFromFile: Failed to load XML file " + e);
-    } finally {
-      if (cstream)
-        cstream.close();
-      if (fstream)
-        fstream.close();
-    }
-
-    if (text)
-        this._loadBlocklistFromString(text);
-  },
+  _loadBlocklistFromXMLString: function(text) {
+    this._addonEntries = [];
+    this._pluginEntries = [];
 
-  _isBlocklistLoaded: function() {
-    return this._addonEntries != null && this._pluginEntries != null;
-  },
-
-  _isBlocklistPreloaded: function() {
-    return this._preloadedBlocklistContent != null;
-  },
-
-  /* Used for testing */
-  _clear: function() {
-    this._addonEntries = null;
-    this._pluginEntries = null;
-    this._preloadedBlocklistContent = null;
-  },
-
-  _preloadBlocklist: Task.async(function*() {
-    let profPath = OS.Path.join(OS.Constants.Path.profileDir, FILE_BLOCKLIST);
-    try {
-      yield this._preloadBlocklistFile(profPath);
-      return;
-    } catch (e) {
-      LOG("Blocklist::_preloadBlocklist: Failed to load XML file " + e)
-    }
-
-    var appFile = FileUtils.getFile(KEY_APPDIR, [FILE_BLOCKLIST]);
-    try{
-      yield this._preloadBlocklistFile(appFile.path);
-      return;
-    } catch (e) {
-      LOG("Blocklist::_preloadBlocklist: Failed to load XML file " + e)
-    }
-
-    LOG("Blocklist::_preloadBlocklist: no XML File found");
-  }),
-
-  _preloadBlocklistFile: Task.async(function*(path){
-    if (this._addonEntries) {
-      // The file has been already loaded.
-      return;
-    }
-
-    if (!gBlocklistEnabled) {
-      LOG("Blocklist::_preloadBlocklistFile: blocklist is disabled");
-      return;
-    }
-
-    let text = yield OS.File.read(path, { encoding: "utf-8" });
-
-    if (!this._addonEntries) {
-      // Store the content only if a sync load has not been performed in the meantime.
-      this._preloadedBlocklistContent = text;
-    }
-  }),
-
-  _loadBlocklistFromString : function(text) {
     try {
       var parser = Cc["@mozilla.org/xmlextras/domparser;1"].
                    createInstance(Ci.nsIDOMParser);
       var doc = parser.parseFromString(text, "text/xml");
       if (doc.documentElement.namespaceURI != XMLURI_BLOCKLIST) {
         LOG("Blocklist::_loadBlocklistFromFile: aborting due to incorrect " +
             "XML Namespace.\r\nExpected: " + XMLURI_BLOCKLIST + "\r\n" +
             "Received: " + doc.documentElement.namespaceURI);