Adding webrtc_video_streaming test
This test is streaming video and audio between two bots using webrtc js api.

R=andresp@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7261 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/tools/rtcbot/bot/browser/bot.js b/webrtc/tools/rtcbot/bot/browser/bot.js
index 130d006..8839802 100644
--- a/webrtc/tools/rtcbot/bot/browser/bot.js
+++ b/webrtc/tools/rtcbot/bot/browser/bot.js
@@ -5,23 +5,80 @@
 // tree. An additional intellectual property rights grant can be found
 // in the file PATENTS.  All contributing project authors may
 // be found in the AUTHORS file in the root of the source tree.
+//
+var localStreams = [];
+var remoteStreams = [];
 
-var botExposedApi = {
-  ping: function (callback) {
-    callback("pong");
-  },
+function ping(callback) {
+  callback("pong");
+}
 
-  createPeerConnection: function (doneCallback) {
-    console.log("Creating peer connection");
-    var pc = new webkitRTCPeerConnection(null);
-    var obj = {};
-    expose(obj, pc, "close");
-    expose(obj, pc, "createOffer");
-    expose(obj, pc, "createAnswer");
-    expose(obj, pc, "setRemoteDescription", { 0: RTCSessionDescription });
-    expose(obj, pc, "setLocalDescription", { 0: RTCSessionDescription });
-    doneCallback(obj);
-  },
+function getUserMedia(constraints, onSuccessCallback, onFailCallback){
+  console.log("Getting user media.");
+  navigator.webkitGetUserMedia(constraints,
+      onSuccessCallbackWraper, onFailCallback);
+
+  function onSuccessCallbackWraper(stream) {
+    console.log("GetUserMedia success.");
+    localStreams[stream.id] = stream;
+    onSuccessCallback(stream);
+  }
+}
+
+function createPeerConnection(doneCallback, failCallback) {
+  console.log("Creating peer connection");
+  var obj = {};
+  var pc = new webkitRTCPeerConnection(null);
+
+  expose(obj, pc, "close");
+  expose(obj, pc, "createOffer");
+  expose(obj, pc, "createAnswer");
+  expose(obj, pc, "addEventListener");
+  expose(obj, pc, "addIceCandidate", { 0: RTCIceCandidate});
+  expose(obj, pc, "setRemoteDescription", { 0: RTCSessionDescription });
+  expose(obj, pc, "setLocalDescription", { 0: RTCSessionDescription });
+
+  obj.addStream = function(stream) {
+    console.log("Adding local stream.");
+    var tempStream = localStreams[stream.id];
+    if (!tempStream) {
+      console.log("Undefined stream!");
+      return;
+    }
+    pc.addStream(tempStream);
+  };
+
+  pc.addEventListener('addstream', function(event) {
+    remoteStreams[event.stream.id] = event.stream;
+  });
+
+  doneCallback(obj);
+}
+
+function showStream(streamId, autoplay, muted) {
+  var stream = getStreamFromIdentifier_(streamId);
+  var video = document.createElement('video');
+  video.autoplay = autoplay;
+  video.muted = muted;
+  document.body.appendChild(video);
+  video.src = URL.createObjectURL(stream);
+  console.log("Stream " + stream.id + " attached to video element");
 };
 
-connectToServer(botExposedApi);
+function getStreamFromIdentifier_(id) {
+  var tempStream = localStreams[id];
+  if (tempStream)
+    return tempStream;
+  tempStream = remoteStreams[id];
+  if (tempStream)
+    return tempStream;
+  console.log(id + " is not id for stream.");
+  return null;
+}
+
+connectToServer({
+  ping: ping,
+  getUserMedia: getUserMedia,
+  createPeerConnection: createPeerConnection,
+  showStream: showStream,
+});
diff --git a/webrtc/tools/rtcbot/test.js b/webrtc/tools/rtcbot/test.js
index c1db4fc..f731773 100644
--- a/webrtc/tools/rtcbot/test.js
+++ b/webrtc/tools/rtcbot/test.js
@@ -17,10 +17,10 @@
 var BotManager = require('./botmanager.js');
 
 function Test(botType) {
-  // Make the test fail if not completed in 3 seconds.
+  // TODO(houssainy) set the time out.
   this.timeout_ = setTimeout(
       this.fail.bind(this, "Test timeout!"),
-      5000);
+      10000);
   this.botType_ = botType;
 }
 
@@ -82,4 +82,4 @@
   script.runInNewContext({ test: new Test(process.argv[2]) });
 }
 
-runTest("./test/simple_offer_answer.js");
+runTest("./test/webrtc_video_streaming.js");
diff --git a/webrtc/tools/rtcbot/test/webrtc_video_streaming.js b/webrtc/tools/rtcbot/test/webrtc_video_streaming.js
new file mode 100644
index 0000000..a907976
--- /dev/null
+++ b/webrtc/tools/rtcbot/test/webrtc_video_streaming.js
@@ -0,0 +1,94 @@
+// Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+//
+// A unidirectional video and audio flowing test from bot 1 to bot 2.
+//
+// Note: the source of the video and audio stream is getUserMedia().
+//
+// TODO(houssainy): get a condition to terminate the test.
+//
+function testVideoStreaming(bot1, bot2) {
+  var pc1 = null;
+  var pc2 = null;
+
+  test.wait([
+      createPeerConnection.bind(bot1),
+      createPeerConnection.bind(bot2) ],
+    onPeerConnectionCreated);
+
+  function createPeerConnection(done) {
+    this.createPeerConnection(done, test.fail);
+  }
+
+  function onPeerConnectionCreated(peer1, peer2) {
+    test.log("RTC Peers created.");
+    pc1 = peer1;
+    pc2 = peer2;
+    pc1.addEventListener('addstream', test.fail);
+    pc2.addEventListener('addstream', onAddStream);
+    pc1.addEventListener('icecandidate', onIceCandidate.bind(pc2));
+    pc2.addEventListener('icecandidate', onIceCandidate.bind(pc1));
+
+    bot1.getUserMedia({video:true, audio:true}, onUserMediaSuccess, test.fail);
+
+    function onUserMediaSuccess(stream) {
+      test.log("User has granted access to local media.");
+      pc1.addStream(stream);
+      bot1.showStream(stream.id, true, true);
+
+      createOfferAndAnswer();
+    }
+  }
+
+  function onAddStream(event) {
+    test.log("On Add stream.");
+    bot2.showStream(event.stream.id, true, false);
+  }
+
+  function onIceCandidate(event) {
+    if(event.candidate){
+      test.log(event.candidate.candidate);
+      this.addIceCandidate(event.candidate,
+         onAddIceCandidateSuccess, test.fail);
+    };
+
+    function onAddIceCandidateSuccess() {
+      test.log("Candidate added successfully");
+    };
+  }
+
+  function createOfferAndAnswer() {
+    test.log("Creating offer.");
+    pc1.createOffer(gotOffer, test.fail);
+
+    function gotOffer(offer) {
+      test.log("Got offer");
+      pc1.setLocalDescription(offer, onSetSessionDescriptionSuccess, test.fail);
+      pc2.setRemoteDescription(offer, onSetSessionDescriptionSuccess,
+          test.fail);
+      test.log("Creating answer");
+      pc2.createAnswer(gotAnswer, test.fail);
+    }
+
+    function gotAnswer(answer) {
+      test.log("Got answer");
+      pc2.setLocalDescription(answer, onSetSessionDescriptionSuccess,
+          test.fail);
+      pc1.setRemoteDescription(answer, onSetSessionDescriptionSuccess,
+          test.fail);
+    }
+
+    function onSetSessionDescriptionSuccess() {
+      test.log("Set session description success.");
+    }
+  }
+}
+
+test.wait( [ test.spawnBot.bind(test, "alice"),
+             test.spawnBot.bind(test, "bob") ],
+          testVideoStreaming);