зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset b3afaf3b4f3a (bug 853388)
This commit is contained in:
Родитель
cd4d374148
Коммит
cf05e6d90d
|
@ -78,7 +78,7 @@ const DIR_STAGE = "staged";
|
|||
const DIR_XPI_STAGE = "staged-xpis";
|
||||
const DIR_TRASH = "trash";
|
||||
|
||||
const FILE_DATABASE = "extensions.json";
|
||||
const FILE_DATABASE = "extensions.sqlite";
|
||||
const FILE_OLD_CACHE = "extensions.cache";
|
||||
const FILE_INSTALL_MANIFEST = "install.rdf";
|
||||
const FILE_XPI_ADDONS_LIST = "extensions.ini";
|
||||
|
@ -120,12 +120,7 @@ const PROP_TARGETAPP = ["id", "minVersion", "maxVersion"];
|
|||
// or calculated
|
||||
const DB_MIGRATE_METADATA= ["installDate", "userDisabled", "softDisabled",
|
||||
"sourceURI", "applyBackgroundUpdates",
|
||||
"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"];
|
||||
"releaseNotesURI", "isForeignInstall", "syncGUID"];
|
||||
|
||||
// Note: When adding/changing/removing items here, remember to change the
|
||||
// DB schema version to ensure changes are picked up ASAP.
|
||||
|
@ -174,15 +169,12 @@ 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) {
|
||||
Object.defineProperty(this, aName, {
|
||||
get: function logFuncGetter() {
|
||||
Components.utils.import("resource://gre/modules/AddonLogging.jsm");
|
||||
this.__defineGetter__(aName, function logFuncGetter() {
|
||||
Components.utils.import("resource://gre/modules/AddonLogging.jsm");
|
||||
|
||||
LogManager.getLogger("addons.xpi", this);
|
||||
return this[aName];
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
LogManager.getLogger("addons.xpi", this);
|
||||
return this[aName];
|
||||
})
|
||||
}, this);
|
||||
|
||||
|
||||
|
@ -205,12 +197,9 @@ function loadLazyObjects() {
|
|||
}
|
||||
|
||||
for (let name of LAZY_OBJECTS) {
|
||||
Object.defineProperty(gGlobalScope, name, {
|
||||
get: function lazyObjectGetter() {
|
||||
let objs = loadLazyObjects();
|
||||
return objs[name];
|
||||
},
|
||||
configurable: true
|
||||
gGlobalScope.__defineGetter__(name, function lazyObjectGetter() {
|
||||
let objs = loadLazyObjects();
|
||||
return objs[name];
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -595,13 +584,10 @@ function isAddonDisabled(aAddon) {
|
|||
return aAddon.appDisabled || aAddon.softDisabled || aAddon.userDisabled;
|
||||
}
|
||||
|
||||
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
|
||||
this.__defineGetter__("gRDF", function gRDFGetter() {
|
||||
delete this.gRDF;
|
||||
return this.gRDF = Cc["@mozilla.org/rdf/rdf-service;1"].
|
||||
getService(Ci.nsIRDFService);
|
||||
});
|
||||
|
||||
function EM_R(aProperty) {
|
||||
|
@ -708,11 +694,8 @@ function loadManifestFromRDF(aUri, aStream) {
|
|||
});
|
||||
|
||||
PROP_LOCALE_MULTI.forEach(function(aProp) {
|
||||
// Don't store empty arrays
|
||||
let props = getPropertyArray(aDs, aSource,
|
||||
aProp.substring(0, aProp.length - 1));
|
||||
if (props.length > 0)
|
||||
locale[aProp] = props;
|
||||
locale[aProp] = getPropertyArray(aDs, aSource,
|
||||
aProp.substring(0, aProp.length - 1));
|
||||
});
|
||||
|
||||
return locale;
|
||||
|
@ -2535,33 +2518,31 @@ var XPIProvider = {
|
|||
newAddon.visible = !(newAddon.id in visibleAddons);
|
||||
|
||||
// Update the database
|
||||
let newDBAddon = XPIDatabase.updateAddonMetadata(aOldAddon, newAddon,
|
||||
aAddonState.descriptor);
|
||||
if (newDBAddon.visible) {
|
||||
visibleAddons[newDBAddon.id] = newDBAddon;
|
||||
XPIDatabase.updateAddonMetadata(aOldAddon, newAddon, aAddonState.descriptor);
|
||||
if (newAddon.visible) {
|
||||
visibleAddons[newAddon.id] = newAddon;
|
||||
// Remember add-ons that were changed during startup
|
||||
AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_CHANGED,
|
||||
newDBAddon.id);
|
||||
newAddon.id);
|
||||
|
||||
// If this was the active theme and it is now disabled then enable the
|
||||
// default theme
|
||||
if (aOldAddon.active && isAddonDisabled(newDBAddon))
|
||||
if (aOldAddon.active && isAddonDisabled(newAddon))
|
||||
XPIProvider.enableDefaultTheme();
|
||||
|
||||
// If the new add-on is bootstrapped and active then call its install method
|
||||
if (newDBAddon.active && newDBAddon.bootstrap) {
|
||||
if (newAddon.active && newAddon.bootstrap) {
|
||||
// Startup cache must be flushed before calling the bootstrap script
|
||||
flushStartupCache();
|
||||
|
||||
let installReason = Services.vc.compare(aOldAddon.version, newDBAddon.version) < 0 ?
|
||||
let installReason = Services.vc.compare(aOldAddon.version, newAddon.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(newDBAddon.id, newDBAddon.version,
|
||||
newDBAddon.type, file, "install",
|
||||
installReason, { oldVersion: aOldAddon.version });
|
||||
XPIProvider.callBootstrapMethod(newAddon.id, newAddon.version, newAddon.type, file,
|
||||
"install", installReason, { oldVersion: aOldAddon.version });
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2588,7 +2569,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
|
||||
|
@ -2649,7 +2630,8 @@ var XPIProvider = {
|
|||
// If it should be active then mark it as active otherwise unload
|
||||
// its scope
|
||||
if (!isAddonDisabled(aOldAddon)) {
|
||||
XPIDatabase.updateAddonActive(aOldAddon, true);
|
||||
aOldAddon.active = true;
|
||||
XPIDatabase.updateAddonActive(aOldAddon);
|
||||
}
|
||||
else {
|
||||
XPIProvider.unloadBootstrapScope(newAddon.id);
|
||||
|
@ -2708,7 +2690,8 @@ var XPIProvider = {
|
|||
AddonManagerPrivate.addStartupChange(change, aOldAddon.id);
|
||||
if (aOldAddon.bootstrap) {
|
||||
// Update the add-ons active state
|
||||
XPIDatabase.updateAddonActive(aOldAddon, !isDisabled);
|
||||
aOldAddon.active = !isDisabled;
|
||||
XPIDatabase.updateAddonActive(aOldAddon);
|
||||
}
|
||||
else {
|
||||
changed = true;
|
||||
|
@ -2730,15 +2713,17 @@ 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(aOldAddon) {
|
||||
function removeMetadata(aInstallLocation, aOldAddon) {
|
||||
// This add-on has disappeared
|
||||
LOG("Add-on " + aOldAddon.id + " removed from " + aOldAddon.location);
|
||||
LOG("Add-on " + aOldAddon.id + " removed from " + aInstallLocation);
|
||||
XPIDatabase.removeAddonMetadata(aOldAddon);
|
||||
|
||||
// Remember add-ons that were uninstalled during startup
|
||||
|
@ -2901,10 +2886,9 @@ var XPIProvider = {
|
|||
newAddon.active = (newAddon.visible && !isAddonDisabled(newAddon))
|
||||
}
|
||||
|
||||
let newDBAddon = null;
|
||||
try {
|
||||
// Update the database.
|
||||
newDBAddon = XPIDatabase.addAddonMetadata(newAddon, aAddonState.descriptor);
|
||||
XPIDatabase.addAddonMetadata(newAddon, aAddonState.descriptor);
|
||||
}
|
||||
catch (e) {
|
||||
// Failing to write the add-on into the database is non-fatal, the
|
||||
|
@ -2915,36 +2899,36 @@ var XPIProvider = {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (newDBAddon.visible) {
|
||||
if (newAddon.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(newDBAddon.id) != -1) {
|
||||
.indexOf(newAddon.id) != -1) {
|
||||
AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_CHANGED,
|
||||
newDBAddon.id);
|
||||
newAddon.id);
|
||||
}
|
||||
else {
|
||||
AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_INSTALLED,
|
||||
newDBAddon.id);
|
||||
newAddon.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Note if any visible add-on is not in the application install location
|
||||
if (newDBAddon._installLocation.name != KEY_APP_GLOBAL)
|
||||
if (newAddon._installLocation.name != KEY_APP_GLOBAL)
|
||||
XPIProvider.allAppGlobal = false;
|
||||
|
||||
visibleAddons[newDBAddon.id] = newDBAddon;
|
||||
visibleAddons[newAddon.id] = newAddon;
|
||||
|
||||
let installReason = BOOTSTRAP_REASONS.ADDON_INSTALL;
|
||||
let extraParams = {};
|
||||
|
||||
// If we're hiding a bootstrapped add-on then call its uninstall method
|
||||
if (newDBAddon.id in oldBootstrappedAddons) {
|
||||
let oldBootstrap = oldBootstrappedAddons[newDBAddon.id];
|
||||
if (newAddon.id in oldBootstrappedAddons) {
|
||||
let oldBootstrap = oldBootstrappedAddons[newAddon.id];
|
||||
extraParams.oldVersion = oldBootstrap.version;
|
||||
XPIProvider.bootstrappedAddons[newDBAddon.id] = oldBootstrap;
|
||||
XPIProvider.bootstrappedAddons[newAddon.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
|
||||
|
@ -2952,7 +2936,7 @@ var XPIProvider = {
|
|||
if (sameVersion || !isNewInstall)
|
||||
return false;
|
||||
|
||||
installReason = Services.vc.compare(oldBootstrap.version, newDBAddon.version) < 0 ?
|
||||
installReason = Services.vc.compare(oldBootstrap.version, newAddon.version) < 0 ?
|
||||
BOOTSTRAP_REASONS.ADDON_UPGRADE :
|
||||
BOOTSTRAP_REASONS.ADDON_DOWNGRADE;
|
||||
|
||||
|
@ -2960,27 +2944,27 @@ var XPIProvider = {
|
|||
createInstance(Ci.nsIFile);
|
||||
oldAddonFile.persistentDescriptor = oldBootstrap.descriptor;
|
||||
|
||||
XPIProvider.callBootstrapMethod(newDBAddon.id, oldBootstrap.version,
|
||||
XPIProvider.callBootstrapMethod(newAddon.id, oldBootstrap.version,
|
||||
oldBootstrap.type, oldAddonFile, "uninstall",
|
||||
installReason, { newVersion: newDBAddon.version });
|
||||
XPIProvider.unloadBootstrapScope(newDBAddon.id);
|
||||
installReason, { newVersion: newAddon.version });
|
||||
XPIProvider.unloadBootstrapScope(newAddon.id);
|
||||
|
||||
// If the new add-on is bootstrapped then we must flush the caches
|
||||
// before calling the new bootstrap script
|
||||
if (newDBAddon.bootstrap)
|
||||
if (newAddon.bootstrap)
|
||||
flushStartupCache();
|
||||
}
|
||||
|
||||
if (!newDBAddon.bootstrap)
|
||||
if (!newAddon.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(newDBAddon.id, newDBAddon.version, newDBAddon.type, file,
|
||||
XPIProvider.callBootstrapMethod(newAddon.id, newAddon.version, newAddon.type, file,
|
||||
"install", installReason, extraParams);
|
||||
if (!newDBAddon.active)
|
||||
XPIProvider.unloadBootstrapScope(newDBAddon.id);
|
||||
if (!newAddon.active)
|
||||
XPIProvider.unloadBootstrapScope(newAddon.id);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -3050,7 +3034,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;
|
||||
}
|
||||
|
@ -3063,7 +3047,7 @@ var XPIProvider = {
|
|||
XPIProvider.allAppGlobal = false;
|
||||
}
|
||||
else {
|
||||
changed = removeMetadata(aOldAddon) || changed;
|
||||
changed = removeMetadata(installLocation.name, aOldAddon) || changed;
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
@ -3087,7 +3071,7 @@ var XPIProvider = {
|
|||
knownLocations.forEach(function(aLocation) {
|
||||
let addons = XPIDatabase.getAddonsInLocation(aLocation);
|
||||
addons.forEach(function(aOldAddon) {
|
||||
changed = removeMetadata(aOldAddon) || changed;
|
||||
changed = removeMetadata(aLocation, aOldAddon) || changed;
|
||||
}, this);
|
||||
}, this);
|
||||
|
||||
|
@ -3481,7 +3465,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.inDatabase))
|
||||
!(aInstall.addon instanceof DBAddonInternal))
|
||||
results.push(createWrapper(aInstall.addon));
|
||||
});
|
||||
aCallback(results);
|
||||
|
@ -3799,7 +3783,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.inDatabase)
|
||||
if (aAddon instanceof DBAddonInternal)
|
||||
return false;
|
||||
|
||||
// If we have an AddonInstall for this add-on then we can see if there is
|
||||
|
@ -4048,7 +4032,7 @@ var XPIProvider = {
|
|||
updateAddonDisabledState: function XPI_updateAddonDisabledState(aAddon,
|
||||
aUserDisabled,
|
||||
aSoftDisabled) {
|
||||
if (!(aAddon.inDatabase))
|
||||
if (!(aAddon instanceof DBAddonInternal))
|
||||
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 " +
|
||||
|
@ -4121,7 +4105,8 @@ var XPIProvider = {
|
|||
}
|
||||
|
||||
if (!needsRestart) {
|
||||
XPIDatabase.updateAddonActive(aAddon, !isDisabled);
|
||||
aAddon.active = !isDisabled;
|
||||
XPIDatabase.updateAddonActive(aAddon);
|
||||
if (isDisabled) {
|
||||
if (aAddon.bootstrap) {
|
||||
let file = aAddon._installLocation.getLocationForID(aAddon.id);
|
||||
|
@ -4157,7 +4142,7 @@ var XPIProvider = {
|
|||
* location that does not allow it
|
||||
*/
|
||||
uninstallAddon: function XPI_uninstallAddon(aAddon) {
|
||||
if (!(aAddon.inDatabase))
|
||||
if (!(aAddon instanceof DBAddonInternal))
|
||||
throw new Error("Can only uninstall installed addons.");
|
||||
|
||||
if (aAddon._installLocation.locked)
|
||||
|
@ -4199,7 +4184,8 @@ var XPIProvider = {
|
|||
AddonManagerPrivate.callAddonListeners("onInstalling", wrappedAddon, false);
|
||||
|
||||
if (!isAddonDisabled(aAddon) && !XPIProvider.enableRequiresRestart(aAddon)) {
|
||||
XPIDatabase.updateAddonActive(aAddon, true);
|
||||
aAddon.active = true;
|
||||
XPIDatabase.updateAddonActive(aAddon);
|
||||
}
|
||||
|
||||
if (aAddon.bootstrap) {
|
||||
|
@ -4269,7 +4255,7 @@ var XPIProvider = {
|
|||
* The DBAddonInternal to cancel uninstall for
|
||||
*/
|
||||
cancelUninstallAddon: function XPI_cancelUninstallAddon(aAddon) {
|
||||
if (!(aAddon.inDatabase))
|
||||
if (!(aAddon instanceof DBAddonInternal))
|
||||
throw new Error("Can only cancel uninstall for installed addons.");
|
||||
|
||||
cleanStagingDir(aAddon._installLocation.getStagingDir(), [aAddon.id]);
|
||||
|
@ -5258,7 +5244,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 compatibility info
|
||||
// Cache the AddonInternal as it may have updated compatibiltiy info
|
||||
let stagedJSON = stagedAddon.clone();
|
||||
stagedJSON.leafName = this.addon.id + ".json";
|
||||
if (stagedJSON.exists())
|
||||
|
@ -5327,7 +5313,8 @@ AddonInstall.prototype = {
|
|||
}
|
||||
|
||||
if (!isUpgrade && this.existingAddon.active) {
|
||||
XPIDatabase.updateAddonActive(this.existingAddon, false);
|
||||
this.existingAddon.active = false;
|
||||
XPIDatabase.updateAddonActive(this.existingAddon);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5343,45 +5330,51 @@ AddonInstall.prototype = {
|
|||
this.addon.updateDate = recursiveLastModifiedTime(file);
|
||||
this.addon.visible = true;
|
||||
if (isUpgrade) {
|
||||
this.addon = XPIDatabase.updateAddonMetadata(this.existingAddon, this.addon,
|
||||
file.persistentDescriptor);
|
||||
XPIDatabase.updateAddonMetadata(this.existingAddon, this.addon,
|
||||
file.persistentDescriptor);
|
||||
}
|
||||
else {
|
||||
this.addon.installDate = this.addon.updateDate;
|
||||
this.addon.active = (this.addon.visible && !isAddonDisabled(this.addon))
|
||||
this.addon = XPIDatabase.addAddonMetadata(this.addon, file.persistentDescriptor);
|
||||
XPIDatabase.addAddonMetadata(this.addon, file.persistentDescriptor);
|
||||
}
|
||||
|
||||
let extraParams = {};
|
||||
if (this.existingAddon) {
|
||||
extraParams.oldVersion = this.existingAddon.version;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
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",
|
||||
if (self.addon.bootstrap) {
|
||||
XPIProvider.callBootstrapMethod(self.addon.id, self.addon.version,
|
||||
self.addon.type, file, "install",
|
||||
reason, extraParams);
|
||||
}
|
||||
else {
|
||||
XPIProvider.unloadBootstrapScope(this.addon.id);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
|
@ -5773,6 +5766,13 @@ 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,7 +5967,10 @@ AddonInternal.prototype = {
|
|||
* A JS object containing the cached metadata
|
||||
*/
|
||||
importMetadata: function AddonInternal_importMetaData(aObj) {
|
||||
PENDING_INSTALL_METADATA.forEach(function(aProp) {
|
||||
["syncGUID", "targetApplications", "userDisabled", "softDisabled",
|
||||
"existingAddonID", "sourceURI", "releaseNotesURI", "installDate",
|
||||
"updateDate", "applyBackgroundUpdates", "compatibilityOverrides"]
|
||||
.forEach(function(aProp) {
|
||||
if (!(aProp in aObj))
|
||||
return;
|
||||
|
||||
|
@ -5979,6 +5982,77 @@ 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.
|
||||
*
|
||||
|
@ -6230,7 +6304,7 @@ function AddonWrapper(aAddon) {
|
|||
if (aAddon.syncGUID == val)
|
||||
return val;
|
||||
|
||||
if (aAddon.inDatabase)
|
||||
if (aAddon instanceof DBAddonInternal)
|
||||
XPIDatabase.setAddonSyncGUID(aAddon, val);
|
||||
|
||||
aAddon.syncGUID = val;
|
||||
|
@ -6257,7 +6331,7 @@ function AddonWrapper(aAddon) {
|
|||
|
||||
this.__defineGetter__("pendingOperations", function AddonWrapper_pendingOperationsGetter() {
|
||||
let pending = 0;
|
||||
if (!(aAddon.inDatabase)) {
|
||||
if (!(aAddon instanceof DBAddonInternal)) {
|
||||
// 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
|
||||
|
@ -6301,7 +6375,7 @@ function AddonWrapper(aAddon) {
|
|||
let permissions = 0;
|
||||
|
||||
// Add-ons that aren't installed cannot be modified in any way
|
||||
if (!(aAddon.inDatabase))
|
||||
if (!(aAddon instanceof DBAddonInternal))
|
||||
return permissions;
|
||||
|
||||
if (!aAddon.appDisabled) {
|
||||
|
@ -6336,7 +6410,7 @@ function AddonWrapper(aAddon) {
|
|||
if (val == this.userDisabled)
|
||||
return val;
|
||||
|
||||
if (aAddon.inDatabase) {
|
||||
if (aAddon instanceof DBAddonInternal) {
|
||||
if (aAddon.type == "theme" && val) {
|
||||
if (aAddon.internalName == XPIProvider.defaultSkin)
|
||||
throw new Error("Cannot disable the default theme");
|
||||
|
@ -6360,7 +6434,7 @@ function AddonWrapper(aAddon) {
|
|||
if (val == aAddon.softDisabled)
|
||||
return val;
|
||||
|
||||
if (aAddon.inDatabase) {
|
||||
if (aAddon instanceof DBAddonInternal) {
|
||||
// When softDisabling a theme just enable the active theme
|
||||
if (aAddon.type == "theme" && val && !aAddon.userDisabled) {
|
||||
if (aAddon.internalName == XPIProvider.defaultSkin)
|
||||
|
@ -6385,7 +6459,7 @@ function AddonWrapper(aAddon) {
|
|||
};
|
||||
|
||||
this.uninstall = function AddonWrapper_uninstall() {
|
||||
if (!(aAddon.inDatabase))
|
||||
if (!(aAddon instanceof DBAddonInternal))
|
||||
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");
|
||||
|
@ -6393,7 +6467,7 @@ function AddonWrapper(aAddon) {
|
|||
};
|
||||
|
||||
this.cancelUninstall = function AddonWrapper_cancelUninstall() {
|
||||
if (!(aAddon.inDatabase))
|
||||
if (!(aAddon instanceof DBAddonInternal))
|
||||
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,60 +1394,6 @@ 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,11 +254,14 @@ function run_test_1() {
|
|||
|
||||
|
||||
function run_test_1_modified_db() {
|
||||
// After restarting the database won't be open so we can alter
|
||||
// the schema
|
||||
shutdownManager();
|
||||
changeXPIDBVersion(100);
|
||||
startupManager();
|
||||
// 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();
|
||||
|
||||
// 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,7 +706,11 @@ add_test(function run_app_update_schema_test() {
|
|||
function update_schema_2() {
|
||||
shutdownManager();
|
||||
|
||||
changeXPIDBVersion(100);
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
var db = Services.storage.openDatabase(dbfile);
|
||||
db.schemaVersion = 100;
|
||||
db.close();
|
||||
gAppInfo.version = "2";
|
||||
startupManager(true);
|
||||
|
||||
|
@ -734,7 +738,11 @@ add_test(function run_app_update_schema_test() {
|
|||
restartManager();
|
||||
|
||||
shutdownManager();
|
||||
changeXPIDBVersion(100);
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
var db = Services.storage.openDatabase(dbfile);
|
||||
db.schemaVersion = 100;
|
||||
db.close();
|
||||
gAppInfo.version = "2.5";
|
||||
startupManager(true);
|
||||
|
||||
|
@ -756,7 +764,11 @@ add_test(function run_app_update_schema_test() {
|
|||
function update_schema_4() {
|
||||
shutdownManager();
|
||||
|
||||
changeXPIDBVersion(100);
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
var db = Services.storage.openDatabase(dbfile);
|
||||
db.schemaVersion = 100;
|
||||
db.close();
|
||||
startupManager(false);
|
||||
|
||||
AddonManager.getAddonsByIDs(ADDON_IDS, function([s1, s2, s3, s4, s5, h, r]) {
|
||||
|
@ -777,7 +789,11 @@ add_test(function run_app_update_schema_test() {
|
|||
function update_schema_5() {
|
||||
shutdownManager();
|
||||
|
||||
changeXPIDBVersion(100);
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append("extensions.sqlite");
|
||||
var db = Services.storage.openDatabase(dbfile);
|
||||
db.schemaVersion = 100;
|
||||
db.close();
|
||||
gAppInfo.version = "1";
|
||||
startupManager(true);
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ 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,6 +5,8 @@
|
|||
// 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,8 +108,14 @@ function run_test_1() {
|
|||
shutdownManager();
|
||||
|
||||
// Make it look like the next time the app is started it has a new DB schema
|
||||
changeXPIDBVersion(1);
|
||||
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;
|
||||
Services.prefs.setIntPref("extensions.databaseSchema", 1);
|
||||
db.close();
|
||||
|
||||
let jsonfile = gProfD.clone();
|
||||
jsonfile.append("extensions");
|
||||
|
@ -249,8 +255,14 @@ function run_test_2() {
|
|||
shutdownManager();
|
||||
|
||||
// Make it look like the next time the app is started it has a new DB schema
|
||||
changeXPIDBVersion(1);
|
||||
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;
|
||||
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.json");
|
||||
dbfile.append("extensions.sqlite");
|
||||
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.json");
|
||||
dbfile.append("extensions.sqlite");
|
||||
dbfile.remove(true);
|
||||
dbfile.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
startupManager(false);
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
/* 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,13 +254,16 @@ 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
|
||||
// mess with permissions
|
||||
// After shutting down the database won't be open so we can lock it
|
||||
shutdownManager();
|
||||
var dbfile = gProfD.clone();
|
||||
dbfile.append(EXTENSIONS_DB);
|
||||
var savedPermissions = dbfile.permissions;
|
||||
dbfile.permissions = 0;
|
||||
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();
|
||||
|
||||
startupManager(false);
|
||||
|
||||
|
@ -428,7 +431,7 @@ function run_test_1() {
|
|||
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||
do_check_true(isThemeInAddonsList(profileDir, t2.id));
|
||||
|
||||
dbfile.permissions = savedPermissions;
|
||||
connection.close();
|
||||
|
||||
// After allowing access to the original DB things should go back to as
|
||||
// they were previously
|
||||
|
|
|
@ -145,9 +145,13 @@ 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_DB);
|
||||
var savedPermissions = dbfile.permissions;
|
||||
dbfile.permissions = 0;
|
||||
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();
|
||||
|
||||
startupManager(false);
|
||||
|
||||
|
@ -199,7 +203,7 @@ function run_test() {
|
|||
do_check_eq(a6.pendingOperations, AddonManager.PENDING_NONE);
|
||||
do_check_true(isExtensionInAddonsList(profileDir, a6.id));
|
||||
|
||||
dbfile.permissions = savedPermissions;
|
||||
connection.close();
|
||||
|
||||
// After allowing access to the original DB things should still be
|
||||
// applied correctly
|
||||
|
|
|
@ -257,9 +257,13 @@ 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_DB);
|
||||
var savedPermissions = dbfile.permissions;
|
||||
dbfile.permissions = 0;
|
||||
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();
|
||||
|
||||
startupManager(false);
|
||||
|
||||
|
@ -425,7 +429,7 @@ function run_test_1() {
|
|||
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||
do_check_true(isThemeInAddonsList(profileDir, t2.id));
|
||||
|
||||
dbfile.permissions = savedPermissions;
|
||||
connection.close();
|
||||
|
||||
// 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 compatibility update
|
||||
// addon5 was enabled in the database but needed a compatibiltiy 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 JSON database
|
||||
// Checks that we migrate data from a previous version of the sqlite database
|
||||
|
||||
// The test extension uses an insecure update url.
|
||||
Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
|
||||
|
@ -172,8 +172,14 @@ function perform_migration() {
|
|||
// Turn on disabling for all scopes
|
||||
Services.prefs.setIntPref("extensions.autoDisableScopes", 15);
|
||||
|
||||
changeXPIDBVersion(1);
|
||||
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;
|
||||
Services.prefs.setIntPref("extensions.databaseSchema", 1);
|
||||
db.close();
|
||||
|
||||
gAppInfo.version = "2"
|
||||
startupManager(true);
|
||||
|
@ -241,7 +247,7 @@ function test_results() {
|
|||
do_check_false(a4.hasBinaryComponents);
|
||||
do_check_true(a4.strictCompatibility);
|
||||
|
||||
// addon5 was enabled in the database but needed a compatibility update
|
||||
// addon5 was enabled in the database but needed a compatibiltiy 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 SQLITE database
|
||||
// Checks that we fail to migrate but still start up ok when there is a 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.json");
|
||||
file.append("extensions.sqlite");
|
||||
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.json");
|
||||
file.append("extensions.sqlite");
|
||||
do_check_true(file.exists());
|
||||
|
||||
file.leafName = "extensions.ini";
|
||||
|
|
|
@ -94,7 +94,8 @@ add_test(function test_error_on_duplicate_syncguid_insert() {
|
|||
do_throw("Should not get here.");
|
||||
}
|
||||
catch (e) {
|
||||
do_check_true(e.message.startsWith("Addon sync GUID conflict"));
|
||||
do_check_eq(e.result,
|
||||
Components.results.NS_ERROR_STORAGE_CONSTRAINT);
|
||||
restartManager();
|
||||
|
||||
AddonManager.getAddonByID(installIDs[1], function(addon) {
|
||||
|
|
|
@ -17,11 +17,7 @@ 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]
|
||||
|
@ -142,8 +138,6 @@ 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]
|
||||
|
@ -153,11 +147,8 @@ fail-if = true
|
|||
[test_ChromeManifestParser.js]
|
||||
[test_compatoverrides.js]
|
||||
[test_corrupt.js]
|
||||
# needs to be converted from sqlite to JSON
|
||||
fail-if = true
|
||||
[test_corrupt_strictcompat.js]
|
||||
# needs to be converted from sqlite to JSON
|
||||
fail-if = true
|
||||
[test_db_sanity.js]
|
||||
[test_dictionary.js]
|
||||
[test_langpack.js]
|
||||
[test_disable.js]
|
||||
|
@ -202,33 +193,17 @@ 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]
|
||||
|
|
Загрузка…
Ссылка в новой задаче