Bug 558823: Migrate compatibility information from extensions.rdf. r=robstrong

This commit is contained in:
Dave Townsend 2010-04-20 15:41:56 -07:00
Родитель 90ab66511f
Коммит bfbf0eb9cf
3 изменённых файлов: 116 добавлений и 66 удалений

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

@ -87,9 +87,13 @@ const KEY_APP_SYSTEM_USER = "app-system-user";
const CATEGORY_UPDATE_PARAMS = "extension-update-params";
const UNKNOWN_XPCOM_ABI = "unknownABI";
const PREFIX_ITEM_URI = "urn:mozilla:item:";
const XPI_PERMISSION = "install";
const PREFIX_ITEM_URI = "urn:mozilla:item:";
const RDFURI_ITEM_ROOT = "urn:mozilla:item:root"
const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest";
const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
const TOOLKIT_ID = "toolkit@mozilla.org";
const BRANCH_REGEXP = /^([^\.]+\.[0-9]+[a-z]*).*/gi;
@ -242,6 +246,48 @@ function isUsableAddon(aAddon) {
return aAddon.blocklistState != Ci.nsIBlocklistService.STATE_BLOCKED;
}
this.__defineGetter__("gRDF", function() {
delete this.gRDF;
return this.gRDF = Cc["@mozilla.org/rdf/rdf-service;1"].
getService(Ci.nsIRDFService);
});
function EM_R(aProperty) {
return gRDF.GetResource(PREFIX_NS_EM + aProperty);
}
/**
* Converts an RDF literal, resource or integer into a string.
*
* @param aLiteral
* The RDF object to convert
* @return a string if the object could be converted or null
*/
function getRDFValue(aLiteral) {
if (aLiteral instanceof Ci.nsIRDFLiteral)
return aLiteral.Value;
if (aLiteral instanceof Ci.nsIRDFResource)
return aLiteral.Value;
if (aLiteral instanceof Ci.nsIRDFInt)
return aLiteral.Value;
return null;
}
/**
* Gets an RDF property as a string
*
* @param aDs
* The RDF datasource to read the property from
* @param aResource
* The RDF resource to read the property from
* @param aProperty
* The property to read
* @return a string if the property existed or null
*/
function getRDFProperty(aDs, aResource, aProperty) {
return getRDFValue(aDs.GetTarget(aResource, EM_R(aProperty), true));
}
/**
* Reads an AddonInternal object from an RDF stream.
*
@ -254,34 +300,11 @@ function isUsableAddon(aAddon) {
* be read
*/
function loadManifestFromRDF(aUri, aStream) {
let RDF = Cc["@mozilla.org/rdf/rdf-service;1"].
getService(Ci.nsIRDFService);
const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest";
const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
function EM_R(aProperty) {
return RDF.GetResource(PREFIX_NS_EM + aProperty);
}
function getValue(aLiteral) {
if (aLiteral instanceof Ci.nsIRDFLiteral)
return aLiteral.Value;
if (aLiteral instanceof Ci.nsIRDFResource)
return aLiteral.Value;
if (aLiteral instanceof Ci.nsIRDFInt)
return aLiteral.Value;
return null;
}
function getProperty(aDs, aSource, aProperty) {
return getValue(aDs.GetTarget(aSource, EM_R(aProperty), true));
}
function getPropertyArray(aDs, aSource, aProperty) {
let values = [];
let targets = aDs.GetTargets(aSource, EM_R(aProperty), true);
while (targets.hasMoreElements())
values.push(getValue(targets.getNext()));
values.push(getRDFValue(targets.getNext()));
return values;
}
@ -292,14 +315,14 @@ function loadManifestFromRDF(aUri, aStream) {
locale.locales = [];
let targets = ds.GetTargets(aSource, EM_R("locale"), true);
while (targets.hasMoreElements())
locale.locales.push(getValue(targets.getNext()));
locale.locales.push(getRDFValue(targets.getNext()));
if (locale.locales.length == 0)
throw new Error("No locales given for localized properties");
}
PROP_LOCALE_SINGLE.forEach(function(aProp) {
locale[aProp] = getProperty(aDs, aSource, aProp);
locale[aProp] = getRDFProperty(aDs, aSource, aProp);
});
PROP_LOCALE_MULTI.forEach(function(aProp) {
@ -339,10 +362,10 @@ function loadManifestFromRDF(aUri, aStream) {
throw e;
}
let root = RDF.GetResource(RDFURI_INSTALL_MANIFEST_ROOT);
let root = gRDF.GetResource(RDFURI_INSTALL_MANIFEST_ROOT);
let addon = new AddonInternal();
PROP_METADATA.forEach(function(aProp) {
addon[aProp] = getProperty(ds, root, aProp);
addon[aProp] = getRDFProperty(ds, root, aProp);
});
if (!addon.id || !addon.version)
throw new Error("No ID or version in install manifest");
@ -385,7 +408,7 @@ function loadManifestFromRDF(aUri, aStream) {
let target = targets.getNext().QueryInterface(Ci.nsIRDFResource);
let targetAppInfo = {};
PROP_TARGETAPP.forEach(function(aProp) {
targetAppInfo[aProp] = getProperty(ds, target, aProp);
targetAppInfo[aProp] = getRDFProperty(ds, target, aProp);
});
if (!targetAppInfo.id || !targetAppInfo.minVersion ||
!targetAppInfo.maxVersion)
@ -1368,6 +1391,8 @@ var XPIProvider = {
newAddon.userDisabled = aMigrateData.userDisabled;
if ("installDate" in aMigrateData)
newAddon.installDate = aMigrateData.installDate;
if ("targetApplications" in aMigrateData)
newAddon.applyCompatibilityUpdate(aMigrateData, true);
}
// Update the database.
@ -2322,33 +2347,40 @@ var XPIDatabase = {
// Migrate data from extensions.rdf
let rdffile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_OLD_DATABASE], true);
if (rdffile.exists()) {
let RDF = Cc["@mozilla.org/rdf/rdf-service;1"].
getService(Ci.nsIRDFService);
const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
let ds = gRDF.GetDataSourceBlocking(Services.io.newFileURI(rdffile).spec);
let root = Cc["@mozilla.org/rdf/container;1"].
createInstance(Ci.nsIRDFContainer);
root.Init(ds, gRDF.GetResource(RDFURI_ITEM_ROOT));
let elements = root.GetElements();
while (elements.hasMoreElements()) {
let source = elements.getNext().QueryInterface(Ci.nsIRDFResource);
function EM_R(aProperty) {
return RDF.GetResource(PREFIX_NS_EM + aProperty);
}
let location = getRDFProperty(ds, source, "installLocation");
if (location) {
if (!(location in migrateData))
migrateData[location] = {};
let id = source.ValueUTF8.substring(PREFIX_ITEM_URI.length);
migrateData[location][id] = {
userDisabled: false,
targetApplications: []
}
let ds = RDF.GetDataSourceBlocking(Services.io.newFileURI(rdffile).spec);
let disabled = getRDFProperty(ds, source, "userDisabled");
if (disabled == "true" || disabled == "needs-disable")
migrateData[location][id].userDisabled = true;
// Look for any add-ons that were disabled or going to be disabled
["true", "needs-disable"].forEach(function(val) {
let sources = ds.GetSources(EM_R("userDisabled"), RDF.GetLiteral(val),
true);
while (sources.hasMoreElements()) {
let source = sources.getNext().QueryInterface(Ci.nsIRDFResource);
let location = ds.GetTarget(source, EM_R("installLocation"), true);
if (location instanceof Ci.nsIRDFLiteral) {
if (!(location.Value in migrateData))
migrateData[location.Value] = {};
let id = source.ValueUTF8.substring(PREFIX_ITEM_URI.length);
migrateData[location.Value][id] = {
userDisabled: true
}
let targetApps = ds.GetTargets(source, EM_R("targetApplication"), true);
while (targetApps.hasMoreElements()) {
let targetApp = targetApps.getNext().QueryInterface(Ci.nsIRDFResource);
let appInfo = {
id: getRDFProperty(ds, targetApp, "id"),
minVersion: getRDFProperty(ds, targetApp, "minVersion"),
maxVersion: getRDFProperty(ds, targetApp, "maxVersion"),
};
migrateData[location][id].targetApplications.push(appInfo);
}
}
});
}
}
}
else {

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

@ -1,21 +1,31 @@
<?xml version="1.0"?>
<!-- This is a copy of extensions.rdf from Firefox 3.5 including four
test extensions. Addon1 was enabled, addon2 was disabled, addon3 was pending
disable at the next restart and addon4 was pending enable at the next
restart. -->
test extensions. Addon1 was user enabled, addon2 was user disabled, addon3
was pending user disable at the next restart and addon4 was pending user
enable at the next restart. Additionally addon1 and 2 have had
compatibility updates applies to make them compatible with the app and
toolkit respectively, addon3 and 4 have not -->
<RDF:RDF xmlns:NS1="http://www.mozilla.org/2004/em-rdf#"
xmlns:NC="http://home.netscape.com/NC-rdf#"
xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<RDF:Description RDF:about="rdf:#$w8dNC1"
<RDF:Description RDF:about="rdf:#$w8dNC3"
NS1:id="xpcshell@tests.mozilla.org"
NS1:minVersion="1"
NS1:maxVersion="1" />
<RDF:Description RDF:about="rdf:#$w8dNC2"
NS1:id="toolkit@mozilla.org"
NS1:minVersion="1"
NS1:maxVersion="1" />
<RDF:Description RDF:about="rdf:#$w8dNC1"
NS1:id="toolkit@mozilla.org"
NS1:minVersion="1"
NS1:maxVersion="2" />
<RDF:Description RDF:about="rdf:#$oadNC1"
NS1:id="xpcshell@tests.mozilla.org"
NS1:minVersion="1"
NS1:maxVersion="1" />
NS1:maxVersion="2" />
<RDF:Description RDF:about="urn:mozilla:item:addon1@tests.mozilla.org"
NS1:installLocation="app-profile"
NS1:version="1.0"
@ -37,7 +47,7 @@
NS1:name="Test 3"
NS1:userDisabled="needs-disable">
<NS1:type NC:parseType="Integer">2</NS1:type>
<NS1:targetApplication RDF:resource="rdf:#$w8dNC1"/>
<NS1:targetApplication RDF:resource="rdf:#$w8dNC3"/>
</RDF:Description>
<RDF:Description RDF:about="urn:mozilla:item:addon4@tests.mozilla.org"
NS1:installLocation="app-profile"
@ -45,7 +55,7 @@
NS1:name="Test 4"
NS1:userDisabled="needs-enable">
<NS1:type NC:parseType="Integer">2</NS1:type>
<NS1:targetApplication RDF:resource="rdf:#$w8dNC1"/>
<NS1:targetApplication RDF:resource="rdf:#$w8dNC2"/>
</RDF:Description>
<RDF:Seq RDF:about="urn:mozilla:item:root">
<RDF:li RDF:resource="urn:mozilla:item:addon1@tests.mozilla.org"/>

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

@ -20,7 +20,7 @@ var addon2 = {
version: "2.0",
name: "Test 2",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
id: "toolkit@mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
@ -42,7 +42,7 @@ var addon4 = {
version: "2.0",
name: "Test 4",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
id: "toolkit@mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
@ -53,7 +53,7 @@ profileDir.append("extensions");
function run_test() {
do_test_pending();
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "2");
var dest = profileDir.clone();
dest.append("addon1@tests.mozilla.org");
@ -76,18 +76,26 @@ function run_test() {
"addon2@tests.mozilla.org",
"addon3@tests.mozilla.org",
"addon4@tests.mozilla.org"], function([a1, a2, a3, a4]) {
// addon1 was enabled in the old extensions.rdf
// addon1 was user and app enabled in the old extensions.rdf
do_check_neq(a1, null);
do_check_false(a1.userDisabled);
// addon1 was disabled in the old extensions.rdf
do_check_false(a1.appDisabled);
// addon2 was user disabled and app enabled in the old extensions.rdf
do_check_neq(a2, null);
do_check_true(a2.userDisabled);
// addon1 was pending-disable in the old extensions.rdf
do_check_false(a2.appDisabled);
// addon3 was pending user disable and app disabled in the old extensions.rdf
do_check_neq(a3, null);
do_check_true(a3.userDisabled);
// addon1 was pending-enable in the old extensions.rdf
do_check_true(a3.appDisabled);
// addon4 was pending user enable and app disabled in the old extensions.rdf
do_check_neq(a4, null);
do_check_false(a4.userDisabled);
do_check_true(a4.appDisabled);
do_test_finished();
});
}