mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Bug 1014023 - [Datastore] Notify apps of changes in datastore without being opened. r=baku, r=gene
This commit is contained in:
parent
d926cc34de
commit
0d34f59084
@ -886,6 +886,10 @@ pref("network.sntp.timeout", 30); // In seconds.
|
||||
|
||||
// Enable dataStore
|
||||
pref("dom.datastore.enabled", true);
|
||||
// When an entry is changed, use two timers to fire system messages in a more
|
||||
// moderate pattern.
|
||||
pref("dom.datastore.sysMsgOnChangeShortTimeoutSec", 10);
|
||||
pref("dom.datastore.sysMsgOnChangeLongTimeoutSec", 60);
|
||||
|
||||
// DOM Inter-App Communication API.
|
||||
pref("dom.inter-app-communication-api.enabled", true);
|
||||
|
@ -23,12 +23,33 @@ XPCOMUtils.defineLazyServiceGetter(this, "dataStoreService",
|
||||
"@mozilla.org/datastore-service;1",
|
||||
"nsIDataStoreService");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "systemMessenger",
|
||||
"@mozilla.org/system-message-internal;1",
|
||||
"nsISystemMessagesInternal");
|
||||
|
||||
var kSysMsgOnChangeShortTimeoutSec =
|
||||
Services.prefs.getIntPref("dom.datastore.sysMsgOnChangeShortTimeoutSec");
|
||||
var kSysMsgOnChangeLongTimeoutSec =
|
||||
Services.prefs.getIntPref("dom.datastore.sysMsgOnChangeLongTimeoutSec");
|
||||
|
||||
this.DataStoreChangeNotifier = {
|
||||
children: [],
|
||||
messages: [ "DataStore:Changed", "DataStore:RegisterForMessages",
|
||||
"DataStore:UnregisterForMessages",
|
||||
"child-process-shutdown" ],
|
||||
|
||||
// These hashes are used for storing the mapping between the datastore
|
||||
// identifiers (name | owner manifest URL) and their correspondent timers.
|
||||
// The object literal is defined as below:
|
||||
//
|
||||
// {
|
||||
// "datastore name 1|owner manifest URL 1": timer1,
|
||||
// "datastore name 2|owner manifest URL 2": timer2,
|
||||
// ...
|
||||
// }
|
||||
sysMsgOnChangeShortTimers: {},
|
||||
sysMsgOnChangeLongTimers: {},
|
||||
|
||||
init: function() {
|
||||
debug("init");
|
||||
|
||||
@ -59,7 +80,8 @@ this.DataStoreChangeNotifier = {
|
||||
},
|
||||
|
||||
broadcastMessage: function broadcastMessage(aData) {
|
||||
debug("Broadast");
|
||||
debug("broadcast");
|
||||
|
||||
this.children.forEach(function(obj) {
|
||||
if (obj.store == aData.store && obj.owner == aData.owner) {
|
||||
obj.mm.sendAsyncMessage("DataStore:Changed:Return:OK", aData);
|
||||
@ -67,6 +89,69 @@ this.DataStoreChangeNotifier = {
|
||||
});
|
||||
},
|
||||
|
||||
broadcastSystemMessage: function(aStore, aOwner) {
|
||||
debug("broadcastSystemMessage");
|
||||
|
||||
// Clear relevant timers.
|
||||
var storeKey = aStore + "|" + aOwner;
|
||||
var shortTimer = this.sysMsgOnChangeShortTimers[storeKey];
|
||||
if (shortTimer) {
|
||||
shortTimer.cancel();
|
||||
delete this.sysMsgOnChangeShortTimers[storeKey];
|
||||
}
|
||||
var longTimer = this.sysMsgOnChangeLongTimers[storeKey];
|
||||
if (longTimer) {
|
||||
longTimer.cancel();
|
||||
delete this.sysMsgOnChangeLongTimers[storeKey];
|
||||
}
|
||||
|
||||
// Get all the manifest URLs of the apps which can access the datastore.
|
||||
var manifestURLs = dataStoreService.getAppManifestURLsForDataStore(aStore);
|
||||
var enumerate = manifestURLs.enumerate();
|
||||
while (enumerate.hasMoreElements()) {
|
||||
var manifestURL = enumerate.getNext().QueryInterface(Ci.nsISupportsString);
|
||||
debug("Notify app " + manifestURL + " of datastore updates");
|
||||
// Send the system message 'datastore-update-{store name}' to all the
|
||||
// pages for these apps. With the manifest URL of the owner in the message
|
||||
// payload, it notifies the consumer a sync operation should be performed.
|
||||
systemMessenger.sendMessage("datastore-update-" + aStore,
|
||||
{ owner: aOwner },
|
||||
null,
|
||||
Services.io.newURI(manifestURL, null, null));
|
||||
}
|
||||
},
|
||||
|
||||
// Use the following logic to broadcast system messages in a moderate pattern.
|
||||
// 1. When an entry is changed, start a short timer and a long timer.
|
||||
// 2. If an entry is changed while the short timer is running, reset it.
|
||||
// Do not reset the long timer.
|
||||
// 3. Once either fires, broadcast the system message and cancel both timers.
|
||||
setSystemMessageTimeout: function(aStore, aOwner) {
|
||||
debug("setSystemMessageTimeout");
|
||||
|
||||
var storeKey = aStore + "|" + aOwner;
|
||||
|
||||
// Reset the short timer.
|
||||
var shortTimer = this.sysMsgOnChangeShortTimers[storeKey];
|
||||
if (!shortTimer) {
|
||||
shortTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
this.sysMsgOnChangeShortTimers[storeKey] = shortTimer;
|
||||
} else {
|
||||
shortTimer.cancel();
|
||||
}
|
||||
shortTimer.initWithCallback({ notify: this.broadcastSystemMessage.bind(this, aStore, aOwner) },
|
||||
kSysMsgOnChangeShortTimeoutSec * 1000,
|
||||
Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
|
||||
// Set the long timer if necessary.
|
||||
if (!this.sysMsgOnChangeLongTimers[storeKey]) {
|
||||
var longTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
this.sysMsgOnChangeLongTimers[storeKey] = longTimer;
|
||||
longTimer.initWithCallback({ notify: this.broadcastSystemMessage.bind(this, aStore, aOwner) },
|
||||
kSysMsgOnChangeLongTimeoutSec * 1000,
|
||||
Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
debug("receiveMessage ");
|
||||
@ -89,6 +174,7 @@ this.DataStoreChangeNotifier = {
|
||||
switch (aMessage.name) {
|
||||
case "DataStore:Changed":
|
||||
this.broadcastMessage(aMessage.data);
|
||||
this.setSystemMessageTimeout(aMessage.data.store, aMessage.data.owner);
|
||||
break;
|
||||
|
||||
case "DataStore:RegisterForMessages":
|
||||
|
@ -33,9 +33,11 @@
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMGlobalPropertyInitializer.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIURI.h"
|
||||
@ -375,6 +377,24 @@ GetDataStoreInfosEnumerator(const uint32_t& aAppId,
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
GetAppManifestURLsEnumerator(const uint32_t& aAppId,
|
||||
DataStoreInfo* aInfo,
|
||||
void* aUserData)
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
auto* manifestURLs = static_cast<nsIMutableArray*>(aUserData);
|
||||
nsCOMPtr<nsISupportsString> manifestURL(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
|
||||
if (manifestURL) {
|
||||
manifestURL->SetData(aInfo->mManifestURL);
|
||||
manifestURLs->AppendElement(manifestURL, false);
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
// This class is useful to enumerate the add permissions for each app.
|
||||
class MOZ_STACK_CLASS AddPermissionsData
|
||||
{
|
||||
@ -1057,6 +1077,31 @@ DataStoreService::GetDataStoreInfos(const nsAString& aName,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DataStoreService::GetAppManifestURLsForDataStore(const nsAString& aName,
|
||||
nsIArray** aManifestURLs)
|
||||
{
|
||||
ASSERT_PARENT_PROCESS()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIMutableArray> manifestURLs = do_CreateInstance(NS_ARRAY_CONTRACTID);
|
||||
if (!manifestURLs) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
HashApp* apps = nullptr;
|
||||
if (mStores.Get(aName, &apps)) {
|
||||
apps->EnumerateRead(GetAppManifestURLsEnumerator, manifestURLs.get());
|
||||
}
|
||||
if (mAccessStores.Get(aName, &apps)) {
|
||||
apps->EnumerateRead(GetAppManifestURLsEnumerator, manifestURLs.get());
|
||||
}
|
||||
|
||||
*aManifestURLs = manifestURLs;
|
||||
NS_ADDREF(*aManifestURLs);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
DataStoreService::CheckPermission(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
|
@ -7,8 +7,9 @@
|
||||
|
||||
interface nsIDOMWindow;
|
||||
interface nsIPrincipal;
|
||||
interface nsIArray;
|
||||
|
||||
[scriptable, uuid(9b59c49a-0cd7-11e4-b096-74d02b97e723)]
|
||||
[scriptable, uuid(79944b1c-187d-11e4-abb6-74d02b97e723)]
|
||||
interface nsIDataStoreService : nsISupports
|
||||
{
|
||||
void installDataStore(in unsigned long appId,
|
||||
@ -27,5 +28,7 @@ interface nsIDataStoreService : nsISupports
|
||||
in DOMString name,
|
||||
in DOMString owner);
|
||||
|
||||
nsIArray getAppManifestURLsForDataStore(in DOMString name);
|
||||
|
||||
boolean checkPermission(in nsIPrincipal principal);
|
||||
};
|
||||
|
122
dom/datastore/tests/file_notify_system_message.html
Normal file
122
dom/datastore/tests/file_notify_system_message.html
Normal file
@ -0,0 +1,122 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for DataStore - notify updates with system messages</title>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
var gStore;
|
||||
var gChangeId = null;
|
||||
var gChangeOperation = null;
|
||||
var gIsSystemMessageFired = false;
|
||||
|
||||
function is(a, b, msg) {
|
||||
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
|
||||
}
|
||||
|
||||
function ok(a, msg) {
|
||||
alert((a ? 'OK' : 'KO')+ ' ' + msg)
|
||||
}
|
||||
|
||||
function cbError() {
|
||||
alert('KO error');
|
||||
}
|
||||
|
||||
function finish() {
|
||||
alert('DONE');
|
||||
}
|
||||
|
||||
function testGetDataStores() {
|
||||
navigator.getDataStores('foo').then(function(stores) {
|
||||
is(stores.length, 1, "getDataStores('foo') returns 1 element");
|
||||
is(stores[0].name, 'foo', 'The dataStore.name is foo');
|
||||
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
|
||||
|
||||
gStore = stores[0];
|
||||
runTest();
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStoreAdd(value, expectedId) {
|
||||
gStore.add(value).then(function(id) {
|
||||
is(id, expectedId, "store.add() is called");
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function eventListener(evt) {
|
||||
ok(evt instanceof DataStoreChangeEvent, "DataStoreChangeEvent has been received");
|
||||
ok(evt, "OnChangeListener is called with data");
|
||||
is(/[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}/.test(evt.revisionId), true, "event.revisionId returns something");
|
||||
is(evt.id, gChangeId, "OnChangeListener is called with the right ID: " + evt.id);
|
||||
is(evt.operation, gChangeOperation, "OnChangeListener is called with the right operation:" + evt.operation + " " + gChangeOperation);
|
||||
runTest();
|
||||
}
|
||||
|
||||
function onDatastoreUpdateFoo(message) {
|
||||
gIsSystemMessageFired = true;
|
||||
ok(true, "System message 'datastore-update-foo' has been received");
|
||||
runTest();
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// Test for GetDataStore.
|
||||
testGetDataStores,
|
||||
|
||||
// Add onchange = function.
|
||||
function() {
|
||||
gStore.onchange = eventListener;
|
||||
is(gStore.onchange, eventListener, "onChange is set");
|
||||
runTest();
|
||||
},
|
||||
|
||||
// Set system message handler.
|
||||
function() {
|
||||
navigator.mozSetMessageHandler('datastore-update-foo', onDatastoreUpdateFoo);
|
||||
runTest();
|
||||
},
|
||||
|
||||
// Add.
|
||||
function() { gChangeId = 1; gChangeOperation = 'added';
|
||||
testStoreAdd({ number: 42 }, 1); },
|
||||
|
||||
// Remove event listener.
|
||||
function() {
|
||||
gStore.removeEventListener('change', eventListener);
|
||||
runTest();
|
||||
},
|
||||
|
||||
// Wait enough amount of time for the system message to fire.
|
||||
function() {
|
||||
setTimeout(runTest, 10000);
|
||||
},
|
||||
|
||||
// Ensure the system message has fired and no more pending ones.
|
||||
function() {
|
||||
ok(!navigator.mozHasPendingMessage('datastore-update-foo'), "No more pending system message");
|
||||
ok(gIsSystemMessageFired, "The system message has fired");
|
||||
runTest();
|
||||
}
|
||||
];
|
||||
|
||||
function runTest() {
|
||||
if (!tests.length) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
||||
|
||||
runTest();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -30,6 +30,7 @@ support-files =
|
||||
file_sync_common.js
|
||||
file_bug1008044.html
|
||||
file_bug957086.html
|
||||
file_notify_system_message.html
|
||||
|
||||
[test_app_install.html]
|
||||
[test_readonly.html]
|
||||
@ -50,3 +51,5 @@ support-files =
|
||||
[test_transactions.html]
|
||||
[test_bug1008044.html]
|
||||
[test_bug957086.html]
|
||||
[test_notify_system_message.html]
|
||||
skip-if = toolkit == 'gonk' # b2g
|
||||
|
@ -10,10 +10,6 @@
|
||||
<div id="container"></div>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var gBaseURL = 'http://test/tests/dom/datastore/tests/';
|
||||
@ -26,8 +22,14 @@
|
||||
{ "type": "webapps-manage", "allow": 1, "context": document }],
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, function() {
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
gGenerator.next(); });
|
||||
});
|
||||
|
||||
|
@ -77,11 +77,17 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
@ -116,10 +122,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -77,11 +77,17 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
@ -116,10 +122,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -77,11 +77,17 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
@ -116,10 +122,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -77,12 +77,18 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.ipc.browser_frames.oop_by_default", true],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
@ -117,10 +123,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -77,11 +77,17 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
@ -116,10 +122,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -81,12 +81,18 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.ipc.browser_frames.oop_by_default", true],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
@ -124,10 +130,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -82,11 +82,17 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
@ -124,10 +130,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -75,12 +75,17 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
// Enabling mozBrowser
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mozBrowserFramesEnabled", true]]}, runTest);
|
||||
},
|
||||
@ -134,10 +139,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -77,6 +77,8 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", false]]}, runTest);
|
||||
},
|
||||
@ -89,6 +91,10 @@
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
@ -123,10 +129,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -121,12 +121,17 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
// Enabling mozBrowser
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mozBrowserFramesEnabled", true]]}, runTest);
|
||||
},
|
||||
@ -169,10 +174,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -77,11 +77,17 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
@ -116,10 +122,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -77,11 +77,17 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
@ -116,10 +122,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
138
dom/datastore/tests/test_notify_system_message.html
Normal file
138
dom/datastore/tests/test_notify_system_message.html
Normal file
@ -0,0 +1,138 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for DataStore - notify updates with system messages</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_notify_system_message.html';
|
||||
var gHostedPageURL = 'http://mochi.test:8888/tests/dom/datastore/tests/file_notify_system_message.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 = [
|
||||
// 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.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.sysmsg.enabled", true],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true],
|
||||
["dom.mozBrowserFramesEnabled", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
// No confirmation needed when an app is installed.
|
||||
SpecialPowers.autoConfirmAppInstall(runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
SpecialPowers.Cu.import("resource://gre/modules/Services.jsm");
|
||||
var ioService = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(SpecialPowers.Ci.nsIIOService);
|
||||
var systemMessenger = SpecialPowers.Cc["@mozilla.org/system-message-internal;1"]
|
||||
.getService(SpecialPowers.Ci.nsISystemMessagesInternal);
|
||||
systemMessenger.registerPage("datastore-update-foo",
|
||||
ioService.newURI(gHostedPageURL, null, null),
|
||||
ioService.newURI(gHostedManifestURL, null, null));
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -77,12 +77,18 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.ipc.browser_frames.oop_by_default", true],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
@ -117,10 +123,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -105,12 +105,18 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.ipc.browser_frames.oop_by_default", true],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
@ -147,10 +153,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -30,6 +30,10 @@
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
|
||||
@ -95,12 +99,10 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
</script>
|
||||
|
@ -77,11 +77,17 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
},
|
||||
@ -115,10 +121,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -77,11 +77,17 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
},
|
||||
@ -115,10 +121,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -77,11 +77,17 @@
|
||||
// Preferences
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
|
||||
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
|
||||
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
|
||||
["dom.testing.ignore_ipc_principal", true],
|
||||
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
runTest();
|
||||
@ -116,10 +122,6 @@
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
</script>
|
||||
|
@ -192,31 +192,48 @@ SystemMessageInternal.prototype = {
|
||||
// clean it up from the pending message queue when apps receive it.
|
||||
let messageID = gUUIDGenerator.generateUUID().toString();
|
||||
|
||||
debug("Sending " + aType + " " + JSON.stringify(aMessage) +
|
||||
" for " + aPageURI.spec + " @ " + aManifestURI.spec +
|
||||
'; extra: ' + JSON.stringify(aExtra));
|
||||
|
||||
let result = this._sendMessageCommon(aType,
|
||||
aMessage,
|
||||
messageID,
|
||||
aPageURI.spec,
|
||||
aManifestURI.spec,
|
||||
aExtra);
|
||||
debug("Returned status of sending message: " + result);
|
||||
|
||||
// Don't need to open the pages and queue the system message
|
||||
// which was not allowed to be sent.
|
||||
if (result === MSG_SENT_FAILURE_PERM_DENIED) {
|
||||
return;
|
||||
let manifestURL = aManifestURI.spec;
|
||||
let pageURLs = [];
|
||||
if (aPageURI) {
|
||||
pageURLs.push(aPageURI.spec);
|
||||
} else {
|
||||
// Send this message to all the registered pages of the app if |aPageURI|
|
||||
// is not specified.
|
||||
for (let i = 0; i < this._pages.length; i++) {
|
||||
let page = this._pages[i];
|
||||
if (page.type === aType && page.manifestURL === manifestURL) {
|
||||
pageURLs.push(page.pageURL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let page = this._findPage(aType, aPageURI.spec, aManifestURI.spec);
|
||||
if (page) {
|
||||
// Queue this message in the corresponding pages.
|
||||
this._queueMessage(page, aMessage, messageID);
|
||||
pageURLs.forEach(function(aPageURL) {
|
||||
debug("Sending " + aType + " " + JSON.stringify(aMessage) +
|
||||
" for " + aPageURL + " @ " + manifestURL +
|
||||
'; extra: ' + JSON.stringify(aExtra));
|
||||
|
||||
this._openAppPage(page, aMessage, aExtra, result);
|
||||
}
|
||||
let result = this._sendMessageCommon(aType,
|
||||
aMessage,
|
||||
messageID,
|
||||
aPageURL,
|
||||
manifestURL,
|
||||
aExtra);
|
||||
debug("Returned status of sending message: " + result);
|
||||
|
||||
// Don't need to open the pages and queue the system message
|
||||
// which was not allowed to be sent.
|
||||
if (result === MSG_SENT_FAILURE_PERM_DENIED) {
|
||||
return;
|
||||
}
|
||||
|
||||
let page = this._findPage(aType, aPageURL, manifestURL);
|
||||
if (page) {
|
||||
// Queue this message in the corresponding pages.
|
||||
this._queueMessage(page, aMessage, messageID);
|
||||
|
||||
this._openAppPage(page, aMessage, aExtra, result);
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
broadcastMessage: function(aType, aMessage, aExtra) {
|
||||
|
@ -15,7 +15,8 @@ Cu.import("resource://gre/modules/PermissionsTable.jsm");
|
||||
Cu.import("resource://gre/modules/PermissionSettings.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["SystemMessagePermissionsChecker",
|
||||
"SystemMessagePermissionsTable"];
|
||||
"SystemMessagePermissionsTable",
|
||||
"SystemMessagePrefixPermissionsTable"];
|
||||
|
||||
function debug(aStr) {
|
||||
// dump("SystemMessagePermissionsChecker.jsm: " + aStr + "\n");
|
||||
@ -122,6 +123,18 @@ this.SystemMessagePermissionsTable = {
|
||||
}
|
||||
};
|
||||
|
||||
// This table maps system message prefix to permission(s), indicating only
|
||||
// the system messages with specified prefixes granted by the page's permissions
|
||||
// are allowed to be registered or sent to that page. Note the empty permission
|
||||
// set means this type of system message is always permitted.
|
||||
//
|
||||
// Note that this table is only used when the permission checker can't find a
|
||||
// match in SystemMessagePermissionsTable listed above.
|
||||
|
||||
this.SystemMessagePrefixPermissionsTable = {
|
||||
"datastore-update-": { },
|
||||
};
|
||||
|
||||
this.SystemMessagePermissionsChecker = {
|
||||
/**
|
||||
* Return all the needed permission names for the given system message.
|
||||
@ -140,16 +153,26 @@ this.SystemMessagePermissionsChecker = {
|
||||
|
||||
let permNames = SystemMessagePermissionsTable[aSysMsgName];
|
||||
if (permNames === undefined) {
|
||||
debug("'" + aSysMsgName + "' is not associated with permissions. " +
|
||||
"Please add them to the SystemMessagePermissionsTable.");
|
||||
return null;
|
||||
// Try to look up in the prefix table.
|
||||
for (let sysMsgPrefix in SystemMessagePrefixPermissionsTable) {
|
||||
if (aSysMsgName.indexOf(sysMsgPrefix) === 0) {
|
||||
permNames = SystemMessagePrefixPermissionsTable[sysMsgPrefix];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (permNames === undefined) {
|
||||
debug("'" + aSysMsgName + "' is not associated with permissions. " +
|
||||
"Please add them to the SystemMessage[Prefix]PermissionsTable.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
let object = { };
|
||||
for (let permName in permNames) {
|
||||
if (PermissionsTable[permName] === undefined) {
|
||||
debug("'" + permName + "' for '" + aSysMsgName + "' is invalid. " +
|
||||
"Please correct it in the SystemMessagePermissionsTable.");
|
||||
"Please correct it in the SystemMessage[Prefix]PermissionsTable.");
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -157,7 +180,7 @@ this.SystemMessagePermissionsChecker = {
|
||||
let access = permNames[permName];
|
||||
if (!access || !Array.isArray(access)) {
|
||||
debug("'" + permName + "' is not associated with access array. " +
|
||||
"Please correct it in the SystemMessagePermissionsTable.");
|
||||
"Please correct it in the SystemMessage[Prefix]PermissionsTable.");
|
||||
return null;
|
||||
}
|
||||
object[permName] = appendAccessToPermName(permName, access);
|
||||
|
@ -13,10 +13,12 @@ interface nsIDOMWindow;
|
||||
interface nsISystemMessagesInternal : nsISupports
|
||||
{
|
||||
/*
|
||||
* Allow any internal user to broadcast a message of a given type.
|
||||
* Allow any internal user to send a message of a given type to a given page
|
||||
* of an app. The message will be sent to all the registered pages of the app
|
||||
* when |pageURI| is not specified.
|
||||
* @param type The type of the message to be sent.
|
||||
* @param message The message payload.
|
||||
* @param pageURI The URI of the page that will be opened.
|
||||
* @param pageURI The URI of the page that will be opened. Nullable.
|
||||
* @param manifestURI The webapp's manifest URI.
|
||||
* @param extra Extra opaque information that will be passed around in the observer
|
||||
* notification to open the page.
|
||||
|
Loading…
Reference in New Issue
Block a user