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: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:button anonid="clear-button" xbl:inherits="label=clearlabel,disabled=cleardisabled,hidden=clearhidden" mousethrough="always"/>
</xul:hbox> </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/> <children/>
</xul:vbox> </xul:vbox>
</content> </content>

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

@ -43,6 +43,13 @@ var gUpdateDialog = {
os.removeObserver(this, this._messages[i]); 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) observe: function (aSubject, aTopic, aData)
{ {
switch (aTopic) { switch (aTopic) {

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

@ -37,7 +37,6 @@
# ***** END LICENSE BLOCK ***** # ***** END LICENSE BLOCK *****
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://mozapps/skin/extensions/about.css" type="text/css"?>
<!DOCTYPE dialog [ <!DOCTYPE dialog [
<!ENTITY % updateDTD SYSTEM "chrome://mozapps/locale/extensions/update.dtd"> <!ENTITY % updateDTD SYSTEM "chrome://mozapps/locale/extensions/update.dtd">
@ -52,7 +51,7 @@
buttons="cancel" buttons="cancel"
onload="gUpdateDialog.init();" onload="gUpdateDialog.init();"
onunload="gUpdateDialog.uninit();" onunload="gUpdateDialog.uninit();"
oncancel="onCancelUpdateCheck();"> ondialogcancel="gUpdateDialog.cancel();">
<script type="application/x-javascript" src="chrome://mozapps/content/extensions/update.js"/> <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... statusProcessing=Processing data...
statusConnectionFailed=Connection to %S failed, skipping... statusConnectionFailed=Connection to %S failed, skipping...
progress=(%S of %S items complete) progress=(%S of %S items complete)
mismatchCheckNow=Check Now
mismatchDontCheck=Dont Check

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

@ -37,13 +37,99 @@
var gExtensionManager = null; 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() function nsExtensionManager()
{ {
var os = Components.classes["@mozilla.org/observer-service;1"] var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService); .getService(Components.interfaces.nsIObserverService);
os.addObserver(this, "profile-after-change", false); os.addObserver(this, "profile-after-change", false);
dump("*** global extensions startup!\n");
} }
nsExtensionManager.prototype = { nsExtensionManager.prototype = {
@ -61,43 +147,44 @@ nsExtensionManager.prototype = {
var pref = Components.classes["@mozilla.org/preferences-service;1"] var pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch); .getService(Components.interfaces.nsIPrefBranch);
var currAppVersion = pref.getCharPref(PREF_EM_APP_VERSION); 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) { if (currAppVersion != lastAppVersion) {
// Version mismatch, we're have to load the extensions datasource // Version mismatch, we're have to load the extensions datasource
// and do version checking. // and do version checking. Time hit here doesn't matter since this
var power = currAppVersion.split(".").length; // doesn't happen all that often.
currAppVersion = this.parseVersion(currAppVersion, power); this._ensureDS();
var currAppID = pref.getCharPref(PREF_EM_APP_ID);
var extensions = this._ds.getIncompatibleExtensionList(currAppID, currAppVersion);
var extensions = ds.getIncompatibleExtensionList(currAppVersion); if (extensions.length > 0) {
var updater = new nsExtensionUpdater(extensions, appID, currAppVersion); var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
updater.checkForUpdates(doneUpdatingExtension); .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 // nsIExtensionManager
installExtensionFromStream: function (aStream, aUseProfile) 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) function EM_NS(aProperty)
{ {
return "http://www.mozilla.org/2004/em-rdf#" + aProperty; return "http://www.mozilla.org/2004/em-rdf#" + aProperty;
@ -307,10 +389,10 @@ nsExtensionsDataSource.prototype = {
{ {
var extensions = []; var extensions = [];
if (aExtensionID) { if (aExtensionID) {
extensions.push({ id: aExtensionID, extensions.push(new Extension(aExtensionID,
version: this.getExtensionProperty(aExtensionID, "version"), this.getExtensionProperty(aExtensionID, "version"),
name: this.getExtensionProperty(aExtensionID, "name"), this.getExtensionProperty(aExtensionID, "name"),
row: -1, xpiURL: "" }); -1, ""));
} }
else { else {
var ctr = Components.classes["@mozilla.org/rdf/container;1"] var ctr = Components.classes["@mozilla.org/rdf/container;1"]
@ -321,9 +403,33 @@ nsExtensionsDataSource.prototype = {
while (elements.hasMoreElements()) { while (elements.hasMoreElements()) {
var e = elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource); var e = elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
var id = this._stripPrefix(e.Value); var id = this._stripPrefix(e.Value);
extensions.push({ id: id, version: this.getExtensionProperty(id, "version"), extensions.push(new Extension(id,
name: this.getExtensionProperty(id, "name"), row: -1, this.getExtensionProperty(id, "version"),
xpiURL: "" }); 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; return extensions;
@ -448,13 +554,23 @@ nsExtensionsDataSource.prototype = {
loadExtensions: function (aProfile) loadExtensions: function (aProfile)
{ {
var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties); 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); var extensionsFile = fileLocator.get(key, Components.interfaces.nsIFile);
extensionsFile.append("Extensions"); extensionsFile.append("extensions");
var extensionsDir = extensionsFile.clone();
extensionsFile.append("extensions.rdf"); extensionsFile.append("extensions.rdf");
if (!extensionsFile.exists()) if (!extensionsFile.exists()) {
return; // 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"] var ioServ = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService); .getService(Components.interfaces.nsIIOService);

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

@ -21,6 +21,8 @@ toolkit.jar:
* content/mozapps/extensions/about.js (extensions/content/about.js) * content/mozapps/extensions/about.js (extensions/content/about.js)
* content/mozapps/extensions/update.xul (extensions/content/update.xul) * content/mozapps/extensions/update.xul (extensions/content/update.xul)
* content/mozapps/extensions/update.js (extensions/content/update.js) * 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/shared/richview.xml (shared/content/richview.xml)
content/mozapps/contents.rdf (contents-content.rdf) 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/extensions.properties (extensions/locale/extensions.properties)
locale/en-US/mozapps/extensions/about.dtd (extensions/locale/about.dtd) 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/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) locale/en-US/mozapps/contents.rdf (contents-locale.rdf)
classic.jar: classic.jar: