Bug 1314177 - remove redundancy in install location classes r?aswan draft
authorRobert Helmer <rhelmer@mozilla.com>
Tue, 28 Mar 2017 12:29:53 -0700
changeset 556494 1e8486acfd2b5fde03ef0837de2b3d53ac82bfa7
parent 556289 1237a9b88402db286ab4144d5113c24533d0fabe
child 622910 d9be052d5842ab017a2e2dea4def220d96bab145
push id52571
push userrhelmer@mozilla.com
push dateThu, 06 Apr 2017 00:06:37 +0000
reviewersaswan
bugs1314177
milestone55.0a1
Bug 1314177 - remove redundancy in install location classes r?aswan MozReview-Commit-ID: H4dTeU3N8zI
toolkit/mozapps/extensions/internal/XPIProvider.jsm
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -8496,53 +8496,16 @@ class SystemAddonInstallLocation extends
     if (aResetSet) {
       this.resetAddonSet();
     }
 
     this.locked = false;
   }
 
   /**
-   * Removes the specified files or directories in the staging directory and
-   * then if the staging directory is empty attempts to remove it.
-   *
-   * @param  aLeafNames
-   *         An array of file or directory to remove from the directory, the
-   *         array may be empty
-   */
-  cleanStagingDir(aLeafNames = []) {
-    let dir = this.getStagingDir();
-
-    for (let name of aLeafNames) {
-      let file = dir.clone();
-      file.append(name);
-      recursiveRemove(file);
-    }
-
-    if (this._stagingDirLock > 0)
-      return;
-
-    let dirEntries = dir.directoryEntries.QueryInterface(Ci.nsIDirectoryEnumerator);
-    try {
-      if (dirEntries.nextFile)
-        return;
-    } finally {
-      dirEntries.close();
-    }
-
-    try {
-      setFilePermissions(dir, FileUtils.PERMS_DIRECTORY);
-      dir.remove(false);
-    } catch (e) {
-      logger.warn("Failed to remove staging dir", e);
-      // Failing to remove the staging directory is ignorable
-    }
-  }
-
-  /**
    * Gets the staging directory to put add-ons that are pending install and
    * uninstall into.
    *
    * @return {nsIFile} - staging directory for system add-on upgrades.
    */
   getStagingDir() {
     this._addonSet = SystemAddonInstallLocation._loadAddonSet();
     let dir = null;
@@ -8554,45 +8517,22 @@ class SystemAddonInstallLocation extends
     } else {
       logger.info("SystemAddonInstallLocation directory is missing");
     }
 
     return dir;
   }
 
   requestStagingDir() {
-    this._stagingDirLock++;
-    if (this._stagingDirPromise)
-      return this._stagingDirPromise;
-
     this._addonSet = SystemAddonInstallLocation._loadAddonSet();
     if (this._addonSet.directory) {
       this._directory = this._baseDir.clone();
       this._directory.append(this._addonSet.directory);
     }
-
-    OS.File.makeDir(this._directory.path);
-    let stagepath = OS.Path.join(this._directory.path, DIR_STAGE);
-    return this._stagingDirPromise = OS.File.makeDir(stagepath).then(null, (e) => {
-      if (e instanceof OS.File.Error && e.becauseExists)
-        return;
-      logger.error("Failed to create staging directory", e);
-      throw e;
-    });
-  }
-
-  releaseStagingDir() {
-    this._stagingDirLock--;
-
-    if (this._stagingDirLock == 0) {
-      this._stagingDirPromise = null;
-      this.cleanStagingDir();
-    }
-
-    return Promise.resolve();
+    return super.requestStagingDir();
   }
 
   /**
    * Reads the current set of system add-ons
    */
   static _loadAddonSet() {
     try {
       let setStr = Preferences.get(PREF_SYSTEM_ADDON_SET, null);
@@ -8610,17 +8550,17 @@ class SystemAddonInstallLocation extends
   }
 
   /**
    * Saves the current set of system add-ons
    *
    * @param {Object} aAddonSet - object containing schema, directory and set
    *                 of system add-on IDs and versions.
    */
-  _saveAddonSet(aAddonSet) {
+  static _saveAddonSet(aAddonSet) {
     Preferences.set(PREF_SYSTEM_ADDON_SET, JSON.stringify(aAddonSet));
   }
 
   getAddonLocations() {
     // Updated system add-ons are ignored in safe mode
     if (Services.appinfo.inSafeMode) {
       return new Map();
     }
@@ -8695,17 +8635,17 @@ class SystemAddonInstallLocation extends
    * Resets the add-on set so on the next startup the default set will be used.
    */
   resetAddonSet() {
     logger.info("Removing all system add-on upgrades.");
 
     // remove everything from the pref first, if uninstall
     // fails then at least they will not be re-activated on
     // next restart.
-    this._saveAddonSet({ schema: 1, addons: {} });
+    SystemAddonInstallLocation._saveAddonSet({ schema: 1, addons: {} });
 
     // If this is running at app startup, the pref being cleared
     // will cause later stages of startup to notice that the
     // old updates are now gone.
     //
     // Updates will only be explicitly uninstalled if they are
     // removed restartlessly, for instance if they are no longer
     // part of the latest update set.
@@ -8715,17 +8655,17 @@ class SystemAddonInstallLocation extends
           if (addon) {
             addon.uninstall();
           }
         });
       }
     }
   }
 
-  /**
+    /**
    * Removes any directories not currently in use or pending use after a
    * restart. Any errors that happen here don't really matter as we'll attempt
    * to cleanup again next time.
    */
   async cleanDirectories() {
     // System add-ons directory does not exist
     if (!(await OS.File.exists(this._baseDir.path))) {
       return;
@@ -8805,17 +8745,17 @@ class SystemAddonInstallLocation extends
         break;
       } catch (e) {
         logger.debug("Could not create new system add-on updates dir, retrying", e);
       }
     }
 
     // Record the new upgrade directory.
     let state = { schema: 1, directory: newDir.leafName, addons: {} };
-    this._saveAddonSet(state);
+    SystemAddonInstallLocation._saveAddonSet(state);
 
     this._nextDir = newDir;
     let location = this;
 
     let installs = [];
     for (let addon of aAddons) {
       let install = await createLocalInstall(addon._sourceBundle, location);
       installs.push(install);
@@ -8846,31 +8786,31 @@ class SystemAddonInstallLocation extends
       state = { schema: 1, directory: newDir.leafName, addons: {} };
       for (let addon of aAddons) {
         state.addons[addon.id] = {
           version: addon.version
         }
       }
 
       previousState = SystemAddonInstallLocation._loadAddonSet();
-      this._saveAddonSet(state);
+      SystemAddonInstallLocation._saveAddonSet(state);
 
       let blockers = aAddons.filter(
         addon => AddonManagerPrivate.hasUpgradeListener(addon.id)
       );
 
       if (blockers.length > 0) {
         await waitForAllPromises(installs.map(postponeAddon));
       } else {
         await waitForAllPromises(installs.map(installAddon));
       }
     } catch (e) {
       // Roll back to previous upgrade set (if present) on restart.
       if (previousState) {
-        this._saveAddonSet(previousState);
+        SystemAddonInstallLocation._saveAddonSet(previousState);
       }
       // Otherwise, roll back to built-in set on restart.
       // TODO try to do these restartlessly
       this.resetAddonSet();
 
       try {
         await OS.File.removeDir(newDir.path, { ignorePermissions: true });
       } catch (e) {
@@ -8879,17 +8819,17 @@ class SystemAddonInstallLocation extends
       throw e;
     }
   }
 
  /**
   * Resumes upgrade of a previously-delayed add-on set.
   */
   async resumeAddonSet(installs) {
-    function resumeAddon(install) {
+    async function resumeAddon(install) {
       install.state = AddonManager.STATE_DOWNLOADED;
       install.installLocation.releaseStagingDir();
       install.install();
     }
 
     let blockers = installs.filter(
       install => AddonManagerPrivate.hasUpgradeListener(install.addon.id)
     );
@@ -9000,16 +8940,18 @@ class WinRegInstallLocation extends Dire
     * @param  aName
     *         The string identifier of this Install Location.
     * @param  aRootKey
     *         The root key (one of the ROOT_KEY_ values from nsIWindowsRegKey).
     * @param  scope
     *         The scope of add-ons installed in this location
     */
   constructor(aName, aRootKey, aScope) {
+    super(aName, undefined, aScope);
+
     this.locked = true;
     this._name = aName;
     this._rootKey = aRootKey;
     this._scope = aScope;
     this._IDToFileMap = {};
 
     let path = this._appKeyPath + "\\Extensions";
     let key = Cc["@mozilla.org/windows-registry-key;1"].
@@ -9072,34 +9014,16 @@ class WinRegInstallLocation extends Dire
   /**
    * Gets the name of this install location.
    */
   get name() {
     return this._name;
   }
 
   /**
-   * Gets the scope of this install location.
-   */
-  get scope() {
-    return this._scope;
-  }
-
-  /**
-   * Gets an array of nsIFiles for add-ons installed in this location.
-   */
-  getAddonLocations() {
-    let locations = new Map();
-    for (let id in this._IDToFileMap) {
-      locations.set(id, this._IDToFileMap[id].clone());
-    }
-    return locations;
-  }
-
-  /**
    * @see DirectoryInstallLocation
    */
   isLinkedAddon(aId) {
     return true;
   }
 }
 
 var addonTypes = [