B2G/gecko/toolkit/mozapps/extensions/XPIProvider.jsm
/**
   * Starts the XPI provider initializes the install locations and prefs.
   *
   * @param  aAppChanged
   *         A tri-state value. Undefined means the current profile was created
   *         for this session, true means the profile already existed but was
   *         last used with an application with a different version number,
   *         false means that the profile was last used by this version of the
   *         application.
   * @param  aOldAppVersion
   *         The version of the application last run with this profile or null
   *         if it is a new profile or the version is unknown
   * @param  aOldPlatformVersion
   *         The version of the platform last run with this profile or null
   *         if it is a new profile or the version is unknown
   */
Starts the XPI provider initializes the install locations and prefs.
@param  aAppChanged
A tri-state value. Undefined means the current profile was created
for this session, true means the profile already existed but was
last used with an application with a different version number,
false means that the profile was last used by this version of the
application.
@param  aOldAppVersion
The version of the application last run with this profile or null
if it is a new profile or the version is unknown
@param  aOldPlatformVersion
The version of the platform last run with this profile or null
if it is a new profile or the version is unknown
Starts the XPI provider initializes the install locations and prefs . @param aAppChanged A tri - state value . Undefined means the current profile was created for this session true means the profile already existed but was last used with an application with a different version number false means that the profile was last used by this version of the application . @param aOldAppVersion The version of the application last run with this profile or null if it is a new profile or the version is unknown @param aOldPlatformVersion The version of the platform last run with this profile or null if it is a new profile or the version is unknown
function XPI_startup(aAppChanged, aOldAppVersion, aOldPlatformVersion) {
    LOG("startup");
    this.installs = [];
    this.installLocations = [];
    this.installLocationsByName = {};
    function addDirectoryInstallLocation(aName, aKey, aPaths, aScope, aLocked) {
      try {
        var dir = FileUtils.getDir(aKey, aPaths);
      }
      catch (e) {
        LOG("Skipping unavailable install location " + aName);
        return;
      }
      try {
        var location = new DirectoryInstallLocation(aName, dir, aScope, aLocked);
      }
      catch (e) {
        WARN("Failed to add directory install location " + aName, e);
        return;
      }
      XPIProvider.installLocations.push(location);
      XPIProvider.installLocationsByName[location.name] = location;
    }
    function addRegistryInstallLocation(aName, aRootkey, aScope) {
      try {
        var location = new WinRegInstallLocation(aName, aRootkey, aScope);
      }
      catch (e) {
        WARN("Failed to add registry install location " + aName, e);
        return;
      }
      XPIProvider.installLocations.push(location);
      XPIProvider.installLocationsByName[location.name] = location;
    }
    let hasRegistry = ("nsIWindowsRegKey" in Ci);
    let enabledScopes = Prefs.getIntPref(PREF_EM_ENABLED_SCOPES,
                                         AddonManager.SCOPE_ALL);
    if (enabledScopes & AddonManager.SCOPE_SYSTEM) {
      if (hasRegistry) {
        addRegistryInstallLocation("winreg-app-global",
                                   Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE,
                                   AddonManager.SCOPE_SYSTEM);
      }
      addDirectoryInstallLocation(KEY_APP_SYSTEM_LOCAL, "XRESysLExtPD",
                                  [Services.appinfo.ID],
                                  AddonManager.SCOPE_SYSTEM, true);
      addDirectoryInstallLocation(KEY_APP_SYSTEM_SHARE, "XRESysSExtPD",
                                  [Services.appinfo.ID],
                                  AddonManager.SCOPE_SYSTEM, true);
    }
    if (enabledScopes & AddonManager.SCOPE_APPLICATION) {
      addDirectoryInstallLocation(KEY_APP_GLOBAL, KEY_APPDIR,
                                  [DIR_EXTENSIONS],
                                  AddonManager.SCOPE_APPLICATION, true);
    }
    if (enabledScopes & AddonManager.SCOPE_USER) {
      if (hasRegistry) {
        addRegistryInstallLocation("winreg-app-user",
                                   Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
                                   AddonManager.SCOPE_USER);
      }
      addDirectoryInstallLocation(KEY_APP_SYSTEM_USER, "XREUSysExt",
                                  [Services.appinfo.ID],
                                  AddonManager.SCOPE_USER, true);
    }
    addDirectoryInstallLocation(KEY_APP_PROFILE, KEY_PROFILEDIR,
                                [DIR_EXTENSIONS],
                                AddonManager.SCOPE_PROFILE, false);
    this.defaultSkin = Prefs.getDefaultCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN,
                                                "classic/1.0");
    this.currentSkin = Prefs.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN,
                                         this.defaultSkin);
    this.selectedSkin = this.currentSkin;
    this.applyThemeChange();
    this.minCompatibleAppVersion = Prefs.getCharPref(PREF_EM_MIN_COMPAT_APP_VERSION,
                                                     null);
    this.minCompatiblePlatformVersion = Prefs.getCharPref(PREF_EM_MIN_COMPAT_PLATFORM_VERSION,
                                                          null);
    this.enabledAddons = [];
    Services.prefs.addObserver(PREF_EM_MIN_COMPAT_APP_VERSION, this, false);
    Services.prefs.addObserver(PREF_EM_MIN_COMPAT_PLATFORM_VERSION, this, false);
    let flushCaches = this.checkForChanges(aAppChanged, aOldAppVersion,
                                           aOldPlatformVersion);
    this.applyThemeChange();
    if (aAppChanged && !this.allAppGlobal &&
        Prefs.getBoolPref(PREF_EM_SHOW_MISMATCH_UI, true)) {
      this.showUpgradeUI();
      flushCaches = true;
    }
    else if (aAppChanged === undefined) {
      Services.prefs.setBoolPref(PREF_SHOWN_SELECTION_UI, true);
    }
    if (flushCaches) {
      flushStartupCache();
      Services.obs.notifyObservers(null, "chrome-flush-skin-caches", null);
      Services.obs.notifyObservers(null, "chrome-flush-caches", null);
    }
    this.enabledAddons = Prefs.getCharPref(PREF_EM_ENABLED_ADDONS, "");
    if ("nsICrashReporter" in Ci &&
        Services.appinfo instanceof Ci.nsICrashReporter) {
      try {
        Services.appinfo.annotateCrashReport("Theme", this.currentSkin);
      } catch (e) { }
      try {
        Services.appinfo.annotateCrashReport("EMCheckCompatibility",
                                             AddonManager.checkCompatibility);
      } catch (e) { }
      this.addAddonsToCrashReporter();
    }
    for (let id in this.bootstrappedAddons) {
      let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
      file.persistentDescriptor = this.bootstrappedAddons[id].descriptor;
      this.callBootstrapMethod(id, this.bootstrappedAddons[id].version,
                               this.bootstrappedAddons[id].type, file,
                               "startup", BOOTSTRAP_REASONS.APP_STARTUP);
    }
    Services.obs.addObserver({
      observe: function shutdownObserver(aSubject, aTopic, aData) {
        Services.prefs.setCharPref(PREF_BOOTSTRAP_ADDONS,
                                   JSON.stringify(XPIProvider.bootstrappedAddons));
        for (let id in XPIProvider.bootstrappedAddons) {
          let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
          file.persistentDescriptor = XPIProvider.bootstrappedAddons[id].descriptor;
          XPIProvider.callBootstrapMethod(id, XPIProvider.bootstrappedAddons[id].version,
                                          XPIProvider.bootstrappedAddons[id].type, file, "shutdown",
                                          BOOTSTRAP_REASONS.APP_SHUTDOWN);
        }
        Services.obs.removeObserver(this, "quit-application-granted");
      }
    }, "quit-application-granted", false);
    this.extensionsActive = true;
  }
function XPI_startup ( aAppChanged , aOldAppVersion , aOldPlatformVersion ) { LOG ( "startup" ) ; this . installs = [ ] ; this . installLocations = [ ] ; this . installLocationsByName = { } ; function addDirectoryInstallLocation ( aName , aKey , aPaths , aScope , aLocked ) { try { var dir = FileUtils . getDir ( aKey , aPaths ) ; } catch ( e ) { LOG ( "Skipping unavailable install location " + aName ) ; return ; } try { var location = new DirectoryInstallLocation ( aName , dir , aScope , aLocked ) ; } catch ( e ) { WARN ( "Failed to add directory install location " + aName , e ) ; return ; } XPIProvider . installLocations . push ( location ) ; XPIProvider . installLocationsByName [ location . name ] = location ; } function addRegistryInstallLocation ( aName , aRootkey , aScope ) { try { var location = new WinRegInstallLocation ( aName , aRootkey , aScope ) ; } catch ( e ) { WARN ( "Failed to add registry install location " + aName , e ) ; return ; } XPIProvider . installLocations . push ( location ) ; XPIProvider . installLocationsByName [ location . name ] = location ; } let hasRegistry = ( "nsIWindowsRegKey" in Ci ) ; let enabledScopes = Prefs . getIntPref ( PREF_EM_ENABLED_SCOPES , AddonManager . SCOPE_ALL ) ; if ( enabledScopes & AddonManager . SCOPE_SYSTEM ) { if ( hasRegistry ) { addRegistryInstallLocation ( "winreg-app-global" , Ci . nsIWindowsRegKey . ROOT_KEY_LOCAL_MACHINE , AddonManager . SCOPE_SYSTEM ) ; } addDirectoryInstallLocation ( KEY_APP_SYSTEM_LOCAL , "XRESysLExtPD" , [ Services . appinfo . ID ] , AddonManager . SCOPE_SYSTEM , true ) ; addDirectoryInstallLocation ( KEY_APP_SYSTEM_SHARE , "XRESysSExtPD" , [ Services . appinfo . ID ] , AddonManager . SCOPE_SYSTEM , true ) ; } if ( enabledScopes & AddonManager . SCOPE_APPLICATION ) { addDirectoryInstallLocation ( KEY_APP_GLOBAL , KEY_APPDIR , [ DIR_EXTENSIONS ] , AddonManager . SCOPE_APPLICATION , true ) ; } if ( enabledScopes & AddonManager . SCOPE_USER ) { if ( hasRegistry ) { addRegistryInstallLocation ( "winreg-app-user" , Ci . nsIWindowsRegKey . ROOT_KEY_CURRENT_USER , AddonManager . SCOPE_USER ) ; } addDirectoryInstallLocation ( KEY_APP_SYSTEM_USER , "XREUSysExt" , [ Services . appinfo . ID ] , AddonManager . SCOPE_USER , true ) ; } addDirectoryInstallLocation ( KEY_APP_PROFILE , KEY_PROFILEDIR , [ DIR_EXTENSIONS ] , AddonManager . SCOPE_PROFILE , false ) ; this . defaultSkin = Prefs . getDefaultCharPref ( PREF_GENERAL_SKINS_SELECTEDSKIN , "classic/1.0" ) ; this . currentSkin = Prefs . getCharPref ( PREF_GENERAL_SKINS_SELECTEDSKIN , this . defaultSkin ) ; this . selectedSkin = this . currentSkin ; this . applyThemeChange ( ) ; this . minCompatibleAppVersion = Prefs . getCharPref ( PREF_EM_MIN_COMPAT_APP_VERSION , null ) ; this . minCompatiblePlatformVersion = Prefs . getCharPref ( PREF_EM_MIN_COMPAT_PLATFORM_VERSION , null ) ; this . enabledAddons = [ ] ; Services . prefs . addObserver ( PREF_EM_MIN_COMPAT_APP_VERSION , this , false ) ; Services . prefs . addObserver ( PREF_EM_MIN_COMPAT_PLATFORM_VERSION , this , false ) ; let flushCaches = this . checkForChanges ( aAppChanged , aOldAppVersion , aOldPlatformVersion ) ; this . applyThemeChange ( ) ; if ( aAppChanged && ! this . allAppGlobal && Prefs . getBoolPref ( PREF_EM_SHOW_MISMATCH_UI , true ) ) { this . showUpgradeUI ( ) ; flushCaches = true ; } else if ( aAppChanged === undefined ) { Services . prefs . setBoolPref ( PREF_SHOWN_SELECTION_UI , true ) ; } if ( flushCaches ) { flushStartupCache ( ) ; Services . obs . notifyObservers ( null , "chrome-flush-skin-caches" , null ) ; Services . obs . notifyObservers ( null , "chrome-flush-caches" , null ) ; } this . enabledAddons = Prefs . getCharPref ( PREF_EM_ENABLED_ADDONS , "" ) ; if ( "nsICrashReporter" in Ci && Services . appinfo instanceof Ci . nsICrashReporter ) { try { Services . appinfo . annotateCrashReport ( "Theme" , this . currentSkin ) ; } catch ( e ) { } try { Services . appinfo . annotateCrashReport ( "EMCheckCompatibility" , AddonManager . checkCompatibility ) ; } catch ( e ) { } this . addAddonsToCrashReporter ( ) ; } for ( let id in this . bootstrappedAddons ) { let file = Cc [ "@mozilla.org/file/local;1" ] . createInstance ( Ci . nsIFile ) ; file . persistentDescriptor = this . bootstrappedAddons [ id ] . descriptor ; this . callBootstrapMethod ( id , this . bootstrappedAddons [ id ] . version , this . bootstrappedAddons [ id ] . type , file , "startup" , BOOTSTRAP_REASONS . APP_STARTUP ) ; } Services . obs . addObserver ( { observe : function shutdownObserver ( aSubject , aTopic , aData ) { Services . prefs . setCharPref ( PREF_BOOTSTRAP_ADDONS , JSON . stringify ( XPIProvider . bootstrappedAddons ) ) ; for ( let id in XPIProvider . bootstrappedAddons ) { let file = Cc [ "@mozilla.org/file/local;1" ] . createInstance ( Ci . nsIFile ) ; file . persistentDescriptor = XPIProvider . bootstrappedAddons [ id ] . descriptor ; XPIProvider . callBootstrapMethod ( id , XPIProvider . bootstrappedAddons [ id ] . version , XPIProvider . bootstrappedAddons [ id ] . type , file , "shutdown" , BOOTSTRAP_REASONS . APP_SHUTDOWN ) ; } Services . obs . removeObserver ( this , "quit-application-granted" ) ; } } , "quit-application-granted" , false ) ; this . extensionsActive = true ; }
Starts the XPI provider initializes the install locations and prefs.
Starts the XPI provider initializes the install locations and prefs .
// Some directories aren't defined on some platforms, ignore them // These must be in order of priority for processFileChanges etc. to work // The profile location is always enabled // Changes to installed extensions may have changed which theme is selected // If the application has been upgraded and there are add-ons outside the // application directory then we may need to synchronize compatibility // information but only if the mismatch UI isn't disabled // For new profiles we will never need to show the add-on selection UI // UI displayed early in startup (like the compatibility UI) may have // caused us to cache parts of the skin or locale in memory. These must // be flushed to allow extension provided skins and locales to take full // effect // Annotate the crash report with relevant add-on information. // Let these shutdown a little earlier when they still have access to most // of XPCOM