зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
026a59aa41
Коммит
d01c25f6a6
|
@ -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:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче