1 /*
2  * libjingle
3  * Copyright 2011, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <string>
29 
30 #include "talk/app/webrtc/mediastream.h"
31 #include "talk/app/webrtc/mediastreamhandler.h"
32 #include "talk/app/webrtc/streamcollectionimpl.h"
33 #include "talk/app/webrtc/videotrack.h"
34 #include "talk/base/thread.h"
35 #include "talk/base/gunit.h"
36 #include "testing/base/public/gmock.h"
37 
38 using ::testing::Exactly;
39 
40 static const char kStreamLabel1[] = "local_stream_1";
41 static const char kVideoDeviceName[] = "dummy_video_cam_1";
42 
43 namespace webrtc {
44 
45 // Helper class to test MediaStreamHandler.
46 class MockMediaProvier : public MediaProviderInterface {
47  public:
48   MOCK_METHOD1(SetCaptureDevice, bool(const std::string& name));
49   MOCK_METHOD1(SetLocalRenderer, void(const std::string& name));
50   MOCK_METHOD1(SetRemoteRenderer, void(const std::string& name));
51 
SetCaptureDevice(const std::string & name,cricket::VideoCapturer * camera)52   virtual bool SetCaptureDevice(const std::string& name,
53                                 cricket::VideoCapturer* camera) {
54     return SetCaptureDevice(name);
55   }
SetLocalRenderer(const std::string & name,cricket::VideoRenderer * renderer)56   virtual void SetLocalRenderer(const std::string& name,
57                                 cricket::VideoRenderer* renderer) {
58     SetLocalRenderer(name);
59   }
60 
SetRemoteRenderer(const std::string & name,cricket::VideoRenderer * renderer)61   virtual void SetRemoteRenderer(const std::string& name,
62                                  cricket::VideoRenderer* renderer) {
63     SetRemoteRenderer(name);
64   }
~MockMediaProvier()65   ~MockMediaProvier() {}
66 };
67 
TEST(MediaStreamHandlerTest,LocalStreams)68 TEST(MediaStreamHandlerTest, LocalStreams) {
69   // Create a local stream.
70   std::string label(kStreamLabel1);
71   talk_base::scoped_refptr<LocalMediaStreamInterface> stream(
72       MediaStream::Create(label));
73   talk_base::scoped_refptr<LocalVideoTrackInterface>
74       video_track(VideoTrack::CreateLocal(kVideoDeviceName, NULL));
75   EXPECT_TRUE(stream->AddTrack(video_track));
76   talk_base::scoped_refptr<VideoRendererWrapperInterface> renderer(
77       CreateVideoRenderer(NULL));
78   video_track->SetRenderer(renderer);
79 
80   MockMediaProvier provider;
81   MediaStreamHandlers handlers(&provider);
82 
83   talk_base::scoped_refptr<StreamCollection> collection(
84       StreamCollection::Create());
85   collection->AddStream(stream);
86 
87   EXPECT_CALL(provider, SetLocalRenderer(kVideoDeviceName))
88       .Times(Exactly(2));  // SetLocalRender will also be called from dtor of
89                            // LocalVideoTrackHandler
90   EXPECT_CALL(provider, SetCaptureDevice(kVideoDeviceName))
91       .Times(Exactly(2)); // SetCaptureDevice will also be called from dtor of
92                           // LocalVideoTrackHandler
93   handlers.CommitLocalStreams(collection);
94 
95   video_track->set_state(MediaStreamTrackInterface::kLive);
96   // Process posted messages.
97   talk_base::Thread::Current()->ProcessMessages(1);
98 
99   collection->RemoveStream(stream);
100   handlers.CommitLocalStreams(collection);
101 
102   video_track->set_state(MediaStreamTrackInterface::kEnded);
103   // Process posted messages.
104   talk_base::Thread::Current()->ProcessMessages(1);
105 }
106 
TEST(MediaStreamHandlerTest,RemoteStreams)107 TEST(MediaStreamHandlerTest, RemoteStreams) {
108   // Create a local stream. We use local stream in this test as well because
109   // they are easier to create.
110   // LocalMediaStreams inherit from MediaStreams.
111   std::string label(kStreamLabel1);
112   talk_base::scoped_refptr<LocalMediaStreamInterface> stream(
113       MediaStream::Create(label));
114   talk_base::scoped_refptr<LocalVideoTrackInterface>
115       video_track(VideoTrack::CreateLocal(kVideoDeviceName, NULL));
116   EXPECT_TRUE(stream->AddTrack(video_track));
117 
118   MockMediaProvier provider;
119   MediaStreamHandlers handlers(&provider);
120 
121   handlers.AddRemoteStream(stream);
122 
123   EXPECT_CALL(provider, SetRemoteRenderer(kVideoDeviceName))
124       .Times(Exactly(3));  // SetRemoteRenderer is also called from dtor of
125                            // RemoteVideoTrackHandler.
126 
127   // Set the renderer once.
128   talk_base::scoped_refptr<VideoRendererWrapperInterface> renderer(
129       CreateVideoRenderer(NULL));
130     video_track->SetRenderer(renderer);
131   talk_base::Thread::Current()->ProcessMessages(1);
132 
133   // Change the already set renderer.
134   renderer = CreateVideoRenderer(NULL);
135     video_track->SetRenderer(renderer);
136   talk_base::Thread::Current()->ProcessMessages(1);
137 
138   handlers.RemoveRemoteStream(stream);
139 
140   // Change the renderer after the stream have been removed from handler.
141   // This should not trigger a call to SetRemoteRenderer.
142   renderer = CreateVideoRenderer(NULL);
143     video_track->SetRenderer(renderer);
144   // Process posted messages.
145   talk_base::Thread::Current()->ProcessMessages(1);
146 }
147 
148 }  // namespace webrtc
149