diff --git a/bin/templates/cordova/defaults.xml b/bin/templates/cordova/defaults.xml
index 1654c136..25a878ba 100644
--- a/bin/templates/cordova/defaults.xml
+++ b/bin/templates/cordova/defaults.xml
@@ -23,6 +23,7 @@
+
diff --git a/bin/templates/cordova/lib/build.js b/bin/templates/cordova/lib/build.js
index 7e0df2f3..6336ecf5 100644
--- a/bin/templates/cordova/lib/build.js
+++ b/bin/templates/cordova/lib/build.js
@@ -74,7 +74,12 @@ module.exports.run = function(build_type) {
* the script will error out. (should we error or just return undefined?)
*/
module.exports.get_apk = function() {
- var binDir = path.join(ROOT, 'ant-build');
+ var binDir = '';
+ if(!hasCustomRules()) {
+ binDir = path.join(ROOT, 'bin');
+ } else {
+ binDir = path.join(ROOT, 'ant-build');
+ }
if (fs.existsSync(binDir)) {
var candidates = fs.readdirSync(binDir).filter(function(p) {
// Need to choose between release and debug .apk.
@@ -87,13 +92,13 @@ module.exports.get_apk = function() {
a.t < b.t ? 1 : 0;
});
if (candidates.length === 0) {
- console.error('ERROR : No .apk found in \'ant-build\' directory');
+ console.error('ERROR : No .apk found in ' + binDir + ' directory');
process.exit(2);
}
console.log('Using apk: ' + candidates[0].p);
return candidates[0].p;
} else {
- console.error('ERROR : unable to find project ant-build directory, could not locate .apk');
+ console.error('ERROR : unable to find project ' + binDir + ' directory, could not locate .apk');
process.exit(2);
}
}
diff --git a/bin/templates/project/AndroidManifest.xml b/bin/templates/project/AndroidManifest.xml
index dba1b445..decb9712 100644
--- a/bin/templates/project/AndroidManifest.xml
+++ b/bin/templates/project/AndroidManifest.xml
@@ -34,7 +34,7 @@
-
diff --git a/framework/assets/www/cordova.js b/framework/assets/www/cordova.js
index 8855fc7f..45c1943a 100644
--- a/framework/assets/www/cordova.js
+++ b/framework/assets/www/cordova.js
@@ -1,5 +1,5 @@
// Platform: android
-// 3.5.0-dev-ddf13aa
+// 3.5.0-dev-81f9a00
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -19,7 +19,7 @@
under the License.
*/
;(function() {
-var CORDOVA_JS_BUILD_LABEL = '3.5.0-dev-ddf13aa';
+var CORDOVA_JS_BUILD_LABEL = '3.5.0-dev-81f9a00';
// file: src/scripts/require.js
/*jshint -W079 */
@@ -437,6 +437,16 @@ base64.fromArrayBuffer = function(arrayBuffer) {
return uint8ToBase64(array);
};
+base64.toArrayBuffer = function(str) {
+ var decodedStr = typeof atob != 'undefined' ? atob(str) : new Buffer(str,'base64').toString('binary');
+ var arrayBuffer = new ArrayBuffer(decodedStr.length);
+ var array = new Uint8Array(arrayBuffer);
+ for (var i=0, len=decodedStr.length; i < len; i++) {
+ array[i] = decodedStr.charCodeAt(i);
+ }
+ return arrayBuffer;
+};
+
//------------------------------------------------------------------------------
/* This code is based on the performance tests at http://jsperf.com/b64tests
@@ -919,7 +929,7 @@ function androidExec(success, fail, service, action, args) {
androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
return;
} else {
- androidExec.processMessages(messages);
+ androidExec.processMessages(messages, true);
}
}
}
@@ -963,7 +973,6 @@ androidExec.nativeToJsModes = nativeToJsModes;
androidExec.setJsToNativeBridgeMode = function(mode) {
if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
- console.log('Falling back on PROMPT mode since _cordovaNative is missing. Expected for Android 3.2 and lower only.');
mode = jsToNativeModes.PROMPT;
}
nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
@@ -1028,48 +1037,64 @@ 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;
});
@@ -1191,9 +1216,13 @@ modulemapper.clobbers('cordova/exec', 'Cordova.exec');
// Call the platform-specific initialization.
platform.bootstrap && platform.bootstrap();
-pluginloader.load(function() {
- channel.onPluginsReady.fire();
-});
+// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
+// The delay allows the attached modules to be defined before the plugin loader looks for them.
+setTimeout(function() {
+ pluginloader.load(function() {
+ channel.onPluginsReady.fire();
+ });
+}, 0);
/**
* Create all cordova objects once native side is ready.
@@ -1444,43 +1473,51 @@ var modulemapper = require('cordova/modulemapper');
var urlutil = require('cordova/urlutil');
// Helper function to inject a