AppRTCDemo(iOS): remote-video reliability fixes

Previously GAE Channel callbacks would be handled by JS string-encoding the
payload into a URL.  Unfortunately this is limited to the (undocumented,
silently problematic) maximum URL length UIWebView supports.  Replaced this
scheme by a notification from JS to ObjC and a getter from ObjC to JS (which
happens out-of-line to avoid worrying about UIWebView's re-entrancy, or lack
thereof).  Part of this change also moved from a combination of: JSON,
URL-escaping, and ad-hoc :-separated values to simply JSON.

Also incidentally:
- Removed outdated TODO about onRenegotiationNeeded, which is unneeded
- Move handling of PeerConnection callbacks to the main queue to avoid having
  to think about concurrency too hard.
- Replaced a bunch of NSOrderedSame with isEqualToString for clearer code and
  not having to worry about the fact that [nil compare:@"foo"]==NSOrderedSame
  is always true (yay ObjC!).
- Auto-scroll messages view.

BUG=3117
R=noahric@google.com

Review URL: https://webrtc-codereview.appspot.com/10899006

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5814 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/examples/ios/AppRTCDemo/ios_channel.html b/talk/examples/ios/AppRTCDemo/ios_channel.html
index a55b8f4..86846dd 100644
--- a/talk/examples/ios/AppRTCDemo/ios_channel.html
+++ b/talk/examples/ios/AppRTCDemo/ios_channel.html
@@ -6,10 +6,11 @@
   Helper HTML that redirects Google AppEngine's Channel API to Objective C.
   This is done by hosting this page in an iOS application.  The hosting
   class creates a UIWebView control and implements the UIWebViewDelegate
-  protocol.  Then when there is a channel message, it is encoded in an IFRAME.
-  That IFRAME is added to the DOM which triggers a navigation event
-  |shouldStartLoadWithRequest| in Objective C which can then be routed in the
-  application as desired.
+  protocol.  Then when there is a channel message it is queued in JS,
+  and an IFRAME is added to the DOM, triggering a navigation event
+  |shouldStartLoadWithRequest| in Objective C which can then fetch the
+  message using |popQueuedMessage|.  This queuing is necessary to avoid URL
+  length limits in UIWebView (which are undocumented).
   -->
   <body onbeforeunload="closeSocket()" onload="openSocket()">
     <script type="text/javascript">
@@ -38,6 +39,10 @@
 
       var channel = null;
       var socket = null;
+      // In-order queue of messages to be delivered to ObjectiveC.
+      // Each is a JSON.stringify()'d dictionary containing a 'type'
+      // field and optionally a 'payload'.
+      var messageQueue = [];
 
       function openSocket() {
         if (!QueryString.token || !QueryString.token.match(/^[A-z0-9_-]+$/)) {
@@ -52,17 +57,13 @@
             sendMessageToObjC("onopen");
           },
           'onmessage': function(msg) {
-            sendMessageToObjC("onmessage:" +
-                              encodeURIComponent(JSON.stringify(msg.data)));
+            sendMessageToObjC("onmessage", msg);
           },
           'onclose': function() {
             sendMessageToObjC("onclose");
           },
           'onerror': function(err) {
-            sendMessageToObjC("onerror:" +
-                              encodeURIComponent(JSON.stringify(err.code)) +
-                              ":message:" +
-                              encodeURIComponent(JSON.stringify(err.description)));
+            sendMessageToObjC("onerror", err);
           }
         });
       }
@@ -73,9 +74,10 @@
 
       // Add an IFRAME to the DOM to trigger a navigation event.  Then remove
       // it as it is no longer needed.  Only one event is generated.
-      function sendMessageToObjC(message) {
+      function sendMessageToObjC(type, payload) {
+        messageQueue.push(JSON.stringify({'type': type, 'payload': payload}));
         var iframe = document.createElement("IFRAME");
-        iframe.setAttribute("src", "js-frame:" + message);
+        iframe.setAttribute("src", "js-frame:");
         // For some reason we need to set a non-empty size for the iOS6
         // simulator...
         iframe.setAttribute("height", "1px");
@@ -83,6 +85,10 @@
         document.documentElement.appendChild(iframe);
         iframe.parentNode.removeChild(iframe);
       }
+
+      function popQueuedMessage() {
+        return messageQueue.shift();
+      }
     </script>
   </body>
 </html>