зеркало из 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: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:
|
||||
|
|
Загрузка…
Ссылка в новой задаче