// 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 video conference between 3 bots streaming video and audio between // each other. // The test succeeds after establishing the call between the three // devices. // // Note: the source of the video and audio stream is getUserMedia(). function testTwoWayVideoStreaming(test, bot1, bot2, bot3) { var answersCount = 0; var statsCollector; test.wait([ createBotPeerConnectionsWithLocalStream.bind(bot1), createBotPeerConnectionsWithLocalStream.bind(bot2), createBotPeerConnectionsWithLocalStream.bind(bot3)], onPeerConnectionCreated); // done() callback is called with list of peers as argument. function createBotPeerConnectionsWithLocalStream(done) { var peerConnections = []; this.getUserMedia({video:true, audio:true}, onUserMediaSuccess.bind(this), test.fail); function onUserMediaSuccess(stream) { test.log("User has granted access to local media."); this.showStream(stream.id, true, true); test.createTurnConfig(onTurnConfig.bind(this), test.fail); function onTurnConfig(config) { this.createPeerConnection(config, addStream.bind(this), test.fail); this.createPeerConnection(config, addStream.bind(this), test.fail); } function addStream(pc) { pc.addStream(stream); pc.addEventListener('addstream', onAddStream.bind(this)); peerConnections.push(pc); if(peerConnections.length == 2) done(peerConnections); } } } function onPeerConnectionCreated(peerConnections1, peerConnections2, peerConnections3) { test.log("RTC Peers created."); // Bot1 and Bot2 establichCall(peerConnections1[0], peerConnections2[1]); // Bot2 and Bot3 establichCall(peerConnections2[0], peerConnections3[1]); // Bot3 and Bot1 establichCall(peerConnections3[0], peerConnections1[1]); } function establichCall(pc1, pc2) { pc1.addEventListener('icecandidate', onIceCandidate.bind(pc2)); pc2.addEventListener('icecandidate', onIceCandidate.bind(pc1)); createOfferAndAnswer(pc1, pc2); } function onAddStream(event) { test.log("On Add stream."); this.showStream(event.stream.id, true, false); } function onIceCandidate(event) { if(event.candidate) { this.addIceCandidate(event.candidate, onAddIceCandidateSuccess, test.fail); }; function onAddIceCandidateSuccess() { test.log("Candidate added successfully"); }; } function createOfferAndAnswer(pc1, pc2) { 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); answersCount++; if(answersCount == 3) { // SetTimeout used because creating the three answers will very fast // and test will success and the vm will be closed before establishing // the calls. setTimeout(function() { test.done(); }, 5000); } } function onSetSessionDescriptionSuccess() { test.log("Set session description success."); } } } registerBotTest('threeBotsVideoConference/android+android+chrome', testTwoWayVideoStreaming, ['android-chrome', 'android-chrome', 'chrome']); registerBotTest('threeBotsVideoConference/chrome-chrome-chrome', testTwoWayVideoStreaming, ['chrome', 'chrome', 'chrome']); registerBotTest('threeBotsVideoConference/android-android-android', testTwoWayVideoStreaming, ['android-chrome', 'android-chrome', 'android-chrome']);