Backed out 4 changesets (bug 1192921) for b2g desktop Gu hangs

Backed out changeset 1bfa2dead61f (bug 1192921)
Backed out changeset f310cab1dd4e (bug 1192921)
Backed out changeset c3009691dfe6 (bug 1192921)
Backed out changeset d8233b994741 (bug 1192921)
This commit is contained in:
Phil Ringnalda 2015-09-03 20:53:50 -07:00
Родитель eaf07adf5d
Коммит 48457bc69c
20 изменённых файлов: 800 добавлений и 1240 удалений

Просмотреть файл

@ -1646,7 +1646,6 @@ var AddonManagerInternal = {
if (gStartupComplete) if (gStartupComplete)
return; return;
logger.debug("Registering startup change '" + aType + "' for " + aID);
// Ensure that an ID is only listed in one type of change // Ensure that an ID is only listed in one type of change
for (let type in this.startupChanges) for (let type in this.startupChanges)

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -314,15 +314,13 @@ function DBAddonInternal(aLoaded) {
this._key = this.location + ":" + this.id; this._key = this.location + ":" + this.id;
if (aLoaded._sourceBundle) { try {
this._sourceBundle = aLoaded._sourceBundle; this._sourceBundle = this._installLocation.getLocationForID(this.id);
} }
else if (aLoaded.descriptor) { catch (e) {
this._sourceBundle = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); // An exception will be thrown if the add-on appears in the database but
this._sourceBundle.persistentDescriptor = aLoaded.descriptor; // not on disk. In general this should only happen during startup as
} // this change is being detected.
else {
throw new Error("Expected passed argument to contain a descriptor");
} }
XPCOMUtils.defineLazyGetter(this, "pendingUpgrade", XPCOMUtils.defineLazyGetter(this, "pendingUpgrade",
@ -787,7 +785,7 @@ this.XPIDatabase = {
if (aRebuildOnError) { if (aRebuildOnError) {
logger.warn("Rebuilding add-ons database from installed extensions."); logger.warn("Rebuilding add-ons database from installed extensions.");
try { try {
XPIDatabaseReconcile.processFileChanges({}, false); XPIProvider.processFileChanges({}, false);
} }
catch (e) { catch (e) {
logger.error("Failed to rebuild XPI database from installed extensions", e); logger.error("Failed to rebuild XPI database from installed extensions", e);
@ -1086,7 +1084,7 @@ this.XPIDatabase = {
}) })
.then(null, .then(null,
error => { error => {
logger.error("getAddon failed", error); logger.error("getAddon failed", e);
makeSafe(aCallback)(null); makeSafe(aCallback)(null);
}); });
}, },
@ -1303,7 +1301,6 @@ this.XPIDatabase = {
if ((otherAddon.id == aAddon.id) && (otherAddon._key != aAddon._key)) { if ((otherAddon.id == aAddon.id) && (otherAddon._key != aAddon._key)) {
logger.debug("Hide addon " + otherAddon._key); logger.debug("Hide addon " + otherAddon._key);
otherAddon.visible = false; otherAddon.visible = false;
otherAddon.active = false;
} }
} }
aAddon.visible = true; aAddon.visible = true;
@ -1491,638 +1488,3 @@ this.XPIDatabase = {
return true; return true;
} }
}; };
this.XPIDatabaseReconcile = {
/**
* Returns a map of ID -> add-on. When the same add-on ID exists in multiple
* install locations the highest priority location is chosen.
*/
flattenByID(addonMap, hideLocation) {
let map = new Map();
for (let installLocation of XPIProvider.installLocations) {
if (installLocation.name == hideLocation)
continue;
let locationMap = addonMap.get(installLocation.name);
if (!locationMap)
continue;
for (let [id, addon] of locationMap) {
if (!map.has(id))
map.set(id, addon);
}
}
return map;
},
/**
* Finds the visible add-ons from the map.
*/
getVisibleAddons(addonMap) {
let map = new Map();
for (let [location, addons] of addonMap) {
for (let [id, addon] of addons) {
if (!addon.visible)
continue;
if (map.has(id)) {
logger.warn("Previous database listed more than one visible add-on with id " + id);
continue;
}
map.set(id, addon);
}
}
return map;
},
/**
* Called to add the metadata for an add-on in one of the install locations
* to the database. This can be called in three different cases. Either an
* add-on has been dropped into the location from outside of Firefox, or
* an add-on has been installed through the application, or the database
* has been upgraded or become corrupt and add-on data has to be reloaded
* into it.
*
* @param aInstallLocation
* The install location containing the add-on
* @param aId
* The ID of the add-on
* @param aAddonState
* The new state of the add-on
* @param aNewAddon
* The manifest for the new add-on if it has already been loaded
* @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
* @param aMigrateData
* If during startup the database had to be upgraded this will
* contain data that used to be held about this add-on
* @return a boolean indicating if flushing caches is required to complete
* changing this add-on
*/
addMetadata(aInstallLocation, aId, aAddonState, aNewAddon, aOldAppVersion,
aOldPlatformVersion, aMigrateData) {
logger.debug("New add-on " + aId + " installed in " + aInstallLocation.name);
// If we had staged data for this add-on or we aren't recovering from a
// corrupt database and we don't have migration data for this add-on then
// this must be a new install.
let isNewInstall = (!!aNewAddon) || (!XPIDatabase.activeBundles && !aMigrateData);
// If it's a new install and we haven't yet loaded the manifest then it
// must be something dropped directly into the install location
let isDetectedInstall = isNewInstall && !aNewAddon;
// Load the manifest if necessary and sanity check the add-on ID
try {
if (!aNewAddon) {
// Load the manifest from the add-on.
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.persistentDescriptor = aAddonState.descriptor;
aNewAddon = syncLoadManifestFromFile(file);
}
// The add-on in the manifest should match the add-on ID.
if (aNewAddon.id != aId) {
throw new Error("Invalid addon ID: expected addon ID " + aId +
", found " + aNewAddon.id + " in manifest");
}
}
catch (e) {
logger.warn("addMetadata: Add-on " + aId + " is invalid", e);
// Remove the invalid add-on from the install location if the install
// location isn't locked, no restart will be necessary
if (!aInstallLocation.locked)
aInstallLocation.uninstallAddon(aId);
else
logger.warn("Could not uninstall invalid item from locked install location");
return null;
}
// Update the AddonInternal properties.
aNewAddon._installLocation = aInstallLocation;
aNewAddon.installDate = aAddonState.mtime;
aNewAddon.updateDate = aAddonState.mtime;
// Assume that add-ons in the system add-ons install location aren't
// foreign and should default to enabled.
aNewAddon.foreignInstall = isDetectedInstall &&
aInstallLocation.name != KEY_APP_SYSTEM_ADDONS &&
aInstallLocation.name != KEY_APP_SYSTEM_DEFAULTS;
// appDisabled depends on whether the add-on is a foreignInstall so update
aNewAddon.appDisabled = !isUsableAddon(aNewAddon);
if (aMigrateData) {
// If there is migration data then apply it.
logger.debug("Migrating data from old database");
DB_MIGRATE_METADATA.forEach(function(aProp) {
// A theme's disabled state is determined by the selected theme
// preference which is read in loadManifestFromRDF
if (aProp == "userDisabled" && aNewAddon.type == "theme")
return;
if (aProp in aMigrateData)
aNewAddon[aProp] = aMigrateData[aProp];
});
// Force all non-profile add-ons to be foreignInstalls since they can't
// have been installed through the API
aNewAddon.foreignInstall |= aInstallLocation.name != KEY_APP_PROFILE;
// Some properties should only be migrated if the add-on hasn't changed.
// The version property isn't a perfect check for this but covers the
// vast majority of cases.
if (aMigrateData.version == aNewAddon.version) {
logger.debug("Migrating compatibility info");
if ("targetApplications" in aMigrateData)
aNewAddon.applyCompatibilityUpdate(aMigrateData, true);
}
// Since the DB schema has changed make sure softDisabled is correct
applyBlocklistChanges(aNewAddon, aNewAddon, aOldAppVersion,
aOldPlatformVersion);
}
// The default theme is never a foreign install
if (aNewAddon.type == "theme" && aNewAddon.internalName == XPIProvider.defaultSkin)
aNewAddon.foreignInstall = false;
if (isDetectedInstall && aNewAddon.foreignInstall) {
// If the add-on is a foreign install and is in a scope where add-ons
// that were dropped in should default to disabled then disable it
let disablingScopes = Preferences.get(PREF_EM_AUTO_DISABLED_SCOPES, 0);
if (aInstallLocation.scope & disablingScopes) {
logger.warn("Disabling foreign installed add-on " + aNewAddon.id + " in "
+ aInstallLocation.name);
aNewAddon.userDisabled = true;
}
}
return XPIDatabase.addAddonMetadata(aNewAddon, aAddonState.descriptor);
},
/**
* Called when an add-on has been removed.
*
* @param aOldAddon
* The AddonInternal as it appeared the last time the application
* ran
* @return a boolean indicating if flushing caches is required to complete
* changing this add-on
*/
removeMetadata(aOldAddon) {
// This add-on has disappeared
logger.debug("Add-on " + aOldAddon.id + " removed from " + aOldAddon.location);
XPIDatabase.removeAddonMetadata(aOldAddon);
},
/**
* Updates an add-on's metadata and determines if a restart of the
* application is necessary. This is called when either the add-on's
* install directory path or last modified time has changed.
*
* @param aInstallLocation
* The install location containing the add-on
* @param aOldAddon
* The AddonInternal as it appeared the last time the application
* ran
* @param aAddonState
* The new state of the add-on
* @param aNewAddon
* The manifest for the new add-on if it has already been loaded
* @return a boolean indicating if flushing caches is required to complete
* changing this add-on
*/
updateMetadata(aInstallLocation, aOldAddon, aAddonState, aNewAddon) {
logger.debug("Add-on " + aOldAddon.id + " modified in " + aInstallLocation.name);
try {
// If there isn't an updated install manifest for this add-on then load it.
if (!aNewAddon) {
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.persistentDescriptor = aAddonState.descriptor;
aNewAddon = syncLoadManifestFromFile(file);
applyBlocklistChanges(aOldAddon, aNewAddon);
// Carry over any pendingUninstall state to add-ons modified directly
// in the profile. This is important when the attempt to remove the
// add-on in processPendingFileChanges failed and caused an mtime
// change to the add-ons files.
aNewAddon.pendingUninstall = aOldAddon.pendingUninstall;
}
// The ID in the manifest that was loaded must match the ID of the old
// add-on.
if (aNewAddon.id != aOldAddon.id)
throw new Error("Incorrect id in install manifest for existing add-on " + aOldAddon.id);
}
catch (e) {
logger.warn("updateMetadata: Add-on " + aOldAddon.id + " is invalid", e);
XPIDatabase.removeAddonMetadata(aOldAddon);
XPIStates.removeAddon(aOldAddon.location, aOldAddon.id);
if (!aInstallLocation.locked)
aInstallLocation.uninstallAddon(aOldAddon.id);
else
logger.warn("Could not uninstall invalid item from locked install location");
return null;
}
// Set the additional properties on the new AddonInternal
aNewAddon._installLocation = aInstallLocation;
aNewAddon.updateDate = aAddonState.mtime;
// Update the database
return XPIDatabase.updateAddonMetadata(aOldAddon, aNewAddon, aAddonState.descriptor);
},
/**
* Updates an add-on's descriptor for when the add-on has moved in the
* filesystem but hasn't changed in any other way.
*
* @param aInstallLocation
* The install location containing the add-on
* @param aOldAddon
* The AddonInternal as it appeared the last time the application
* ran
* @param aAddonState
* The new state of the add-on
* @return a boolean indicating if flushing caches is required to complete
* changing this add-on
*/
updateDescriptor(aInstallLocation, aOldAddon, aAddonState) {
logger.debug("Add-on " + aOldAddon.id + " moved to " + aAddonState.descriptor);
aOldAddon.descriptor = aAddonState.descriptor;
aOldAddon._sourceBundle.persistentDescriptor = aAddonState.descriptor;
return aOldAddon;
},
/**
* Called when no change has been detected for an add-on's metadata but the
* application has changed so compatibility may have changed.
*
* @param aInstallLocation
* The install location containing the add-on
* @param aOldAddon
* The AddonInternal as it appeared the last time the application
* ran
* @param aAddonState
* The new state of the add-on
* @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
* @return a boolean indicating if flushing caches is required to complete
* changing this add-on
*/
updateCompatibility(aInstallLocation, aOldAddon, aAddonState, aOldAppVersion, aOldPlatformVersion) {
logger.debug("Updating compatibility for add-on " + aOldAddon.id + " in " + aInstallLocation.name);
// If updating from a version of the app that didn't support signedState
// then fetch that property now
if (aOldAddon.signedState === undefined && ADDON_SIGNING &&
SIGNED_TYPES.has(aOldAddon.type)) {
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.persistentDescriptor = aAddonState.descriptor;
let manifest = syncLoadManifestFromFile(file);
aOldAddon.signedState = manifest.signedState;
}
// This updates the addon's JSON cached data in place
applyBlocklistChanges(aOldAddon, aOldAddon, aOldAppVersion,
aOldPlatformVersion);
aOldAddon.appDisabled = !isUsableAddon(aOldAddon);
return aOldAddon;
},
/**
* Compares the add-ons that are currently installed to those that were
* known to be installed when the application last ran and applies any
* changes found to the database. Also sends "startupcache-invalidate" signal to
* observerservice if it detects that data may have changed.
* Always called after XPIProviderUtils.js and extensions.json have been loaded.
*
* @param aManifests
* A dictionary of cached AddonInstalls for add-ons that have been
* installed
* @param aUpdateCompatibility
* true to update add-ons appDisabled property when the application
* version has changed
* @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
* @return a boolean indicating if a change requiring flushing the caches was
* detected
*/
processFileChanges(aManifests, aUpdateCompatibility, aOldAppVersion, aOldPlatformVersion) {
let loadedManifest = (aInstallLocation, aId) => {
if (!(aInstallLocation.name in aManifests))
return null;
if (!(aId in aManifests[aInstallLocation.name]))
return null;
return aManifests[aInstallLocation.name][aId];
};
// Get the previous add-ons from the database and put them into maps by location
let previousAddons = new Map();
for (let a of XPIDatabase.getAddons()) {
let locationAddonMap = previousAddons.get(a.location);
if (!locationAddonMap) {
locationAddonMap = new Map();
previousAddons.set(a.location, locationAddonMap);
}
locationAddonMap.set(a.id, a);
}
// Build the list of current add-ons into similar maps. When add-ons are still
// present we re-use the add-on objects from the database and update their
// details directly
let currentAddons = new Map();
for (let installLocation of XPIProvider.installLocations) {
let locationAddonMap = new Map();
currentAddons.set(installLocation.name, locationAddonMap);
// Get all the on-disk XPI states for this location, and keep track of which
// ones we see in the database.
let states = XPIStates.getLocation(installLocation.name);
// Iterate through the add-ons installed the last time the application
// ran
let dbAddons = previousAddons.get(installLocation.name);
if (dbAddons) {
for (let [id, oldAddon] of dbAddons) {
// Check if the add-on is still installed
let xpiState = states && states.get(id);
if (xpiState) {
// Here the add-on was present in the database and on disk
recordAddonTelemetry(oldAddon);
// Check if the add-on has been changed outside the XPI provider
if (oldAddon.updateDate != xpiState.mtime) {
// Did time change in the wrong direction?
if (xpiState.mtime < oldAddon.updateDate) {
XPIProvider.setTelemetry(oldAddon.id, "olderFile", {
name: XPIProvider._mostRecentlyModifiedFile[id],
mtime: xpiState.mtime,
oldtime: oldAddon.updateDate
});
} else {
XPIProvider.setTelemetry(oldAddon.id, "modifiedFile",
XPIProvider._mostRecentlyModifiedFile[id]);
}
}
// The add-on has changed if the modification time has changed, or
// we have an updated manifest for it. Also reload the metadata for
// add-ons in the application directory when the application version
// has changed
let newAddon = loadedManifest(installLocation, id);
if (newAddon || oldAddon.updateDate != xpiState.mtime ||
(aUpdateCompatibility && (installLocation.name == KEY_APP_GLOBAL ||
installLocation.name == KEY_APP_SYSTEM_DEFAULTS))) {
newAddon = this.updateMetadata(installLocation, oldAddon, xpiState, newAddon);
}
else if (oldAddon.descriptor != xpiState.descriptor) {
newAddon = this.updateDescriptor(installLocation, oldAddon, xpiState);
}
else if (aUpdateCompatibility) {
newAddon = this.updateCompatibility(installLocation, oldAddon, xpiState,
aOldAppVersion, aOldPlatformVersion);
}
else {
// No change
newAddon = oldAddon;
}
if (newAddon)
locationAddonMap.set(newAddon.id, newAddon);
}
else {
// The add-on is in the DB, but not in xpiState (and thus not on disk).
this.removeMetadata(oldAddon);
}
}
}
// Any add-on in our current location that we haven't seen needs to
// be added to the database.
// Get the migration data for this install location so we can include that as
// we add, in case this is a database upgrade or rebuild.
let locMigrateData = {};
if (XPIDatabase.migrateData && installLocation.name in XPIDatabase.migrateData)
locMigrateData = XPIDatabase.migrateData[installLocation.name];
if (states) {
for (let [id, xpiState] of states) {
if (locationAddonMap.has(id))
continue;
let migrateData = id in locMigrateData ? locMigrateData[id] : null;
let newAddon = loadedManifest(installLocation, id);
let addon = this.addMetadata(installLocation, id, xpiState, newAddon,
aOldAppVersion, aOldPlatformVersion, migrateData);
if (addon)
locationAddonMap.set(addon.id, addon);
}
}
}
// previousAddons may contain locations where the database contains add-ons
// but the browser is no longer configured to use that location. The metadata
// for those add-ons must be removed from the database.
for (let [locationName, addons] of previousAddons) {
if (!currentAddons.has(locationName)) {
for (let [id, oldAddon] of addons)
this.removeMetadata(oldAddon);
}
}
// Validate the updated system add-ons
let systemAddonLocation = XPIProvider.installLocationsByName[KEY_APP_SYSTEM_ADDONS];
let addons = currentAddons.get(KEY_APP_SYSTEM_ADDONS) || new Map();
let hideLocation;
if (systemAddonLocation.isActive() && systemAddonLocation.isValid(addons)) {
// Hide the system add-on defaults
logger.info("Hiding the default system add-ons.");
hideLocation = KEY_APP_SYSTEM_DEFAULTS;
}
else {
// Hide the system add-on updates
logger.info("Hiding the updated system add-ons.");
hideLocation = KEY_APP_SYSTEM_ADDONS;
}
let previousVisible = this.getVisibleAddons(previousAddons);
let currentVisible = this.flattenByID(currentAddons, hideLocation);
let sawActiveTheme = false;
XPIProvider.bootstrappedAddons = {};
// Pass over the new set of visible add-ons, record any changes that occured
// during startup and call bootstrap install/uninstall scripts as necessary
for (let [id, currentAddon] of currentVisible) {
let previousAddon = previousVisible.get(id);
// Note if any visible add-on is not in the application install location
if (currentAddon._installLocation.name != KEY_APP_GLOBAL)
XPIProvider.allAppGlobal = false;
let isActive = !currentAddon.disabled;
let wasActive = previousAddon ? previousAddon.active : currentAddon.active
if (!previousAddon) {
// If we had a manifest for this add-on it was a staged install and
// so wasn't something recovered from a corrupt database
let wasStaged = !!loadedManifest(currentAddon._installLocation, id);
// We might be recovering from a corrupt database, if so use the
// list of known active add-ons to update the new add-on
if (!wasStaged && XPIDatabase.activeBundles) {
// For themes we know which is active by the current skin setting
if (currentAddon.type == "theme")
isActive = currentAddon.internalName == XPIProvider.currentSkin;
else
isActive = XPIDatabase.activeBundles.indexOf(currentAddon.descriptor) != -1;
// If the add-on wasn't active and it isn't already disabled in some way
// then it was probably either softDisabled or userDisabled
if (!isActive && !currentAddon.disabled) {
// If the add-on is softblocked then assume it is softDisabled
if (currentAddon.blocklistState == Blocklist.STATE_SOFTBLOCKED)
currentAddon.softDisabled = true;
else
currentAddon.userDisabled = true;
}
}
else {
// This is a new install
if (currentAddon.foreignInstall)
AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_INSTALLED, id);
if (currentAddon.bootstrap) {
// Visible bootstrapped add-ons need to have their install method called
XPIProvider.callBootstrapMethod(currentAddon, currentAddon._sourceBundle,
"install", BOOTSTRAP_REASONS.ADDON_INSTALL);
if (!isActive)
XPIProvider.unloadBootstrapScope(currentAddon.id);
}
}
}
else {
if (previousAddon !== currentAddon) {
// This is an add-on that has changed, either the metadata was reloaded
// or the version in a different location has become visible
AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_CHANGED, id);
let installReason = Services.vc.compare(previousAddon.version, currentAddon.version) < 0 ?
BOOTSTRAP_REASONS.ADDON_UPGRADE :
BOOTSTRAP_REASONS.ADDON_DOWNGRADE;
// If the previous add-on was in a different location, bootstrapped
// and still exists then call its uninstall method.
if (previousAddon.bootstrap && previousAddon._installLocation &&
currentAddon._installLocation != previousAddon._installLocation &&
previousAddon._sourceBundle.exists()) {
XPIProvider.callBootstrapMethod(previousAddon, previousAddon._sourceBundle,
"uninstall", installReason,
{ newVersion: currentAddon.version });
XPIProvider.unloadBootstrapScope(previousAddon.id);
}
// Make sure to flush the cache when an old add-on has gone away
flushStartupCache();
if (currentAddon.bootstrap) {
// Visible bootstrapped add-ons need to have their install method called
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.persistentDescriptor = currentAddon._sourceBundle.persistentDescriptor;
XPIProvider.callBootstrapMethod(currentAddon, file,
"install", installReason,
{ oldVersion: previousAddon.version });
if (currentAddon.disabled)
XPIProvider.unloadBootstrapScope(currentAddon.id);
}
}
if (isActive != wasActive) {
let change = isActive ? AddonManager.STARTUP_CHANGE_ENABLED
: AddonManager.STARTUP_CHANGE_DISABLED;
AddonManagerPrivate.addStartupChange(change, id);
}
}
XPIDatabase.makeAddonVisible(currentAddon);
currentAddon.active = isActive;
// Make sure the bootstrap information is up to date for this ID
if (currentAddon.bootstrap && currentAddon.active) {
XPIProvider.bootstrappedAddons[id] = {
version: currentAddon.version,
type: currentAddon.type,
descriptor: currentAddon._sourceBundle.persistentDescriptor,
multiprocessCompatible: currentAddon.multiprocessCompatible
};
}
if (currentAddon.active && currentAddon.internalName == XPIProvider.selectedSkin)
sawActiveTheme = true;
}
// Pass over the set of previously visible add-ons that have now gone away
// and record the change.
for (let [id, previousAddon] of previousVisible) {
if (currentVisible.has(id))
continue;
// This add-on vanished
AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_UNINSTALLED, id);
}
// Make sure add-ons from hidden locations are marked invisible and inactive
let locationAddonMap = currentAddons.get(hideLocation);
if (locationAddonMap) {
for (let addon of locationAddonMap.values()) {
addon.visible = false;
addon.active = false;
}
}
// None of the active add-ons match the selected theme, enable the default.
if (!sawActiveTheme) {
XPIProvider.enableDefaultTheme();
}
// Finally update XPIStates to match everything
for (let [locationName, locationAddonMap] of currentAddons) {
for (let [id, addon] of locationAddonMap) {
let xpiState = XPIStates.getAddon(locationName, id);
xpiState.syncWithDB(addon);
}
}
XPIStates.save();
XPIProvider.persistBootstrappedAddons();
// Clear out any cached migration data.
XPIDatabase.migrateData = null;
XPIDatabase.saveChanges();
return true;
},
}

Просмотреть файл

Двоичный файл не отображается.

Двоичный файл не отображается.

Просмотреть файл

@ -1,18 +0,0 @@
Components.utils.import("resource://gre/modules/Services.jsm");
const ID = "system1@tests.mozilla.org";
const VERSION = "1.0";
function install(data, reason) {
}
function startup(data, reason) {
Services.prefs.setCharPref("bootstraptest." + ID + ".active_version", VERSION);
}
function shutdown(data, reason) {
Services.prefs.clearUserPref("bootstraptest." + ID + ".active_version");
}
function uninstall(data, reason) {
}

Просмотреть файл

@ -1,23 +0,0 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>system1@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:bootstrap>true</em:bootstrap>
<!-- Front End MetaData -->
<em:name>System Add-on 1</em:name>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>5</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>

Просмотреть файл

@ -1,18 +0,0 @@
Components.utils.import("resource://gre/modules/Services.jsm");
const ID = "system2@tests.mozilla.org";
const VERSION = "1.0";
function install(data, reason) {
}
function startup(data, reason) {
Services.prefs.setCharPref("bootstraptest." + ID + ".active_version", VERSION);
}
function shutdown(data, reason) {
Services.prefs.clearUserPref("bootstraptest." + ID + ".active_version");
}
function uninstall(data, reason) {
}

Просмотреть файл

@ -1,23 +0,0 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>system2@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:bootstrap>true</em:bootstrap>
<!-- Front End MetaData -->
<em:name>System Add-on 2</em:name>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>5</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>

Двоичный файл не отображается.

Двоичный файл не отображается.

Просмотреть файл

@ -1,18 +0,0 @@
Components.utils.import("resource://gre/modules/Services.jsm");
const ID = "system1@tests.mozilla.org";
const VERSION = "2.0";
function install(data, reason) {
}
function startup(data, reason) {
Services.prefs.setCharPref("bootstraptest." + ID + ".active_version", VERSION);
}
function shutdown(data, reason) {
Services.prefs.clearUserPref("bootstraptest." + ID + ".active_version");
}
function uninstall(data, reason) {
}

Просмотреть файл

@ -1,23 +0,0 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>system1@tests.mozilla.org</em:id>
<em:version>2.0</em:version>
<em:bootstrap>true</em:bootstrap>
<!-- Front End MetaData -->
<em:name>System Add-on 1</em:name>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>5</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>

Просмотреть файл

@ -1,18 +0,0 @@
Components.utils.import("resource://gre/modules/Services.jsm");
const ID = "system3@tests.mozilla.org";
const VERSION = "1.0";
function install(data, reason) {
}
function startup(data, reason) {
Services.prefs.setCharPref("bootstraptest." + ID + ".active_version", VERSION);
}
function shutdown(data, reason) {
Services.prefs.clearUserPref("bootstraptest." + ID + ".active_version");
}
function uninstall(data, reason) {
}

Просмотреть файл

@ -1,23 +0,0 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>system3@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:bootstrap>true</em:bootstrap>
<!-- Front End MetaData -->
<em:name>System Add-on 3</em:name>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>5</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>

Просмотреть файл

@ -1026,7 +1026,7 @@ function getFileForAddon(aDir, aId) {
function registerDirectory(aKey, aDir) { function registerDirectory(aKey, aDir) {
var dirProvider = { var dirProvider = {
getFile: function(aProp, aPersistent) { getFile: function(aProp, aPersistent) {
aPersistent.value = false; aPersistent.value = true;
if (aProp == aKey) if (aProp == aKey)
return aDir.clone(); return aDir.clone();
return null; return null;

Просмотреть файл

@ -1067,8 +1067,9 @@ function run_test_21() {
do_check_eq(getUninstallReason(), -1); do_check_eq(getUninstallReason(), -1);
do_check_eq(getUninstallNewVersion(), -1); do_check_eq(getUninstallNewVersion(), -1);
do_check_eq(getInstallReason(), ADDON_DOWNGRADE); // TODO this reason should probably be ADDON_DOWNGRADE (bug 607818)
do_check_eq(getInstallOldVersion(), 2); do_check_eq(getInstallReason(), ADDON_INSTALL);
do_check_eq(getInstallOldVersion(), 0);
do_check_eq(getStartupReason(), APP_STARTUP); do_check_eq(getStartupReason(), APP_STARTUP);
do_check_eq(getStartupOldVersion(), 0); do_check_eq(getStartupOldVersion(), 0);

Просмотреть файл

@ -1,200 +0,0 @@
// Tests that we reset to the default system add-ons correctly when switching
// application versions
const PREF_SYSTEM_ADDON_SET = "extensions.systemAddonSet";
const featureDir = gProfD.clone();
featureDir.append("features");
const distroDir = do_get_file("data/system_addons/app0");
registerDirectory("XREAppDist", distroDir);
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "0");
function makeUUID() {
let uuidGen = AM_Cc["@mozilla.org/uuid-generator;1"].
getService(AM_Ci.nsIUUIDGenerator);
return uuidGen.generateUUID().toString();
}
function* check_installed(inProfile, ...versions) {
let expectedDir;
if (inProfile) {
expectedDir = featureDir;
}
else {
expectedDir = distroDir.clone();
expectedDir.append("features");
}
for (let i = 0; i < versions.length; i++) {
let id = "system" + (i + 1) + "@tests.mozilla.org";
let addon = yield promiseAddonByID(id);
if (versions[i]) {
// Add-on should be installed
do_check_neq(addon, null);
do_check_eq(addon.version, versions[i]);
do_check_true(addon.isActive);
do_check_false(addon.foreignInstall);
// Verify the add-ons file is in the right place
let file = expectedDir.clone();
file.append(id + ".xpi");
do_check_true(file.exists());
do_check_true(file.isFile());
let uri = addon.getResourceURI(null);
do_check_true(uri instanceof AM_Ci.nsIFileURL);
do_check_eq(uri.file.path, file.path);
// Verify the add-on actually started
let installed = Services.prefs.getCharPref("bootstraptest." + id + ".active_version");
do_check_eq(installed, versions[i]);
}
else {
// Add-on should not be installed
do_check_eq(addon, null);
try {
Services.prefs.getCharPref("bootstraptest." + id + ".active_version");
do_throw("Expected pref to be missing");
}
catch (e) {
}
}
}
}
// Test with a missing features directory
add_task(function* test_missing_app_dir() {
startupManager();
yield check_installed(false, null, null, null);
do_check_false(featureDir.exists());
yield promiseShutdownManager();
});
// Add some features in a new version
add_task(function* test_new_version() {
gAppInfo.version = "1";
distroDir.leafName = "app1";
startupManager();
yield check_installed(false, "1.0", "1.0", null);
do_check_false(featureDir.exists());
yield promiseShutdownManager();
});
// Another new version swaps one feature and upgrades another
add_task(function* test_upgrade() {
gAppInfo.version = "2";
distroDir.leafName = "app2";
startupManager();
yield check_installed(false, "2.0", null, "1.0");
do_check_false(featureDir.exists());
yield promiseShutdownManager();
});
// Downgrade
add_task(function* test_downgrade() {
gAppInfo.version = "1";
distroDir.leafName = "app1";
startupManager();
yield check_installed(false, "1.0", "1.0", null);
do_check_false(featureDir.exists());
yield promiseShutdownManager();
});
// Fake a mid-cycle install
add_task(function* test_updated() {
// Create a random dir to install into
let dirname = makeUUID();
FileUtils.getDir("ProfD", ["features", dirname], true);
featureDir.append(dirname);
// Copy in the system add-ons
let file = do_get_file("data/system_addons/app1/features/system2@tests.mozilla.org.xpi");
file.copyTo(featureDir, file.leafName);
file = do_get_file("data/system_addons/app2/features/system3@tests.mozilla.org.xpi");
file.copyTo(featureDir, file.leafName);
// Inject it into the system set
let addonSet = {
schema: 1,
directory: dirname,
addons: {
"system2@tests.mozilla.org": {
version: "1.0"
},
"system3@tests.mozilla.org": {
version: "1.0"
},
}
};
Services.prefs.setCharPref(PREF_SYSTEM_ADDON_SET, JSON.stringify(addonSet));
startupManager(false);
yield check_installed(true, null, "1.0", "1.0");
yield promiseShutdownManager();
});
// An additional add-on in the directory should be ignored
add_task(function* test_skips_additional() {
// Copy in the system add-ons
let file = do_get_file("data/system_addons/app1/features/system1@tests.mozilla.org.xpi");
file.copyTo(featureDir, file.leafName);
startupManager(false);
yield check_installed(true, null, "1.0", "1.0");
yield promiseShutdownManager();
});
// Missing add-on should revert to the default set
add_task(function* test_revert() {
manuallyUninstall(featureDir, "system2@tests.mozilla.org");
startupManager(false);
// With system add-on 2 gone the updated set is now invalid so it reverts to
// the default set which is system add-ons 1 and 2.
yield check_installed(false, "1.0", "1.0", null);
yield promiseShutdownManager();
});
// Putting it back will make the set work again
add_task(function* test_reuse() {
let file = do_get_file("data/system_addons/app1/features/system2@tests.mozilla.org.xpi");
file.copyTo(featureDir, file.leafName);
startupManager(false);
yield check_installed(true, null, "1.0", "1.0");
yield promiseShutdownManager();
});
// Making the pref corrupt should revert to the default set
add_task(function* test_corrupt_pref() {
Services.prefs.setCharPref(PREF_SYSTEM_ADDON_SET, "foo");
startupManager(false);
yield check_installed(false, "1.0", "1.0", null);
yield promiseShutdownManager();
});

Просмотреть файл

@ -24,7 +24,6 @@ skip-if = appname != "firefox"
[test_provider_unsafe_access_shutdown.js] [test_provider_unsafe_access_shutdown.js]
[test_provider_unsafe_access_startup.js] [test_provider_unsafe_access_startup.js]
[test_shutdown.js] [test_shutdown.js]
[test_system_reset.js]
[test_XPIcancel.js] [test_XPIcancel.js]
[test_XPIStates.js] [test_XPIStates.js]