170006 - add support for extension app version incompatbility checking to extension manager to disable incompatible extensions when a new version of the app is installed

This commit is contained in:
ben%bengoodger.com 2004-04-21 08:48:30 +00:00
Родитель 026a59aa41
Коммит d01c25f6a6
6 изменённых файлов: 180 добавлений и 52 удалений

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

@ -14,7 +14,7 @@
<xul:label class="header expanderButton" anonid="label" xbl:inherits="value=label,disabled" mousethrough="always" flex="1"/>
<xul:button anonid="clear-button" xbl:inherits="label=clearlabel,disabled=cleardisabled,hidden=clearhidden" mousethrough="always"/>
</xul:hbox>
<xul:vbox flex="1" anonid="settings" class="settingsContainer" collapsed="true">
<xul:vbox flex="1" anonid="settings" class="settingsContainer" collapsed="true" xbl:inherits="align">
<children/>
</xul:vbox>
</content>

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

@ -43,6 +43,13 @@ var gUpdateDialog = {
os.removeObserver(this, this._messages[i]);
},
cancel: function ()
{
// This will cause uninit to be called, removing our listener, so the extension manager's
// notifications will go nowhere.
window.close();
},
observe: function (aSubject, aTopic, aData)
{
switch (aTopic) {

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

@ -37,7 +37,6 @@
# ***** END LICENSE BLOCK *****
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://mozapps/skin/extensions/about.css" type="text/css"?>
<!DOCTYPE dialog [
<!ENTITY % updateDTD SYSTEM "chrome://mozapps/locale/extensions/update.dtd">
@ -52,7 +51,7 @@
buttons="cancel"
onload="gUpdateDialog.init();"
onunload="gUpdateDialog.uninit();"
oncancel="onCancelUpdateCheck();">
ondialogcancel="gUpdateDialog.cancel();">
<script type="application/x-javascript" src="chrome://mozapps/content/extensions/update.js"/>

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

@ -15,3 +15,6 @@ statusConnecting=Connecting to %S, please wait...
statusProcessing=Processing data...
statusConnectionFailed=Connection to %S failed, skipping...
progress=(%S of %S items complete)
mismatchCheckNow=Check Now
mismatchDontCheck=Dont Check

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

@ -37,13 +37,99 @@
var gExtensionManager = null;
const PREF_EM_APP_ID = "app.id";
const PREF_EM_APP_VERSION = "app.version";
const PREF_EM_LAST_APP_VERSION = "extensions.lastAppVersion";
const PREF_UPDATE_EXTENSIONS = "update.extensions.enabled";
const PREF_UPDATE_AUTOUPDATE = "update.extensions.autoUpdate";
const PREF_UPDATE_APP = "update.app.enabled";
function Extension (aID, aVersion, aName, aRow, aXPIURL)
{
this.id = aID;
this.version = aVersion;
this.name = aName;
this.row = aRow;
this.xpiURL = aXPIURL;
}
function VersionChecker(aExtensionResource, aAppID, aAppVersion, aDataSource)
{
this._extensionResource = aExtensionResource;
this._appID = aAppID;
this._appVersion = aAppVersion;
this._ds = aDataSource;
}
VersionChecker.prototype = {
get isCompatible ()
{
var targets = this._ds.GetTargets(this._extensionResource, this._ds._emR("targetApplication"), true);
while (targets.hasMoreElements()) {
var targetAppString = targets.getNext().QueryInterface(Components.interfaces.nsIRDFLiteral);
var versionParts = targetAppString.Value.split(",");
if (versionParts[0] == this._appID) {
var minRequiredVersionStr = versionParts[1];
var maxRequiredVersionStr = versionParts[2];
var power = this._getLargestPower([this._appVersion,
minRequiredVersionStr,
maxRequiredVersionStr]);
var minRequiredVersion = this._parseVersion(minRequiredVersionStr, power);
var maxRequiredVersion = this._parseVersion(maxRequiredVersionStr, power);
var appVersion = this._parseVersion(this._appVersion, power);
return (appVersion >= minRequiredVersion &&
appVersion <= maxRequiredVersion);
}
}
return false;
},
// Convert a version string into an integer value
_parseVersion: function (aVersion, aPower)
{
var parts = aVersion.split(".");
var version = 0;
if (aPower == 0)
aPower = parts.length;
for (var i = 0; i < parts.length; ++i) {
var token = parts[i];
if (token.charAt(token.length-1) == "+") {
token = token.substr(0, token.lastIndexOf("+"));
version += 1;
if (token.length == 0)
continue;
}
version += parseInt(token) * Math.pow(10, aPower - i);
}
return version;
},
_parsePower: function (aVersion)
{
return aVersion.split(".").length;
},
_getLargestPower: function (aVersionArray)
{
var biggestPower = 0;
for (var i = 0; i < aVersionArray.length; ++i) {
var power = this._parsePower(aVersionArray[i]);
if (power > biggestPower)
biggestPower = power;
}
return biggestPower;
}
}
function nsExtensionManager()
{
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
os.addObserver(this, "profile-after-change", false);
dump("*** global extensions startup!\n");
}
nsExtensionManager.prototype = {
@ -61,43 +147,44 @@ nsExtensionManager.prototype = {
var pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
var currAppVersion = pref.getCharPref(PREF_EM_APP_VERSION);
var lastAppVersion = pref.getCharPref(PREF_EM_LAST_APP_VERSION);
try {
var lastAppVersion = pref.getCharPref(PREF_EM_LAST_APP_VERSION);
}
catch (e) {}
if (currAppVersion != lastAppVersion) {
// Version mismatch, we're have to load the extensions datasource
// and do version checking.
var power = currAppVersion.split(".").length;
currAppVersion = this.parseVersion(currAppVersion, power);
// and do version checking. Time hit here doesn't matter since this
// doesn't happen all that often.
this._ensureDS();
var currAppID = pref.getCharPref(PREF_EM_APP_ID);
var extensions = this._ds.getIncompatibleExtensionList(currAppID, currAppVersion);
var extensions = ds.getIncompatibleExtensionList(currAppVersion);
var updater = new nsExtensionUpdater(extensions, appID, currAppVersion);
updater.checkForUpdates(doneUpdatingExtension);
if (extensions.length > 0) {
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
var ary = Components.classes["@mozilla.org/supports-array;1"]
.createInstance(Components.interfaces.nsISupportsArray);
for (var i = 0; i < extensions.length; ++i) {
var str = Components.classes["@mozilla.org/supports-string;1"]
.createInstance(Components.interfaces.nsISupportsString);
str.data = extensions[i].toSource();
ary.AppendElement(str);
// Now disable the extension so it won't hurt anything.
this.disableExtension(extensions[i].id);
}
ww.openWindow(null, "chrome://mozapps/content/extensions/mismatch.xul",
"", "chrome,centerscreen,modal", ary);
//
}
}
dump("*** profile extensions startup\n");
// Now update the last app version so we don't do this checking
// again.
// pref.setCharPref(PREF_EM_LAST_APP_VERSION, currAppVersion);
}
},
parseVersion: function (aVersion, aPower)
{
var parts = aVersion.split(".");
var vrsion = 0;
if (aPower == 0)
aPower = parts.length;
for (var i = 0; i < parts.length; ++i) {
var token = parts[i];
if (token.charAt(token.length-1) == "+") {
token = token.substr(0, token.lastIndexOf("+"));
version += 1;
if (token.length == 0)
continue;
}
version += parseInt(token) * Math.pow(10, aPower - i);
}
return version;
},
// nsIExtensionManager
installExtensionFromStream: function (aStream, aUseProfile)
{
@ -269,11 +356,6 @@ nsExtensionUpdater.prototype = {
};
const PREF_EM_DEFAULTUPDATEURL = "update.url.extensions";
const PREF_EM_APP_ID = "app.id";
const PREF_EM_LAST_APP_VERSION = "extensions.lastAppVersion";
const PREF_EM_APP_VERSION = "general.useragent.vendorSub";
function EM_NS(aProperty)
{
return "http://www.mozilla.org/2004/em-rdf#" + aProperty;
@ -307,10 +389,10 @@ nsExtensionsDataSource.prototype = {
{
var extensions = [];
if (aExtensionID) {
extensions.push({ id: aExtensionID,
version: this.getExtensionProperty(aExtensionID, "version"),
name: this.getExtensionProperty(aExtensionID, "name"),
row: -1, xpiURL: "" });
extensions.push(new Extension(aExtensionID,
this.getExtensionProperty(aExtensionID, "version"),
this.getExtensionProperty(aExtensionID, "name"),
-1, ""));
}
else {
var ctr = Components.classes["@mozilla.org/rdf/container;1"]
@ -321,9 +403,33 @@ nsExtensionsDataSource.prototype = {
while (elements.hasMoreElements()) {
var e = elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
var id = this._stripPrefix(e.Value);
extensions.push({ id: id, version: this.getExtensionProperty(id, "version"),
name: this.getExtensionProperty(id, "name"), row: -1,
xpiURL: "" });
extensions.push(new Extension(id,
this.getExtensionProperty(id, "version"),
this.getExtensionProperty(id, "name"),
-1, ""));
}
}
return extensions;
},
getIncompatibleExtensionList: function (aAppID, aAppVersion)
{
var extensions = [];
var ctr = Components.classes["@mozilla.org/rdf/container;1"]
.createInstance(Components.interfaces.nsIRDFContainer);
ctr.Init(this, this._rdf.GetResource("urn:mozilla:extension:root"));
var elements = ctr.GetElements();
while (elements.hasMoreElements()) {
var e = elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
var checker = new VersionChecker(e, aAppID, aAppVersion, this);
if (!checker.isCompatible) {
var id = this._stripPrefix(e.Value);
extensions.push(new Extension(id,
this.getExtensionProperty(id, "version"),
this.getExtensionProperty(id, "name"),
-1, ""));
}
}
return extensions;
@ -448,13 +554,23 @@ nsExtensionsDataSource.prototype = {
loadExtensions: function (aProfile)
{
var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
var key = aProfile ? "ProfD" : "ProfD"; // XCurProcDir
var key = aProfile ? "ProfD" : "ProfD"; // XXXben - XCurProcDir
var extensionsFile = fileLocator.get(key, Components.interfaces.nsIFile);
extensionsFile.append("Extensions");
extensionsFile.append("extensions");
var extensionsDir = extensionsFile.clone();
extensionsFile.append("extensions.rdf");
if (!extensionsFile.exists())
return;
if (!extensionsFile.exists()) {
// XXXben - Copy over the default file - temporary.
if (key == "ProfD") {
var defaultExtensionsFile = fileLocator.get("ProfDefNoLoc", Components.interfaces.nsIFile);
defaultExtensionsFile.append("extensions");
defaultExtensionsFile.append("extensions.rdf");
defaultExtensionsFile.copyTo(extensionsDir, "extensions.rdf");
}
else
return;
}
var ioServ = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);

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

@ -21,6 +21,8 @@ toolkit.jar:
* content/mozapps/extensions/about.js (extensions/content/about.js)
* content/mozapps/extensions/update.xul (extensions/content/update.xul)
* content/mozapps/extensions/update.js (extensions/content/update.js)
* content/mozapps/extensions/mismatch.xul (extensions/content/mismatch.xul)
* content/mozapps/extensions/mismatch.js (extensions/content/mismatch.js)
* content/mozapps/shared/richview.xml (shared/content/richview.xml)
content/mozapps/contents.rdf (contents-content.rdf)
@ -36,6 +38,7 @@ en-US.jar:
locale/en-US/mozapps/extensions/extensions.properties (extensions/locale/extensions.properties)
locale/en-US/mozapps/extensions/about.dtd (extensions/locale/about.dtd)
locale/en-US/mozapps/extensions/update.dtd (extensions/locale/update.dtd)
locale/en-US/mozapps/extensions/mismatch.dtd (extensions/locale/mismatch.dtd)
locale/en-US/mozapps/contents.rdf (contents-locale.rdf)
classic.jar: