You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by an...@apache.org on 2014/03/27 15:22:20 UTC
[11/34] js commit: CB-6181 android: Always execute exec() callbacks
async.
CB-6181 android: Always execute exec() callbacks async.
Project: http://git-wip-us.apache.org/repos/asf/cordova-js/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-js/commit/7b681f2a
Tree: http://git-wip-us.apache.org/repos/asf/cordova-js/tree/7b681f2a
Diff: http://git-wip-us.apache.org/repos/asf/cordova-js/diff/7b681f2a
Branch: refs/heads/browserify
Commit: 7b681f2acc894c010342e9de3cfd2000be7e9360
Parents: fb16e9a
Author: Andrew Grieve <ag...@chromium.org>
Authored: Thu Mar 6 12:14:43 2014 -0500
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Thu Mar 6 12:14:43 2014 -0500
----------------------------------------------------------------------
src/android/exec.js | 64 ++++++++++++++++++++++++++----------------
test/android/test.exec.js | 16 ++++++++++-
2 files changed, 55 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/7b681f2a/src/android/exec.js
----------------------------------------------------------------------
diff --git a/src/android/exec.js b/src/android/exec.js
index 0d35ff1..e6a53d6 100644
--- a/src/android/exec.js
+++ b/src/android/exec.js
@@ -98,7 +98,7 @@ function androidExec(success, fail, service, action, args) {
androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
return;
} else {
- androidExec.processMessages(messages);
+ androidExec.processMessages(messages, true);
}
}
}
@@ -207,46 +207,62 @@ function processMessage(message) {
}
cordova.callbackFromNative(callbackId, success, status, [payload], keepCallback);
} else {
- console.log("processMessage failed: invalid message:" + message);
+ console.log("processMessage failed: invalid message: " + JSON.stringify(message));
}
} catch (e) {
- console.log("processMessage failed: Message: " + message);
console.log("processMessage failed: Error: " + e);
console.log("processMessage failed: Stack: " + e.stack);
+ console.log("processMessage failed: Message: " + message);
}
}
+var isProcessing = false;
+
// This is called from the NativeToJsMessageQueue.java.
-androidExec.processMessages = function(messages) {
+androidExec.processMessages = function(messages, opt_useTimeout) {
if (messages) {
messagesFromNative.push(messages);
- // Check for the reentrant case, and enqueue the message if that's the case.
- if (messagesFromNative.length > 1) {
- return;
- }
+ }
+ // Check for the reentrant case.
+ if (isProcessing) {
+ return;
+ }
+ if (opt_useTimeout) {
+ window.setTimeout(androidExec.processMessages, 0);
+ return;
+ }
+ isProcessing = true;
+ try {
+ // TODO: add setImmediate polyfill and process only one message at a time.
while (messagesFromNative.length) {
- // Don't unshift until the end so that reentrancy can be detected.
- messages = messagesFromNative[0];
+ var msg = popMessageFromQueue();
// The Java side can send a * message to indicate that it
// still has messages waiting to be retrieved.
- if (messages == '*') {
- messagesFromNative.shift();
- window.setTimeout(pollOnce, 0);
+ if (msg == '*' && messagesFromNative.length === 0) {
+ setTimeout(pollOnce, 0);
return;
}
-
- var spaceIdx = messages.indexOf(' ');
- var msgLen = +messages.slice(0, spaceIdx);
- var message = messages.substr(spaceIdx + 1, msgLen);
- messages = messages.slice(spaceIdx + msgLen + 1);
- processMessage(message);
- if (messages) {
- messagesFromNative[0] = messages;
- } else {
- messagesFromNative.shift();
- }
+ processMessage(msg);
}
+ } finally {
+ isProcessing = false;
}
};
+function popMessageFromQueue() {
+ var messageBatch = messagesFromNative.shift();
+ if (messageBatch == '*') {
+ return '*';
+ }
+
+ var spaceIdx = messageBatch.indexOf(' ');
+ var msgLen = +messageBatch.slice(0, spaceIdx);
+ var message = messageBatch.substr(spaceIdx + 1, msgLen);
+ messageBatch = messageBatch.slice(spaceIdx + msgLen + 1);
+ if (messageBatch) {
+ messagesFromNative.unshift(messageBatch);
+ }
+ return message;
+}
+
module.exports = androidExec;
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/7b681f2a/test/android/test.exec.js
----------------------------------------------------------------------
diff --git a/test/android/test.exec.js b/test/android/test.exec.js
index 5271d81..736db04 100644
--- a/test/android/test.exec.js
+++ b/test/android/test.exec.js
@@ -89,7 +89,21 @@ describe('exec.processMessages', function () {
exec(win1, null, 'Service', 'action', []);
exec(win2, null, 'Service', 'action', []);
- expect(winSpy3).toHaveBeenCalledWith('three');
+ waitsFor(function() { return winSpy3.wasCalled }, 200);
+ runs(function() {
+ expect(winSpy3).toHaveBeenCalledWith('three');
+ });
+ });
+ it('should process messages asynchronously', function() {
+ nativeApi.exec.andCallFake(function(service, action, callbackId, argsJson) {
+ return createCallbackMessage(true, false, 1, callbackId, 'stwo');
+ });
+
+ var winSpy = jasmine.createSpy('win');
+
+ exec(winSpy, null, 'Service', 'action', []);
+ expect(winSpy).not.toHaveBeenCalled();
+ waitsFor(function() { return winSpy.wasCalled }, 200);
});
});