Hallo,
vielleicht weiss einer Rat;ich benutze o.e. FF-Version und seit einiger Zeit wenn ich FF aufmache erscheint jedesmal beim start 1. meine gewählte Startseite und zusätzlich eine 2.Seite in einem neuen tab,die ich gar nicht will.
Ich muss warten,bis die 2.Seite fertiggeladen wurden und kann erst dann durch löschen des 2. tabs auf meine startseite
Beiträge von presla
-
-
Themes werden nicht installiert,es kommt folgende Fehlermeldung:
Firefox konnte das Add-on von folgender Adresse nicht installieren:http://releases.mozilla.org/pub/mozilla.or…x-1.8.49-fx.jar
Grund: Bei der Installation ist ein unbekannter Fehler aufgetreten.
Schauen Sie in der Fehlerkonsole für weitere Informationen nach.
-203Dies ist der Fehlercode:
/**
* Write the Extensions List
*/
_updateExtensionsManifest: function() {
// When an operation is performed that requires a component re-registration
// (extension enabled/disabled, installed, uninstalled), we must write the
// set of paths where extensions live so that the startup system can determine
// where additional components, preferences, chrome manifests etc live.
//
// To do this we obtain a list of active extensions and themes and write
// these to the extensions.ini file in the profile directory.
var validExtensions = this._getActiveItems(Ci.nsIUpdateItem.TYPE_ANY -
Ci.nsIUpdateItem.TYPE_THEME);
var validThemes = this._getActiveItems(Ci.nsIUpdateItem.TYPE_THEME);var extensionsLocationsFile = getFile(KEY_PROFILEDIR, [FILE_EXTENSION_MANIFEST]);
var fos = openSafeFileOutputStream(extensionsLocationsFile);var enabledItems = [];
var extensionSectionHeader = "[ExtensionDirs]\r\n";
fos.write(extensionSectionHeader, extensionSectionHeader.length);
for (var i = 0; i < validExtensions.length; ++i) {
var e = validExtensions[i];
var itemLocation = e.location.getItemLocation(e.id).QueryInterface(Ci.nsILocalFile);
var descriptor = getAbsoluteDescriptor(itemLocation);
var line = "Extension" + i + "=" + descriptor + "\r\n";
fos.write(line, line.length);
enabledItems.push(e.id + ":" + e.version);
}var themeSectionHeader = "[ThemeDirs]\r\n";
fos.write(themeSectionHeader, themeSectionHeader.length);
for (i = 0; i < validThemes.length; ++i) {
var e = validThemes[i];
var itemLocation = e.location.getItemLocation(e.id).QueryInterface(Ci.nsILocalFile);
var descriptor = getAbsoluteDescriptor(itemLocation);
var line = "Extension" + i + "=" + descriptor + "\r\n";
fos.write(line, line.length);
enabledItems.push(e.id + ":" + e.version);
}closeSafeFileOutputStream(fos);
// Cache the enabled list for annotating the crash report subsequently
gPref.setCharPref(PREF_EM_ENABLED_ITEMS, enabledItems.join(","));
},/**
* Say whether or not the Extension List has changed (and thus whether or not
* the system will have to restart the next time it is started).
* Param val
* true if the Extension List has changed, false otherwise.
* @returns |val|
*/
set _extensionListChanged(val) {
// When an extension has an operation perform on it (e.g. install, upgrade,
// disable, etc.) we are responsible for creating the .autoreg file and
// nsAppRunner is responsible for removing it on restart. At some point it
// may make sense to be able to cancel a registration but for now we only
// create the file.
try {
var autoregFile = getFile(KEY_PROFILEDIR, [FILE_AUTOREG]);
if (val && !autoregFile.exists())
autoregFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
}
catch (e) {
}
return val;
},/**
* Gathers data about an item specified by the supplied Install Manifest
* and determines whether or not it can be installed as-is. It makes this
* determination by validating the item's GUID, Version, and determining
* if it is compatible with this application.
* Param installManifest
* A nsIRDFDataSource representing the Install Manifest of the
* item to be installed.
* @return A JS Object with the following properties:
* "id" The GUID of the Item being installed.
* "version" The Version string of the Item being installed.
* "name" The Name of the Item being installed.
* "type" The nsIUpdateItem type of the Item being installed.
* "targetApps" An array of TargetApplication Info Objects
* with "id", "minVersion" and "maxVersion" properties,
* representing applications targeted by this item.
* "error" The result code:
* INSTALLERROR_SUCCESS
* no error, item can be installed
* INSTALLERROR_INVALID_GUID
* error, GUID is not well-formed
* INSTALLERROR_INVALID_VERSION
* error, Version is not well-formed
* INSTALLERROR_INCOMPATIBLE_VERSION
* error, item is not compatible with this version
* of the application.
* INSTALLERROR_INCOMPATIBLE_PLATFORM
* error, item is not compatible with the operating
* system or ABI the application was built for.
* INSTALLERROR_INSECURE_UPDATE
* error, item has no secure method of providing updates
* INSTALLERROR_BLOCKLISTED
* error, item is blocklisted
*/
_getInstallData: function(installManifest) {
var installData = { id : "",
version : "",
name : "",
type : 0,
error : INSTALLERROR_SUCCESS,
targetApps : [],
updateURL : "",
updateKey : "",
currentApp : null };// Fetch properties from the Install Manifest
installData.id = getManifestProperty(installManifest, "id");
installData.version = getManifestProperty(installManifest, "version");
installData.name = getManifestProperty(installManifest, "name");
installData.type = getAddonTypeFromInstallManifest(installManifest);
installData.updateURL= getManifestProperty(installManifest, "updateURL");
installData.updateKey= getManifestProperty(installManifest, "updateKey");/**
* Reads a property off a Target Application resource
* Param resource
* The RDF Resource for a Target Application
* Param property
* The property (less EM_NS) to read
* @returns The string literal value of the property.
*/
function readTAProperty(resource, property) {
return stringData(installManifest.GetTarget(resource, EM_R(property), true));
}var targetApps = installManifest.GetTargets(gInstallManifestRoot,
EM_R("targetApplication"),
true);
while (targetApps.hasMoreElements()) {
var targetApp = targetApps.getNext();
if (targetApp instanceof Ci.nsIRDFResource) {
try {
var data = { id : readTAProperty(targetApp, "id"),
minVersion: readTAProperty(targetApp, "minVersion"),
maxVersion: readTAProperty(targetApp, "maxVersion") };
installData.targetApps.push(data);
if ((data.id == gApp.ID)
(data.id == TOOLKIT_ID) && !installData.currentApp)
installData.currentApp = data;
}
catch (e) {
continue;
}
}
}// If the item specifies one or more target platforms, make sure our OS/ABI
// combination is in the list - otherwise, refuse to install the item.
var targetPlatforms = null;
try {
targetPlatforms = installManifest.GetTargets(gInstallManifestRoot,
EM_R("targetPlatform"),
true);
} catch(e) {
// No targetPlatform nodes, continue.
}
if (targetPlatforms != null && targetPlatforms.hasMoreElements()) {
var foundMatchingOS = false;
var foundMatchingOSAndABI = false;
var requireABICompatibility = false;
while (targetPlatforms.hasMoreElements()) {
var targetPlatform = stringData(targetPlatforms.getNext());
var os = targetPlatform.split("_")[0];
var index = targetPlatform.indexOf("_");
var abi = index != -1 ? targetPlatform.substr(index + 1) : null;
if (os == gOSTarget) {
foundMatchingOS = true;
// The presence of any ABI part after our OS means ABI is important.
if (abi != null) {
requireABICompatibility = true;
// If we don't know our ABI, we can't be compatible
if (abi == gXPCOMABI && abi != UNKNOWN_XPCOM_ABI) {
foundMatchingOSAndABI = true;
break;
}
}
}
}
if (!foundMatchingOS (requireABICompatibility && !foundMatchingOSAndABI)) {
installData.error = INSTALLERROR_INCOMPATIBLE_PLATFORM;
return installData;
}
}// Validate the Item ID
if (!gIDTest.test(installData.id)) {
installData.error = INSTALLERROR_INVALID_GUID;
return installData;
}
// Check that the add-on provides a secure update method.
if (gCheckUpdateSecurity &&
installData.updateURL &&
installData.updateURL.substring(0, 6) != "https:" &&
!installData.updateKey) {
installData.error = INSTALLERROR_INSECURE_UPDATE;
return installData;
}
// Check that the target application range allows compatibility with the app
if (gCheckCompatibility &&
!this.datasource.isCompatible(installManifest, gInstallManifestRoot, undefined)) {
installData.error = INSTALLERROR_INCOMPATIBLE_VERSION;
return installData;
}
// Check if the item is blocklisted.
if (!gBlocklist)
gBlocklist = Cc["@http://mozilla.org/extensions/blocklist;1"].
getService(Ci.nsIBlocklistService);
if (gBlocklist.isAddonBlocklisted(installData.id, installData.version,
null, null))
installData.error = INSTALLERROR_BLOCKLISTED;return installData;
},/**
* Installs an item from a XPI/JAR file.
* This is the main entry point into the Install system from outside code
* (e.g. XPInstall).
* Param aXPIFile
* The file to install from.
* Param aInstallLocationKey
* The name of the Install Location where this item should be
* installed.
*/
installItemFromFile: function(xpiFile, installLocationKey) {
this.installItemFromFileInternal(xpiFile, installLocationKey, null);// If there are no compatibility checks running and no downloads in
// progress then the install operations are complete.
if (this._compatibilityCheckCount == 0 && this._transactions.length == 0) {
for (var i = 0; i < this._installListeners.length; ++i)
this._installListeners[i].onInstallsCompleted();
}
},/**
* Installs an item from a XPI/JAR file.
* Param aXPIFile
* The file to install from.
* Param aInstallLocationKey
* The name of the Install Location where this item should be
* installed.
* Param aInstallManifest
* An updated Install Manifest from the Version Update check.
* Can be null when invoked from callers other than the Version
* Update check.
*/
installItemFromFileInternal: function(aXPIFile, aInstallLocationKey, aInstallManifest) {
var em = this;
/**
* Gets the Install Location for an Item.
* Param itemID
* The GUID of the item to find an Install Location for.
* @return An object implementing nsIInstallLocation which represents the
* location where the specified item should be installed.
* This can be:
* 1. an object that corresponds to the location key supplied to
* |installItemFromFileInternal|,
* 2. the default install location (the App Profile Extensions Folder)
* if no location key was supplied, or the location key supplied
* was not in the set of registered locations
* 3. null, if the location selected by 1 or 2 above does not support
* installs from XPI/JAR files, or that location is not writable
* with the current access privileges.
*/
function getInstallLocation(itemID) {
// Here I use "upgrade" to mean "install a different version of an item".
var installLocation = em.getInstallLocation(itemID);
if (!installLocation) {
// This is not an "upgrade", since we don't have any location data for the
// extension ID specified - that is, it's not in our database.// Caller supplied a key to a registered location, use that location
// for the installation
installLocation = InstallLocations.get(aInstallLocationKey);
if (installLocation) {
// If the specified location does not have a common metadata location
// (e.g. extensions have no common root, or other location specified
// by the location implementation) - e.g. for a Registry Key enumeration
// location - we cannot install or upgrade using a XPI file, probably
// because these application types will be handling upgrading themselves.
// Just bail.
if (!installLocation.location) {
LOG("Install Location \"" + installLocation.name + "\" does not support " +
"installation of items from XPI/JAR files. You must manage " +
"installation and update of these items yourself.");
installLocation = null;
}
}
else {
// In the absence of a preferred install location, just default to
// the App-Profile
installLocation = InstallLocations.get(KEY_APP_PROFILE);
}
}
else {
// This is an "upgrade", but not through the Update System, because the
// Update code will not let an extension with an incompatible target
// app version range through to this point. This is an "upgrade" in the
// sense that the user found a different version of an installed extension
// and installed it through the web interface, so we have metadata.// If the location is different, return the preferred location rather than
// the location of the currently installed version, because we may be in
// the situation where an item is being installed into the global app
// dir when there's a version in the profile dir.
if (installLocation.name != aInstallLocationKey)
installLocation = InstallLocations.get(aInstallLocationKey);
}
if (!installLocation.canAccess) {
LOG("Install Location\"" + installLocation.name + "\" cannot be written " +
"to with your access privileges. Installation will not proceed.");
installLocation = null;
}
return installLocation;
}/**
* Stages a XPI file in the default item location specified by other
* applications when they registered with XulRunner if the item's
* install manifest specified compatibility with them.
*/
function stageXPIForOtherApps(xpiFile, installData) {
for (var i = 0; i < installData.targetApps.length; ++i) {
var targetApp = installData.targetApps[i];
if (targetApp.id != gApp.ID && targetApp.id != TOOLKIT_ID) {
/* XXXben uncomment when this works!
var settingsThingy = Cc[].
getService(Ci.nsIXULRunnerSettingsThingy);
try {
var appPrefix = "SOFTWARE\\Mozilla\\XULRunner\\Applications\\";
var branch = settingsThingy.getBranch(appPrefix + targetApp.id);
var path = branch.getProperty("ExtensionsLocation");
var destination = Cc["@http://mozilla.org/file/local;1"].
createInstance(Ci.nsILocalFile);
destination.initWithPath(path);
xpiFile.copyTo(file, xpiFile.leafName);
}
catch (e) {
}
*/
}
}
}/**
* Extracts and then starts the install for extensions / themes contained
* within a xpi.
*/
function installMultiXPI(xpiFile, installData) {
var fileURL = getURIFromFile(xpiFile).QueryInterface(Ci.nsIURL);
if (fileURL.fileExtension.toLowerCase() != "xpi") {
LOG("Invalid File Extension: Item: \"" + fileURL.fileName + "\" has an " +
"invalid file extension. Only xpi file extensions are allowed for " +
"multiple item packages.");
var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
showMessage("invalidFileExtTitle", [],
"invalidFileExtMessage", [installData.name,
fileURL.fileExtension,
bundle.GetStringFromName("type-" + installData.type)]);
return;
}try {
var zipReader = getZipReaderForFile(xpiFile);
}
catch (e) {
LOG("installMultiXPI: failed to open xpi file: " + xpiFile.path);
throw e;
}var searchForEntries = ["*.xpi", "*.jar"];
var files = [];
for (var i = 0; i < searchForEntries.length; ++i) {
var entries = zipReader.findEntries(searchForEntries[i]);
while (entries.hasMore()) {
var entryName = entries.getNext();
var target = getFile(KEY_TEMPDIR, [entryName]);
try {
target.createUnique(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
}
catch (e) {
LOG("installMultiXPI: failed to create target file for extraction " +
" file = " + target.path + ", exception = " + e + "\n");
}
zipReader.extract(entryName, target);
files.push(target);
}
}
zipReader.close();if (files.length == 0) {
LOG("Multiple Item Package: Item: \"" + fileURL.fileName + "\" does " +
"not contain a valid package to install.");
var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
showMessage("missingPackageFilesTitle",
[bundle.GetStringFromName("type-" + installData.type)],
"missingPackageFilesMessage", [installData.name,
bundle.GetStringFromName("type-" + installData.type)]);
return;
}for (i = 0; i < files.length; ++i) {
em.installItemFromFileInternal(files[i], aInstallLocationKey, null);
files[i].remove(false);
}
}/**
* An observer for the Extension Update System.
* @constructor
*/
function IncompatibleObserver() {}
IncompatibleObserver.prototype = {
_xpi: null,
_installManifest: null,/**
* Ask the Extension Update System if there are any version updates for
* this item that will allow it to be compatible with this version of
* the Application.
* Param item
* An nsIUpdateItem representing the item being installed.
* Param installManifest
* The Install Manifest datasource for the item.
* Param xpiFile
* The staged source XPI file that contains the item. Cleaned
* up by this process.
* Param installRDF
* The install.rdf file that was extracted from the xpi.
*/
checkForUpdates: function(item, installManifest, xpiFile) {
this._xpi = xpiFile;
this._installManifest = installManifest;for (var i = 0; i < em._installListeners.length; ++i)
em._installListeners[i].onCompatibilityCheckStarted(item);
em._compatibilityCheckCount++;
em.update([item], 1, Ci.nsIExtensionManager.UPDATE_CHECK_COMPATIBILITY, this);
},/**
* See nsIExtensionManager.idl
*/
onUpdateStarted: function() {
LOG("Phone Home Listener: Update Started");
},/**
* See nsIExtensionManager.idl
*/
onUpdateEnded: function() {
LOG("Phone Home Listener: Update Ended");
},/**
* See nsIExtensionManager.idl
*/
onAddonUpdateStarted: function(addon) {
if (!addon)
throw Cr.NS_ERROR_INVALID_ARG;LOG("Phone Home Listener: Update For " + addon.id + " started");
em.datasource.addIncompatibleUpdateItem(addon.name, this._xpi.path,
addon.type, addon.version);
},/**
* See nsIExtensionManager.idl
*/
onAddonUpdateEnded: function(addon, status) {
if (!addon)
throw Cr.NS_ERROR_INVALID_ARG;LOG("Phone Home Listener: Update For " + addon.id + " ended, status = " + status);
em.datasource.removeDownload(this._xpi.path);
LOG("Version Check Phone Home Completed");for (var i = 0; i < em._installListeners.length; ++i)
em._installListeners[i].onCompatibilityCheckEnded(addon, status);// Only compatibility updates (e.g. STATUS_VERSIONINFO) are currently
// supported
if (status == Ci.nsIAddonUpdateCheckListener.STATUS_VERSIONINFO) {
em.datasource.setTargetApplicationInfo(addon.id,
addon.targetAppID,
addon.minAppVersion,
addon.maxAppVersion,
this._installManifest);// Try and install again, but use the updated compatibility DB.
// This will send out an apropriate onInstallEnded notification for us.
em.installItemFromFileInternal(this._xpi, aInstallLocationKey,
this._installManifest);// Add the updated compatibility info to the datasource if done
if (StartupCache.entries[aInstallLocationKey][addon.id].op == OP_NONE) {
em.datasource.setTargetApplicationInfo(addon.id,
addon.targetAppID,
addon.minAppVersion,
addon.maxAppVersion,
null);
}
else { // needs a restart
// Add updatedMinVersion and updatedMaxVersion so it can be used
// to update the datasource during the installation or upgrade.
em.datasource.setUpdatedTargetAppInfo(addon.id,
addon.targetAppID,
addon.minAppVersion,
addon.maxAppVersion,
null);
}
}
else {
em.datasource.removeDownload(this._xpi.path);
showIncompatibleError(installData);
LOG("Add-on " + addon.id + " is incompatible with " +
BundleManager.appName + " " + gApp.version + ", Toolkit " +
gApp.platformVersion + ". Remote compatibility check did not " +
"resolve this.");
for (var i = 0; i < em._installListeners.length; ++i)
em._installListeners[i].onInstallEnded(addon, INSTALLERROR_INCOMPATIBLE_VERSION);// We are responsible for cleaning up this file!
InstallLocations.get(aInstallLocationKey).removeFile(this._xpi);
}em._compatibilityCheckCount--;
// If there are no more compatibility checks running and no downloads in
// progress then the install operations are complete.
if (em._compatibilityCheckCount == 0 && em._transactions.length == 0) {
for (var i = 0; i < em._installListeners.length; ++i)
em._installListeners[i].onInstallsCompleted();
}
},QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonUpdateCheckListener])
}var shouldPhoneHomeIfNecessary = false;
if (!aInstallManifest) {
// If we were not called with an Install Manifest, we were called from
// some other path than the Phone Home system, so we do want to phone
// home if the version is incompatible. As this is the first point in the
// install process we must notify observers here.var addon = makeItem(getURIFromFile(aXPIFile).spec, "",
aInstallLocationKey, "", "", "",
getURIFromFile(aXPIFile).spec,
"", "", "", "", 0, gApp.id);
for (var i = 0; i < this._installListeners.length; ++i)
this._installListeners[i].onInstallStarted(addon);shouldPhoneHomeIfNecessary = true;
var installManifest = null;
var installManifestFile = extractRDFFileToTempDir(aXPIFile,
FILE_INSTALL_MANIFEST,
true);
if (installManifestFile.exists()) {
installManifest = getInstallManifest(installManifestFile);
installManifestFile.remove(false);
}
if (!installManifest) {
LOG("The Install Manifest supplied by this item is not well-formed. " +
"Installation will not proceed.");
for (var i = 0; i < this._installListeners.length; ++i)
this._installListeners[i].onInstallEnded(addon, INSTALLERROR_INVALID_MANIFEST);
return;
}
}
else
installManifest = aInstallManifest;var installData = this._getInstallData(installManifest);
// Recreate the add-on item with the full detail from the install manifest
addon = makeItem(installData.id, installData.version,
aInstallLocationKey,
installData.currentApp ? installData.currentApp.minVersion : "",
installData.currentApp ? installData.currentApp.maxVersion : "",
installData.name,
getURIFromFile(aXPIFile).spec,
"", /* XPI Update Hash */
"", /* Icon URL */
installData.updateURL "",
installData.updateKey "",
installData.type,
installData.currentApp ? installData.currentApp.id : "");switch (installData.error) {
case INSTALLERROR_INCOMPATIBLE_VERSION:
// Since the caller cleans up |aXPIFile|, and we're not yet sure whether or
// not we need it (we may need it if a remote version bump that makes it
// compatible is discovered by the call home) - so we must stage it for
// later ourselves.
if (shouldPhoneHomeIfNecessary && installData.currentApp) {
var installLocation = getInstallLocation(installData.id, aInstallLocationKey);
if (!installLocation)
return;
var stagedFile = installLocation.stageFile(aXPIFile, installData.id);
(new IncompatibleObserver(this)).checkForUpdates(addon, installManifest,
stagedFile);
// Return early to prevent deletion of the install manifest file.
return;
}
else {
// XXXben Look up XULRunnerSettingsThingy to see if there is a registered
// app that can handle this item, if so just stage and don't show
// this error!
showIncompatibleError(installData);
LOG("Add-on " + installData.id + " is incompatible with " +
BundleManager.appName + " " + gApp.version + ", Toolkit " +
gApp.platformVersion + ". Remote compatibility check was not performed.");
}
break;
case INSTALLERROR_SUCCESS:
// Installation of multiple extensions / themes contained within a single xpi.
if (installData.type == Ci.nsIUpdateItem.TYPE_MULTI_XPI) {
installMultiXPI(aXPIFile, installData);
break;
}// Stage the extension's XPI so it can be extracted at the next restart.
var installLocation = getInstallLocation(installData.id, aInstallLocationKey);
if (!installLocation) {
// No cleanup of any of the staged XPI files should be required here,
// because this should only ever fail on the first recurse through
// this function, BEFORE staging takes place... technically speaking
// a location could become readonly during the phone home process,
// but that's an edge case I don't care about.
for (var i = 0; i < this._installListeners.length; ++i)
this._installListeners[i].onInstallEnded(addon, INSTALLERROR_RESTRICTED);
return;
}// Stage a copy of the XPI/JAR file for our own evil purposes...
stagedFile = installLocation.stageFile(aXPIFile, installData.id);var restartRequired = this.installRequiresRestart(installData.id,
installData.type);
// Determine which configuration function to use based on whether or not
// there is data about this item in our datasource already - if there is
// we want to upgrade, otherwise we install fresh.
var ds = this.datasource;
if (installData.id in ds.visibleItems && ds.visibleItems[installData.id]) {
// We enter this function if any data corresponding to an existing GUID
// is found, regardless of its Install Location. We need to check before
// "upgrading" an item that Install Location of the new item is of equal
// or higher priority than the old item, to make sure the datasource only
// ever tracks metadata for active items.
var oldInstallLocation = this.getInstallLocation(installData.id);
if (oldInstallLocation.priority >= installLocation.priority) {
this._upgradeItem(installManifest, installData.id, installLocation,
installData.type);
if (!restartRequired) {
this._finalizeUpgrade(installData.id, installLocation);
this._finalizeInstall(installData.id, stagedFile);
}
}
}
else {
this._configureForthcomingItem(installManifest, installData.id,
installLocation, installData.type);
if (!restartRequired) {
this._finalizeInstall(installData.id, stagedFile);
if (installData.type == Ci.nsIUpdateItem.TYPE_THEME) {
var internalName = this.datasource.getItemProperty(installData.id, "internalName");
if (gPref.getBoolPref(PREF_EM_DSS_ENABLED)) {
gPref.setCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN, internalName);
}
else {
gPref.setBoolPref(PREF_DSS_SWITCHPENDING, true);
gPref.setCharPref(PREF_DSS_SKIN_TO_SELECT, internalName);
}
}
}
}
this._updateManifests(restartRequired);
break;
case INSTALLERROR_INVALID_GUID:
LOG("Invalid GUID: Item has GUID: \"" + installData.id + "\"" +
" which is not well-formed.");
var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
showMessage("incompatibleTitle",
[bundle.GetStringFromName("type-" + installData.type)],
"invalidGUIDMessage", [installData.name, installData.id]);
break;
case INSTALLERROR_INVALID_VERSION:
LOG("Invalid Version: Item: \"" + installData.id + "\" has version " +
installData.version + " which is not well-formed.");
var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
showMessage("incompatibleTitle",
[bundle.GetStringFromName("type-" + installData.type)],
"invalidVersionMessage", [installData.name, installData.version]);
break;
case INSTALLERROR_INCOMPATIBLE_PLATFORM:
const osABI = gOSTarget + "_" + gXPCOMABI;
LOG("Incompatible Platform: Item: \"" + installData.id + "\" is not " +
"compatible with '" + osABI + "'.");
var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
showMessage("incompatibleTitle",
[bundle.GetStringFromName("type-" + installData.type)],
"incompatiblePlatformMessage",
[installData.name, BundleManager.appName, osABI]);
break;
case INSTALLERROR_BLOCKLISTED:
LOG("Blocklisted Item: Item: \"" + installData.id + "\" version " +
installData.version + " was not installed.");
showBlocklistMessage([installData], true);
break;
case INSTALLERROR_INSECURE_UPDATE:
LOG("No secure updates: Item: \"" + installData.id + "\" version " +
installData.version + " was not installed.");
var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
showMessage("incompatibleTitle",
[bundle.GetStringFromName("type-" + installData.type)],
"insecureUpdateMessage", [installData.name]);
break;
default:
break;
}// Check to see if this item supports other applications and in that case
// stage the the XPI file in the location specified by those applications.
stageXPIForOtherApps(aXPIFile, installData);// The install of this item is complete, notify observers
for (var i = 0; i < this._installListeners.length; ++i)
this._installListeners[i].onInstallEnded(addon, installData.error);
},/**
* Whether or not this type's installation/uninstallation requires
* the application to be restarted.
* Param id
* The GUID of the item
* Param type
* The nsIUpdateItem type of the item
* @returns true if installation of an item of this type requires a
* restart.
*/
installRequiresRestart: function(id, type) {
switch (type) {
case Ci.nsIUpdateItem.TYPE_THEME:
var internalName = this.datasource.getItemProperty(id, "internalName");
var needsRestart = false;
if (gPref.prefHasUserValue(PREF_DSS_SKIN_TO_SELECT))
needsRestart = internalName == gPref.getCharPref(PREF_DSS_SKIN_TO_SELECT);
if (!needsRestart &&
gPref.prefHasUserValue(PREF_GENERAL_SKINS_SELECTEDSKIN))
needsRestart = internalName == gPref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
return needsRestart;
}
return ((type & Ci.nsIUpdateItem.TYPE_ADDON) > 0);
},/**
* Perform initial configuration on an item that has just or will be
* installed. This inserts the item into the appropriate container in the
* datasource, so that the application UI shows the item even if it will
* not actually be installed until the next restart.
* Param installManifest
* The Install Manifest datasource that describes this item.
* Param id
* The GUID of this item.
* Param installLocation
* The Install Location where this item is installed.
* Param type
* The nsIUpdateItem type of this item.
*/
_configureForthcomingItem: function(installManifest, id, installLocation, type) {
var ds = this.datasource;
ds.updateVisibleList(id, installLocation.name, false);var name = null;
var localized = findClosestLocalizedResource(installManifest, gInstallManifestRoot);
if (localized)
name = installManifest.GetTarget(localized, EM_R("name"), true);
else
name = EM_L(getManifestProperty(installManifest, "name"));var props = { name : name,
version : EM_L(getManifestProperty(installManifest, "version")),
newVersion : EM_L(getManifestProperty(installManifest, "version")),
installLocation : EM_L(installLocation.name),
type : EM_I(type),
availableUpdateURL : null,
availableUpdateHash : null,
availableUpdateVersion: null,
availableUpdateInfo : null };
ds.setItemProperties(id, props);
ds.updateProperty(id, "availableUpdateURL");this._setOp(id, OP_NEEDS_INSTALL);
// Insert it into the child list NOW rather than later because:
// - extensions installed using the command line need to be a member
// of a container during the install phase for the code to be able
// to identify profile vs. global
// - extensions installed through the UI should show some kind of
// feedback to indicate their presence is forthcoming (i.e. they
// will be available after a restart).
ds.insertItemIntoContainer(id);this._notifyAction(id, EM_ITEM_INSTALLED);
},/**
* Perform configuration on an item that has just or will be upgraded.
* Param installManifest
* The Install Manifest datasource that describes this item.
* Param itemID
* The GUID of this item.
* Param installLocation
* The Install Location where this item is installed.
* Param type
* The nsIUpdateItem type of this item.
*/
_upgradeItem: function (installManifest, id, installLocation, type) {
// Don't change any props that would need to be reset if the install fails.
// They will be reset as appropriate by the upgrade/install process.
var ds = this.datasource;
ds.updateVisibleList(id, installLocation.name, false);
var props = { installLocation : EM_L(installLocation.name),
type : EM_I(type),
newVersion : EM_L(getManifestProperty(installManifest, "version")),
availableUpdateURL : null,
availableUpdateHash : null,
availableUpdateVersion : null,
availableUpdateInfo : null };
ds.setItemProperties(id, props);
ds.updateProperty(id, "availableUpdateURL");this._setOp(id, OP_NEEDS_UPGRADE);
this._notifyAction(id, EM_ITEM_UPGRADED);
},/**
* Completes an Extension's installation.
* Param id
* The GUID of the Extension to install.
* Param file
* The XPI/JAR file to install from. If this is null, we try to
* determine the stage file location from the ID.
*/
_finalizeInstall: function(id, file) {
var ds = this.datasource;
var type = ds.getItemProperty(id, "type");
if (id == 0 id == -1) {
ds.removeCorruptItem(id);
return;
}
var installLocation = this.getInstallLocation(id);
if (!installLocation) {
// If the install location is null, that means we've reached the finalize
// state without the item ever having metadata added for it, which implies
// bogus data in the Startup Cache. Clear the entries and don't do anything
// else.
var entries = StartupCache.findEntries(id);
for (var i = 0; i < entries.length; ++i) {
var location = InstallLocations.get(entries[i].location);
StartupCache.clearEntry(location, id);
PendingOperations.clearItem(OP_NEEDS_INSTALL, id);
}
return;
}
var itemLocation = installLocation.getItemLocation(id);if (!file && "stageFile" in installLocation)
file = installLocation.getStageFile(id);// If |file| is null or does not exist, the installer assumes the item is
// a dropped-in directory.
var installer = new Installer(this.datasource, id, installLocation, type);
installer.installFromFile(file);// If the file was staged, we must clean it up ourselves, otherwise the
// EM caller is responsible for doing so (e.g. XPInstall)
if (file)
installLocation.removeFile(file);// Clear the op flag from the Startup Cache and Pending Operations sets
StartupCache.put(installLocation, id, OP_NONE, true);
PendingOperations.clearItem(OP_NEEDS_INSTALL, id);
},/**
* Removes an item's metadata in preparation for an upgrade-install.
* Param id
* The GUID of the item to uninstall.
* Param installLocation
* The nsIInstallLocation of the item
*/
_finalizeUpgrade: function(id, installLocation) {
// Retrieve the item properties *BEFORE* we clean the resource!
var ds = this.datasource;var stagedFile = null;
if ("getStageFile" in installLocation)
stagedFile = installLocation.getStageFile(id);if (stagedFile)
var installRDF = extractRDFFileToTempDir(stagedFile, FILE_INSTALL_MANIFEST, true);
else
installRDF = installLocation.getItemFile(id, FILE_INSTALL_MANIFEST);
if (installRDF.exists()) {
var installManifest = getInstallManifest(installRDF);
if (installManifest) {
var type = getAddonTypeFromInstallManifest(installManifest);
var userDisabled = ds.getItemProperty(id, "userDisabled") == "true";// Clean the item resource
ds.removeItemMetadata(id);
// Now set up the properties on the item to mimic an item in its
// "initial state" for installation.
this._configureForthcomingItem(installManifest, id, installLocation,
type);
if (userDisabled)
ds.setItemProperty(id, EM_R("userDisabled"), EM_L("true"));
}
if (stagedFile)
installRDF.remove(false);
}
// Clear the op flag from the Pending Operations set. Do NOT clear op flag in
// the startup cache since this may have been reset to OP_NEEDS_INSTALL by
// |_configureForthcomingItem|.
PendingOperations.clearItem(OP_NEEDS_UPGRADE, id);
},/**
* Completes an item's uninstallation.
* Param id
* The GUID of the item to uninstall.
*/
_finalizeUninstall: function(id) {
var ds = this.datasource;var installLocation = this.getInstallLocation(id);
if (!installLocation.itemIsManagedIndependently(id)) {
try {
// Having a callback that does nothing just causes the directory to be
// removed.
safeInstallOperation(id, installLocation,
{ data: null, callback: function() { } });
}
catch (e) {
ERROR("_finalizeUninstall: failed to remove directory for item: " + id +
" at Install Location: " + installLocation.name + ", rolling back uninstall");
var manifest = installLocation.getItemFile(id, "FILE_INSTALL_MANIFEST");
// If there is no manifest then either the rollback failed, or there was
// no manifest in the first place. Either way this item is now invalid
// and we shouldn't try to re-install it.
if (manifest.exists()) {
// Removal of the files failed, reset the uninstalled flag and rewrite
// the install manifests so this item's components are registered.
// Clear the op flag from the Startup Cache
StartupCache.put(installLocation, id, OP_NONE, true);
var restartRequired = this.installRequiresRestart(id, ds.getItemProperty(id, "type"))
this._updateManifests(restartRequired);
return;
}
}
}
else if (installLocation.name == KEY_APP_PROFILE
installLocation.name == KEY_APP_GLOBAL
installLocation.name == KEY_APP_SYSTEM_USER) {
// Check for a pointer file and remove it if it exists
var pointerFile = installLocation.location.clone();
pointerFile.append(id);
if (pointerFile.exists() && !pointerFile.isDirectory())
pointerFile.remove(false);
}// Clean the item resource
ds.removeItemMetadata(id);// Do this LAST since inferences are made about an item based on
// what container it's in.
ds.removeItemFromContainer(id);// Clear the op flag from the Startup Cache and the Pending Operations set.
StartupCache.clearEntry(installLocation, id);
PendingOperations.clearItem(OP_NEEDS_UNINSTALL, id);
},/**
* Uninstalls an item. If the uninstallation cannot be performed immediately
* it is scheduled for the next restart.
* Param id
* The GUID of the item to uninstall.
*/
uninstallItem: function(id) {
var ds = this.datasource;
ds.updateDownloadState(PREFIX_ITEM_URI + id, null);
if (!ds.isDownloadItem(id)) {
var opType = ds.getItemProperty(id, "opType");
var installLocation = this.getInstallLocation(id);
// Removes any staged xpis for this item.
if (opType == OP_NEEDS_UPGRADE opType == OP_NEEDS_INSTALL) {
var stageFile = installLocation.getStageFile(id);
if (stageFile)
installLocation.removeFile(stageFile);
}
// Addons with an opType of OP_NEEDS_INSTALL only have a staged xpi file
// and are removed immediately since the uninstall can't be canceled.
if (opType == OP_NEEDS_INSTALL) {
ds.removeItemMetadata(id);
ds.removeItemFromContainer(id);
ds.updateVisibleList(id, null, true);
StartupCache.clearEntry(installLocation, id);
this._updateManifests(false);
}
else {
if (opType == OP_NEEDS_UPGRADE)
ds.setItemProperty(id, "newVersion", null);
this._setOp(id, OP_NEEDS_UNINSTALL);
var type = ds.getItemProperty(id, "type");
var restartRequired = this.installRequiresRestart(id, type);
if (!restartRequired) {
this._finalizeUninstall(id);
this._updateManifests(restartRequired);
}
}
}
else {
// Bad download entry - uri is url, e.g. "http://www.foo.com/test.xpi"
// ... just remove it from the list.
ds.removeCorruptDLItem(id);
}this._notifyAction(id, EM_ITEM_UNINSTALLED);
},/* See nsIExtensionManager.idl */
cancelInstallItem: function(id) {
var ds = this.datasource;
var opType = ds.getItemProperty(id, "opType");
if (opType != OP_NEEDS_UPGRADE && opType != OP_NEEDS_INSTALL)
return;ds.updateDownloadState(PREFIX_ITEM_URI + id, null);
var installLocation = this.getInstallLocation(id);
// Removes any staged xpis for this item.
var stageFile = installLocation.getStageFile(id);
if (stageFile)
installLocation.removeFile(stageFile);
// Addons with an opType of OP_NEEDS_INSTALL only have a staged xpi file
// and just need to be removed completely from the ds.
if (opType == OP_NEEDS_INSTALL) {
ds.removeItemMetadata(id);
ds.removeItemFromContainer(id);
ds.updateVisibleList(id, null, true);
StartupCache.clearEntry(installLocation, id);
this._updateManifests(false);
this._notifyAction(id, EM_ITEM_CANCEL);
}
else {
// Clear upgrade information and reset any request to enable/disable.
ds.setItemProperty(id, EM_R("newVersion"), null);
var appDisabled = ds.getItemProperty(id, "appDisabled");
var userDisabled = ds.getItemProperty(id, "userDisabled");
if (appDisabled == "true" appDisabled == OP_NONE && userDisabled == OP_NONE) {
this._setOp(id, OP_NONE);
this._notifyAction(id, EM_ITEM_CANCEL);
}
else if (appDisabled == OP_NEEDS_DISABLE userDisabled == OP_NEEDS_DISABLE) {
this._setOp(id, OP_NEEDS_DISABLE);
this._notifyAction(id, EM_ITEM_DISABLED);
}
else if (appDisabled == OP_NEEDS_ENABLE userDisabled == OP_NEEDS_ENABLE) {
this._setOp(id, OP_NEEDS_ENABLE);
this._notifyAction(id, EM_ITEM_ENABLED);
}
else {
this._setOp(id, OP_NONE);
this._notifyAction(id, EM_ITEM_CANCEL);
}
}
},/**
* Cancels a pending uninstall of an item
* Param id
* The ID of the item.
*/
cancelUninstallItem: function(id) {
var ds = this.datasource;
var appDisabled = ds.getItemProperty(id, "appDisabled");
var userDisabled = ds.getItemProperty(id, "userDisabled");
if (appDisabled == "true" appDisabled == OP_NONE && userDisabled == OP_NONE) {
this._setOp(id, OP_NONE);
this._notifyAction(id, EM_ITEM_CANCEL);
}
else if (appDisabled == OP_NEEDS_DISABLE userDisabled == OP_NEEDS_DISABLE) {
this._setOp(id, OP_NEEDS_DISABLE);
this._notifyAction(id, EM_ITEM_DISABLED);
}
else if (appDisabled == OP_NEEDS_ENABLE userDisabled == OP_NEEDS_ENABLE) {
this._setOp(id, OP_NEEDS_ENABLE);
this._notifyAction(id, EM_ITEM_ENABLED);
}
else {
this._setOp(id, OP_NONE);
this._notifyAction(id, EM_ITEM_CANCEL);
}
},/**
* Sets the pending operation for a visible item.
* Param id
* The GUID of the item
* Param op
* The name of the operation to be performed
*/
_setOp: function(id, op) {
var location = this.getInstallLocation(id);
StartupCache.put(location, id, op, true);
PendingOperations.addItem(op, { locationKey: location.name, id: id });
var ds = this.datasource;
if (op == OP_NEEDS_INSTALL op == OP_NEEDS_UPGRADE)
ds.updateDownloadState(PREFIX_ITEM_URI + id, "success");ds.updateProperty(id, "opType");
ds.updateProperty(id, "updateable");
ds.updateProperty(id, "satisfiesDependencies");
var restartRequired = this.installRequiresRestart(id, ds.getItemProperty(id, "type"))
this._updateDependentItemsForID(id);
this._updateManifests(restartRequired);
},/**
* Note on appDisabled and userDisabled property arcs.
* The appDisabled and userDisabled RDF property arcs are used to store
* the pending operation for app disabling and user disabling for an item as
* well as the user and app disabled status after the pending operation has
* been completed upon restart. When the appDisabled value changes the value
* of userDisabled is reset to prevent the state of widgets and status
* messages from being in an incorrect state.
*//**
* Enables an item for the application (e.g. the item satisfies all
* requirements like app compatibility for it to be enabled). The appDisabled
* property arc will be removed if the item will be app disabled on next
* restart to cancel the app disabled operation for the item otherwise the
* property value will be set to OP_NEEDS_ENABLE. The item's pending
* operations are then evaluated in order to set the operation to perform
* and notify the observers if the operation has been changed.
* See "Note on appDisabled and userDisabled property arcs" above.
* Param id
* The ID of the item to be enabled by the application.
*/
_appEnableItem: function(id) {
var ds = this.datasource;
var appDisabled = ds.getItemProperty(id, "appDisabled");
if (appDisabled == OP_NONE appDisabled == OP_NEEDS_ENABLE)
return;var opType = ds.getItemProperty(id, "opType");
var userDisabled = ds.getItemProperty(id, "userDisabled");
// reset user disabled if it has a pending operation to prevent the ui
// state from getting confused as to an item's current state.
if (userDisabled == OP_NEEDS_DISABLE)
ds.setItemProperty(id, EM_R("userDisabled"), null);
else if (userDisabled == OP_NEEDS_ENABLE)
ds.setItemProperty(id, EM_R("userDisabled"), EM_L("true"));if (appDisabled == OP_NEEDS_DISABLE)
ds.setItemProperty(id, EM_R("appDisabled"), null);
else if (appDisabled == "true")
ds.setItemProperty(id, EM_R("appDisabled"), EM_L(OP_NEEDS_ENABLE));// Don't set a new operation when there is a pending uninstall operation.
if (opType == OP_NEEDS_UNINSTALL) {
this._updateDependentItemsForID(id);
return;
}var operation, action;
// if this item is already enabled or user disabled don't set a pending
// operation - instead immediately enable it and reset the operation type
// if needed.
if (appDisabled == OP_NEEDS_DISABLE appDisabled == OP_NONE
userDisabled == "true") {
if (opType != OP_NONE) {
operation = OP_NONE;
action = EM_ITEM_CANCEL;
}
}
else {
if (opType != OP_NEEDS_ENABLE) {
operation = OP_NEEDS_ENABLE;
action = EM_ITEM_ENABLED;
}
}if (action) {
this._setOp(id, operation);
this._notifyAction(id, action);
}
else {
ds.updateProperty(id, "satisfiesDependencies");
this._updateDependentItemsForID(id);
}
},/**
* Disables an item for the application (e.g. the item doesn't satisfy all
* requirements like app compatibility for it to be enabled). The appDisabled
* property arc will be set to true if the item will be app enabled on next
* restart to cancel the app enabled operation for the item otherwise the
* property value will be set to OP_NEEDS_DISABLE. The item's pending
* operations are then evaluated in order to set the operation to perform
* and notify the observers if the operation has been changed.
* See "Note on appDisabled and userDisabled property arcs" above.
* Param id
* The ID of the item to be disabled by the application.
*/
_appDisableItem: function(id) {
var ds = this.datasource;
var appDisabled = ds.getItemProperty(id, "appDisabled");
if (appDisabled == "true" appDisabled == OP_NEEDS_DISABLE)
return;var opType = ds.getItemProperty(id, "opType");
var userDisabled = ds.getItemProperty(id, "userDisabled");// reset user disabled if it has a pending operation to prevent the ui
// state from getting confused as to an item's current state.
if (userDisabled == OP_NEEDS_DISABLE)
ds.setItemProperty(id, EM_R("userDisabled"), null);
else if (userDisabled == OP_NEEDS_ENABLE)
ds.setItemProperty(id, EM_R("userDisabled"), EM_L("true"));if (appDisabled == OP_NEEDS_ENABLE userDisabled == OP_NEEDS_ENABLE
ds.getItemProperty(id, "userDisabled") == "true")
ds.setItemProperty(id, EM_R("appDisabled"), EM_L("true"));
else if (appDisabled == OP_NONE)
ds.setItemProperty(id, EM_R("appDisabled"), EM_L(OP_NEEDS_DISABLE));// Don't set a new operation when there is a pending uninstall operation.
if (opType == OP_NEEDS_UNINSTALL) {
this._updateDependentItemsForID(id);
return;
}var operation, action;
// if this item is already disabled don't set a pending operation - instead
// immediately disable it and reset the operation type if needed.
if (appDisabled == OP_NEEDS_ENABLE appDisabled == "true"
userDisabled == OP_NEEDS_ENABLE userDisabled == "true") {
if (opType != OP_NONE) {
operation = OP_NONE;
action = EM_ITEM_CANCEL;
}
}
else {
if (opType != OP_NEEDS_DISABLE) {
operation = OP_NEEDS_DISABLE;
action = EM_ITEM_DISABLED;
}
}if (action) {
this._setOp(id, operation);
this._notifyAction(id, action);
}
else {
ds.updateProperty(id, "satisfiesDependencies");
this._updateDependentItemsForID(id);
}
},/**
* Sets an item to be enabled by the user. If the item is already enabled this
* clears the needs-enable operation for the next restart.
* See "Note on appDisabled and userDisabled property arcs" above.
* Param id
* The ID of the item to be enabled by the user.
*/
enableItem: function(id) {
var ds = this.datasource;
var opType = ds.getItemProperty(id, "opType");
var appDisabled = ds.getItemProperty(id, "appDisabled");
var userDisabled = ds.getItemProperty(id, "userDisabled");var operation, action;
// if this item is already enabled don't set a pending operation - instead
// immediately enable it and reset the operation type if needed.
if (appDisabled == OP_NONE &&
userDisabled == OP_NEEDS_DISABLE userDisabled == OP_NONE) {
if (userDisabled == OP_NEEDS_DISABLE)
ds.setItemProperty(id, EM_R("userDisabled"), null);
if (opType != OP_NONE) {
operation = OP_NONE;
action = EM_ITEM_CANCEL;
}
}
else {
if (userDisabled == "true")
ds.setItemProperty(id, EM_R("userDisabled"), EM_L(OP_NEEDS_ENABLE));
if (opType != OP_NEEDS_ENABLE) {
operation = OP_NEEDS_ENABLE;
action = EM_ITEM_ENABLED;
}
}if (action) {
this._setOp(id, operation);
this._notifyAction(id, action);
}
else {
ds.updateProperty(id, "satisfiesDependencies");
this._updateDependentItemsForID(id);
}
},/**
* Sets an item to be disabled by the user. If the item is already disabled
* this clears the needs-disable operation for the next restart.
* See "Note on appDisabled and userDisabled property arcs" above.
* Param id
* The ID of the item to be disabled by the user.
*/
disableItem: function(id) {
var ds = this.datasource;
var opType = ds.getItemProperty(id, "opType");
var appDisabled = ds.getItemProperty(id, "appDisabled");
var userDisabled = ds.getItemProperty(id, "userDisabled");var operation, action;
// if this item is already disabled don't set a pending operation - instead
// immediately disable it and reset the operation type if needed.
if (userDisabled == OP_NEEDS_ENABLE userDisabled == "true"
appDisabled == OP_NEEDS_ENABLE) {
if (userDisabled != "true")
ds.setItemProperty(id, EM_R("userDisabled"), EM_L("true"));
if (opType != OP_NONE) {
operation = OP_NONE;
action = EM_ITEM_CANCEL;
}
}
else {
if (userDisabled == OP_NONE)
ds.setItemProperty(id, EM_R("userDisabled"), EM_L(OP_NEEDS_DISABLE));
if (opType != OP_NEEDS_DISABLE) {
operation = OP_NEEDS_DISABLE;
action = EM_ITEM_DISABLED;
}
}if (action) {
this._setOp(id, operation);
this._notifyAction(id, action);
}
else {
ds.updateProperty(id, "satisfiesDependencies");
this._updateDependentItemsForID(id);
}
},/**
* Determines whether an item should be disabled by the application.
* Param id
* The ID of the item to check
*/
_isUsableItem: function(id) {
var ds = this.datasource;
/* If we're not compatibility checking or if the item is compatible
* and if it isn't blocklisted and has all dependencies satisfied then
* proceed to the security check */
if ((!gCheckCompatibility ds.getItemProperty(id, "compatible") == "true") &&
ds.getItemProperty(id, "blocklisted") == "false" &&
ds.getItemProperty(id, "satisfiesDependencies") == "true") {// appManaged items aren't updated so no need to check update security.
if (ds.getItemProperty(id, "appManaged") == "true")
return true;/* If we are not ignoring update security then check that the item has
* a secure update mechanism */
return (!gCheckUpdateSecurity
ds.getItemProperty(id, "providesUpdatesSecurely") == "true");
}
return false;
},/**
* Sets an item's dependent items disabled state for the app based on whether
* its dependencies are met and the item is compatible.
* Param id
* The ID of the item whose dependent items will be checked
*/
_updateDependentItemsForID: function(id) {
var ds = this.datasource;
var dependentItems = this.getDependentItemListForID(id, true, { });
for (var i = 0; i < dependentItems.length; ++i) {
var dependentID = dependentItems[i].id;
ds.updateProperty(dependentID, "satisfiesDependencies");
if (this._isUsableItem(dependentID))
this._appEnableItem(dependentID);
else
this._appDisableItem(dependentID);
}
},/**
* Notify observers of a change to an item that has been requested by the
* user.
*/
_notifyAction: function(id, reason) {
gOS.notifyObservers(this.datasource.getItemForID(id),
EM_ACTION_REQUESTED_TOPIC, reason);
},/**
* See nsIExtensionManager.idl
*/
update: function(items, itemCount, updateCheckType, listener) {
for (i = 0; i < itemCount; ++i) {
var currItem = items[i];
if (!currItem)
throw Cr.NS_ERROR_ILLEGAL_VALUE;
}if (items.length == 0)
items = this.getItemList(Ci.nsIUpdateItem.TYPE_ANY, { });var updater = new ExtensionItemUpdater(this);
updater.checkForUpdates(items, items.length, updateCheckType, listener);
},/**
* Checks for changes to the blocklist using the local blocklist file,
* application disables / enables items that have been added / removed from
* the blocklist, and if there are additions to the blocklist this will
* inform the user by displaying a list of the items added.
*
* XXXrstrong - this method is not terribly useful and was added so we ca