Bug 397073 - "Allow runtime overrides by OS version for chrome" [p=Mossop r=bsmedberg a1.9=schrep]

git-svn-id: svn://10.0.0.236/trunk@239266 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
reed%reedloden.com 2007-11-13 05:38:49 +00:00
parent 837aeded28
commit cb58218dac
3 changed files with 264 additions and 7 deletions

View File

@ -44,6 +44,11 @@
#include "prio.h"
#include "prprf.h"
#if defined(XP_WIN)
#include <windows.h>
#elif defined(XP_MACOSX)
#include <Carbon/Carbon.h>
#endif
#include "nsAppDirectoryServiceDefs.h"
#include "nsArrayEnumerator.h"
@ -63,6 +68,7 @@
#include "nsWidgetsCID.h"
#include "nsXPIDLString.h"
#include "nsXULAppAPI.h"
#include "nsTextFormatter.h"
#include "nsIAtom.h"
#include "nsICommandLine.h"
@ -1970,7 +1976,8 @@ CheckStringFlag(const nsSubstring& aFlag, const nsSubstring& aData,
* @param aFlag The flag to compare.
* @param aData The tokenized data to check; this is lowercased
* before being passed in.
* @param aValue The value that is expected.
* @param aValue The value that is expected. If this is empty then no
* comparison will match.
* @param aChecker the version checker to use. If null, aResult will always
* be eBad.
* @param aResult If this is eOK when passed in, this is left alone.
@ -1993,6 +2000,12 @@ CheckVersionFlag(const nsSubstring& aFlag, const nsSubstring& aData,
if (!StringBeginsWith(aData, aFlag))
return PR_FALSE;
if (aValue.Length() == 0) {
if (aResult != eOK)
aResult = eBad;
return PR_TRUE;
}
PRUint32 comparison;
nsAutoString testdata;
@ -2077,6 +2090,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
NS_NAMED_LITERAL_STRING(kXPCNativeWrappers, "xpcnativewrappers");
NS_NAMED_LITERAL_STRING(kApplication, "application");
NS_NAMED_LITERAL_STRING(kAppVersion, "appversion");
NS_NAMED_LITERAL_STRING(kOs, "os");
NS_NAMED_LITERAL_STRING(kOsVersion, "osversion");
nsCOMPtr<nsIIOService> io (do_GetIOService());
if (!io) return NS_ERROR_FAILURE;
@ -2090,6 +2105,7 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
nsAutoString appID;
nsAutoString appVersion;
nsAutoString osTarget;
nsCOMPtr<nsIXULAppInfo> xapp (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
if (xapp) {
nsCAutoString s;
@ -2100,7 +2116,34 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
rv = xapp->GetVersion(s);
if (NS_SUCCEEDED(rv))
CopyUTF8toUTF16(s, appVersion);
nsCOMPtr<nsIXULRuntime> xruntime (do_QueryInterface(xapp));
if (xruntime) {
rv = xruntime->GetOS(s);
if (NS_SUCCEEDED(rv)) {
CopyUTF8toUTF16(s, osTarget);
ToLowerCase(osTarget);
}
}
}
nsAutoString osVersion;
#if defined(XP_WIN)
OSVERSIONINFO info = { sizeof(OSVERSIONINFO) };
if (GetVersionEx(&info)) {
nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
info.dwMajorVersion,
info.dwMinorVersion);
}
#elif defined(XP_MACOSX)
long majorVersion, minorVersion;
if ((Gestalt(gestaltSystemVersionMajor, &majorVersion) == noErr) &&
(Gestalt(gestaltSystemVersionMinor, &minorVersion) == noErr)) {
nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
majorVersion,
minorVersion);
}
#endif
char *token;
char *newline = buf;
@ -2140,6 +2183,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
PRBool xpcNativeWrappers = PR_TRUE;
TriState stAppVersion = eUnspecified;
TriState stApp = eUnspecified;
TriState stOsVersion = eUnspecified;
TriState stOs = eUnspecified;
PRBool badFlag = PR_FALSE;
@ -2151,6 +2196,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
if (CheckFlag(kPlatform, wtoken, platform) ||
CheckFlag(kXPCNativeWrappers, wtoken, xpcNativeWrappers) ||
CheckStringFlag(kApplication, wtoken, appID, stApp) ||
CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
continue;
@ -2160,7 +2207,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
badFlag = PR_TRUE;
}
if (badFlag || stApp == eBad || stAppVersion == eBad)
if (badFlag || stApp == eBad || stAppVersion == eBad ||
stOs == eBad || stOsVersion == eBad)
continue;
nsCOMPtr<nsIURI> resolved;
@ -2211,6 +2259,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
TriState stAppVersion = eUnspecified;
TriState stApp = eUnspecified;
TriState stOs = eUnspecified;
TriState stOsVersion = eUnspecified;
PRBool badFlag = PR_FALSE;
@ -2220,6 +2270,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
ToLowerCase(wtoken);
if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
continue;
@ -2229,7 +2281,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
badFlag = PR_TRUE;
}
if (badFlag || stApp == eBad || stAppVersion == eBad)
if (badFlag || stApp == eBad || stAppVersion == eBad ||
stOs == eBad || stOsVersion == eBad)
continue;
nsCOMPtr<nsIURI> resolved;
@ -2261,6 +2314,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
TriState stAppVersion = eUnspecified;
TriState stApp = eUnspecified;
TriState stOs = eUnspecified;
TriState stOsVersion = eUnspecified;
PRBool badFlag = PR_FALSE;
@ -2270,6 +2325,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
ToLowerCase(wtoken);
if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
continue;
@ -2279,7 +2336,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
badFlag = PR_TRUE;
}
if (badFlag || stApp == eBad || stAppVersion == eBad)
if (badFlag || stApp == eBad || stAppVersion == eBad ||
stOs == eBad || stOsVersion == eBad)
continue;
nsCOMPtr<nsIURI> resolved;
@ -2313,6 +2371,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
TriState stAppVersion = eUnspecified;
TriState stApp = eUnspecified;
TriState stOs = eUnspecified;
TriState stOsVersion = eUnspecified;
PRBool badFlag = PR_FALSE;
@ -2322,6 +2382,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
ToLowerCase(wtoken);
if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
continue;
@ -2331,7 +2393,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
badFlag = PR_TRUE;
}
if (badFlag || stApp == eBad || stAppVersion == eBad)
if (badFlag || stApp == eBad || stAppVersion == eBad ||
stOs == eBad || stOsVersion == eBad)
continue;
nsCOMPtr<nsIURI> baseuri, overlayuri;
@ -2357,6 +2420,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
TriState stAppVersion = eUnspecified;
TriState stApp = eUnspecified;
TriState stOs = eUnspecified;
TriState stOsVersion = eUnspecified;
PRBool badFlag = PR_FALSE;
@ -2366,6 +2431,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
ToLowerCase(wtoken);
if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
continue;
@ -2375,7 +2442,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
badFlag = PR_TRUE;
}
if (badFlag || stApp == eBad || stAppVersion == eBad)
if (badFlag || stApp == eBad || stAppVersion == eBad ||
stOs == eBad || stOsVersion == eBad)
continue;
nsCOMPtr<nsIURI> baseuri, overlayuri;
@ -2405,6 +2473,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
TriState stAppVersion = eUnspecified;
TriState stApp = eUnspecified;
TriState stOs = eUnspecified;
TriState stOsVersion = eUnspecified;
PRBool badFlag = PR_FALSE;
@ -2414,6 +2484,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
ToLowerCase(wtoken);
if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
continue;
@ -2423,7 +2495,8 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
badFlag = PR_TRUE;
}
if (badFlag || stApp == eBad || stAppVersion == eBad)
if (badFlag || stApp == eBad || stAppVersion == eBad ||
stOs == eBad || stOsVersion == eBad)
continue;
nsCOMPtr<nsIURI> chromeuri, resolveduri;

View File

@ -0,0 +1,6 @@
# Success cases
content test1 test/ os=xpcshell
content test2 test/ os=XPCshell
# Failure cases
content test3 test/ os=FOOshell

View File

@ -0,0 +1,178 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Dave Townsend <dtownsend@oxymoronical.com>.
*
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK *****
*/
const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1";
const XULAPPINFO_CID = Components.ID("{48a4e946-1f9f-4224-b4b0-9a54183cb81e}");
const NS_CHROME_MANIFESTS_FILE_LIST = "ChromeML";
const Cc = Components.classes;
const Ci = Components.interfaces;
var MANIFESTS = [
do_get_file("chrome/test/unit/data/test_bug397073.manifest")
];
function ArrayEnumerator(array)
{
this.array = array;
}
ArrayEnumerator.prototype = {
pos: 0,
array: null,
hasMoreElements: function() {
return this.pos < this.array.length;
},
getNext: function() {
if (this.pos < this.array.length)
return this.array[this.pos++];
throw Components.results.NS_ERROR_FAILURE;
},
QueryInterface: function(iid) {
if (iid.equals(Ci.nsISimpleEnumerator)
|| iid.equals(Ci.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
}
};
var ChromeProvider = {
getFile: function(prop, persistent) {
throw Components.results.NS_ERROR_FAILURE
},
getFiles: function(prop) {
if (prop == NS_CHROME_MANIFESTS_FILE_LIST) {
return new ArrayEnumerator(MANIFESTS);
}
throw Components.results.NS_ERROR_FAILURE
},
QueryInterface: function(iid) {
if (iid.equals(Ci.nsIDirectoryServiceProvider)
|| iid.equals(Ci.nsIDirectoryServiceProvider2)
|| iid.equals(Ci.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
}
};
var dirSvc = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIDirectoryService);
dirSvc.registerProvider(ChromeProvider);
var XULAppInfo = {
vendor: "Mozilla",
name: "XPCShell",
ID: "{39885e5f-f6b4-4e2a-87e5-6259ecf79011}",
version: "5",
appBuildID: "2007010101",
platformVersion: "1.9",
platformBuildID: "2007010101",
inSafeMode: false,
logConsoleErrors: true,
OS: "XPCShell",
XPCOMABI: "noarch-spidermonkey",
QueryInterface: function QueryInterface(iid) {
if (iid.equals(Ci.nsIXULAppInfo)
|| iid.equals(Ci.nsIXULRuntime)
|| iid.equals(Ci.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
}
};
var XULAppInfoFactory = {
createInstance: function (outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return XULAppInfo.QueryInterface(iid);
}
};
var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
registrar.registerFactory(XULAPPINFO_CID, "XULAppInfo",
XULAPPINFO_CONTRACTID, XULAppInfoFactory);
var gIOS = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
var chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"]
.getService(Ci.nsIChromeRegistry);
chromeReg.checkForNewChrome();
var target = gIOS.newFileURI(do_get_file("chrome/test/unit/data"));
target = target.spec + "test/test.xul";
function test_succeeded_mapping(namespace)
{
var uri = gIOS.newURI("chrome://" + namespace + "/content/test.xul",
null, null);
try {
var result = chromeReg.convertChromeURL(uri);
do_check_eq(result.spec, target);
}
catch (ex) {
do_throw(namespace);
}
}
function test_failed_mapping(namespace)
{
var uri = gIOS.newURI("chrome://" + namespace + "/content/test.xul",
null, null);
try {
var result = chromeReg.convertChromeURL(uri);
do_throw(namespace);
}
catch (ex) {
}
}
function run_test()
{
test_succeeded_mapping("test1");
test_succeeded_mapping("test2");
test_failed_mapping("test3");
}