Implement the online events based Native->JS bridge.

Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/commit/e239fd97
Tree: 
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/tree/e239fd97
Diff: 
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/diff/e239fd97

Branch: refs/heads/master
Commit: e239fd970f836285ffe11fd5387c7db87f764a74
Parents: 7fa4515
Author: Andrew Grieve <agri...@chromium.org>
Authored: Tue Aug 21 14:15:04 2012 -0400
Committer: Andrew Grieve <agri...@chromium.org>
Committed: Wed Aug 22 09:46:30 2012 -0400

----------------------------------------------------------------------
 .../src/org/apache/cordova/CordovaWebView.java     |    2 +-
 .../org/apache/cordova/NativeToJsMessageQueue.java |  139 ++++++++-------
 2 files changed, 79 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/e239fd97/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebView.java 
b/framework/src/org/apache/cordova/CordovaWebView.java
index 131f754..7e78de8 100755
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@ -198,7 +198,7 @@ public class CordovaWebView extends WebView {
     @SuppressWarnings("deprecation")
     @SuppressLint("NewApi")
     private void setup() {
-       jsMessageQueue = new NativeToJsMessageQueue(this);
+       jsMessageQueue = new NativeToJsMessageQueue(this, cordova);
        
         this.setInitialScale(0);
         this.setVerticalScrollBarEnabled(false);

http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/e239fd97/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/NativeToJsMessageQueue.java 
b/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
index 6abb970..e9f093a 100755
--- a/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
+++ b/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
@@ -20,6 +20,8 @@ package org.apache.cordova;
 
 import java.util.LinkedList;
 
+import org.apache.cordova.api.CordovaInterface;
+
 import android.util.Log;
 
 /**
@@ -32,26 +34,32 @@ public class NativeToJsMessageQueue {
     private static final int DEFAULT_BRIDGE_MODE = 1;
     
     /**
-     * The list of JavaScript statements to be sent to JavaScript.
-     */
-    private LinkedList<String> queue = new LinkedList<String>();
-
-    /**
      * The index into registeredListeners to treat as active. 
      */
     private int activeListenerIndex;
     
     /**
+     * The list of JavaScript statements to be sent to JavaScript.
+     */
+    private final LinkedList<String> queue = new LinkedList<String>();
+
+    /**
      * The array of listeners that can be used to send messages to JS.
      */
-    private BridgeMode[] registeredListeners;    
+    private final BridgeMode[] registeredListeners;    
+    
+    private final CordovaInterface cordova;
+    private final CordovaWebView webView;
         
-    public NativeToJsMessageQueue(CordovaWebView webView) {
-       registeredListeners = new BridgeMode[3];
-       registeredListeners[0] = null;
-       registeredListeners[1] = new CallbackBridgeMode(webView);
-       registeredListeners[2] = new LoadUrlBridgeMode(webView);
-       reset();
+    public NativeToJsMessageQueue(CordovaWebView webView, CordovaInterface 
cordova) {
+        this.cordova = cordova;
+        this.webView = webView;
+        registeredListeners = new BridgeMode[4];
+        registeredListeners[0] = null;
+        registeredListeners[1] = new CallbackBridgeMode();
+        registeredListeners[2] = new LoadUrlBridgeMode();
+        registeredListeners[3] = new OnlineEventsBridgeMode();
+        reset();
 //        POLLING: 0,
 //        HANGING_GET: 1,
 //        LOAD_URL: 2,
@@ -63,30 +71,30 @@ public class NativeToJsMessageQueue {
      * Changes the bridge mode.
      */
     public void setBridgeMode(int value) {
-       if (value < 0 || value >= registeredListeners.length) {
-               Log.d(LOG_TAG, "Invalid NativeToJsBridgeMode: " + value);
-       } else {
-               if (value != activeListenerIndex) {
-                       Log.d(LOG_TAG, "Set native->JS mode to " + value);
-                       synchronized (this) {
-                           activeListenerIndex = value;
-                           BridgeMode activeListener = 
registeredListeners[value];
-                           if (!queue.isEmpty() && activeListener != null) {
-                               
activeListener.onNativeToJsMessageAvailable(this);
-                           }
-                       }
-               }
-       }
+        if (value < 0 || value >= registeredListeners.length) {
+            Log.d(LOG_TAG, "Invalid NativeToJsBridgeMode: " + value);
+        } else {
+            if (value != activeListenerIndex) {
+                Log.d(LOG_TAG, "Set native->JS mode to " + value);
+                synchronized (this) {
+                    activeListenerIndex = value;
+                    BridgeMode activeListener = registeredListeners[value];
+                    if (!queue.isEmpty() && activeListener != null) {
+                        activeListener.onNativeToJsMessageAvailable();
+                    }
+                }
+            }
+        }
     }
     
-       /**
-        * Clears all messages and resets to the default bridge mode.
+    /**
+     * Clears all messages and resets to the default bridge mode.
      */
     public void reset() {
-       synchronized (this) {
-               queue.clear();
-               setBridgeMode(DEFAULT_BRIDGE_MODE);
-       }
+        synchronized (this) {
+            queue.clear();
+            setBridgeMode(DEFAULT_BRIDGE_MODE);
+        }
     }
 
     /**
@@ -116,17 +124,17 @@ public class NativeToJsMessageQueue {
             // Wrap each statement in a try/finally so that if one throws it 
does 
             // not affect the next.
             int i = 0;
-                       for (String message : queue) {
-               if (++i == length) {
-                       sb.append(message);
-               } else {
-                       sb.append("try{")
-                         .append(message)
-                         .append("}finally{");
-               }
+            for (String message : queue) {
+                if (++i == length) {
+                    sb.append(message);
+                } else {
+                    sb.append("try{")
+                      .append(message)
+                      .append("}finally{");
+                }
             }
             for ( i = 1; i < length; ++i) {
-               sb.append('}');
+                sb.append('}');
             }
             queue.clear();
             return sb.toString();
@@ -140,37 +148,46 @@ public class NativeToJsMessageQueue {
         synchronized (this) {
             queue.add(statement);
             if (registeredListeners[activeListenerIndex] != null) {
-               
registeredListeners[activeListenerIndex].onNativeToJsMessageAvailable(this);
+                
registeredListeners[activeListenerIndex].onNativeToJsMessageAvailable();
             }
         }
     }
 
     private interface BridgeMode {
-               void onNativeToJsMessageAvailable(NativeToJsMessageQueue queue);
-       }
-       
+        void onNativeToJsMessageAvailable();
+    }
+    
     /** Uses a local server to send messages to JS via an XHR */
-    private static class CallbackBridgeMode implements BridgeMode {
-       private CordovaWebView webView;
-               public CallbackBridgeMode(CordovaWebView webView) {
-               this.webView = webView;
-       }
-       public void onNativeToJsMessageAvailable(NativeToJsMessageQueue queue) {
-               if (webView.callbackServer != null) {
-                       
webView.callbackServer.onNativeToJsMessageAvailable(queue);
-               }
+    private class CallbackBridgeMode implements BridgeMode {
+        public void onNativeToJsMessageAvailable() {
+            if (webView.callbackServer != null) {
+                
webView.callbackServer.onNativeToJsMessageAvailable(NativeToJsMessageQueue.this);
+            }
         }
     }
     
     /** Uses webView.loadUrl("javascript:") to execute messages. */
-    public static class LoadUrlBridgeMode implements BridgeMode {
-               private CordovaWebView webView;
-               public LoadUrlBridgeMode(CordovaWebView webView) {
-               this.webView = webView;
-       }
-       public void onNativeToJsMessageAvailable(NativeToJsMessageQueue queue) {
-               webView.loadUrlNow("javascript:" + queue.popAll());
+    public class LoadUrlBridgeMode implements BridgeMode {
+        public void onNativeToJsMessageAvailable() {
+            webView.loadUrlNow("javascript:" + popAll());
         }
     }
 
+    /** Uses online/offline events to tell the JS when to poll for messages. */
+    public class OnlineEventsBridgeMode implements BridgeMode {
+        boolean online = true;
+        final Runnable runnable = new Runnable() {
+            @Override
+            public void run() {
+                if (!queue.isEmpty()) {
+                    online = !online;
+                    webView.setNetworkAvailable(online);
+                }
+            }                
+        };
+        
+        public void onNativeToJsMessageAvailable() {
+            cordova.getActivity().runOnUiThread(runnable);
+        }
+    }
 }

Reply via email to