B2G/gecko/toolkit/mozapps/extensions/XPIProvider.jsm
/**
   * Initialises this install to be an install from a local file.
   *
   * @param  aCallback
   *         The callback to pass the initialised AddonInstall to
   */
Initialises this install to be an install from a local file.
@param  aCallback
The callback to pass the initialised AddonInstall to
Initialises this install to be an install from a local file . @param aCallback The callback to pass the initialised AddonInstall to
function AI_initLocalInstall(aCallback) {
    this.file = this.sourceURI.QueryInterface(Ci.nsIFileURL).file;
    if (!this.file.exists()) {
      WARN("XPI file " + this.file.path + " does not exist");
      this.state = AddonManager.STATE_DOWNLOAD_FAILED;
      this.error = AddonManager.ERROR_NETWORK_FAILURE;
      aCallback(this);
      return;
    }
    this.state = AddonManager.STATE_DOWNLOADED;
    this.progress = this.file.fileSize;
    this.maxProgress = this.file.fileSize;
    if (this.hash) {
      let crypto = Cc["@mozilla.org/security/hash;1"].
                   createInstance(Ci.nsICryptoHash);
      try {
        crypto.initWithString(this.hash.algorithm);
      }
      catch (e) {
        WARN("Unknown hash algorithm " + this.hash.algorithm);
        this.state = AddonManager.STATE_DOWNLOAD_FAILED;
        this.error = AddonManager.ERROR_INCORRECT_HASH;
        aCallback(this);
        return;
      }
      let fis = Cc["@mozilla.org/network/file-input-stream;1"].
                createInstance(Ci.nsIFileInputStream);
      fis.init(this.file, -1, -1, false);
      crypto.updateFromStream(fis, this.file.fileSize);
      let calculatedHash = getHashStringForCrypto(crypto);
      if (calculatedHash != this.hash.data) {
        WARN("File hash (" + calculatedHash + ") did not match provided hash (" +
             this.hash.data + ")");
        this.state = AddonManager.STATE_DOWNLOAD_FAILED;
        this.error = AddonManager.ERROR_INCORRECT_HASH;
        aCallback(this);
        return;
      }
    }
    try {
      let self = this;
      this.loadManifest(function  initLocalInstall_loadManifest() {
        XPIDatabase.getVisibleAddonForID(self.addon.id, function initLocalInstall_getVisibleAddon(aAddon) {
          self.existingAddon = aAddon;
          if (aAddon)
            applyBlocklistChanges(aAddon, self.addon);
          self.addon.updateDate = Date.now();
          self.addon.installDate = aAddon ? aAddon.installDate : self.addon.updateDate;
          if (!self.addon.isCompatible) {
            self.state = AddonManager.STATE_CHECKING;
            new UpdateChecker(self.addon, {
              onUpdateFinished: function updateChecker_onUpdateFinished(aAddon) {
                self.state = AddonManager.STATE_DOWNLOADED;
                XPIProvider.installs.push(self);
                AddonManagerPrivate.callInstallListeners("onNewInstall",
                                                         self.listeners,
                                                         self.wrapper);
                aCallback(self);
              }
            }, AddonManager.UPDATE_WHEN_ADDON_INSTALLED);
          }
          else {
            XPIProvider.installs.push(self);
            AddonManagerPrivate.callInstallListeners("onNewInstall",
                                                     self.listeners,
                                                     self.wrapper);
            aCallback(self);
          }
        });
      });
    }
    catch (e) {
      WARN("Invalid XPI", e);
      this.state = AddonManager.STATE_DOWNLOAD_FAILED;
      this.error = AddonManager.ERROR_CORRUPT_FILE;
      aCallback(this);
      return;
    }
  }
function AI_initLocalInstall ( aCallback ) { this . file = this . sourceURI . QueryInterface ( Ci . nsIFileURL ) . file ; if ( ! this . file . exists ( ) ) { WARN ( "XPI file " + this . file . path + " does not exist" ) ; this . state = AddonManager . STATE_DOWNLOAD_FAILED ; this . error = AddonManager . ERROR_NETWORK_FAILURE ; aCallback ( this ) ; return ; } this . state = AddonManager . STATE_DOWNLOADED ; this . progress = this . file . fileSize ; this . maxProgress = this . file . fileSize ; if ( this . hash ) { let crypto = Cc [ "@mozilla.org/security/hash;1" ] . createInstance ( Ci . nsICryptoHash ) ; try { crypto . initWithString ( this . hash . algorithm ) ; } catch ( e ) { WARN ( "Unknown hash algorithm " + this . hash . algorithm ) ; this . state = AddonManager . STATE_DOWNLOAD_FAILED ; this . error = AddonManager . ERROR_INCORRECT_HASH ; aCallback ( this ) ; return ; } let fis = Cc [ "@mozilla.org/network/file-input-stream;1" ] . createInstance ( Ci . nsIFileInputStream ) ; fis . init ( this . file , - 1 , - 1 , false ) ; crypto . updateFromStream ( fis , this . file . fileSize ) ; let calculatedHash = getHashStringForCrypto ( crypto ) ; if ( calculatedHash != this . hash . data ) { WARN ( "File hash (" + calculatedHash + ") did not match provided hash (" + this . hash . data + ")" ) ; this . state = AddonManager . STATE_DOWNLOAD_FAILED ; this . error = AddonManager . ERROR_INCORRECT_HASH ; aCallback ( this ) ; return ; } } try { let self = this ; this . loadManifest ( function initLocalInstall_loadManifest ( ) { XPIDatabase . getVisibleAddonForID ( self . addon . id , function initLocalInstall_getVisibleAddon ( aAddon ) { self . existingAddon = aAddon ; if ( aAddon ) applyBlocklistChanges ( aAddon , self . addon ) ; self . addon . updateDate = Date . now ( ) ; self . addon . installDate = aAddon ? aAddon . installDate : self . addon . updateDate ; if ( ! self . addon . isCompatible ) { self . state = AddonManager . STATE_CHECKING ; new UpdateChecker ( self . addon , { onUpdateFinished : function updateChecker_onUpdateFinished ( aAddon ) { self . state = AddonManager . STATE_DOWNLOADED ; XPIProvider . installs . push ( self ) ; AddonManagerPrivate . callInstallListeners ( "onNewInstall" , self . listeners , self . wrapper ) ; aCallback ( self ) ; } } , AddonManager . UPDATE_WHEN_ADDON_INSTALLED ) ; } else { XPIProvider . installs . push ( self ) ; AddonManagerPrivate . callInstallListeners ( "onNewInstall" , self . listeners , self . wrapper ) ; aCallback ( self ) ; } } ) ; } ) ; } catch ( e ) { WARN ( "Invalid XPI" , e ) ; this . state = AddonManager . STATE_DOWNLOAD_FAILED ; this . error = AddonManager . ERROR_CORRUPT_FILE ; aCallback ( this ) ; return ; } }
Initialises this install to be an install from a local file.
Initialises this install to be an install from a local file .
// TODO Should we send some event here?