mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1018320 - RequestSync API - patch 5 - mozSetMessageHandlerPromise, r=fabrice
This commit is contained in:
parent
058b8f3dc5
commit
e0c9ad5d76
@ -1847,6 +1847,33 @@ Navigator::MozHasPendingMessage(const nsAString& aType, ErrorResult& aRv)
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
Navigator::MozSetMessageHandlerPromise(Promise& aPromise,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// The WebIDL binding is responsible for the pref check here.
|
||||
aRv = EnsureMessagesManager();
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
aRv = mMessagesManager->MozIsHandlingMessage(&result);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
aRv = mMessagesManager->MozSetMessageHandlerPromise(&aPromise);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Navigator::MozSetMessageHandler(const nsAString& aType,
|
||||
systemMessageCallback* aCallback,
|
||||
|
@ -235,6 +235,8 @@ public:
|
||||
systemMessageCallback* aCallback,
|
||||
ErrorResult& aRv);
|
||||
bool MozHasPendingMessage(const nsAString& aType, ErrorResult& aRv);
|
||||
void MozSetMessageHandlerPromise(Promise& aPromise, ErrorResult& aRv);
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
already_AddRefed<Promise> GetMobileIdAssertion(const MobileIdOptions& options,
|
||||
ErrorResult& aRv);
|
||||
|
@ -42,6 +42,10 @@ function SystemMessageManager() {
|
||||
// Flag to specify if this process has already registered the manifest URL.
|
||||
this._registerManifestURLReady = false;
|
||||
|
||||
// Used to know if the promise has to be accepted or not.
|
||||
this._isHandling = false;
|
||||
this._promise = null;
|
||||
|
||||
// Flag to determine this process is a parent or child process.
|
||||
let appInfo = Cc["@mozilla.org/xre/app-info;1"];
|
||||
this._isParentProcess =
|
||||
@ -71,6 +75,7 @@ SystemMessageManager.prototype = {
|
||||
}
|
||||
|
||||
aDispatcher.isHandling = true;
|
||||
this._isHandling = true;
|
||||
|
||||
// We get a json blob, but in some cases we want another kind of object
|
||||
// to be dispatched. To do so, we check if we have a valid contract ID of
|
||||
@ -94,15 +99,29 @@ SystemMessageManager.prototype = {
|
||||
.handleMessage(wrapped ? aMessage
|
||||
: Cu.cloneInto(aMessage, this._window));
|
||||
|
||||
// We need to notify the parent one of the system messages has been handled,
|
||||
// so the parent can release the CPU wake lock it took on our behalf.
|
||||
cpmm.sendAsyncMessage("SystemMessageManager:HandleMessageDone",
|
||||
{ type: aType,
|
||||
manifestURL: this._manifestURL,
|
||||
pageURL: this._pageURL,
|
||||
msgID: aMessageID });
|
||||
|
||||
aDispatcher.isHandling = false;
|
||||
this._isHandling = false;
|
||||
|
||||
let self = this;
|
||||
function sendResponse() {
|
||||
// We need to notify the parent one of the system messages has been
|
||||
// handled, so the parent can release the CPU wake lock it took on our
|
||||
// behalf.
|
||||
cpmm.sendAsyncMessage("SystemMessageManager:HandleMessageDone",
|
||||
{ type: aType,
|
||||
manifestURL: self._manifestURL,
|
||||
pageURL: self._pageURL,
|
||||
msgID: aMessageID });
|
||||
}
|
||||
|
||||
if (!this._promise) {
|
||||
debug("No promise set, sending the response immediately");
|
||||
sendResponse();
|
||||
} else {
|
||||
debug("Using the promise to postpone the response.");
|
||||
this._promise.then(sendResponse, sendResponse);
|
||||
this._promise = null;
|
||||
}
|
||||
|
||||
if (aDispatcher.messages.length > 0) {
|
||||
let msg = aDispatcher.messages.shift();
|
||||
@ -171,9 +190,25 @@ SystemMessageManager.prototype = {
|
||||
manifestURL: this._manifestURL })[0];
|
||||
},
|
||||
|
||||
mozIsHandlingMessage: function() {
|
||||
debug("is handling message: " + this._isHandling);
|
||||
return this._isHandling;
|
||||
},
|
||||
|
||||
mozSetMessageHandlerPromise: function(aPromise) {
|
||||
debug("setting a promise");
|
||||
|
||||
if (!this._isHandling) {
|
||||
throw "Not in a handleMessage method";
|
||||
}
|
||||
|
||||
this._promise = aPromise;
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
this._dispatchers = null;
|
||||
this._pendings = null;
|
||||
this._promise = null;
|
||||
|
||||
if (this._isParentProcess) {
|
||||
Services.obs.removeObserver(this, kSystemMessageInternalReady);
|
||||
|
@ -10,10 +10,15 @@ interface nsIDOMSystemMessageCallback : nsISupports
|
||||
void handleMessage(in jsval message);
|
||||
};
|
||||
|
||||
[scriptable, uuid(091e90dd-0e8b-463d-8cdc-9225d3a6ff90)]
|
||||
[scriptable, uuid(d04d3c11-26aa-46eb-a981-353af101f9cf)]
|
||||
interface nsIDOMNavigatorSystemMessages : nsISupports
|
||||
{
|
||||
void mozSetMessageHandler(in DOMString type, in nsIDOMSystemMessageCallback callback);
|
||||
|
||||
boolean mozHasPendingMessage(in DOMString type);
|
||||
|
||||
// the parameter is a promise object.
|
||||
void mozSetMessageHandlerPromise(in nsISupports promise);
|
||||
|
||||
bool mozIsHandlingMessage();
|
||||
};
|
||||
|
@ -587,10 +587,16 @@ this.RequestSyncService = {
|
||||
timer = null;
|
||||
}
|
||||
|
||||
let timeout = RSYNC_OPERATION_TIMEOUT;
|
||||
try {
|
||||
let tmp = Services.prefs.getIntPref("dom.requestSync.maxTaskTimeout");
|
||||
timeout = tmp;
|
||||
} catch(e) {}
|
||||
|
||||
timer.initWithCallback(function() {
|
||||
debug("Task is taking too much, let's ignore the promise.");
|
||||
taskCompleted();
|
||||
}, RSYNC_OPERATION_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}, timeout, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
|
||||
// Sending the message.
|
||||
let promise =
|
||||
|
@ -14,3 +14,6 @@ support-files =
|
||||
run-if = buildapp != 'b2g'
|
||||
[test_wakeUp.html]
|
||||
run-if = buildapp == 'b2g' && toolkit == 'gonk'
|
||||
[test_promise.html]
|
||||
[test_promise_app.html]
|
||||
run-if = buildapp == 'b2g' && toolkit == 'gonk'
|
||||
|
@ -72,7 +72,7 @@
|
||||
SpecialPowers.pushPermissions(
|
||||
[{ "type": "browser", "allow": 1, "context": document },
|
||||
{ "type": "embed-apps", "allow": 1, "context": document },
|
||||
{"type": "requestsync-manager", "allow": 1, "context": document },
|
||||
{ "type": "requestsync-manager", "allow": 1, "context": document },
|
||||
{ "type": "webapps-manage", "allow": 1, "context": document }], runTests);
|
||||
},
|
||||
|
||||
|
56
dom/requestsync/tests/test_promise.html
Normal file
56
dom/requestsync/tests/test_promise.html
Normal file
@ -0,0 +1,56 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for requestSync - promise</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="common_basic.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">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.sysmsg.enabled", true]]}, function() {
|
||||
|
||||
ok("mozSetMessageHandlerPromise" in navigator, "mozSetMessageHandlerPromise exists");
|
||||
|
||||
var status = false;
|
||||
try {
|
||||
navigator.mozSetMessageHandlerPromise();
|
||||
} catch(e) {
|
||||
status = true;
|
||||
}
|
||||
ok(status, "mozSetMessageHandlerPromise wants a promise 1");
|
||||
|
||||
status = false;
|
||||
try {
|
||||
navigator.mozSetMessageHandlerPromise(42);
|
||||
} catch(e) {
|
||||
status = true;
|
||||
}
|
||||
ok(status, "mozSetMessageHandlerPromise wants a promise 2");
|
||||
|
||||
status = false;
|
||||
try {
|
||||
navigator.mozSetMessageHandlerPromise("hello world");
|
||||
} catch(e) {
|
||||
status = true;
|
||||
}
|
||||
ok(status, "mozSetMessageHandlerPromise wants a promise 3");
|
||||
|
||||
status = false;
|
||||
try {
|
||||
navigator.mozSetMessageHandlerPromise(new Promise(function(a, b) {}));
|
||||
} catch(e) {
|
||||
info(e);
|
||||
status = true;
|
||||
}
|
||||
ok(status, "mozSetMessageHandlerPromise cannot be called outside a messageHandler");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
138
dom/requestsync/tests/test_promise_app.html
Normal file
138
dom/requestsync/tests/test_promise_app.html
Normal file
@ -0,0 +1,138 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for requestSync - promise</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="common_basic.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 foobarCounter = 0;
|
||||
var pendingCounter = 0;
|
||||
function setMessageHandler() {
|
||||
navigator.mozSetMessageHandler('request-sync', function(e) {
|
||||
|
||||
if (e.task == 'foobar') {
|
||||
ok(true, "foobar message received:" + foobarCounter);
|
||||
|
||||
if (++foobarCounter == 1) {
|
||||
// The first time we wait 2 seconds.
|
||||
info("Setting a promise object.");
|
||||
navigator.mozSetMessageHandlerPromise(new Promise(function(a, b) {
|
||||
setTimeout(a, 2000);
|
||||
}));
|
||||
} else {
|
||||
// The second time we don't reply at all.
|
||||
navigator.mozSetMessageHandlerPromise(new Promise(function(a, b) {}));
|
||||
}
|
||||
}
|
||||
|
||||
else if (e.task == 'pending') {
|
||||
ok(true, "pending message received: " + pendingCounter);
|
||||
if (++pendingCounter == 2) {
|
||||
runTests();
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
ok(false, "Unknown message");
|
||||
}
|
||||
});
|
||||
|
||||
runTests();
|
||||
}
|
||||
|
||||
function test_register_foobar() {
|
||||
navigator.sync.register('foobar', { minInterval: 5,
|
||||
oneShot: false,
|
||||
data: 42,
|
||||
wifiOnly: false,
|
||||
wakeUpPage: location.href }).then(
|
||||
function() {
|
||||
ok(true, "navigator.sync.register() foobar done");
|
||||
runTests();
|
||||
}, genericError);
|
||||
}
|
||||
|
||||
function test_register_pending() {
|
||||
navigator.sync.register('pending', { minInterval: 6,
|
||||
oneShot: false,
|
||||
data: 'hello world!',
|
||||
wifiOnly: false,
|
||||
wakeUpPage: location.href }).then(
|
||||
function() {
|
||||
ok(true, "navigator.sync.register() pending done");
|
||||
runTests();
|
||||
}, genericError);
|
||||
}
|
||||
|
||||
function test_unregister_foobar() {
|
||||
navigator.sync.unregister('foobar').then(
|
||||
function() {
|
||||
ok(true, "navigator.sync.unregister() foobar done");
|
||||
runTests();
|
||||
}, genericError);
|
||||
}
|
||||
|
||||
function test_unregister_pending() {
|
||||
navigator.sync.unregister('pending').then(
|
||||
function() {
|
||||
ok(true, "navigator.sync.unregister() pending done");
|
||||
runTests();
|
||||
}, genericError);
|
||||
}
|
||||
|
||||
function test_wait() {
|
||||
// nothing to do here.
|
||||
}
|
||||
|
||||
var tests = [
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.requestSync.enabled", true],
|
||||
["dom.requestSync.minInterval", 1],
|
||||
["dom.requestSync.maxTaskTimeout", 10000 /* 10 seconds */],
|
||||
["dom.ignore_webidl_scope_checks", true]]}, runTests);
|
||||
},
|
||||
|
||||
function() {
|
||||
SpecialPowers.pushPermissions(
|
||||
[{ "type": "requestsync-manager", "allow": 1, "context": document } ], runTests);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/RequestSyncService.jsm");
|
||||
}
|
||||
runTests();
|
||||
},
|
||||
|
||||
setMessageHandler,
|
||||
|
||||
test_register_foobar,
|
||||
test_register_pending,
|
||||
|
||||
test_wait,
|
||||
|
||||
test_unregister_foobar,
|
||||
test_unregister_pending,
|
||||
];
|
||||
|
||||
function runTests() {
|
||||
if (!tests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTests();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -84,6 +84,22 @@
|
||||
}, genericError);
|
||||
}
|
||||
|
||||
function test_unregister_oneShot() {
|
||||
navigator.sync.unregister('oneShot').then(
|
||||
function() {
|
||||
ok(true, "navigator.sync.unregister() oneShot done");
|
||||
runTests();
|
||||
}, genericError);
|
||||
}
|
||||
|
||||
function test_unregister_multiShots() {
|
||||
navigator.sync.unregister('multiShots').then(
|
||||
function() {
|
||||
ok(true, "navigator.sync.unregister() multiShots done");
|
||||
runTests();
|
||||
}, genericError);
|
||||
}
|
||||
|
||||
function test_wait() {
|
||||
// nothing to do here.
|
||||
}
|
||||
@ -113,6 +129,9 @@
|
||||
test_register_multiShots,
|
||||
|
||||
test_wait,
|
||||
|
||||
test_unregister_oneShot,
|
||||
test_unregister_multiShots,
|
||||
];
|
||||
|
||||
function runTests() {
|
||||
|
@ -285,6 +285,12 @@ partial interface Navigator {
|
||||
void mozSetMessageHandler (DOMString type, systemMessageCallback? callback);
|
||||
[Throws, Pref="dom.sysmsg.enabled"]
|
||||
boolean mozHasPendingMessage (DOMString type);
|
||||
|
||||
// This method can be called only from the systeMessageCallback function and
|
||||
// it allows the page to set a promise to keep alive the app until the
|
||||
// current operation is not fully completed.
|
||||
[Throws, Pref="dom.sysmsg.enabled"]
|
||||
void mozSetMessageHandlerPromise (Promise<any> promise);
|
||||
};
|
||||
|
||||
#ifdef MOZ_B2G_RIL
|
||||
|
Loading…
Reference in New Issue
Block a user