diff --git a/framework/assets/js/phonegap.js.base b/framework/assets/js/phonegap.js.base
index 4345e2f1..0ebc8383 100755
--- a/framework/assets/js/phonegap.js.base
+++ b/framework/assets/js/phonegap.js.base
@@ -238,7 +238,14 @@ PhoneGap.onDeviceReady = new PhoneGap.Channel('onDeviceReady');
PhoneGap.Channel.join(function() {
// Start listening for XHR callbacks
- PhoneGap.JSCallback();
+ setTimeout(function() {
+ if (CallbackServer.usePolling()) {
+ PhoneGap.JSCallbackPolling();
+ }
+ else {
+ PhoneGap.JSCallback();
+ }
+ }, 1);
// Run PhoneGap constructors
PhoneGap.onPhoneGapInit.fire();
@@ -603,6 +610,37 @@ PhoneGap.JSCallback = function() {
xmlhttp.send();
};
+/**
+ * The polling period to use with JSCallbackPolling.
+ * This can be changed by the application. The default is 50ms.
+ */
+PhoneGap.JSCallbackPollingPeriod = 50;
+
+/**
+ * This is only for Android.
+ *
+ * Internal function that uses polling to call into PhoneGap Java code and retrieve
+ * any JavaScript code that needs to be run. This is used for callbacks from
+ * Java to JavaScript.
+ */
+PhoneGap.JSCallbackPolling = function() {
+ var msg = CallbackServer.getJavascript();
+ if (msg) {
+ setTimeout(function() {
+ try {
+ var t = eval(""+msg);
+ }
+ catch (e) {
+ console.log("JSCallbackPolling Error: "+e);
+ }
+ }, 1);
+ setTimeout(PhoneGap.JSCallbackPolling, 1);
+ }
+ else {
+ setTimeout(PhoneGap.JSCallbackPolling, PhoneGap.JSCallbackPollingPeriod);
+ }
+};
+
/**
* Create a UUID
*
diff --git a/framework/src/com/phonegap/CallbackServer.java b/framework/src/com/phonegap/CallbackServer.java
index 154c7b2f..6bf74c52 100755
--- a/framework/src/com/phonegap/CallbackServer.java
+++ b/framework/src/com/phonegap/CallbackServer.java
@@ -17,10 +17,10 @@ import java.util.LinkedList;
/**
* This class provides a way for Java to run JavaScript in the web page that has loaded PhoneGap.
- * The CallbackServer class implements an XHR server and a list of JavaScript statements
- * that are to be executed on the web page.
+ * The CallbackServer class implements an XHR server and a polling server with a list of JavaScript
+ * statements that are to be executed on the web page.
*
- * The process flow is:
+ * The process flow for XHR is:
* 1. JavaScript makes an async XHR call.
* 2. The server holds the connection open until data is available.
* 3. The server writes the data to the client and closes the connection.
@@ -30,6 +30,14 @@ import java.util.LinkedList;
*
* The CallbackServer class requires the following permission in Android manifest file
*
+ *
+ * If the device has a proxy set, then XHR cannot be used, so polling must be used instead.
+ * This can be determined by the client by calling CallbackServer.usePolling().
+ *
+ * The process flow for polling is:
+ * 1. The client calls CallbackServer.getJavascript() to retrieve next statement.
+ * 2. If statement available, then client processes it.
+ * 3. The client repeats #1 in loop.
*/
public class CallbackServer implements Runnable {
@@ -58,6 +66,11 @@ public class CallbackServer implements Runnable {
*/
private boolean empty;
+ /**
+ * Indicates that polling should be used instead of XHR.
+ */
+ private boolean usePolling;
+
/**
* Constructor.
*/
@@ -67,7 +80,23 @@ public class CallbackServer implements Runnable {
this.empty = true;
this.port = 0;
this.javascript = new LinkedList();
- this.startServer();
+
+ if (android.net.Proxy.getDefaultHost() != null) {
+ this.usePolling = true;
+ }
+ else {
+ this.usePolling = false;
+ this.startServer();
+ }
+ }
+
+ /**
+ * Determine if polling should be used instead of XHR.
+ *
+ * @return
+ */
+ public boolean usePolling() {
+ return this.usePolling;
}
/**
diff --git a/framework/src/com/phonegap/api/Plugin.java b/framework/src/com/phonegap/api/Plugin.java
index c16c6960..f22e4972 100755
--- a/framework/src/com/phonegap/api/Plugin.java
+++ b/framework/src/com/phonegap/api/Plugin.java
@@ -99,7 +99,7 @@ public abstract class Plugin implements IPlugin {
* @param statement
*/
public void sendJavascript(String statement) {
- this.ctx.callbackServer.sendJavascript(statement);
+ this.ctx.sendJavascript(statement);
}
/**
@@ -113,7 +113,7 @@ public abstract class Plugin implements IPlugin {
* @param callbackId The callback id used when calling back into JavaScript.
*/
public void success(PluginResult pluginResult, String callbackId) {
- this.ctx.callbackServer.sendJavascript(pluginResult.toSuccessCallbackString(callbackId));
+ this.ctx.sendJavascript(pluginResult.toSuccessCallbackString(callbackId));
}
/**
@@ -123,6 +123,6 @@ public abstract class Plugin implements IPlugin {
* @param callbackId The callback id used when calling back into JavaScript.
*/
public void error(PluginResult pluginResult, String callbackId) {
- this.ctx.callbackServer.sendJavascript(pluginResult.toErrorCallbackString(callbackId));
+ this.ctx.sendJavascript(pluginResult.toErrorCallbackString(callbackId));
}
}