зеркало из https://github.com/mozilla/gecko-dev.git
Bug 942639 - Make DataStore API Certified-only for 1.3, r=ehsan, r=fabrice
This commit is contained in:
Родитель
a953805af0
Коммит
8780029785
|
@ -383,12 +383,12 @@ interface nsIFrameScriptLoader : nsISupports
|
||||||
nsIDOMDOMStringList getDelayedFrameScripts();
|
nsIDOMDOMStringList getDelayedFrameScripts();
|
||||||
};
|
};
|
||||||
|
|
||||||
[scriptable, builtinclass, uuid(b37821ff-df79-44d4-821c-6d6ec4dfe1e9)]
|
[scriptable, builtinclass, uuid(ad57800b-ff21-4e2f-91d3-e68615ae8afe)]
|
||||||
interface nsIProcessChecker : nsISupports
|
interface nsIProcessChecker : nsISupports
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true iff the "remote" process has |aPermission|. This is
|
* Return true if the "remote" process has |aPermission|. This is
|
||||||
* intended to be used by JS implementations of cross-process DOM
|
* intended to be used by JS implementations of cross-process DOM
|
||||||
* APIs, like so
|
* APIs, like so
|
||||||
*
|
*
|
||||||
|
@ -409,7 +409,7 @@ interface nsIProcessChecker : nsISupports
|
||||||
boolean assertPermission(in DOMString aPermission);
|
boolean assertPermission(in DOMString aPermission);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true iff the "remote" process has |aManifestURL|. This is
|
* Return true if the "remote" process has |aManifestURL|. This is
|
||||||
* intended to be used by JS implementations of cross-process DOM
|
* intended to be used by JS implementations of cross-process DOM
|
||||||
* APIs, like so
|
* APIs, like so
|
||||||
*
|
*
|
||||||
|
@ -432,14 +432,17 @@ interface nsIProcessChecker : nsISupports
|
||||||
boolean assertAppHasPermission(in DOMString aPermission);
|
boolean assertAppHasPermission(in DOMString aPermission);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true iff the "remote" process' principal has an appStatus equal to
|
* Return true if the "remote" process' principal has an appStatus equal to
|
||||||
* |aStatus|.
|
* |aStatus|.
|
||||||
*
|
*
|
||||||
* This interface only returns meaningful data when our content is
|
* This interface only returns meaningful data when our content is
|
||||||
* in a separate process. If it shares the same OS process as us,
|
* in a separate process. If it shares the same OS process as us,
|
||||||
* then applying this permission check doesn't add any security,
|
* then applying this permission check doesn't add any security,
|
||||||
* though it doesn't hurt anything either.
|
* though it doesn't hurt anything either.
|
||||||
|
*
|
||||||
|
* Note: If the remote content process does *not* has the |aStatus|,
|
||||||
|
* it will be killed as a precaution.
|
||||||
*/
|
*/
|
||||||
boolean checkAppHasStatus(in unsigned short aStatus);
|
boolean assertAppHasStatus(in unsigned short aStatus);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -805,8 +805,8 @@ nsFrameMessageManager::AssertAppHasPermission(const nsAString& aPermission,
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFrameMessageManager::CheckAppHasStatus(unsigned short aStatus,
|
nsFrameMessageManager::AssertAppHasStatus(unsigned short aStatus,
|
||||||
bool* aHasStatus)
|
bool* aHasStatus)
|
||||||
{
|
{
|
||||||
*aHasStatus = false;
|
*aHasStatus = false;
|
||||||
|
|
||||||
|
@ -1592,6 +1592,12 @@ public:
|
||||||
// In a single-process scenario, the child always has all capabilities.
|
// In a single-process scenario, the child always has all capabilities.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool CheckAppHasStatus(unsigned short aStatus)
|
||||||
|
{
|
||||||
|
// In a single-process scenario, the child always has all capabilities.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -313,10 +313,9 @@ this.DOMApplicationRegistry = {
|
||||||
|
|
||||||
// Create or Update the DataStore for this app
|
// Create or Update the DataStore for this app
|
||||||
this._readManifests([{ id: aId }], (function(aResult) {
|
this._readManifests([{ id: aId }], (function(aResult) {
|
||||||
this.updateDataStore(this.webapps[aId].localId,
|
let app = this.webapps[aId];
|
||||||
this.webapps[aId].origin,
|
this.updateDataStore(app.localId, app.origin, app.manifestURL,
|
||||||
this.webapps[aId].manifestURL,
|
aResult[0].manifest, app.appStatus);
|
||||||
aResult[0].manifest);
|
|
||||||
}).bind(this));
|
}).bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -588,7 +587,15 @@ this.DOMApplicationRegistry = {
|
||||||
}).bind(this));
|
}).bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
updateDataStore: function(aId, aOrigin, aManifestURL, aManifest) {
|
updateDataStore: function(aId, aOrigin, aManifestURL, aManifest, aAppStatus) {
|
||||||
|
// Just Certified Apps can use DataStores
|
||||||
|
let prefName = "dom.testing.datastore_enabled_for_hosted_apps";
|
||||||
|
if (aAppStatus != Ci.nsIPrincipal.APP_STATUS_CERTIFIED &&
|
||||||
|
(Services.prefs.getPrefType(prefName) == Services.prefs.PREF_INVALID ||
|
||||||
|
!Services.prefs.getBoolPref(prefName))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ('datastores-owned' in aManifest) {
|
if ('datastores-owned' in aManifest) {
|
||||||
for (let name in aManifest['datastores-owned']) {
|
for (let name in aManifest['datastores-owned']) {
|
||||||
let readonly = "access" in aManifest['datastores-owned'][name]
|
let readonly = "access" in aManifest['datastores-owned'][name]
|
||||||
|
@ -1477,7 +1484,7 @@ this.DOMApplicationRegistry = {
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
this.updateDataStore(this.webapps[id].localId, app.origin,
|
this.updateDataStore(this.webapps[id].localId, app.origin,
|
||||||
app.manifestURL, aData);
|
app.manifestURL, aData, app.appStatus);
|
||||||
this.broadcastMessage("Webapps:UpdateState", {
|
this.broadcastMessage("Webapps:UpdateState", {
|
||||||
app: app,
|
app: app,
|
||||||
manifest: aData,
|
manifest: aData,
|
||||||
|
@ -1651,7 +1658,7 @@ this.DOMApplicationRegistry = {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateDataStore(this.webapps[id].localId, app.origin,
|
this.updateDataStore(this.webapps[id].localId, app.origin,
|
||||||
app.manifestURL, app.manifest);
|
app.manifestURL, app.manifest, app.appStatus);
|
||||||
|
|
||||||
app.name = manifest.name;
|
app.name = manifest.name;
|
||||||
app.csp = manifest.csp || "";
|
app.csp = manifest.csp || "";
|
||||||
|
@ -2287,7 +2294,8 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateDataStore(this.webapps[id].localId, this.webapps[id].origin,
|
this.updateDataStore(this.webapps[id].localId, this.webapps[id].origin,
|
||||||
this.webapps[id].manifestURL, jsonManifest);
|
this.webapps[id].manifestURL, jsonManifest,
|
||||||
|
this.webapps[id].appStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
for each (let prop in ["installState", "downloadAvailable", "downloading",
|
for each (let prop in ["installState", "downloadAvailable", "downloading",
|
||||||
|
@ -2398,7 +2406,7 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateDataStore(this.webapps[aId].localId, aNewApp.origin,
|
this.updateDataStore(this.webapps[aId].localId, aNewApp.origin,
|
||||||
aNewApp.manifestURL, aManifest);
|
aNewApp.manifestURL, aManifest, aNewApp.appStatus);
|
||||||
|
|
||||||
this.broadcastMessage("Webapps:UpdateState", {
|
this.broadcastMessage("Webapps:UpdateState", {
|
||||||
app: app,
|
app: app,
|
||||||
|
|
|
@ -50,6 +50,8 @@
|
||||||
#include "TimeManager.h"
|
#include "TimeManager.h"
|
||||||
#include "DeviceStorage.h"
|
#include "DeviceStorage.h"
|
||||||
#include "nsIDOMNavigatorSystemMessages.h"
|
#include "nsIDOMNavigatorSystemMessages.h"
|
||||||
|
#include "nsIAppsService.h"
|
||||||
|
#include "mozIApplication.h"
|
||||||
|
|
||||||
#ifdef MOZ_MEDIA_NAVIGATOR
|
#ifdef MOZ_MEDIA_NAVIGATOR
|
||||||
#include "MediaManager.h"
|
#include "MediaManager.h"
|
||||||
|
@ -1849,6 +1851,38 @@ bool Navigator::HasInputMethodSupport(JSContext* /* unused */,
|
||||||
win && CheckPermission(win, "input"));
|
win && CheckPermission(win, "input"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
bool
|
||||||
|
Navigator::HasDataStoreSupport(JSContext* /* unused */, JSObject* aGlobal)
|
||||||
|
{
|
||||||
|
// First of all, the general pref has to be turned on.
|
||||||
|
bool enabled = false;
|
||||||
|
Preferences::GetBool("dom.datastore.enabled", &enabled);
|
||||||
|
NS_ENSURE_TRUE(enabled, false);
|
||||||
|
|
||||||
|
// Just for testing, we can enable DataStore for any kind of app.
|
||||||
|
if (Preferences::GetBool("dom.testing.datastore_enabled_for_hosted_apps", false)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
|
||||||
|
if (!win) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIDocument* doc = win->GetExtantDoc();
|
||||||
|
if (!doc || !doc->NodePrincipal()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t status;
|
||||||
|
if (NS_FAILED(doc->NodePrincipal()->GetAppStatus(&status))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status == nsIPrincipal::APP_STATUS_CERTIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
already_AddRefed<nsPIDOMWindow>
|
already_AddRefed<nsPIDOMWindow>
|
||||||
Navigator::GetWindowFromGlobal(JSObject* aGlobal)
|
Navigator::GetWindowFromGlobal(JSObject* aGlobal)
|
||||||
|
|
|
@ -286,6 +286,8 @@ public:
|
||||||
|
|
||||||
static bool HasInputMethodSupport(JSContext* /* unused */, JSObject* aGlobal);
|
static bool HasInputMethodSupport(JSContext* /* unused */, JSObject* aGlobal);
|
||||||
|
|
||||||
|
static bool HasDataStoreSupport(JSContext* /* unused */, JSObject* aGlobal);
|
||||||
|
|
||||||
nsPIDOMWindow* GetParentObject() const
|
nsPIDOMWindow* GetParentObject() const
|
||||||
{
|
{
|
||||||
return GetWindow();
|
return GetWindow();
|
||||||
|
|
|
@ -68,6 +68,13 @@ this.DataStoreChangeNotifier = {
|
||||||
receiveMessage: function(aMessage) {
|
receiveMessage: function(aMessage) {
|
||||||
debug("receiveMessage");
|
debug("receiveMessage");
|
||||||
|
|
||||||
|
let prefName = 'dom.testing.datastore_enabled_for_hosted_apps';
|
||||||
|
if ((Services.prefs.getPrefType(prefName) == Services.prefs.PREF_INVALID ||
|
||||||
|
!Services.prefs.getBoolPref(prefName)) &&
|
||||||
|
!aMessage.target.assertAppHasStatus(Ci.nsIPrincipal.APP_STATUS_CERTIFIED)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (aMessage.name) {
|
switch (aMessage.name) {
|
||||||
case "DataStore:Changed":
|
case "DataStore:Changed":
|
||||||
this.broadcastMessage("DataStore:Changed:Return:OK", aMessage.data);
|
this.broadcastMessage("DataStore:Changed:Return:OK", aMessage.data);
|
||||||
|
|
|
@ -234,6 +234,10 @@ DataStoreService.prototype = {
|
||||||
// window, so we can skip the ipc communication.
|
// window, so we can skip the ipc communication.
|
||||||
if (self.inParent) {
|
if (self.inParent) {
|
||||||
let stores = self.getDataStoresInfo(aName, aWindow.document.nodePrincipal.appId);
|
let stores = self.getDataStoresInfo(aName, aWindow.document.nodePrincipal.appId);
|
||||||
|
if (stores === null) {
|
||||||
|
reject(new aWindow.DOMError("SecurityError", "Access denied"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
self.getDataStoreCreate(aWindow, resolve, stores);
|
self.getDataStoreCreate(aWindow, resolve, stores);
|
||||||
} else {
|
} else {
|
||||||
// This method can be called in the child so we need to send a request
|
// This method can be called in the child so we need to send a request
|
||||||
|
@ -252,6 +256,20 @@ DataStoreService.prototype = {
|
||||||
getDataStoresInfo: function(aName, aAppId) {
|
getDataStoresInfo: function(aName, aAppId) {
|
||||||
debug('GetDataStoresInfo');
|
debug('GetDataStoresInfo');
|
||||||
|
|
||||||
|
let appsService = Cc["@mozilla.org/AppsService;1"]
|
||||||
|
.getService(Ci.nsIAppsService);
|
||||||
|
let app = appsService.getAppByLocalId(aAppId);
|
||||||
|
if (!app) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let prefName = "dom.testing.datastore_enabled_for_hosted_apps";
|
||||||
|
if (app.appStatus != Ci.nsIPrincipal.APP_STATUS_CERTIFIED &&
|
||||||
|
(Services.prefs.getPrefType(prefName) == Services.prefs.PREF_INVALID ||
|
||||||
|
!Services.prefs.getBoolPref(prefName))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
let results = [];
|
let results = [];
|
||||||
|
|
||||||
if (aName in this.stores) {
|
if (aName in this.stores) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ function debug(s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
||||||
"@mozilla.org/parentprocessmessagemanager;1",
|
"@mozilla.org/parentprocessmessagemanager;1",
|
||||||
|
@ -40,6 +41,13 @@ this.DataStoreServiceInternal = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let prefName = 'dom.testing.datastore_enabled_for_hosted_apps';
|
||||||
|
if ((Services.prefs.getPrefType(prefName) == Services.prefs.PREF_INVALID ||
|
||||||
|
!Services.prefs.getBoolPref(prefName)) &&
|
||||||
|
!aMessage.target.assertAppHasStatus(Ci.nsIPrincipal.APP_STATUS_CERTIFIED)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let msg = aMessage.data;
|
let msg = aMessage.data;
|
||||||
|
|
||||||
if (!aMessage.principal ||
|
if (!aMessage.principal ||
|
||||||
|
@ -49,6 +57,10 @@ this.DataStoreServiceInternal = {
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.stores = dataStoreService.getDataStoresInfo(msg.name, aMessage.principal.appId);
|
msg.stores = dataStoreService.getDataStoresInfo(msg.name, aMessage.principal.appId);
|
||||||
|
if (msg.stores === null) {
|
||||||
|
aMessage.target.sendAsyncMessage("DataStore:Get:Return:KO");
|
||||||
|
return;
|
||||||
|
}
|
||||||
aMessage.target.sendAsyncMessage("DataStore:Get:Return:OK", msg);
|
aMessage.target.sendAsyncMessage("DataStore:Get:Return:OK", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test for DataStore just for certified Apps</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="container"></div>
|
||||||
|
<script type="application/javascript;version=1.7">
|
||||||
|
|
||||||
|
function ok(a, msg) {
|
||||||
|
alert((a ? 'OK' : 'KO')+ ' ' + msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish() {
|
||||||
|
alert('DONE');
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(!("getDataStores" in navigator), "DataStore not available");
|
||||||
|
finish();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -11,6 +11,7 @@ support-files =
|
||||||
file_arrays.html
|
file_arrays.html
|
||||||
file_sync.html
|
file_sync.html
|
||||||
file_bug924104.html
|
file_bug924104.html
|
||||||
|
file_certifiedApp.html
|
||||||
|
|
||||||
[test_app_install.html]
|
[test_app_install.html]
|
||||||
[test_readonly.html]
|
[test_readonly.html]
|
||||||
|
@ -20,3 +21,4 @@ support-files =
|
||||||
[test_oop.html]
|
[test_oop.html]
|
||||||
[test_sync.html]
|
[test_sync.html]
|
||||||
[test_bug924104.html]
|
[test_bug924104.html]
|
||||||
|
[test_certifiedApp.html]
|
||||||
|
|
|
@ -27,7 +27,8 @@
|
||||||
function() {
|
function() {
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||||
["dom.promise.enabled", true],
|
["dom.promise.enabled", true],
|
||||||
["dom.testing.ignore_ipc_principal", true]]}, function() {
|
["dom.testing.ignore_ipc_principal", true],
|
||||||
|
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, function() {
|
||||||
gGenerator.next(); });
|
gGenerator.next(); });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -44,11 +45,6 @@
|
||||||
function runTest() {
|
function runTest() {
|
||||||
ok("getDataStores" in navigator, "getDataStores exists");
|
ok("getDataStores" in navigator, "getDataStores exists");
|
||||||
is(typeof navigator.getDataStores, "function", "getDataStores exists and it's a function");
|
is(typeof navigator.getDataStores, "function", "getDataStores exists and it's a function");
|
||||||
navigator.getDataStores('foo').then(function(stores) {
|
|
||||||
is(stores.length, 0, "getDataStores('foo') returns 0 elements");
|
|
||||||
continueTest();
|
|
||||||
}, cbError);
|
|
||||||
yield undefined;
|
|
||||||
|
|
||||||
SpecialPowers.setAllAppsLaunchable(true);
|
SpecialPowers.setAllAppsLaunchable(true);
|
||||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||||
|
|
|
@ -78,7 +78,8 @@
|
||||||
function() {
|
function() {
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
||||||
["dom.datastore.enabled", true],
|
["dom.datastore.enabled", true],
|
||||||
["dom.testing.ignore_ipc_principal", true]]}, runTest);
|
["dom.testing.ignore_ipc_principal", true],
|
||||||
|
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||||
},
|
},
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
|
|
|
@ -78,7 +78,8 @@
|
||||||
function() {
|
function() {
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
||||||
["dom.datastore.enabled", true],
|
["dom.datastore.enabled", true],
|
||||||
["dom.testing.ignore_ipc_principal", true]]}, runTest);
|
["dom.testing.ignore_ipc_principal", true],
|
||||||
|
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||||
},
|
},
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
|
|
|
@ -78,7 +78,8 @@
|
||||||
function() {
|
function() {
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
||||||
["dom.datastore.enabled", true],
|
["dom.datastore.enabled", true],
|
||||||
["dom.testing.ignore_ipc_principal", true]]}, runTest);
|
["dom.testing.ignore_ipc_principal", true],
|
||||||
|
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||||
},
|
},
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test DataStore for certifiedApp only</title>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="container"></div>
|
||||||
|
<script type="application/javascript;version=1.7">
|
||||||
|
|
||||||
|
var gHostedManifestURL = 'http://test/tests/dom/datastore/tests/file_app.sjs?testToken=file_certifiedApp.html';
|
||||||
|
var gApp;
|
||||||
|
|
||||||
|
function cbError() {
|
||||||
|
ok(false, "Error callback invoked");
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function installApp() {
|
||||||
|
var request = navigator.mozApps.install(gHostedManifestURL);
|
||||||
|
request.onerror = cbError;
|
||||||
|
request.onsuccess = function() {
|
||||||
|
gApp = request.result;
|
||||||
|
runTest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function uninstallApp() {
|
||||||
|
// Uninstall the app.
|
||||||
|
var request = navigator.mozApps.mgmt.uninstall(gApp);
|
||||||
|
request.onerror = cbError;
|
||||||
|
request.onsuccess = function() {
|
||||||
|
// All done.
|
||||||
|
info("All done");
|
||||||
|
runTest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testApp() {
|
||||||
|
var ifr = document.createElement('iframe');
|
||||||
|
ifr.setAttribute('mozbrowser', 'true');
|
||||||
|
ifr.setAttribute('mozapp', gApp.manifestURL);
|
||||||
|
ifr.setAttribute('src', gApp.manifest.launch_path);
|
||||||
|
var domParent = document.getElementById('container');
|
||||||
|
|
||||||
|
// Set us up to listen for messages from the app.
|
||||||
|
var listener = function(e) {
|
||||||
|
var message = e.detail.message;
|
||||||
|
if (/^OK/.exec(message)) {
|
||||||
|
ok(true, "Message from app: " + message);
|
||||||
|
} else if (/KO/.exec(message)) {
|
||||||
|
ok(false, "Message from app: " + message);
|
||||||
|
} else if (/DONE/.exec(message)) {
|
||||||
|
ok(true, "Messaging from app complete");
|
||||||
|
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
|
||||||
|
domParent.removeChild(ifr);
|
||||||
|
runTest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This event is triggered when the app calls "alert".
|
||||||
|
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
|
||||||
|
domParent.appendChild(ifr);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tests = [
|
||||||
|
function() {
|
||||||
|
ok(!("getDataStores" in navigator), "getDataStores should not exist");
|
||||||
|
runTest();
|
||||||
|
},
|
||||||
|
|
||||||
|
// Permissions
|
||||||
|
function() {
|
||||||
|
SpecialPowers.pushPermissions(
|
||||||
|
[{ "type": "browser", "allow": 1, "context": document },
|
||||||
|
{ "type": "embed-apps", "allow": 1, "context": document },
|
||||||
|
{ "type": "webapps-manage", "allow": 1, "context": document }], runTest);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Preferences
|
||||||
|
function() {
|
||||||
|
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
||||||
|
["dom.datastore.enabled", true],
|
||||||
|
["dom.testing.ignore_ipc_principal", true]]}, runTest);
|
||||||
|
},
|
||||||
|
|
||||||
|
function() {
|
||||||
|
SpecialPowers.setAllAppsLaunchable(true);
|
||||||
|
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||||
|
runTest();
|
||||||
|
},
|
||||||
|
|
||||||
|
// No confirmation needed when an app is installed
|
||||||
|
function() {
|
||||||
|
SpecialPowers.autoConfirmAppInstall(runTest);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Installing the app
|
||||||
|
installApp,
|
||||||
|
|
||||||
|
// Run tests in app
|
||||||
|
testApp,
|
||||||
|
|
||||||
|
// Uninstall the app
|
||||||
|
uninstallApp
|
||||||
|
];
|
||||||
|
|
||||||
|
function runTest() {
|
||||||
|
if (!tests.length) {
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var test = tests.shift();
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish() {
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SpecialPowers.isMainProcess()) {
|
||||||
|
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
runTest();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -122,7 +122,8 @@
|
||||||
function() {
|
function() {
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
||||||
["dom.datastore.enabled", true],
|
["dom.datastore.enabled", true],
|
||||||
["dom.testing.ignore_ipc_principal", true]]}, runTest);
|
["dom.testing.ignore_ipc_principal", true],
|
||||||
|
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Enabling mozBrowser
|
// Enabling mozBrowser
|
||||||
|
|
|
@ -78,11 +78,9 @@
|
||||||
function() {
|
function() {
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
||||||
["dom.datastore.enabled", true],
|
["dom.datastore.enabled", true],
|
||||||
["dom.testing.ignore_ipc_principal", true]]}, runTest);
|
["dom.ipc.browser_frames.oop_by_default", true],
|
||||||
},
|
["dom.testing.ignore_ipc_principal", true],
|
||||||
|
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||||
function() {
|
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.ipc.browser_frames.oop_by_default", true]]}, runTest);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
|
|
|
@ -102,7 +102,8 @@
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
||||||
["dom.datastore.enabled", true],
|
["dom.datastore.enabled", true],
|
||||||
["dom.testing.ignore_ipc_principal", true]]}, runTest);
|
["dom.testing.ignore_ipc_principal", true],
|
||||||
|
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -78,7 +78,8 @@
|
||||||
function() {
|
function() {
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
SpecialPowers.pushPrefEnv({"set": [["dom.promise.enabled", true],
|
||||||
["dom.datastore.enabled", true],
|
["dom.datastore.enabled", true],
|
||||||
["dom.testing.ignore_ipc_principal", true]]}, runTest);
|
["dom.testing.ignore_ipc_principal", true],
|
||||||
|
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||||
},
|
},
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
|
|
|
@ -96,14 +96,22 @@ AssertAppStatus(PBrowserParent* aActor,
|
||||||
TabParent* tab = static_cast<TabParent*>(aActor);
|
TabParent* tab = static_cast<TabParent*>(aActor);
|
||||||
nsCOMPtr<mozIApplication> app = tab->GetOwnOrContainingApp();
|
nsCOMPtr<mozIApplication> app = tab->GetOwnOrContainingApp();
|
||||||
|
|
||||||
|
bool valid = false;
|
||||||
|
|
||||||
if (app) {
|
if (app) {
|
||||||
unsigned short appStatus = 0;
|
unsigned short appStatus = 0;
|
||||||
if (NS_SUCCEEDED(app->GetAppStatus(&appStatus))) {
|
if (NS_SUCCEEDED(app->GetAppStatus(&appStatus))) {
|
||||||
return appStatus == aStatus;
|
valid = appStatus == aStatus;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (!valid) {
|
||||||
|
printf_stderr("Security problem: Content process does not have `%d' status. It will be killed.\n", aStatus);
|
||||||
|
ContentParent* process = tab->Manager();
|
||||||
|
process->KillHard();
|
||||||
|
}
|
||||||
|
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -30,7 +30,7 @@ enum AssertAppProcessType {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true iff the specified browser has the specified capability.
|
* Return true if the specified browser has the specified capability.
|
||||||
* If this returns false, the browser didn't have the capability and
|
* If this returns false, the browser didn't have the capability and
|
||||||
* will be killed.
|
* will be killed.
|
||||||
*/
|
*/
|
||||||
|
@ -39,12 +39,16 @@ AssertAppProcess(mozilla::dom::PBrowserParent* aActor,
|
||||||
AssertAppProcessType aType,
|
AssertAppProcessType aType,
|
||||||
const char* aCapability);
|
const char* aCapability);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the specified app has the specified status.
|
||||||
|
* If this returns false, the browser will be killed.
|
||||||
|
*/
|
||||||
bool
|
bool
|
||||||
AssertAppStatus(mozilla::dom::PBrowserParent* aActor,
|
AssertAppStatus(mozilla::dom::PBrowserParent* aActor,
|
||||||
unsigned short aStatus);
|
unsigned short aStatus);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true iff any of the PBrowsers loaded in this content process
|
* Return true if any of the PBrowsers loaded in this content process
|
||||||
* has the specified capability. If this returns false, the process
|
* has the specified capability. If this returns false, the process
|
||||||
* didn't have the capability and will be killed.
|
* didn't have the capability and will be killed.
|
||||||
*/
|
*/
|
||||||
|
@ -53,6 +57,11 @@ AssertAppProcess(mozilla::dom::PContentParent* aActor,
|
||||||
AssertAppProcessType aType,
|
AssertAppProcessType aType,
|
||||||
const char* aCapability);
|
const char* aCapability);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if any of the PBrowsers loaded in this content process
|
||||||
|
* has an app with the specified status. If this returns false, the process
|
||||||
|
* didn't have the status and will be killed.
|
||||||
|
*/
|
||||||
bool
|
bool
|
||||||
AssertAppStatus(mozilla::dom::PContentParent* aActor,
|
AssertAppStatus(mozilla::dom::PContentParent* aActor,
|
||||||
unsigned short aStatus);
|
unsigned short aStatus);
|
||||||
|
|
|
@ -115,7 +115,7 @@ Navigator implements NavigatorBattery;
|
||||||
// https://wiki.mozilla.org/WebAPI/DataStore
|
// https://wiki.mozilla.org/WebAPI/DataStore
|
||||||
[NoInterfaceObject]
|
[NoInterfaceObject]
|
||||||
interface NavigatorDataStore {
|
interface NavigatorDataStore {
|
||||||
[Throws, NewObject, Pref="dom.datastore.enabled"]
|
[Throws, NewObject, Func="Navigator::HasDataStoreSupport"]
|
||||||
Promise getDataStores(DOMString name);
|
Promise getDataStores(DOMString name);
|
||||||
};
|
};
|
||||||
Navigator implements NavigatorDataStore;
|
Navigator implements NavigatorDataStore;
|
||||||
|
|
|
@ -274,6 +274,8 @@
|
||||||
"dom/browser-element/mochitest/test_browserElement_inproc_CloseFromOpener.html":"",
|
"dom/browser-element/mochitest/test_browserElement_inproc_CloseFromOpener.html":"",
|
||||||
"dom/browser-element/":"",
|
"dom/browser-element/":"",
|
||||||
|
|
||||||
|
"dom/datastore/tests/test_certifiedApp.html":"",
|
||||||
|
|
||||||
"dom/file/test/test_progress_events.html":"All of these fail fairly regularly with: UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. at http://mochi.test:8888/tests/dom/file/test/helpers.js:126",
|
"dom/file/test/test_progress_events.html":"All of these fail fairly regularly with: UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. at http://mochi.test:8888/tests/dom/file/test/helpers.js:126",
|
||||||
"dom/file/test/test_request_readyState.html":"",
|
"dom/file/test/test_request_readyState.html":"",
|
||||||
"dom/file/test/test_stream_tracking.html":"",
|
"dom/file/test/test_stream_tracking.html":"",
|
||||||
|
|
|
@ -282,6 +282,8 @@
|
||||||
"dom/browser-element/mochitest/test_browserElement_inproc_CloseFromOpener.html":"",
|
"dom/browser-element/mochitest/test_browserElement_inproc_CloseFromOpener.html":"",
|
||||||
"dom/browser-element/":"",
|
"dom/browser-element/":"",
|
||||||
|
|
||||||
|
"dom/datastore/tests/test_certifiedApp.html":"",
|
||||||
|
|
||||||
"dom/file/test/test_progress_events.html":"All of these fail fairly regularly with: UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. at http://mochi.test:8888/tests/dom/file/test/helpers.js:126",
|
"dom/file/test/test_progress_events.html":"All of these fail fairly regularly with: UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. at http://mochi.test:8888/tests/dom/file/test/helpers.js:126",
|
||||||
"dom/file/test/test_request_readyState.html":"",
|
"dom/file/test/test_request_readyState.html":"",
|
||||||
"dom/file/test/test_stream_tracking.html":"",
|
"dom/file/test/test_stream_tracking.html":"",
|
||||||
|
|
|
@ -7,3 +7,4 @@ user_pref("dom.ipc.tabs.disabled", false);
|
||||||
user_pref("dom.ipc.browser_frames.oop_by_default", false);
|
user_pref("dom.ipc.browser_frames.oop_by_default", false);
|
||||||
user_pref("dom.mozBrowserFramesWhitelist","app://test-container.gaiamobile.org,http://mochi.test:8888");
|
user_pref("dom.mozBrowserFramesWhitelist","app://test-container.gaiamobile.org,http://mochi.test:8888");
|
||||||
user_pref("marionette.force-local", true);
|
user_pref("marionette.force-local", true);
|
||||||
|
user_pref("dom.testing.datastore_enabled_for_hosted_apps", true);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче