[android] Fix synch exec return values when made recursively.
For an explanation of the case, refer to the added unit test.
Related to: https://issues.apache.org/jira/browse/CB-1745
diff --git a/lib/android/exec.js b/lib/android/exec.js
index c339e2c..490633f 100644
--- a/lib/android/exec.js
+++ b/lib/android/exec.js
@@ -105,8 +105,8 @@
function pollingTimerFunc() {
if (pollEnabled) {
- pollOnce();
- setTimeout(pollingTimerFunc, 50);
+ pollOnce();
+ setTimeout(pollingTimerFunc, 50);
}
}
@@ -199,25 +199,34 @@
// This is called from the NativeToJsMessageQueue.java.
androidExec.processMessages = function(messages) {
- 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) {
+ messagesFromNative.push(messages);
+ while (messagesFromNative.length) {
+ messages = messagesFromNative.shift();
+ // The Java side can send a * message to indicate that it
+ // still has messages waiting to be retrieved.
+ // TODO(agrieve): This is currently disabled on the Java side
+ // since it breaks returning the result in exec of synchronous
+ // plugins. Once we remove this ability, we can remove this comment.
if (messages == '*') {
window.setTimeout(pollOnce, 0);
- break;
+ continue;
}
+
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);
+ // Put the remaining messages back into queue in case an exec()
+ // is made by the callback.
+ if (messages) {
+ messagesFromNative.unshift(messages);
+ }
+
+ if (message) {
+ processMessage(message);
+ }
}
- messagesFromNative.shift();
}
};
diff --git a/test/android/test.exec.js b/test/android/test.exec.js
index f4e760f..3363e45 100644
--- a/test/android/test.exec.js
+++ b/test/android/test.exec.js
@@ -74,6 +74,22 @@
var result = exec(null, null, 'Service', 'action', []);
expect(result).toBe(true);
});
+ it('should return payload value when plugin is synchronous even when called recursively', function() {
+ var winSpy = jasmine.createSpy('win');
+ nativeApi.exec.andCallFake(function(service, action, callbackId, argsJson) {
+ return createCallbackMessage(true, true, 1, callbackId, 't');
+ });
+
+ function firstWin(value) {
+ expect(value).toBe(true);
+ var result = exec(winSpy, null, 'Service', 'action', []);
+ expect(result).toBe(true);
+ }
+
+ var result2 = exec(firstWin, null, 'Service', 'action', []);
+ expect(winSpy).toHaveBeenCalledWith(true);
+ expect(result2).toBe(true);
+ });
});
describe('processMessages', function() {