You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by st...@apache.org on 2015/02/07 02:35:41 UTC
android commit: CB-8417 renamed platform_modules into cordova-js-src
Repository: cordova-android
Updated Branches:
refs/heads/master 828edb3a4 -> ad7ce085f
CB-8417 renamed platform_modules into cordova-js-src
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/ad7ce085
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/ad7ce085
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/ad7ce085
Branch: refs/heads/master
Commit: ad7ce085f7d6ea7039f02419d3830682f26dc63e
Parents: 828edb3
Author: Steve Gill <st...@gmail.com>
Authored: Fri Feb 6 17:35:35 2015 -0800
Committer: Steve Gill <st...@gmail.com>
Committed: Fri Feb 6 17:35:35 2015 -0800
----------------------------------------------------------------------
cordova-js-src/android/nativeapiprovider.js | 36 +++
cordova-js-src/android/promptbasednativeapi.js | 35 +++
cordova-js-src/exec.js | 287 +++++++++++++++++++
cordova-js-src/platform.js | 91 ++++++
cordova-js-src/plugin/android/app.js | 108 +++++++
platform_modules/android/nativeapiprovider.js | 36 ---
.../android/promptbasednativeapi.js | 35 ---
platform_modules/exec.js | 287 -------------------
platform_modules/platform.js | 91 ------
platform_modules/plugin/android/app.js | 108 -------
10 files changed, 557 insertions(+), 557 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ad7ce085/cordova-js-src/android/nativeapiprovider.js
----------------------------------------------------------------------
diff --git a/cordova-js-src/android/nativeapiprovider.js b/cordova-js-src/android/nativeapiprovider.js
new file mode 100644
index 0000000..2e9aa67
--- /dev/null
+++ b/cordova-js-src/android/nativeapiprovider.js
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+
+/**
+ * Exports the ExposedJsApi.java object if available, otherwise exports the PromptBasedNativeApi.
+ */
+
+var nativeApi = this._cordovaNative || require('cordova/android/promptbasednativeapi');
+var currentApi = nativeApi;
+
+module.exports = {
+ get: function() { return currentApi; },
+ setPreferPrompt: function(value) {
+ currentApi = value ? require('cordova/android/promptbasednativeapi') : nativeApi;
+ },
+ // Used only by tests.
+ set: function(value) {
+ currentApi = value;
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ad7ce085/cordova-js-src/android/promptbasednativeapi.js
----------------------------------------------------------------------
diff --git a/cordova-js-src/android/promptbasednativeapi.js b/cordova-js-src/android/promptbasednativeapi.js
new file mode 100644
index 0000000..f7fb6bc
--- /dev/null
+++ b/cordova-js-src/android/promptbasednativeapi.js
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+
+/**
+ * Implements the API of ExposedJsApi.java, but uses prompt() to communicate.
+ * This is used pre-JellyBean, where addJavascriptInterface() is disabled.
+ */
+
+module.exports = {
+ exec: function(bridgeSecret, service, action, callbackId, argsJson) {
+ return prompt(argsJson, 'gap:'+JSON.stringify([bridgeSecret, service, action, callbackId]));
+ },
+ setNativeToJsBridgeMode: function(bridgeSecret, value) {
+ prompt(value, 'gap_bridge_mode:' + bridgeSecret);
+ },
+ retrieveJsMessages: function(bridgeSecret, fromOnlineEvent) {
+ return prompt(+fromOnlineEvent, 'gap_poll:' + bridgeSecret);
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ad7ce085/cordova-js-src/exec.js
----------------------------------------------------------------------
diff --git a/cordova-js-src/exec.js b/cordova-js-src/exec.js
new file mode 100644
index 0000000..b9112d7
--- /dev/null
+++ b/cordova-js-src/exec.js
@@ -0,0 +1,287 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+/**
+ * Execute a cordova command. It is up to the native side whether this action
+ * is synchronous or asynchronous. The native side can return:
+ * Synchronous: PluginResult object as a JSON string
+ * Asynchronous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} success The success callback
+ * @param {Function} fail The fail callback
+ * @param {String} service The name of the service to use
+ * @param {String} action Action to be run in cordova
+ * @param {String[]} [args] Zero or more arguments to pass to the method
+ */
+var cordova = require('cordova'),
+ nativeApiProvider = require('cordova/android/nativeapiprovider'),
+ utils = require('cordova/utils'),
+ base64 = require('cordova/base64'),
+ channel = require('cordova/channel'),
+ jsToNativeModes = {
+ PROMPT: 0,
+ JS_OBJECT: 1
+ },
+ nativeToJsModes = {
+ // Polls for messages using the JS->Native bridge.
+ POLLING: 0,
+ // For LOAD_URL to be viable, it would need to have a work-around for
+ // the bug where the soft-keyboard gets dismissed when a message is sent.
+ LOAD_URL: 1,
+ // For the ONLINE_EVENT to be viable, it would need to intercept all event
+ // listeners (both through addEventListener and window.ononline) as well
+ // as set the navigator property itself.
+ ONLINE_EVENT: 2,
+ // Uses reflection to access private APIs of the WebView that can send JS
+ // to be executed.
+ // Requires Android 3.2.4 or above.
+ PRIVATE_API: 3
+ },
+ jsToNativeBridgeMode, // Set lazily.
+ nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT,
+ pollEnabled = false,
+ bridgeSecret = -1;
+
+var messagesFromNative = [];
+var isProcessing = false;
+var resolvedPromise = typeof Promise == 'undefined' ? null : Promise.resolve();
+var nextTick = resolvedPromise ? function(fn) { resolvedPromise.then(fn); } : function(fn) { setTimeout(fn); };
+
+function androidExec(success, fail, service, action, args) {
+ if (bridgeSecret < 0) {
+ // If we ever catch this firing, we'll need to queue up exec()s
+ // and fire them once we get a secret. For now, I don't think
+ // it's possible for exec() to be called since plugins are parsed but
+ // not run until until after onNativeReady.
+ throw new Error('exec() called without bridgeSecret');
+ }
+ // Set default bridge modes if they have not already been set.
+ // By default, we use the failsafe, since addJavascriptInterface breaks too often
+ if (jsToNativeBridgeMode === undefined) {
+ androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
+ }
+
+ // Process any ArrayBuffers in the args into a string.
+ for (var i = 0; i < args.length; i++) {
+ if (utils.typeName(args[i]) == 'ArrayBuffer') {
+ args[i] = base64.fromArrayBuffer(args[i]);
+ }
+ }
+
+ var callbackId = service + cordova.callbackId++,
+ argsJson = JSON.stringify(args);
+
+ if (success || fail) {
+ cordova.callbacks[callbackId] = {success:success, fail:fail};
+ }
+
+ var msgs = nativeApiProvider.get().exec(bridgeSecret, service, action, callbackId, argsJson);
+ // If argsJson was received by Java as null, try again with the PROMPT bridge mode.
+ // This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2. See CB-2666.
+ if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT && msgs === "@Null arguments.") {
+ androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
+ androidExec(success, fail, service, action, args);
+ androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
+ } else if (msgs) {
+ messagesFromNative.push(msgs);
+ // Always process async to avoid exceptions messing up stack.
+ nextTick(processMessages);
+ }
+}
+
+androidExec.init = function() {
+ bridgeSecret = +prompt('', 'gap_init:' + nativeToJsBridgeMode);
+ channel.onNativeReady.fire();
+};
+
+function pollOnceFromOnlineEvent() {
+ pollOnce(true);
+}
+
+function pollOnce(opt_fromOnlineEvent) {
+ if (bridgeSecret < 0) {
+ // This can happen when the NativeToJsMessageQueue resets the online state on page transitions.
+ // We know there's nothing to retrieve, so no need to poll.
+ return;
+ }
+ var msgs = nativeApiProvider.get().retrieveJsMessages(bridgeSecret, !!opt_fromOnlineEvent);
+ if (msgs) {
+ messagesFromNative.push(msgs);
+ // Process sync since we know we're already top-of-stack.
+ processMessages();
+ }
+}
+
+function pollingTimerFunc() {
+ if (pollEnabled) {
+ pollOnce();
+ setTimeout(pollingTimerFunc, 50);
+ }
+}
+
+function hookOnlineApis() {
+ function proxyEvent(e) {
+ cordova.fireWindowEvent(e.type);
+ }
+ // The network module takes care of firing online and offline events.
+ // It currently fires them only on document though, so we bridge them
+ // to window here (while first listening for exec()-releated online/offline
+ // events).
+ window.addEventListener('online', pollOnceFromOnlineEvent, false);
+ window.addEventListener('offline', pollOnceFromOnlineEvent, false);
+ cordova.addWindowEventHandler('online');
+ cordova.addWindowEventHandler('offline');
+ document.addEventListener('online', proxyEvent, false);
+ document.addEventListener('offline', proxyEvent, false);
+}
+
+hookOnlineApis();
+
+androidExec.jsToNativeModes = jsToNativeModes;
+androidExec.nativeToJsModes = nativeToJsModes;
+
+androidExec.setJsToNativeBridgeMode = function(mode) {
+ if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
+ mode = jsToNativeModes.PROMPT;
+ }
+ nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
+ jsToNativeBridgeMode = mode;
+};
+
+androidExec.setNativeToJsBridgeMode = function(mode) {
+ if (mode == nativeToJsBridgeMode) {
+ return;
+ }
+ if (nativeToJsBridgeMode == nativeToJsModes.POLLING) {
+ pollEnabled = false;
+ }
+
+ nativeToJsBridgeMode = mode;
+ // Tell the native side to switch modes.
+ // Otherwise, it will be set by androidExec.init()
+ if (bridgeSecret >= 0) {
+ nativeApiProvider.get().setNativeToJsBridgeMode(bridgeSecret, mode);
+ }
+
+ if (mode == nativeToJsModes.POLLING) {
+ pollEnabled = true;
+ setTimeout(pollingTimerFunc, 1);
+ }
+};
+
+function buildPayload(payload, message) {
+ var payloadKind = message.charAt(0);
+ if (payloadKind == 's') {
+ payload.push(message.slice(1));
+ } else if (payloadKind == 't') {
+ payload.push(true);
+ } else if (payloadKind == 'f') {
+ payload.push(false);
+ } else if (payloadKind == 'N') {
+ payload.push(null);
+ } else if (payloadKind == 'n') {
+ payload.push(+message.slice(1));
+ } else if (payloadKind == 'A') {
+ var data = message.slice(1);
+ payload.push(base64.toArrayBuffer(data));
+ } else if (payloadKind == 'S') {
+ payload.push(window.atob(message.slice(1)));
+ } else if (payloadKind == 'M') {
+ var multipartMessages = message.slice(1);
+ while (multipartMessages !== "") {
+ var spaceIdx = multipartMessages.indexOf(' ');
+ var msgLen = +multipartMessages.slice(0, spaceIdx);
+ var multipartMessage = multipartMessages.substr(spaceIdx + 1, msgLen);
+ multipartMessages = multipartMessages.slice(spaceIdx + msgLen + 1);
+ buildPayload(payload, multipartMessage);
+ }
+ } else {
+ payload.push(JSON.parse(message));
+ }
+}
+
+// Processes a single message, as encoded by NativeToJsMessageQueue.java.
+function processMessage(message) {
+ var firstChar = message.charAt(0);
+ if (firstChar == 'J') {
+ // This is deprecated on the .java side. It doesn't work with CSP enabled.
+ eval(message.slice(1));
+ } else if (firstChar == 'S' || firstChar == 'F') {
+ var success = firstChar == 'S';
+ var keepCallback = message.charAt(1) == '1';
+ var spaceIdx = message.indexOf(' ', 2);
+ var status = +message.slice(2, spaceIdx);
+ var nextSpaceIdx = message.indexOf(' ', spaceIdx + 1);
+ var callbackId = message.slice(spaceIdx + 1, nextSpaceIdx);
+ var payloadMessage = message.slice(nextSpaceIdx + 1);
+ var payload = [];
+ buildPayload(payload, payloadMessage);
+ cordova.callbackFromNative(callbackId, success, status, payload, keepCallback);
+ } else {
+ console.log("processMessage failed: invalid message: " + JSON.stringify(message));
+ }
+}
+
+function processMessages() {
+ // Check for the reentrant case.
+ if (isProcessing) {
+ return;
+ }
+ if (messagesFromNative.length === 0) {
+ return;
+ }
+ isProcessing = true;
+ try {
+ var msg = popMessageFromQueue();
+ // The Java side can send a * message to indicate that it
+ // still has messages waiting to be retrieved.
+ if (msg == '*' && messagesFromNative.length === 0) {
+ nextTick(pollOnce);
+ return;
+ }
+ processMessage(msg);
+ } finally {
+ isProcessing = false;
+ if (messagesFromNative.length > 0) {
+ nextTick(processMessages);
+ }
+ }
+}
+
+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-android/blob/ad7ce085/cordova-js-src/platform.js
----------------------------------------------------------------------
diff --git a/cordova-js-src/platform.js b/cordova-js-src/platform.js
new file mode 100644
index 0000000..bffc675
--- /dev/null
+++ b/cordova-js-src/platform.js
@@ -0,0 +1,91 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+module.exports = {
+ id: 'android',
+ bootstrap: function() {
+ var channel = require('cordova/channel'),
+ cordova = require('cordova'),
+ exec = require('cordova/exec'),
+ modulemapper = require('cordova/modulemapper');
+
+ // Get the shared secret needed to use the bridge.
+ exec.init();
+
+ // TODO: Extract this as a proper plugin.
+ modulemapper.clobbers('cordova/plugin/android/app', 'navigator.app');
+
+ var APP_PLUGIN_NAME = Number(cordova.platformVersion.split('.')[0]) >= 4 ? 'CoreAndroid' : 'App';
+
+ // Inject a listener for the backbutton on the document.
+ var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
+ backButtonChannel.onHasSubscribersChange = function() {
+ // If we just attached the first handler or detached the last handler,
+ // let native know we need to override the back button.
+ exec(null, null, APP_PLUGIN_NAME, "overrideBackbutton", [this.numHandlers == 1]);
+ };
+
+ // Add hardware MENU and SEARCH button handlers
+ cordova.addDocumentEventHandler('menubutton');
+ cordova.addDocumentEventHandler('searchbutton');
+
+ function bindButtonChannel(buttonName) {
+ // generic button bind used for volumeup/volumedown buttons
+ var volumeButtonChannel = cordova.addDocumentEventHandler(buttonName + 'button');
+ volumeButtonChannel.onHasSubscribersChange = function() {
+ exec(null, null, APP_PLUGIN_NAME, "overrideButton", [buttonName, this.numHandlers == 1]);
+ };
+ }
+ // Inject a listener for the volume buttons on the document.
+ bindButtonChannel('volumeup');
+ bindButtonChannel('volumedown');
+
+ // Let native code know we are all done on the JS side.
+ // Native code will then un-hide the WebView.
+ channel.onCordovaReady.subscribe(function() {
+ exec(onMessageFromNative, null, APP_PLUGIN_NAME, 'messageChannel', []);
+ exec(null, null, APP_PLUGIN_NAME, "show", []);
+ });
+ }
+};
+
+function onMessageFromNative(msg) {
+ var cordova = require('cordova');
+ var action = msg.action;
+
+ switch (action)
+ {
+ // Button events
+ case 'backbutton':
+ case 'menubutton':
+ case 'searchbutton':
+ // App life cycle events
+ case 'pause':
+ case 'resume':
+ // Volume events
+ case 'volumedownbutton':
+ case 'volumeupbutton':
+ cordova.fireDocumentEvent(action);
+ break;
+ default:
+ throw new Error('Unknown event action ' + action);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ad7ce085/cordova-js-src/plugin/android/app.js
----------------------------------------------------------------------
diff --git a/cordova-js-src/plugin/android/app.js b/cordova-js-src/plugin/android/app.js
new file mode 100644
index 0000000..22cf96e
--- /dev/null
+++ b/cordova-js-src/plugin/android/app.js
@@ -0,0 +1,108 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var exec = require('cordova/exec');
+var APP_PLUGIN_NAME = Number(require('cordova').platformVersion.split('.')[0]) >= 4 ? 'CoreAndroid' : 'App';
+
+module.exports = {
+ /**
+ * Clear the resource cache.
+ */
+ clearCache:function() {
+ exec(null, null, APP_PLUGIN_NAME, "clearCache", []);
+ },
+
+ /**
+ * Load the url into the webview or into new browser instance.
+ *
+ * @param url The URL to load
+ * @param props Properties that can be passed in to the activity:
+ * wait: int => wait msec before loading URL
+ * loadingDialog: "Title,Message" => display a native loading dialog
+ * loadUrlTimeoutValue: int => time in msec to wait before triggering a timeout error
+ * clearHistory: boolean => clear webview history (default=false)
+ * openExternal: boolean => open in a new browser (default=false)
+ *
+ * Example:
+ * navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000});
+ */
+ loadUrl:function(url, props) {
+ exec(null, null, APP_PLUGIN_NAME, "loadUrl", [url, props]);
+ },
+
+ /**
+ * Cancel loadUrl that is waiting to be loaded.
+ */
+ cancelLoadUrl:function() {
+ exec(null, null, APP_PLUGIN_NAME, "cancelLoadUrl", []);
+ },
+
+ /**
+ * Clear web history in this web view.
+ * Instead of BACK button loading the previous web page, it will exit the app.
+ */
+ clearHistory:function() {
+ exec(null, null, APP_PLUGIN_NAME, "clearHistory", []);
+ },
+
+ /**
+ * Go to previous page displayed.
+ * This is the same as pressing the backbutton on Android device.
+ */
+ backHistory:function() {
+ exec(null, null, APP_PLUGIN_NAME, "backHistory", []);
+ },
+
+ /**
+ * Override the default behavior of the Android back button.
+ * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired.
+ *
+ * Note: The user should not have to call this method. Instead, when the user
+ * registers for the "backbutton" event, this is automatically done.
+ *
+ * @param override T=override, F=cancel override
+ */
+ overrideBackbutton:function(override) {
+ exec(null, null, APP_PLUGIN_NAME, "overrideBackbutton", [override]);
+ },
+
+ /**
+ * Override the default behavior of the Android volume button.
+ * If overridden, when the volume button is pressed, the "volume[up|down]button"
+ * JavaScript event will be fired.
+ *
+ * Note: The user should not have to call this method. Instead, when the user
+ * registers for the "volume[up|down]button" event, this is automatically done.
+ *
+ * @param button volumeup, volumedown
+ * @param override T=override, F=cancel override
+ */
+ overrideButton:function(button, override) {
+ exec(null, null, APP_PLUGIN_NAME, "overrideButton", [button, override]);
+ },
+
+ /**
+ * Exit and terminate the application.
+ */
+ exitApp:function() {
+ return exec(null, null, APP_PLUGIN_NAME, "exitApp", []);
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ad7ce085/platform_modules/android/nativeapiprovider.js
----------------------------------------------------------------------
diff --git a/platform_modules/android/nativeapiprovider.js b/platform_modules/android/nativeapiprovider.js
deleted file mode 100644
index 2e9aa67..0000000
--- a/platform_modules/android/nativeapiprovider.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
-*/
-
-/**
- * Exports the ExposedJsApi.java object if available, otherwise exports the PromptBasedNativeApi.
- */
-
-var nativeApi = this._cordovaNative || require('cordova/android/promptbasednativeapi');
-var currentApi = nativeApi;
-
-module.exports = {
- get: function() { return currentApi; },
- setPreferPrompt: function(value) {
- currentApi = value ? require('cordova/android/promptbasednativeapi') : nativeApi;
- },
- // Used only by tests.
- set: function(value) {
- currentApi = value;
- }
-};
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ad7ce085/platform_modules/android/promptbasednativeapi.js
----------------------------------------------------------------------
diff --git a/platform_modules/android/promptbasednativeapi.js b/platform_modules/android/promptbasednativeapi.js
deleted file mode 100644
index f7fb6bc..0000000
--- a/platform_modules/android/promptbasednativeapi.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
-*/
-
-/**
- * Implements the API of ExposedJsApi.java, but uses prompt() to communicate.
- * This is used pre-JellyBean, where addJavascriptInterface() is disabled.
- */
-
-module.exports = {
- exec: function(bridgeSecret, service, action, callbackId, argsJson) {
- return prompt(argsJson, 'gap:'+JSON.stringify([bridgeSecret, service, action, callbackId]));
- },
- setNativeToJsBridgeMode: function(bridgeSecret, value) {
- prompt(value, 'gap_bridge_mode:' + bridgeSecret);
- },
- retrieveJsMessages: function(bridgeSecret, fromOnlineEvent) {
- return prompt(+fromOnlineEvent, 'gap_poll:' + bridgeSecret);
- }
-};
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ad7ce085/platform_modules/exec.js
----------------------------------------------------------------------
diff --git a/platform_modules/exec.js b/platform_modules/exec.js
deleted file mode 100644
index b9112d7..0000000
--- a/platform_modules/exec.js
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/**
- * Execute a cordova command. It is up to the native side whether this action
- * is synchronous or asynchronous. The native side can return:
- * Synchronous: PluginResult object as a JSON string
- * Asynchronous: Empty string ""
- * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
- * depending upon the result of the action.
- *
- * @param {Function} success The success callback
- * @param {Function} fail The fail callback
- * @param {String} service The name of the service to use
- * @param {String} action Action to be run in cordova
- * @param {String[]} [args] Zero or more arguments to pass to the method
- */
-var cordova = require('cordova'),
- nativeApiProvider = require('cordova/android/nativeapiprovider'),
- utils = require('cordova/utils'),
- base64 = require('cordova/base64'),
- channel = require('cordova/channel'),
- jsToNativeModes = {
- PROMPT: 0,
- JS_OBJECT: 1
- },
- nativeToJsModes = {
- // Polls for messages using the JS->Native bridge.
- POLLING: 0,
- // For LOAD_URL to be viable, it would need to have a work-around for
- // the bug where the soft-keyboard gets dismissed when a message is sent.
- LOAD_URL: 1,
- // For the ONLINE_EVENT to be viable, it would need to intercept all event
- // listeners (both through addEventListener and window.ononline) as well
- // as set the navigator property itself.
- ONLINE_EVENT: 2,
- // Uses reflection to access private APIs of the WebView that can send JS
- // to be executed.
- // Requires Android 3.2.4 or above.
- PRIVATE_API: 3
- },
- jsToNativeBridgeMode, // Set lazily.
- nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT,
- pollEnabled = false,
- bridgeSecret = -1;
-
-var messagesFromNative = [];
-var isProcessing = false;
-var resolvedPromise = typeof Promise == 'undefined' ? null : Promise.resolve();
-var nextTick = resolvedPromise ? function(fn) { resolvedPromise.then(fn); } : function(fn) { setTimeout(fn); };
-
-function androidExec(success, fail, service, action, args) {
- if (bridgeSecret < 0) {
- // If we ever catch this firing, we'll need to queue up exec()s
- // and fire them once we get a secret. For now, I don't think
- // it's possible for exec() to be called since plugins are parsed but
- // not run until until after onNativeReady.
- throw new Error('exec() called without bridgeSecret');
- }
- // Set default bridge modes if they have not already been set.
- // By default, we use the failsafe, since addJavascriptInterface breaks too often
- if (jsToNativeBridgeMode === undefined) {
- androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
- }
-
- // Process any ArrayBuffers in the args into a string.
- for (var i = 0; i < args.length; i++) {
- if (utils.typeName(args[i]) == 'ArrayBuffer') {
- args[i] = base64.fromArrayBuffer(args[i]);
- }
- }
-
- var callbackId = service + cordova.callbackId++,
- argsJson = JSON.stringify(args);
-
- if (success || fail) {
- cordova.callbacks[callbackId] = {success:success, fail:fail};
- }
-
- var msgs = nativeApiProvider.get().exec(bridgeSecret, service, action, callbackId, argsJson);
- // If argsJson was received by Java as null, try again with the PROMPT bridge mode.
- // This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2. See CB-2666.
- if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT && msgs === "@Null arguments.") {
- androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
- androidExec(success, fail, service, action, args);
- androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
- } else if (msgs) {
- messagesFromNative.push(msgs);
- // Always process async to avoid exceptions messing up stack.
- nextTick(processMessages);
- }
-}
-
-androidExec.init = function() {
- bridgeSecret = +prompt('', 'gap_init:' + nativeToJsBridgeMode);
- channel.onNativeReady.fire();
-};
-
-function pollOnceFromOnlineEvent() {
- pollOnce(true);
-}
-
-function pollOnce(opt_fromOnlineEvent) {
- if (bridgeSecret < 0) {
- // This can happen when the NativeToJsMessageQueue resets the online state on page transitions.
- // We know there's nothing to retrieve, so no need to poll.
- return;
- }
- var msgs = nativeApiProvider.get().retrieveJsMessages(bridgeSecret, !!opt_fromOnlineEvent);
- if (msgs) {
- messagesFromNative.push(msgs);
- // Process sync since we know we're already top-of-stack.
- processMessages();
- }
-}
-
-function pollingTimerFunc() {
- if (pollEnabled) {
- pollOnce();
- setTimeout(pollingTimerFunc, 50);
- }
-}
-
-function hookOnlineApis() {
- function proxyEvent(e) {
- cordova.fireWindowEvent(e.type);
- }
- // The network module takes care of firing online and offline events.
- // It currently fires them only on document though, so we bridge them
- // to window here (while first listening for exec()-releated online/offline
- // events).
- window.addEventListener('online', pollOnceFromOnlineEvent, false);
- window.addEventListener('offline', pollOnceFromOnlineEvent, false);
- cordova.addWindowEventHandler('online');
- cordova.addWindowEventHandler('offline');
- document.addEventListener('online', proxyEvent, false);
- document.addEventListener('offline', proxyEvent, false);
-}
-
-hookOnlineApis();
-
-androidExec.jsToNativeModes = jsToNativeModes;
-androidExec.nativeToJsModes = nativeToJsModes;
-
-androidExec.setJsToNativeBridgeMode = function(mode) {
- if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
- mode = jsToNativeModes.PROMPT;
- }
- nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
- jsToNativeBridgeMode = mode;
-};
-
-androidExec.setNativeToJsBridgeMode = function(mode) {
- if (mode == nativeToJsBridgeMode) {
- return;
- }
- if (nativeToJsBridgeMode == nativeToJsModes.POLLING) {
- pollEnabled = false;
- }
-
- nativeToJsBridgeMode = mode;
- // Tell the native side to switch modes.
- // Otherwise, it will be set by androidExec.init()
- if (bridgeSecret >= 0) {
- nativeApiProvider.get().setNativeToJsBridgeMode(bridgeSecret, mode);
- }
-
- if (mode == nativeToJsModes.POLLING) {
- pollEnabled = true;
- setTimeout(pollingTimerFunc, 1);
- }
-};
-
-function buildPayload(payload, message) {
- var payloadKind = message.charAt(0);
- if (payloadKind == 's') {
- payload.push(message.slice(1));
- } else if (payloadKind == 't') {
- payload.push(true);
- } else if (payloadKind == 'f') {
- payload.push(false);
- } else if (payloadKind == 'N') {
- payload.push(null);
- } else if (payloadKind == 'n') {
- payload.push(+message.slice(1));
- } else if (payloadKind == 'A') {
- var data = message.slice(1);
- payload.push(base64.toArrayBuffer(data));
- } else if (payloadKind == 'S') {
- payload.push(window.atob(message.slice(1)));
- } else if (payloadKind == 'M') {
- var multipartMessages = message.slice(1);
- while (multipartMessages !== "") {
- var spaceIdx = multipartMessages.indexOf(' ');
- var msgLen = +multipartMessages.slice(0, spaceIdx);
- var multipartMessage = multipartMessages.substr(spaceIdx + 1, msgLen);
- multipartMessages = multipartMessages.slice(spaceIdx + msgLen + 1);
- buildPayload(payload, multipartMessage);
- }
- } else {
- payload.push(JSON.parse(message));
- }
-}
-
-// Processes a single message, as encoded by NativeToJsMessageQueue.java.
-function processMessage(message) {
- var firstChar = message.charAt(0);
- if (firstChar == 'J') {
- // This is deprecated on the .java side. It doesn't work with CSP enabled.
- eval(message.slice(1));
- } else if (firstChar == 'S' || firstChar == 'F') {
- var success = firstChar == 'S';
- var keepCallback = message.charAt(1) == '1';
- var spaceIdx = message.indexOf(' ', 2);
- var status = +message.slice(2, spaceIdx);
- var nextSpaceIdx = message.indexOf(' ', spaceIdx + 1);
- var callbackId = message.slice(spaceIdx + 1, nextSpaceIdx);
- var payloadMessage = message.slice(nextSpaceIdx + 1);
- var payload = [];
- buildPayload(payload, payloadMessage);
- cordova.callbackFromNative(callbackId, success, status, payload, keepCallback);
- } else {
- console.log("processMessage failed: invalid message: " + JSON.stringify(message));
- }
-}
-
-function processMessages() {
- // Check for the reentrant case.
- if (isProcessing) {
- return;
- }
- if (messagesFromNative.length === 0) {
- return;
- }
- isProcessing = true;
- try {
- var msg = popMessageFromQueue();
- // The Java side can send a * message to indicate that it
- // still has messages waiting to be retrieved.
- if (msg == '*' && messagesFromNative.length === 0) {
- nextTick(pollOnce);
- return;
- }
- processMessage(msg);
- } finally {
- isProcessing = false;
- if (messagesFromNative.length > 0) {
- nextTick(processMessages);
- }
- }
-}
-
-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-android/blob/ad7ce085/platform_modules/platform.js
----------------------------------------------------------------------
diff --git a/platform_modules/platform.js b/platform_modules/platform.js
deleted file mode 100644
index bffc675..0000000
--- a/platform_modules/platform.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-module.exports = {
- id: 'android',
- bootstrap: function() {
- var channel = require('cordova/channel'),
- cordova = require('cordova'),
- exec = require('cordova/exec'),
- modulemapper = require('cordova/modulemapper');
-
- // Get the shared secret needed to use the bridge.
- exec.init();
-
- // TODO: Extract this as a proper plugin.
- modulemapper.clobbers('cordova/plugin/android/app', 'navigator.app');
-
- var APP_PLUGIN_NAME = Number(cordova.platformVersion.split('.')[0]) >= 4 ? 'CoreAndroid' : 'App';
-
- // Inject a listener for the backbutton on the document.
- var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
- backButtonChannel.onHasSubscribersChange = function() {
- // If we just attached the first handler or detached the last handler,
- // let native know we need to override the back button.
- exec(null, null, APP_PLUGIN_NAME, "overrideBackbutton", [this.numHandlers == 1]);
- };
-
- // Add hardware MENU and SEARCH button handlers
- cordova.addDocumentEventHandler('menubutton');
- cordova.addDocumentEventHandler('searchbutton');
-
- function bindButtonChannel(buttonName) {
- // generic button bind used for volumeup/volumedown buttons
- var volumeButtonChannel = cordova.addDocumentEventHandler(buttonName + 'button');
- volumeButtonChannel.onHasSubscribersChange = function() {
- exec(null, null, APP_PLUGIN_NAME, "overrideButton", [buttonName, this.numHandlers == 1]);
- };
- }
- // Inject a listener for the volume buttons on the document.
- bindButtonChannel('volumeup');
- bindButtonChannel('volumedown');
-
- // Let native code know we are all done on the JS side.
- // Native code will then un-hide the WebView.
- channel.onCordovaReady.subscribe(function() {
- exec(onMessageFromNative, null, APP_PLUGIN_NAME, 'messageChannel', []);
- exec(null, null, APP_PLUGIN_NAME, "show", []);
- });
- }
-};
-
-function onMessageFromNative(msg) {
- var cordova = require('cordova');
- var action = msg.action;
-
- switch (action)
- {
- // Button events
- case 'backbutton':
- case 'menubutton':
- case 'searchbutton':
- // App life cycle events
- case 'pause':
- case 'resume':
- // Volume events
- case 'volumedownbutton':
- case 'volumeupbutton':
- cordova.fireDocumentEvent(action);
- break;
- default:
- throw new Error('Unknown event action ' + action);
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/ad7ce085/platform_modules/plugin/android/app.js
----------------------------------------------------------------------
diff --git a/platform_modules/plugin/android/app.js b/platform_modules/plugin/android/app.js
deleted file mode 100644
index 22cf96e..0000000
--- a/platform_modules/plugin/android/app.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-var exec = require('cordova/exec');
-var APP_PLUGIN_NAME = Number(require('cordova').platformVersion.split('.')[0]) >= 4 ? 'CoreAndroid' : 'App';
-
-module.exports = {
- /**
- * Clear the resource cache.
- */
- clearCache:function() {
- exec(null, null, APP_PLUGIN_NAME, "clearCache", []);
- },
-
- /**
- * Load the url into the webview or into new browser instance.
- *
- * @param url The URL to load
- * @param props Properties that can be passed in to the activity:
- * wait: int => wait msec before loading URL
- * loadingDialog: "Title,Message" => display a native loading dialog
- * loadUrlTimeoutValue: int => time in msec to wait before triggering a timeout error
- * clearHistory: boolean => clear webview history (default=false)
- * openExternal: boolean => open in a new browser (default=false)
- *
- * Example:
- * navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000});
- */
- loadUrl:function(url, props) {
- exec(null, null, APP_PLUGIN_NAME, "loadUrl", [url, props]);
- },
-
- /**
- * Cancel loadUrl that is waiting to be loaded.
- */
- cancelLoadUrl:function() {
- exec(null, null, APP_PLUGIN_NAME, "cancelLoadUrl", []);
- },
-
- /**
- * Clear web history in this web view.
- * Instead of BACK button loading the previous web page, it will exit the app.
- */
- clearHistory:function() {
- exec(null, null, APP_PLUGIN_NAME, "clearHistory", []);
- },
-
- /**
- * Go to previous page displayed.
- * This is the same as pressing the backbutton on Android device.
- */
- backHistory:function() {
- exec(null, null, APP_PLUGIN_NAME, "backHistory", []);
- },
-
- /**
- * Override the default behavior of the Android back button.
- * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired.
- *
- * Note: The user should not have to call this method. Instead, when the user
- * registers for the "backbutton" event, this is automatically done.
- *
- * @param override T=override, F=cancel override
- */
- overrideBackbutton:function(override) {
- exec(null, null, APP_PLUGIN_NAME, "overrideBackbutton", [override]);
- },
-
- /**
- * Override the default behavior of the Android volume button.
- * If overridden, when the volume button is pressed, the "volume[up|down]button"
- * JavaScript event will be fired.
- *
- * Note: The user should not have to call this method. Instead, when the user
- * registers for the "volume[up|down]button" event, this is automatically done.
- *
- * @param button volumeup, volumedown
- * @param override T=override, F=cancel override
- */
- overrideButton:function(button, override) {
- exec(null, null, APP_PLUGIN_NAME, "overrideButton", [button, override]);
- },
-
- /**
- * Exit and terminate the application.
- */
- exitApp:function() {
- return exec(null, null, APP_PLUGIN_NAME, "exitApp", []);
- }
-};
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org