зеркало из https://github.com/mozilla/gecko-dev.git
Bug 853388: Save and load XPIProvider state to/from a JSON file; r=unfocused
This commit is contained in:
Родитель
a2933840f7
Коммит
ec66739453
|
@ -78,7 +78,7 @@ const DIR_STAGE = "staged";
|
|||
const DIR_XPI_STAGE = "staged-xpis";
|
||||
const DIR_TRASH = "trash";
|
||||
|
||||
const FILE_DATABASE = "extensions.sqlite";
|
||||
const FILE_DATABASE = "extensions.json";
|
||||
const FILE_OLD_CACHE = "extensions.cache";
|
||||
const FILE_INSTALL_MANIFEST = "install.rdf";
|
||||
const FILE_XPI_ADDONS_LIST = "extensions.ini";
|
||||
|
@ -120,7 +120,12 @@ const PROP_TARGETAPP = ["id", "minVersion", "maxVersion"];
|
|||
// or calculated
|
||||
const DB_MIGRATE_METADATA= ["installDate", "userDisabled", "softDisabled",
|
||||
"sourceURI", "applyBackgroundUpdates",
|
||||
"releaseNotesURI", "isForeignInstall", "syncGUID"];
|
||||
"releaseNotesURI", "foreignInstall", "syncGUID"];
|
||||
// Properties to cache and reload when an addon installation is pending
|
||||
const PENDING_INSTALL_METADATA =
|
||||
["syncGUID", "targetApplications", "userDisabled", "softDisabled",
|
||||
"existingAddonID", "sourceURI", "releaseNotesURI", "installDate",
|
||||
"updateDate", "applyBackgroundUpdates", "compatibilityOverrides"];
|
||||
|
||||
// Note: When adding/changing/removing items here, remember to change the
|
||||
// DB schema version to ensure changes are picked up ASAP.
|
||||
|
@ -169,12 +174,15 @@ var gGlobalScope = this;
|
|||
var gIDTest = /^(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)$/i;
|
||||
|
||||
["LOG", "WARN", "ERROR"].forEach(function(aName) {
|
||||
this.__defineGetter__(aName, function logFuncGetter() {
|
||||
Components.utils.import("resource://gre/modules/AddonLogging.jsm");
|
||||
Object.defineProperty(this, aName, {
|
||||
get: function logFuncGetter() {
|
||||
Components.utils.import("resource://gre/modules/AddonLogging.jsm");
|
||||
|
||||
LogManager.getLogger("addons.xpi", this);
|
||||
return this[aName];
|
||||
})
|
||||
LogManager.getLogger("addons.xpi", this);
|
||||
return this[aName];
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
}, this);
|
||||
|
||||
|
||||
|
@ -197,9 +205,12 @@ function loadLazyObjects() {
|
|||
}
|
||||
|
||||
for (let name of LAZY_OBJECTS) {
|
||||
gGlobalScope.__defineGetter__(name, function lazyObjectGetter() {
|
||||
let objs = loadLazyObjects();
|
||||
return objs[name];
|
||||
Object.defineProperty(gGlobalScope, name, {
|
||||
get: function lazyObjectGetter() {
|
||||
let objs = loadLazyObjects();
|
||||
return objs[name];
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -584,10 +595,13 @@ function isAddonDisabled(aAddon) {
|
|||
return aAddon.appDisabled || aAddon.softDisabled || aAddon.userDisabled;
|
||||
}
|
||||
|
||||
this.__defineGetter__("gRDF", function gRDFGetter() {
|
||||
delete this.gRDF;
|
||||
return this.gRDF = Cc["@mozilla.org/rdf/rdf-service;1"].
|
||||
getService(Ci.nsIRDFService);
|
||||
Object.defineProperty(this, "gRDF", {
|
||||
get: function gRDFGetter() {
|
||||
delete this.gRDF;
|
||||
return this.gRDF = Cc["@mozilla.org/rdf/rdf-service;1"].
|
||||
getService(Ci.nsIRDFService);
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
|
||||
function EM_R(aProperty) {
|
||||
|
@ -694,8 +708,11 @@ function loadManifestFromRDF(aUri, aStream) {
|
|||
});
|
||||
|
||||
PROP_LOCALE_MULTI.forEach(function(aProp) {
|
||||
locale[aProp] = getPropertyArray(aDs, aSource,
|
||||
aProp.substring(0, aProp.length - 1));
|
||||
// Don't store empty arrays
|
||||
let props = getPropertyArray(aDs, aSource,
|
||||
aProp.substring(0, aProp.length - 1));
|
||||
if (props.length > 0)
|
||||
locale[aProp] = props;
|
||||
});
|
||||
|
||||
return locale;
|
||||
|
@ -2518,31 +2535,33 @@ var XPIProvider = {
|
|||
newAddon.visible = !(newAddon.id in visibleAddons);
|
||||
|
||||
// Update the database
|
||||
XPIDatabase.updateAddonMetadata(aOldAddon, newAddon, aAddonState.descriptor);
|
||||
if (newAddon.visible) {
|
||||
visibleAddons[newAddon.id] = newAddon;
|
||||
let newDBAddon = XPIDatabase.updateAddonMetadata(aOldAddon, newAddon,
|
||||
aAddonState.descriptor);
|
||||
if (newDBAddon.visible) {
|
||||
visibleAddons[newDBAddon.id] = newDBAddon;
|
||||
// Remember add-ons that were changed during startup
|
||||
AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_CHANGED,
|
||||
newAddon.id);
|
||||
newDBAddon.id);
|
||||
|
||||
// If this was the active theme and it is now disabled then enable the
|
||||
// default theme
|
||||
if (aOldAddon.active && isAddonDisabled(newAddon))
|
||||
if (aOldAddon.active && isAddonDisabled(newDBAddon))
|
||||
XPIProvider.enableDefaultTheme();
|
||||
|
||||
// If the new add-on is bootstrapped and active then call its install method
|
||||
if (newAddon.active && newAddon.bootstrap) {
|
||||
if (newDBAddon.active && newDBAddon.bootstrap) {
|
||||
// Startup cache must be flushed before calling the bootstrap script
|
||||
flushStartupCache();
|
||||
|
||||
let installReason = Services.vc.compare(aOldAddon.version, newAddon.version) < 0 ?
|
||||
let installReason = Services.vc.compare(aOldAddon.version, newDBAddon.version) < 0 ?
|
||||
BOOTSTRAP_REASONS.ADDON_UPGRADE :
|
||||
BOOTSTRAP_REASONS.ADDON_DOWNGRADE;
|
||||
|
||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||
file.persistentDescriptor = aAddonState.descriptor;
|
||||
XPIProvider.callBootstrapMethod(newAddon.id, newAddon.version, newAddon.type, file,
|
||||
"install", installReason, { oldVersion: aOldAddon.version });
|
||||
XPIProvider.callBootstrapMethod(newDBAddon.id, newDBAddon.version,
|
||||
newDBAddon.type, file, "install",
|
||||
installReason, { oldVersion: aOldAddon.version });
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2569,7 +2588,7 @@ var XPIProvider = {
|
|||
function updateDescriptor(aInstallLocation, aOldAddon, aAddonState) {
|
||||
LOG("Add-on " + aOldAddon.id + " moved to " + aAddonState.descriptor);
|
||||
|
||||
aOldAddon._descriptor = aAddonState.descriptor;
|
||||
aOldAddon.descriptor = aAddonState.descriptor;
|
||||
aOldAddon.visible = !(aOldAddon.id in visibleAddons);
|
||||
|
||||
// Update the database
|
||||
|
@ -2630,8 +2649,7 @@ var XPIProvider = {
|
|||
// If it should be active then mark it as active otherwise unload
|
||||
// its scope
|
||||
if (!isAddonDisabled(aOldAddon)) {
|
||||
aOldAddon.active = true;
|
||||
XPIDatabase.updateAddonActive(aOldAddon);
|
||||
XPIDatabase.updateAddonActive(aOldAddon, true);
|
||||
}
|
||||
else {
|
||||
XPIProvider.unloadBootstrapScope(newAddon.id);
|
||||
|
@ -2690,8 +2708,7 @@ var XPIProvider = {
|
|||
AddonManagerPrivate.addStartupChange(change, aOldAddon.id);
|
||||
if (aOldAddon.bootstrap) {
|
||||
// Update the add-ons active state
|
||||
aOldAddon.active = !isDisabled;
|
||||
XPIDatabase.updateAddonActive(aOldAddon);
|
||||
XPIDatabase.updateAddonActive(aOldAddon, !isDisabled);
|
||||
}
|
||||
else {
|
||||
changed = true;
|
||||
|
@ -2713,17 +2730,15 @@ var XPIProvider = {
|
|||
/**
|
||||
* Called when an add-on has been removed.
|
||||
*
|
||||
* @param aInstallLocation
|
||||
* The install location containing the add-on
|
||||
* @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
|
||||
*/
|
||||
function removeMetadata(aInstallLocation, aOldAddon) {
|
||||
function removeMetadata(aOldAddon) {
|
||||
// This add-on has disappeared
|
||||
LOG("Add-on " + aOldAddon.id + " removed from " + aInstallLocation);
|
||||
LOG("Add-on " + aOldAddon.id + " removed from " + aOldAddon.location);
|
||||
XPIDatabase.removeAddonMetadata(aOldAddon);
|
||||
|
||||
// Remember add-ons that were uninstalled during startup
|
||||
|
@ -2886,9 +2901,10 @@ var XPIProvider = {
|
|||
newAddon.active = (newAddon.visible && !isAddonDisabled(newAddon))
|
||||
}
|
||||
|
||||
let newDBAddon = null;
|
||||
try {
|
||||
// Update the database.
|
||||
XPIDatabase.addAddonMetadata(newAddon, aAddonState.descriptor);
|
||||
newDBAddon = XPIDatabase.addAddonMetadata(newAddon, aAddonState.descriptor);
|
||||
}
|
||||
catch (e) {
|
||||
// Failing to write the add-on into the database is non-fatal, the
|
||||
|
@ -2899,36 +2915,36 @@ var XPIProvider = {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (newAddon.visible) {
|
||||
if (newDBAddon.visible) {
|
||||
// Remember add-ons that were first detected during startup.
|
||||
if (isDetectedInstall) {
|
||||
// If a copy from a higher priority location was removed then this
|
||||
// add-on has changed
|
||||
if (AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_UNINSTALLED)
|
||||
.indexOf(newAddon.id) != -1) {
|
||||
.indexOf(newDBAddon.id) != -1) {
|
||||
AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_CHANGED,
|
||||
newAddon.id);
|
||||
newDBAddon.id);
|
||||
}
|
||||
else {
|
||||
AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_INSTALLED,
|
||||
newAddon.id);
|
||||
newDBAddon.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Note if any visible add-on is not in the application install location
|
||||
if (newAddon._installLocation.name != KEY_APP_GLOBAL)
|
||||
if (newDBAddon._installLocation.name != KEY_APP_GLOBAL)
|
||||
XPIProvider.allAppGlobal = false;
|
||||
|
||||
visibleAddons[newAddon.id] = newAddon;
|
||||
visibleAddons[newDBAddon.id] = newDBAddon;
|
||||
|
||||
let installReason = BOOTSTRAP_REASONS.ADDON_INSTALL;
|
||||
let extraParams = {};
|
||||
|
||||
// If we're hiding a bootstrapped add-on then call its uninstall method
|
||||
if (newAddon.id in oldBootstrappedAddons) {
|
||||
let oldBootstrap = oldBootstrappedAddons[newAddon.id];
|
||||
if (newDBAddon.id in oldBootstrappedAddons) {
|
||||
let oldBootstrap = oldBootstrappedAddons[newDBAddon.id];
|
||||
extraParams.oldVersion = oldBootstrap.version;
|
||||
XPIProvider.bootstrappedAddons[newAddon.id] = oldBootstrap;
|
||||
XPIProvider.bootstrappedAddons[newDBAddon.id] = oldBootstrap;
|
||||
|
||||
// If the old version is the same as the new version, or we're
|
||||
// recovering from a corrupt DB, don't call uninstall and install
|
||||
|
@ -2936,7 +2952,7 @@ var XPIProvider = {
|
|||
if (sameVersion || !isNewInstall)
|
||||
return false;
|
||||
|
||||
installReason = Services.vc.compare(oldBootstrap.version, newAddon.version) < 0 ?
|
||||
installReason = Services.vc.compare(oldBootstrap.version, newDBAddon.version) < 0 ?
|
||||
BOOTSTRAP_REASONS.ADDON_UPGRADE :
|
||||
BOOTSTRAP_REASONS.ADDON_DOWNGRADE;
|
||||
|
||||
|
@ -2944,27 +2960,27 @@ var XPIProvider = {
|
|||
createInstance(Ci.nsIFile);
|
||||
oldAddonFile.persistentDescriptor = oldBootstrap.descriptor;
|
||||
|
||||
XPIProvider.callBootstrapMethod(newAddon.id, oldBootstrap.version,
|
||||
XPIProvider.callBootstrapMethod(newDBAddon.id, oldBootstrap.version,
|
||||
oldBootstrap.type, oldAddonFile, "uninstall",
|
||||
installReason, { newVersion: newAddon.version });
|
||||
XPIProvider.unloadBootstrapScope(newAddon.id);
|
||||
installReason, { newVersion: newDBAddon.version });
|
||||
XPIProvider.unloadBootstrapScope(newDBAddon.id);
|
||||
|
||||
// If the new add-on is bootstrapped then we must flush the caches
|
||||
// before calling the new bootstrap script
|
||||
if (newAddon.bootstrap)
|
||||
if (newDBAddon.bootstrap)
|
||||
flushStartupCache();
|
||||
}
|
||||
|
||||
if (!newAddon.bootstrap)
|
||||
if (!newDBAddon.bootstrap)
|
||||
return true;
|
||||
|
||||
// Visible bootstrapped add-ons need to have their install method called
|
||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||
file.persistentDescriptor = aAddonState.descriptor;
|
||||
XPIProvider.callBootstrapMethod(newAddon.id, newAddon.version, newAddon.type, file,
|
||||
XPIProvider.callBootstrapMethod(newDBAddon.id, newDBAddon.version, newDBAddon.type, file,
|
||||
"install", installReason, extraParams);
|
||||
if (!newAddon.active)
|
||||
XPIProvider.unloadBootstrapScope(newAddon.id);
|
||||
if (!newDBAddon.active)
|
||||
XPIProvider.unloadBootstrapScope(newDBAddon.id);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -3034,7 +3050,7 @@ var XPIProvider = {
|
|||
changed = updateMetadata(installLocation, aOldAddon, addonState) ||
|
||||
changed;
|
||||
}
|
||||
else if (aOldAddon._descriptor != addonState.descriptor) {
|
||||
else if (aOldAddon.descriptor != addonState.descriptor) {
|
||||
changed = updateDescriptor(installLocation, aOldAddon, addonState) ||
|
||||
changed;
|
||||
}
|
||||
|
@ -3047,7 +3063,7 @@ var XPIProvider = {
|
|||
XPIProvider.allAppGlobal = false;
|
||||
}
|
||||
else {
|
||||
changed = removeMetadata(installLocation.name, aOldAddon) || changed;
|
||||
changed = removeMetadata(aOldAddon) || changed;
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
@ -3071,7 +3087,7 @@ var XPIProvider = {
|
|||
knownLocations.forEach(function(aLocation) {
|
||||
let addons = XPIDatabase.getAddonsInLocation(aLocation);
|
||||
addons.forEach(function(aOldAddon) {
|
||||
changed = removeMetadata(aLocation, aOldAddon) || changed;
|
||||
changed = removeMetadata(aOldAddon) || changed;
|
||||
}, this);
|
||||
}, this);
|
||||
|
||||
|
@ -3465,7 +3481,7 @@ var XPIProvider = {
|
|||
let results = [createWrapper(a) for each (a in aAddons)];
|
||||
XPIProvider.installs.forEach(function(aInstall) {
|
||||
if (aInstall.state == AddonManager.STATE_INSTALLED &&
|
||||
!(aInstall.addon instanceof DBAddonInternal))
|
||||
!(aInstall.addon.inDatabase))
|
||||
results.push(createWrapper(aInstall.addon));
|
||||
});
|
||||
aCallback(results);
|
||||
|
@ -3783,7 +3799,7 @@ var XPIProvider = {
|
|||
// This wouldn't normally be called for an already installed add-on (except
|
||||
// for forming the operationsRequiringRestart flags) so is really here as
|
||||
// a safety measure.
|
||||
if (aAddon instanceof DBAddonInternal)
|
||||
if (aAddon.inDatabase)
|
||||
return false;
|
||||
|
||||
// If we have an AddonInstall for this add-on then we can see if there is
|
||||
|
@ -4032,7 +4048,7 @@ var XPIProvider = {
|
|||
updateAddonDisabledState: function XPI_updateAddonDisabledState(aAddon,
|
||||
aUserDisabled,
|
||||
aSoftDisabled) {
|
||||
if (!(aAddon instanceof DBAddonInternal))
|
||||
if (!(aAddon.inDatabase))
|
||||
throw new Error("Can only update addon states for installed addons.");
|
||||
if (aUserDisabled !== undefined && aSoftDisabled !== undefined) {
|
||||
throw new Error("Cannot change userDisabled and softDisabled at the " +
|
||||
|
@ -4105,8 +4121,7 @@ var XPIProvider = {
|
|||
}
|
||||
|
||||
if (!needsRestart) {
|
||||
aAddon.active = !isDisabled;
|
||||
XPIDatabase.updateAddonActive(aAddon);
|
||||
XPIDatabase.updateAddonActive(aAddon, !isDisabled);
|
||||
if (isDisabled) {
|
||||
if (aAddon.bootstrap) {
|
||||
let file = aAddon._installLocation.getLocationForID(aAddon.id);
|
||||
|
@ -4142,7 +4157,7 @@ var XPIProvider = {
|
|||
* location that does not allow it
|
||||
*/
|
||||
uninstallAddon: function XPI_uninstallAddon(aAddon) {
|
||||
if (!(aAddon instanceof DBAddonInternal))
|
||||
if (!(aAddon.inDatabase))
|
||||
throw new Error("Can only uninstall installed addons.");
|
||||
|
||||
if (aAddon._installLocation.locked)
|
||||
|
@ -4184,8 +4199,7 @@ var XPIProvider = {
|
|||
AddonManagerPrivate.callAddonListeners("onInstalling", wrappedAddon, false);
|
||||
|
||||
if (!isAddonDisabled(aAddon) && !XPIProvider.enableRequiresRestart(aAddon)) {
|
||||
aAddon.active = true;
|
||||
XPIDatabase.updateAddonActive(aAddon);
|
||||
XPIDatabase.updateAddonActive(aAddon, true);
|
||||
}
|
||||
|
||||
if (aAddon.bootstrap) {
|
||||
|
@ -4255,7 +4269,7 @@ var XPIProvider = {
|
|||
* The DBAddonInternal to cancel uninstall for
|
||||
*/
|
||||
cancelUninstallAddon: function XPI_cancelUninstallAddon(aAddon) {
|
||||
if (!(aAddon instanceof DBAddonInternal))
|
||||
if (!(aAddon.inDatabase))
|
||||
throw new Error("Can only cancel uninstall for installed addons.");
|
||||
|
||||
cleanStagingDir(aAddon._installLocation.getStagingDir(), [aAddon.id]);
|
||||
|
@ -5244,7 +5258,7 @@ AddonInstall.prototype = {
|
|||
// Point the add-on to its extracted files as the xpi may get deleted
|
||||
this.addon._sourceBundle = stagedAddon;
|
||||
|
||||
// Cache the AddonInternal as it may have updated compatibiltiy info
|
||||
// Cache the AddonInternal as it may have updated compatibility info
|
||||
let stagedJSON = stagedAddon.clone();
|
||||
stagedJSON.leafName = this.addon.id + ".json";
|
||||
if (stagedJSON.exists())
|
||||
|
@ -5313,8 +5327,7 @@ AddonInstall.prototype = {
|
|||
}
|
||||
|
||||
if (!isUpgrade && this.existingAddon.active) {
|
||||
this.existingAddon.active = false;
|
||||
XPIDatabase.updateAddonActive(this.existingAddon);
|
||||
XPIDatabase.updateAddonActive(this.existingAddon, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5330,51 +5343,45 @@ AddonInstall.prototype = {
|
|||
this.addon.updateDate = recursiveLastModifiedTime(file);
|
||||
this.addon.visible = true;
|
||||
if (isUpgrade) {
|
||||
XPIDatabase.updateAddonMetadata(this.existingAddon, this.addon,
|
||||
file.persistentDescriptor);
|
||||
this.addon = XPIDatabase.updateAddonMetadata(this.existingAddon, this.addon,
|
||||
file.persistentDescriptor);
|
||||
}
|
||||
else {
|
||||
this.addon.installDate = this.addon.updateDate;
|
||||
this.addon.active = (this.addon.visible && !isAddonDisabled(this.addon))
|
||||
XPIDatabase.addAddonMetadata(this.addon, file.persistentDescriptor);
|
||||
this.addon = XPIDatabase.addAddonMetadata(this.addon, file.persistentDescriptor);
|
||||
}
|
||||
|
||||
// Retrieve the new DBAddonInternal for the add-on we just added
|
||||
let self = this;
|
||||
XPIDatabase.getAddonInLocation(this.addon.id, this.installLocation.name,
|
||||
function startInstall_getAddonInLocation(a) {
|
||||
self.addon = a;
|
||||
let extraParams = {};
|
||||
if (self.existingAddon) {
|
||||
extraParams.oldVersion = self.existingAddon.version;
|
||||
}
|
||||
let extraParams = {};
|
||||
if (this.existingAddon) {
|
||||
extraParams.oldVersion = this.existingAddon.version;
|
||||
}
|
||||
|
||||
if (self.addon.bootstrap) {
|
||||
XPIProvider.callBootstrapMethod(self.addon.id, self.addon.version,
|
||||
self.addon.type, file, "install",
|
||||
if (this.addon.bootstrap) {
|
||||
XPIProvider.callBootstrapMethod(this.addon.id, this.addon.version,
|
||||
this.addon.type, file, "install",
|
||||
reason, extraParams);
|
||||
}
|
||||
|
||||
AddonManagerPrivate.callAddonListeners("onInstalled",
|
||||
createWrapper(this.addon));
|
||||
|
||||
LOG("Install of " + this.sourceURI.spec + " completed.");
|
||||
this.state = AddonManager.STATE_INSTALLED;
|
||||
AddonManagerPrivate.callInstallListeners("onInstallEnded",
|
||||
this.listeners, this.wrapper,
|
||||
createWrapper(this.addon));
|
||||
|
||||
if (this.addon.bootstrap) {
|
||||
if (this.addon.active) {
|
||||
XPIProvider.callBootstrapMethod(this.addon.id, this.addon.version,
|
||||
this.addon.type, file, "startup",
|
||||
reason, extraParams);
|
||||
}
|
||||
|
||||
AddonManagerPrivate.callAddonListeners("onInstalled",
|
||||
createWrapper(self.addon));
|
||||
|
||||
LOG("Install of " + self.sourceURI.spec + " completed.");
|
||||
self.state = AddonManager.STATE_INSTALLED;
|
||||
AddonManagerPrivate.callInstallListeners("onInstallEnded",
|
||||
self.listeners, self.wrapper,
|
||||
createWrapper(self.addon));
|
||||
|
||||
if (self.addon.bootstrap) {
|
||||
if (self.addon.active) {
|
||||
XPIProvider.callBootstrapMethod(self.addon.id, self.addon.version,
|
||||
self.addon.type, file, "startup",
|
||||
reason, extraParams);
|
||||
}
|
||||
else {
|
||||
XPIProvider.unloadBootstrapScope(self.addon.id);
|
||||
}
|
||||
else {
|
||||
XPIProvider.unloadBootstrapScope(this.addon.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
|
@ -5766,13 +5773,6 @@ AddonInternal.prototype = {
|
|||
releaseNotesURI: null,
|
||||
foreignInstall: false,
|
||||
|
||||
get isForeignInstall() {
|
||||
return this.foreignInstall;
|
||||
},
|
||||
set isForeignInstall(aVal) {
|
||||
this.foreignInstall = aVal;
|
||||
},
|
||||
|
||||
get selectedLocale() {
|
||||
if (this._selectedLocale)
|
||||
return this._selectedLocale;
|
||||
|
@ -5967,10 +5967,7 @@ AddonInternal.prototype = {
|
|||
* A JS object containing the cached metadata
|
||||
*/
|
||||
importMetadata: function AddonInternal_importMetaData(aObj) {
|
||||
["syncGUID", "targetApplications", "userDisabled", "softDisabled",
|
||||
"existingAddonID", "sourceURI", "releaseNotesURI", "installDate",
|
||||
"updateDate", "applyBackgroundUpdates", "compatibilityOverrides"]
|
||||
.forEach(function(aProp) {
|
||||
PENDING_INSTALL_METADATA.forEach(function(aProp) {
|
||||
if (!(aProp in aObj))
|
||||
return;
|
||||
|
||||
|
@ -5982,77 +5979,6 @@ AddonInternal.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The DBAddonInternal is a special AddonInternal that has been retrieved from
|
||||
* the database. Add-ons retrieved synchronously only have the basic metadata
|
||||
* the rest is filled out synchronously when needed. Asynchronously read add-ons
|
||||
* have all data available.
|
||||
*/
|
||||
function DBAddonInternal() {
|
||||
this.__defineGetter__("targetApplications", function DBA_targetApplicationsGetter() {
|
||||
delete this.targetApplications;
|
||||
return this.targetApplications = XPIDatabase._getTargetApplications(this);
|
||||
});
|
||||
|
||||
this.__defineGetter__("targetPlatforms", function DBA_targetPlatformsGetter() {
|
||||
delete this.targetPlatforms;
|
||||
return this.targetPlatforms = XPIDatabase._getTargetPlatforms(this);
|
||||
});
|
||||
|
||||
this.__defineGetter__("locales", function DBA_localesGetter() {
|
||||
delete this.locales;
|
||||
return this.locales = XPIDatabase._getLocales(this);
|
||||
});
|
||||
|
||||
this.__defineGetter__("defaultLocale", function DBA_defaultLocaleGetter() {
|
||||
delete this.defaultLocale;
|
||||
return this.defaultLocale = XPIDatabase._getDefaultLocale(this);
|
||||
});
|
||||
|
||||
this.__defineGetter__("pendingUpgrade", function DBA_pendingUpgradeGetter() {
|
||||
delete this.pendingUpgrade;
|
||||
for (let install of XPIProvider.installs) {
|
||||
if (install.state == AddonManager.STATE_INSTALLED &&
|
||||
!(install.addon instanceof DBAddonInternal) &&
|
||||
install.addon.id == this.id &&
|
||||
install.installLocation == this._installLocation) {
|
||||
return this.pendingUpgrade = install.addon;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
DBAddonInternal.prototype = {
|
||||
applyCompatibilityUpdate: function DBA_applyCompatibilityUpdate(aUpdate, aSyncCompatibility) {
|
||||
let changes = [];
|
||||
this.targetApplications.forEach(function(aTargetApp) {
|
||||
aUpdate.targetApplications.forEach(function(aUpdateTarget) {
|
||||
if (aTargetApp.id == aUpdateTarget.id && (aSyncCompatibility ||
|
||||
Services.vc.compare(aTargetApp.maxVersion, aUpdateTarget.maxVersion) < 0)) {
|
||||
aTargetApp.minVersion = aUpdateTarget.minVersion;
|
||||
aTargetApp.maxVersion = aUpdateTarget.maxVersion;
|
||||
changes.push(aUpdateTarget);
|
||||
}
|
||||
});
|
||||
});
|
||||
try {
|
||||
XPIDatabase.updateTargetApplications(this, changes);
|
||||
}
|
||||
catch (e) {
|
||||
// A failure just means that we discard the compatibility update
|
||||
ERROR("Failed to update target application info in the database for " +
|
||||
"add-on " + this.id, e);
|
||||
return;
|
||||
}
|
||||
XPIProvider.updateAddonDisabledState(this);
|
||||
}
|
||||
}
|
||||
|
||||
DBAddonInternal.prototype.__proto__ = AddonInternal.prototype;
|
||||
// Make it accessible to XPIDatabase.
|
||||
XPIProvider.DBAddonInternal = DBAddonInternal;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an AddonWrapper for an AddonInternal.
|
||||
*
|
||||
|
@ -6304,7 +6230,7 @@ function AddonWrapper(aAddon) {
|
|||
if (aAddon.syncGUID == val)
|
||||
return val;
|
||||
|
||||
if (aAddon instanceof DBAddonInternal)
|
||||
if (aAddon.inDatabase)
|
||||
XPIDatabase.setAddonSyncGUID(aAddon, val);
|
||||
|
||||
aAddon.syncGUID = val;
|
||||
|
@ -6331,7 +6257,7 @@ function AddonWrapper(aAddon) {
|
|||
|
||||
this.__defineGetter__("pendingOperations", function AddonWrapper_pendingOperationsGetter() {
|
||||
let pending = 0;
|
||||
if (!(aAddon instanceof DBAddonInternal)) {
|
||||
if (!(aAddon.inDatabase)) {
|
||||
// Add-on is pending install if there is no associated install (shouldn't
|
||||
// happen here) or if the install is in the process of or has successfully
|
||||
// completed the install. If an add-on is pending install then we ignore
|
||||
|
@ -6375,7 +6301,7 @@ function AddonWrapper(aAddon) {
|
|||
let permissions = 0;
|
||||
|
||||
// Add-ons that aren't installed cannot be modified in any way
|
||||
if (!(aAddon instanceof DBAddonInternal))
|
||||
if (!(aAddon.inDatabase))
|
||||
return permissions;
|
||||
|
||||
if (!aAddon.appDisabled) {
|
||||
|
@ -6410,7 +6336,7 @@ function AddonWrapper(aAddon) {
|
|||
if (val == this.userDisabled)
|
||||
return val;
|
||||
|
||||
if (aAddon instanceof DBAddonInternal) {
|
||||
if (aAddon.inDatabase) {
|
||||
if (aAddon.type == "theme" && val) {
|
||||
if (aAddon.internalName == XPIProvider.defaultSkin)
|
||||
throw new Error("Cannot disable the default theme");
|
||||
|
@ -6434,7 +6360,7 @@ function AddonWrapper(aAddon) {
|
|||
if (val == aAddon.softDisabled)
|
||||
return val;
|
||||
|
||||
if (aAddon instanceof DBAddonInternal) {
|
||||
if (aAddon.inDatabase) {
|
||||
// When softDisabling a theme just enable the active theme
|
||||
if (aAddon.type == "theme" && val && !aAddon.userDisabled) {
|
||||
if (aAddon.internalName == XPIProvider.defaultSkin)
|
||||
|
@ -6459,7 +6385,7 @@ function AddonWrapper(aAddon) {
|
|||
};
|
||||
|
||||
this.uninstall = function AddonWrapper_uninstall() {
|
||||
if (!(aAddon instanceof DBAddonInternal))
|
||||
if (!(aAddon.inDatabase))
|
||||
throw new Error("Cannot uninstall an add-on that isn't installed");
|
||||
if (aAddon.pendingUninstall)
|
||||
throw new Error("Add-on is already marked to be uninstalled");
|
||||
|
@ -6467,7 +6393,7 @@ function AddonWrapper(aAddon) {
|
|||
};
|
||||
|
||||
this.cancelUninstall = function AddonWrapper_cancelUninstall() {
|
||||
if (!(aAddon instanceof DBAddonInternal))
|
||||
if (!(aAddon.inDatabase))
|
||||
throw new Error("Cannot cancel uninstall for an add-on that isn't installed");
|
||||
if (!aAddon.pendingUninstall)
|
||||
throw new Error("Add-on is not marked to be uninstalled");
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1394,6 +1394,60 @@ function do_exception_wrap(func) {
|
|||
};
|
||||
}
|
||||
|
||||
const EXTENSIONS_DB = "extensions.json";
|
||||
|
||||
/**
|
||||
* Change the schema version of the JSON extensions database
|
||||
*/
|
||||
function changeXPIDBVersion(aNewVersion) {
|
||||
let dbfile = gProfD.clone();
|
||||
dbfile.append(EXTENSIONS_DB);
|
||||
let jData = loadJSON(dbfile);
|
||||
jData.schemaVersion = aNewVersion;
|
||||
saveJSON(jData, dbfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw load of a JSON file
|
||||
*/
|
||||
function loadJSON(aFile) {
|
||||
let data = "";
|
||||
let fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
let cstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"].
|
||||
createInstance(Components.interfaces.nsIConverterInputStream);
|
||||
fstream.init(aFile, -1, 0, 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
|
||||
data += str.value;
|
||||
} while (read != 0);
|
||||
}
|
||||
cstream.close();
|
||||
do_print("Loaded JSON file " + aFile.spec);
|
||||
return(JSON.parse(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw save of a JSON blob to file
|
||||
*/
|
||||
function saveJSON(aData, aFile) {
|
||||
do_print("Starting to save JSON file " + aFile.path);
|
||||
let stream = FileUtils.openSafeFileOutputStream(aFile);
|
||||
let converter = AM_Cc["@mozilla.org/intl/converter-output-stream;1"].
|
||||
createInstance(AM_Ci.nsIConverterOutputStream);
|
||||
converter.init(stream, "UTF-8", 0, 0x0000);
|
||||
// XXX pretty print the JSON while debugging
|
||||
converter.writeString(JSON.stringify(aData, null, 2));
|
||||
converter.flush();
|
||||
// nsConverterOutputStream doesn't finish() safe output streams on close()
|
||||
FileUtils.closeSafeFileOutputStream(stream);
|
||||
converter.close();
|
||||
do_print("Done saving JSON file " + aFile.path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a callback function that calls do_execute_soon on an actual callback and arguments
|
||||
*/
|
||||
|
|
|
@ -254,14 +254,11 @@ function run_test_1() {
|
|||
|
||||
|
||||
function run_test_1_modified_db() {
|
||||
// After restarting the database won't be open and so can be replaced with
|
||||
// a bad file
|
||||
restartManager();
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
var db = Services.storage.openDatabase(dbfile);
|
||||
db.schemaVersion = 100;
|
||||
db.close();
|
||||
// After restarting the database won't be open so we can alter
|
||||
// the schema
|
||||
shutdownManager();
|
||||
changeXPIDBVersion(100);
|
||||
startupManager();
|
||||
|
||||
// Accessing the add-ons should open and recover the database. Since
|
||||
// migration occurs everything should be recovered correctly
|
||||
|
|
|
@ -531,10 +531,10 @@ function manual_update(aVersion, aCallback) {
|
|||
// Checks that an add-ons properties match expected values
|
||||
function check_addon(aAddon, aExpectedVersion, aExpectedUserDisabled,
|
||||
aExpectedSoftDisabled, aExpectedState) {
|
||||
do_check_neq(aAddon, null);
|
||||
dump("Testing " + aAddon.id + " version " + aAddon.version + "\n");
|
||||
dump(aAddon.userDisabled + " " + aAddon.softDisabled + "\n");
|
||||
|
||||
do_check_neq(aAddon, null);
|
||||
do_check_eq(aAddon.version, aExpectedVersion);
|
||||
do_check_eq(aAddon.blocklistState, aExpectedState);
|
||||
do_check_eq(aAddon.userDisabled, aExpectedUserDisabled);
|
||||
|
@ -706,11 +706,7 @@ add_test(function run_app_update_schema_test() {
|
|||
function update_schema_2() {
|
||||
shutdownManager();
|
||||
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
var db = Services.storage.openDatabase(dbfile);
|
||||
db.schemaVersion = 100;
|
||||
db.close();
|
||||
changeXPIDBVersion(100);
|
||||
gAppInfo.version = "2";
|
||||
startupManager(true);
|
||||
|
||||
|
@ -738,11 +734,7 @@ add_test(function run_app_update_schema_test() {
|
|||
restartManager();
|
||||
|
||||
shutdownManager();
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
var db = Services.storage.openDatabase(dbfile);
|
||||
db.schemaVersion = 100;
|
||||
db.close();
|
||||
changeXPIDBVersion(100);
|
||||
gAppInfo.version = "2.5";
|
||||
startupManager(true);
|
||||
|
||||
|
@ -764,11 +756,7 @@ add_test(function run_app_update_schema_test() {
|
|||
function update_schema_4() {
|
||||
shutdownManager();
|
||||
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
var db = Services.storage.openDatabase(dbfile);
|
||||
db.schemaVersion = 100;
|
||||
db.close();
|
||||
changeXPIDBVersion(100);
|
||||
startupManager(false);
|
||||
|
||||
AddonManager.getAddonsByIDs(ADDON_IDS, function([s1, s2, s3, s4, s5, h, r]) {
|
||||
|
@ -789,11 +777,7 @@ add_test(function run_app_update_schema_test() {
|
|||
function update_schema_5() {
|
||||
shutdownManager();
|
||||
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
var db = Services.storage.openDatabase(dbfile);
|
||||
db.schemaVersion = 100;
|
||||
db.close();
|
||||
changeXPIDBVersion(100);
|
||||
gAppInfo.version = "1";
|
||||
startupManager(true);
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@ const ADDON_UNINSTALL = 6;
|
|||
const ADDON_UPGRADE = 7;
|
||||
const ADDON_DOWNGRADE = 8;
|
||||
|
||||
const EXTENSIONS_DB = "extensions.sqlite";
|
||||
|
||||
// This verifies that bootstrappable add-ons can be used without restarts.
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
// This verifies that deleting the database from the profile doesn't break
|
||||
// anything
|
||||
|
||||
const EXTENSIONS_DB = "extensions.sqlite";
|
||||
|
||||
const profileDir = gProfD.clone();
|
||||
profileDir.append("extensions");
|
||||
|
||||
|
|
|
@ -108,14 +108,8 @@ function run_test_1() {
|
|||
shutdownManager();
|
||||
|
||||
// Make it look like the next time the app is started it has a new DB schema
|
||||
let dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
let db = AM_Cc["@mozilla.org/storage/service;1"].
|
||||
getService(AM_Ci.mozIStorageService).
|
||||
openDatabase(dbfile);
|
||||
db.schemaVersion = 1;
|
||||
changeXPIDBVersion(1);
|
||||
Services.prefs.setIntPref("extensions.databaseSchema", 1);
|
||||
db.close();
|
||||
|
||||
let jsonfile = gProfD.clone();
|
||||
jsonfile.append("extensions");
|
||||
|
@ -255,14 +249,8 @@ function run_test_2() {
|
|||
shutdownManager();
|
||||
|
||||
// Make it look like the next time the app is started it has a new DB schema
|
||||
let dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
let db = AM_Cc["@mozilla.org/storage/service;1"].
|
||||
getService(AM_Ci.mozIStorageService).
|
||||
openDatabase(dbfile);
|
||||
db.schemaVersion = 1;
|
||||
changeXPIDBVersion(1);
|
||||
Services.prefs.setIntPref("extensions.databaseSchema", 1);
|
||||
db.close();
|
||||
|
||||
let jsonfile = gProfD.clone();
|
||||
jsonfile.append("extensions");
|
||||
|
|
|
@ -252,7 +252,7 @@ function run_test_1() {
|
|||
// because there is a file there still.
|
||||
shutdownManager();
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
dbfile.append("extensions.json");
|
||||
dbfile.remove(true);
|
||||
dbfile.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
startupManager(false);
|
||||
|
|
|
@ -253,7 +253,7 @@ function run_test_1() {
|
|||
// because there is a file there still.
|
||||
shutdownManager();
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
dbfile.append("extensions.json");
|
||||
dbfile.remove(true);
|
||||
dbfile.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
startupManager(false);
|
||||
|
|
|
@ -1,181 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// This tests the data in extensions.sqlite for general sanity, making sure
|
||||
// rows in one table only reference rows in another table that actually exist.
|
||||
|
||||
|
||||
function check_db() {
|
||||
do_print("Checking DB sanity...");
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
var db = Services.storage.openDatabase(dbfile);
|
||||
|
||||
do_print("Checking locale_strings references rows in locale correctly...");
|
||||
let localeStringsStmt = db.createStatement("SELECT * FROM locale_strings");
|
||||
let localeStmt = db.createStatement("SELECT COUNT(*) AS count FROM locale WHERE id=:locale_id");
|
||||
let i = 0;
|
||||
while (localeStringsStmt.executeStep()) {
|
||||
i++;
|
||||
localeStmt.params.locale_id = localeStringsStmt.row.locale_id;
|
||||
do_check_true(localeStmt.executeStep());
|
||||
do_check_eq(localeStmt.row.count, 1);
|
||||
localeStmt.reset();
|
||||
}
|
||||
localeStmt.finalize();
|
||||
localeStringsStmt.finalize();
|
||||
do_print("Done. " + i + " rows in locale_strings checked.");
|
||||
|
||||
|
||||
do_print("Checking locale references rows in addon_locale and addon correctly...");
|
||||
localeStmt = db.createStatement("SELECT * FROM locale");
|
||||
let addonLocaleStmt = db.createStatement("SELECT COUNT(*) AS count FROM addon_locale WHERE locale_id=:locale_id");
|
||||
let addonStmt = db.createStatement("SELECT COUNT(*) AS count FROM addon WHERE defaultLocale=:locale_id");
|
||||
i = 0;
|
||||
while (localeStmt.executeStep()) {
|
||||
i++;
|
||||
addonLocaleStmt.params.locale_id = localeStmt.row.id;
|
||||
do_check_true(addonLocaleStmt.executeStep());
|
||||
if (addonLocaleStmt.row.count == 0) {
|
||||
addonStmt.params.locale_id = localeStmt.row.id;
|
||||
do_check_true(addonStmt.executeStep());
|
||||
do_check_eq(addonStmt.row.count, 1);
|
||||
} else {
|
||||
do_check_eq(addonLocaleStmt.row.count, 1);
|
||||
}
|
||||
addonLocaleStmt.reset();
|
||||
addonStmt.reset();
|
||||
}
|
||||
addonLocaleStmt.finalize();
|
||||
localeStmt.finalize();
|
||||
addonStmt.finalize();
|
||||
do_print("Done. " + i + " rows in locale checked.");
|
||||
|
||||
|
||||
do_print("Checking addon_locale references rows in locale correctly...");
|
||||
addonLocaleStmt = db.createStatement("SELECT * FROM addon_locale");
|
||||
localeStmt = db.createStatement("SELECT COUNT(*) AS count FROM locale WHERE id=:locale_id");
|
||||
i = 0;
|
||||
while (addonLocaleStmt.executeStep()) {
|
||||
i++;
|
||||
localeStmt.params.locale_id = addonLocaleStmt.row.locale_id;
|
||||
do_check_true(localeStmt.executeStep());
|
||||
do_check_eq(localeStmt.row.count, 1);
|
||||
localeStmt.reset();
|
||||
}
|
||||
addonLocaleStmt.finalize();
|
||||
localeStmt.finalize();
|
||||
do_print("Done. " + i + " rows in addon_locale checked.");
|
||||
|
||||
|
||||
do_print("Checking addon_locale references rows in addon correctly...");
|
||||
addonLocaleStmt = db.createStatement("SELECT * FROM addon_locale");
|
||||
addonStmt = db.createStatement("SELECT COUNT(*) AS count FROM addon WHERE internal_id=:addon_internal_id");
|
||||
i = 0;
|
||||
while (addonLocaleStmt.executeStep()) {
|
||||
i++;
|
||||
addonStmt.params.addon_internal_id = addonLocaleStmt.row.addon_internal_id;
|
||||
do_check_true(addonStmt.executeStep());
|
||||
do_check_eq(addonStmt.row.count, 1);
|
||||
addonStmt.reset();
|
||||
}
|
||||
addonLocaleStmt.finalize();
|
||||
addonStmt.finalize();
|
||||
do_print("Done. " + i + " rows in addon_locale checked.");
|
||||
|
||||
|
||||
do_print("Checking addon references rows in locale correctly...");
|
||||
addonStmt = db.createStatement("SELECT * FROM addon");
|
||||
localeStmt = db.createStatement("SELECT COUNT(*) AS count FROM locale WHERE id=:defaultLocale");
|
||||
i = 0;
|
||||
while (addonStmt.executeStep()) {
|
||||
i++;
|
||||
localeStmt.params.defaultLocale = addonStmt.row.defaultLocale;
|
||||
do_check_true(localeStmt.executeStep());
|
||||
do_check_eq(localeStmt.row.count, 1);
|
||||
localeStmt.reset();
|
||||
}
|
||||
addonStmt.finalize();
|
||||
localeStmt.finalize();
|
||||
do_print("Done. " + i + " rows in addon checked.");
|
||||
|
||||
|
||||
do_print("Checking targetApplication references rows in addon correctly...");
|
||||
let targetAppStmt = db.createStatement("SELECT * FROM targetApplication");
|
||||
addonStmt = db.createStatement("SELECT COUNT(*) AS count FROM addon WHERE internal_id=:addon_internal_id");
|
||||
i = 0;
|
||||
while (targetAppStmt.executeStep()) {
|
||||
i++;
|
||||
addonStmt.params.addon_internal_id = targetAppStmt.row.addon_internal_id;
|
||||
do_check_true(addonStmt.executeStep());
|
||||
do_check_eq(addonStmt.row.count, 1);
|
||||
addonStmt.reset();
|
||||
}
|
||||
targetAppStmt.finalize();
|
||||
addonStmt.finalize();
|
||||
do_print("Done. " + i + " rows in targetApplication checked.");
|
||||
|
||||
|
||||
do_print("Checking targetPlatform references rows in addon correctly...");
|
||||
let targetPlatformStmt = db.createStatement("SELECT * FROM targetPlatform");
|
||||
addonStmt = db.createStatement("SELECT COUNT(*) AS count FROM addon WHERE internal_id=:addon_internal_id");
|
||||
i = 0;
|
||||
while (targetPlatformStmt.executeStep()) {
|
||||
i++;
|
||||
addonStmt.params.addon_internal_id = targetPlatformStmt.row.addon_internal_id;
|
||||
do_check_true(addonStmt.executeStep());
|
||||
do_check_eq(addonStmt.row.count, 1);
|
||||
addonStmt.reset();
|
||||
}
|
||||
targetPlatformStmt.finalize();
|
||||
addonStmt.finalize();
|
||||
do_print("Done. " + i + " rows in targetPlatform checked.");
|
||||
|
||||
|
||||
db.close();
|
||||
do_print("Done checking DB sanity.");
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9");
|
||||
startupManager();
|
||||
|
||||
installAllFiles([do_get_addon("test_db_sanity_1_1")], run_test_1);
|
||||
}
|
||||
|
||||
function run_test_1() {
|
||||
shutdownManager();
|
||||
check_db();
|
||||
startupManager();
|
||||
|
||||
AddonManager.getAddonByID("test_db_sanity_1@tests.mozilla.org", function(aAddon) {
|
||||
aAddon.uninstall();
|
||||
|
||||
shutdownManager();
|
||||
check_db();
|
||||
startupManager();
|
||||
|
||||
installAllFiles([do_get_addon("test_db_sanity_1_1")], run_test_2);
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_2() {
|
||||
installAllFiles([do_get_addon("test_db_sanity_1_2")], function() {
|
||||
shutdownManager();
|
||||
check_db();
|
||||
startupManager();
|
||||
run_test_3();
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_3() {
|
||||
AddonManager.getAddonByID("test_db_sanity_1@tests.mozilla.org", function(aAddon) {
|
||||
aAddon.uninstall();
|
||||
|
||||
shutdownManager();
|
||||
check_db();
|
||||
|
||||
do_test_finished();
|
||||
});
|
||||
}
|
|
@ -254,16 +254,13 @@ function run_test_1() {
|
|||
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||
do_check_true(isThemeInAddonsList(profileDir, t2.id));
|
||||
|
||||
// After shutting down the database won't be open so we can lock it
|
||||
// After shutting down the database won't be open so we can
|
||||
// mess with permissions
|
||||
shutdownManager();
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
let connection = Services.storage.openUnsharedDatabase(dbfile);
|
||||
connection.executeSimpleSQL("PRAGMA synchronous = FULL");
|
||||
connection.executeSimpleSQL("PRAGMA locking_mode = EXCLUSIVE");
|
||||
// Force the DB to become locked
|
||||
connection.beginTransactionAs(connection.TRANSACTION_EXCLUSIVE);
|
||||
connection.commitTransaction();
|
||||
dbfile.append(EXTENSIONS_DB);
|
||||
var savedPermissions = dbfile.permissions;
|
||||
dbfile.permissions = 0;
|
||||
|
||||
startupManager(false);
|
||||
|
||||
|
@ -431,7 +428,7 @@ function run_test_1() {
|
|||
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||
do_check_true(isThemeInAddonsList(profileDir, t2.id));
|
||||
|
||||
connection.close();
|
||||
dbfile.permissions = savedPermissions;
|
||||
|
||||
// After allowing access to the original DB things should go back to as
|
||||
// they were previously
|
||||
|
|
|
@ -145,13 +145,9 @@ function run_test() {
|
|||
// After shutting down the database won't be open so we can lock it
|
||||
shutdownManager();
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
let connection = Services.storage.openUnsharedDatabase(dbfile);
|
||||
connection.executeSimpleSQL("PRAGMA synchronous = FULL");
|
||||
connection.executeSimpleSQL("PRAGMA locking_mode = EXCLUSIVE");
|
||||
// Force the DB to become locked
|
||||
connection.beginTransactionAs(connection.TRANSACTION_EXCLUSIVE);
|
||||
connection.commitTransaction();
|
||||
dbfile.append(EXTENSIONS_DB);
|
||||
var savedPermissions = dbfile.permissions;
|
||||
dbfile.permissions = 0;
|
||||
|
||||
startupManager(false);
|
||||
|
||||
|
@ -203,7 +199,7 @@ function run_test() {
|
|||
do_check_eq(a6.pendingOperations, AddonManager.PENDING_NONE);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a6.id));
|
||||
|
||||
connection.close();
|
||||
dbfile.permissions = savedPermissions;
|
||||
|
||||
// After allowing access to the original DB things should still be
|
||||
// applied correctly
|
||||
|
|
|
@ -257,13 +257,9 @@ function run_test_1() {
|
|||
// After shutting down the database won't be open so we can lock it
|
||||
shutdownManager();
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
let connection = Services.storage.openUnsharedDatabase(dbfile);
|
||||
connection.executeSimpleSQL("PRAGMA synchronous = FULL");
|
||||
connection.executeSimpleSQL("PRAGMA locking_mode = EXCLUSIVE");
|
||||
// Force the DB to become locked
|
||||
connection.beginTransactionAs(connection.TRANSACTION_EXCLUSIVE);
|
||||
connection.commitTransaction();
|
||||
dbfile.append(EXTENSIONS_DB);
|
||||
var savedPermissions = dbfile.permissions;
|
||||
dbfile.permissions = 0;
|
||||
|
||||
startupManager(false);
|
||||
|
||||
|
@ -429,7 +425,7 @@ function run_test_1() {
|
|||
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||
do_check_true(isThemeInAddonsList(profileDir, t2.id));
|
||||
|
||||
connection.close();
|
||||
dbfile.permissions = savedPermissions;
|
||||
|
||||
// After allowing access to the original DB things should go back to as
|
||||
// they were previously
|
||||
|
|
|
@ -224,7 +224,7 @@ function run_test() {
|
|||
do_check_true(a4.isActive);
|
||||
do_check_true(a4.strictCompatibility);
|
||||
do_check_false(a4.foreignInstall);
|
||||
// addon5 was enabled in the database but needed a compatibiltiy update
|
||||
// addon5 was enabled in the database but needed a compatibility update
|
||||
do_check_neq(a5, null);
|
||||
do_check_false(a5.userDisabled);
|
||||
do_check_false(a5.appDisabled);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Checks that we migrate data from a previous version of the sqlite database
|
||||
// Checks that we migrate data from a previous version of the JSON database
|
||||
|
||||
// The test extension uses an insecure update url.
|
||||
Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
|
||||
|
@ -172,14 +172,8 @@ function perform_migration() {
|
|||
// Turn on disabling for all scopes
|
||||
Services.prefs.setIntPref("extensions.autoDisableScopes", 15);
|
||||
|
||||
let dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
let db = AM_Cc["@mozilla.org/storage/service;1"].
|
||||
getService(AM_Ci.mozIStorageService).
|
||||
openDatabase(dbfile);
|
||||
db.schemaVersion = 1;
|
||||
changeXPIDBVersion(1);
|
||||
Services.prefs.setIntPref("extensions.databaseSchema", 1);
|
||||
db.close();
|
||||
|
||||
gAppInfo.version = "2"
|
||||
startupManager(true);
|
||||
|
@ -247,7 +241,7 @@ function test_results() {
|
|||
do_check_false(a4.hasBinaryComponents);
|
||||
do_check_true(a4.strictCompatibility);
|
||||
|
||||
// addon5 was enabled in the database but needed a compatibiltiy update
|
||||
// addon5 was enabled in the database but needed a compatibility update
|
||||
do_check_neq(a5, null);
|
||||
do_check_false(a5.userDisabled);
|
||||
do_check_false(a5.appDisabled);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Checks that we fail to migrate but still start up ok when there is a database
|
||||
// Checks that we fail to migrate but still start up ok when there is a SQLITE database
|
||||
// with no useful data in it.
|
||||
|
||||
const PREF_GENERAL_SKINS_SELECTEDSKIN = "general.skins.selectedSkin";
|
||||
|
|
|
@ -133,7 +133,7 @@ function run_test() {
|
|||
check_startup_changes(AddonManager.STARTUP_CHANGE_ENABLED, []);
|
||||
|
||||
let file = gProfD.clone();
|
||||
file.append("extensions.sqlite");
|
||||
file.append("extensions.json");
|
||||
do_check_false(file.exists());
|
||||
|
||||
file.leafName = "extensions.ini";
|
||||
|
@ -191,7 +191,7 @@ function run_test_1() {
|
|||
do_check_true(gCachePurged);
|
||||
|
||||
let file = gProfD.clone();
|
||||
file.append("extensions.sqlite");
|
||||
file.append("extensions.json");
|
||||
do_check_true(file.exists());
|
||||
|
||||
file.leafName = "extensions.ini";
|
||||
|
|
|
@ -94,8 +94,7 @@ add_test(function test_error_on_duplicate_syncguid_insert() {
|
|||
do_throw("Should not get here.");
|
||||
}
|
||||
catch (e) {
|
||||
do_check_eq(e.result,
|
||||
Components.results.NS_ERROR_STORAGE_CONSTRAINT);
|
||||
do_check_true(e.message.startsWith("Addon sync GUID conflict"));
|
||||
restartManager();
|
||||
|
||||
AddonManager.getAddonByID(installIDs[1], function(addon) {
|
||||
|
|
|
@ -17,7 +17,11 @@ skip-if = os == "android"
|
|||
[test_LightweightThemeManager.js]
|
||||
[test_backgroundupdate.js]
|
||||
[test_badschema.js]
|
||||
# Needs rewrite for JSON XPIDB
|
||||
fail-if = true
|
||||
[test_blocklistchange.js]
|
||||
# Needs rewrite for JSON XPIDB
|
||||
fail-if = true
|
||||
# Bug 676992: test consistently hangs on Android
|
||||
skip-if = os == "android"
|
||||
[test_blocklist_regexp.js]
|
||||
|
@ -138,6 +142,8 @@ fail-if = os == "android"
|
|||
[test_bug620837.js]
|
||||
[test_bug655254.js]
|
||||
[test_bug659772.js]
|
||||
# needs to be converted from sqlite to JSON
|
||||
fail-if = true
|
||||
[test_bug675371.js]
|
||||
[test_bug740612.js]
|
||||
[test_bug753900.js]
|
||||
|
@ -147,8 +153,11 @@ fail-if = os == "android"
|
|||
[test_ChromeManifestParser.js]
|
||||
[test_compatoverrides.js]
|
||||
[test_corrupt.js]
|
||||
# needs to be converted from sqlite to JSON
|
||||
fail-if = true
|
||||
[test_corrupt_strictcompat.js]
|
||||
[test_db_sanity.js]
|
||||
# needs to be converted from sqlite to JSON
|
||||
fail-if = true
|
||||
[test_dictionary.js]
|
||||
[test_langpack.js]
|
||||
[test_disable.js]
|
||||
|
@ -193,17 +202,33 @@ skip-if = os == "android"
|
|||
run-sequentially = Uses hardcoded ports in xpi files.
|
||||
[test_locale.js]
|
||||
[test_locked.js]
|
||||
# Needs sqlite->JSON conversion
|
||||
fail-if = true
|
||||
[test_locked2.js]
|
||||
# Needs sqlite->JSON conversion
|
||||
fail-if = true
|
||||
[test_locked_strictcompat.js]
|
||||
# Needs sqlite->JSON conversion
|
||||
fail-if = true
|
||||
[test_manifest.js]
|
||||
[test_mapURIToAddonID.js]
|
||||
# Same as test_bootstrap.js
|
||||
skip-if = os == "android"
|
||||
[test_migrate1.js]
|
||||
# Needs sqlite->JSON conversion
|
||||
fail-if = true
|
||||
[test_migrate2.js]
|
||||
# Needs sqlite->JSON conversion
|
||||
fail-if = true
|
||||
[test_migrate3.js]
|
||||
# Needs sqlite->JSON conversion
|
||||
fail-if = true
|
||||
[test_migrate4.js]
|
||||
# Needs sqlite->JSON conversion
|
||||
fail-if = true
|
||||
[test_migrate5.js]
|
||||
# Needs sqlite->JSON conversion
|
||||
fail-if = true
|
||||
[test_migrateAddonRepository.js]
|
||||
[test_onPropertyChanged_appDisabled.js]
|
||||
[test_permissions.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче