Updated Branches: refs/heads/master fe6f8c618 -> e799aef6a
[android] Use a queue to process native->JS messages. Fixes issue: https://issues.apache.org/jira/browse/CB-1537 Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/commit/e799aef6 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/tree/e799aef6 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/diff/e799aef6 Branch: refs/heads/master Commit: e799aef6a4e24e95b341798e19ffeb39b43ce2c1 Parents: fe6f8c6 Author: Andrew Grieve <agri...@chromium.org> Authored: Fri Sep 28 15:33:29 2012 -0400 Committer: Andrew Grieve <agri...@chromium.org> Committed: Fri Sep 28 15:33:29 2012 -0400 ---------------------------------------------------------------------- lib/android/exec.js | 32 +++++++++++++++++++++----------- test/android/test.exec.js | 16 ++++++++++++++++ 2 files changed, 37 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e799aef6/lib/android/exec.js ---------------------------------------------------------------------- diff --git a/lib/android/exec.js b/lib/android/exec.js index e3fbf4f..90e5ea2 100644 --- a/lib/android/exec.js +++ b/lib/android/exec.js @@ -59,8 +59,9 @@ var cordova = require('cordova'), PRIVATE_API: 4 }, jsToNativeBridgeMode, // Set lazily. - nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT - pollEnabled = false; + nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT, + pollEnabled = false, + messagesFromNative = []; function androidExec(success, fail, service, action, args) { // Set default bridge modes if they have not already been set. @@ -186,16 +187,25 @@ function processMessage(message) { // This is called from the NativeToJsMessageQueue.java. androidExec.processMessages = function(messages) { - while (messages) { - if (messages == '*') { - window.setTimeout(pollOnce, 0); - break; + messagesFromNative.push(messages); + // Check for the reentrant case, and enqueue the message if that's the case. + if (messagesFromNative.length > 1) { + return; + } + while (messagesFromNative.length) { + messages = messagesFromNative[0]; + while (messages) { + if (messages == '*') { + window.setTimeout(pollOnce, 0); + break; + } + 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); } - 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); + messagesFromNative.shift(); } }; http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e799aef6/test/android/test.exec.js ---------------------------------------------------------------------- diff --git a/test/android/test.exec.js b/test/android/test.exec.js index 14360bd..97fbb10 100644 --- a/test/android/test.exec.js +++ b/test/android/test.exec.js @@ -106,5 +106,21 @@ describe('exec.processMessages', function () { expect(callbackSpy).toHaveBeenCalledWith('id', true, 1, false, true); }); }); + it('should call callbacks in order when one callback enqueues another.', function() { + var message1 = createCallbackMessage(false, false, 3, 'id', 'scall1'); + var message2 = createCallbackMessage(false, false, 3, 'id', 'scall2'); + var message3 = createCallbackMessage(false, false, 3, 'id', 'scall3'); + + callbackSpy.andCallFake(function() { + if (callbackSpy.calls.length == 1) { + exec.processMessages(message3); + } + }); + exec.processMessages(message1 + message2); + expect(callbackSpy.argsForCall.length).toEqual(3); + expect(callbackSpy.argsForCall[0]).toEqual(['id', false, 3, 'call1', false]); + expect(callbackSpy.argsForCall[1]).toEqual(['id', false, 3, 'call2', false]); + expect(callbackSpy.argsForCall[2]).toEqual(['id', false, 3, 'call3', false]); + }); }); });