3
* Copyright 2011, Google Inc.
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
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.
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.
30
#include "talk/app/webrtc/mediastreamproxy.h"
31
#include "talk/app/webrtc/mediastreamtrackproxy.h"
32
#include "talk/base/refcount.h"
33
#include "talk/base/scoped_ptr.h"
34
#include "talk/base/thread.h"
35
#include "talk/base/gunit.h"
36
#include "testing/base/public/gmock.h"
38
static const char kStreamLabel1[] = "local_stream_1";
39
static const char kVideoTrackLabel[] = "dummy_video_cam_1";
40
static const char kAudioTrackLabel[] = "dummy_microphone_1";
42
using talk_base::scoped_refptr;
43
using ::testing::Exactly;
47
class ReadyStateMessageData : public talk_base::MessageData {
49
ReadyStateMessageData(
50
webrtc::MediaStreamInterface* stream,
51
webrtc::MediaStreamInterface::ReadyState new_state)
53
ready_state_(new_state) {
56
scoped_refptr<webrtc::MediaStreamInterface> stream_;
57
webrtc::MediaStreamInterface::ReadyState ready_state_;
60
class TrackStateMessageData : public talk_base::MessageData {
62
TrackStateMessageData(
63
webrtc::MediaStreamTrackInterface* track,
64
webrtc::MediaStreamTrackInterface::TrackState state)
69
scoped_refptr<webrtc::MediaStreamTrackInterface> track_;
70
webrtc::MediaStreamTrackInterface::TrackState state_;
73
} // namespace anonymous
77
// Helper class to test Observer.
78
class MockObserver : public ObserverInterface {
80
explicit MockObserver(talk_base::Thread* signaling_thread)
81
: signaling_thread_(signaling_thread) {
84
MOCK_METHOD0(DoOnChanged, void());
85
virtual void OnChanged() {
86
ASSERT_TRUE(talk_base::Thread::Current() == signaling_thread_);
90
talk_base::Thread* signaling_thread_;
93
class MockMediaStream: public LocalMediaStreamInterface {
95
MockMediaStream(const std::string& label, talk_base::Thread* signaling_thread)
96
: stream_impl_(MediaStream::Create(label)),
97
signaling_thread_(signaling_thread) {
99
virtual void RegisterObserver(webrtc::ObserverInterface* observer) {
100
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
101
stream_impl_->RegisterObserver(observer);
103
virtual void UnregisterObserver(webrtc::ObserverInterface* observer) {
104
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
105
stream_impl_->UnregisterObserver(observer);
107
virtual std::string label() const {
108
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
109
return stream_impl_->label();
111
virtual AudioTracks* audio_tracks() {
112
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
113
return stream_impl_->audio_tracks();
115
virtual VideoTracks* video_tracks() {
116
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
117
return stream_impl_->video_tracks();
119
virtual ReadyState ready_state() const {
120
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
121
return stream_impl_->ready_state();
123
virtual void set_ready_state(ReadyState state) {
124
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
125
return stream_impl_->set_ready_state(state);
127
virtual bool AddTrack(AudioTrackInterface* audio_track) {
128
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
129
return stream_impl_->AddTrack(audio_track);
131
virtual bool AddTrack(VideoTrackInterface* video_track) {
132
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
133
return stream_impl_->AddTrack(video_track);
137
scoped_refptr<MediaStream> stream_impl_;
138
talk_base::Thread* signaling_thread_;
142
class MockMediaStreamTrack: public T {
144
MockMediaStreamTrack(T* implementation,
145
talk_base::Thread* signaling_thread)
146
: track_impl_(implementation),
147
signaling_thread_(signaling_thread) {
149
virtual void RegisterObserver(webrtc::ObserverInterface* observer) {
150
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
151
track_impl_->RegisterObserver(observer);
153
virtual void UnregisterObserver(webrtc::ObserverInterface* observer) {
154
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
155
track_impl_->UnregisterObserver(observer);
157
virtual std::string kind() const {
158
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
159
return track_impl_->kind();
161
virtual std::string label() const {
162
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
163
return track_impl_->label();
165
virtual bool enabled() const {
166
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
167
return track_impl_->enabled();
169
virtual MediaStreamTrackInterface::TrackState state() const {
170
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
171
return track_impl_->state();
173
virtual bool set_enabled(bool enabled) {
174
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
175
return track_impl_->set_enabled(enabled);
177
virtual bool set_state(webrtc::MediaStreamTrackInterface::TrackState state) {
178
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
179
return track_impl_->set_state(state);
183
scoped_refptr<T> track_impl_;
184
talk_base::Thread* signaling_thread_;
187
class MockLocalVideoTrack
188
: public MockMediaStreamTrack<LocalVideoTrackInterface> {
190
MockLocalVideoTrack(LocalVideoTrackInterface* implementation,
191
talk_base::Thread* signaling_thread)
192
: MockMediaStreamTrack<LocalVideoTrackInterface>(implementation,
195
virtual void SetRenderer(webrtc::VideoRendererWrapperInterface* renderer) {
196
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
197
track_impl_->SetRenderer(renderer);
199
virtual VideoRendererWrapperInterface* GetRenderer() {
200
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
201
return track_impl_->GetRenderer();
203
virtual cricket::VideoCapturer* GetVideoCapture() {
204
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
205
return track_impl_->GetVideoCapture();
209
class MockLocalAudioTrack
210
: public MockMediaStreamTrack<LocalAudioTrackInterface> {
212
MockLocalAudioTrack(LocalAudioTrackInterface* implementation,
213
talk_base::Thread* signaling_thread)
214
: MockMediaStreamTrack<LocalAudioTrackInterface>(implementation,
218
virtual AudioDeviceModule* GetAudioDevice() {
219
EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
220
return track_impl_->GetAudioDevice();
224
class MediaStreamTest: public testing::Test,
225
public talk_base::MessageHandler {
227
virtual void SetUp() {
228
signaling_thread_ .reset(new talk_base::Thread());
229
ASSERT_TRUE(signaling_thread_->Start());
231
std::string label(kStreamLabel1);
232
// Create a stream proxy object that uses our mocked
233
// version of a LocalMediaStream.
234
scoped_refptr<MockMediaStream> mock_stream(
235
new talk_base::RefCountedObject<MockMediaStream>(label,
236
signaling_thread_.get()));
237
stream_ = MediaStreamProxy::Create(label, signaling_thread_.get(),
239
ASSERT_TRUE(stream_.get() != NULL);
240
EXPECT_EQ(label, stream_->label());
241
EXPECT_EQ(MediaStreamInterface::kInitializing, stream_->ready_state());
243
// Create a video track proxy object that uses our mocked
244
// version of a LocalVideoTrack
245
scoped_refptr<VideoTrack> video_track_impl(
246
VideoTrack::CreateLocal(kVideoTrackLabel, NULL));
247
scoped_refptr<MockLocalVideoTrack> mock_videotrack(
248
new talk_base::RefCountedObject<MockLocalVideoTrack>(video_track_impl,
249
signaling_thread_.get()));
250
video_track_ = VideoTrackProxy::CreateLocal(mock_videotrack,
251
signaling_thread_.get());
253
ASSERT_TRUE(video_track_.get() != NULL);
254
EXPECT_EQ(MediaStreamTrackInterface::kInitializing, video_track_->state());
256
// Create an audio track proxy object that uses our mocked
257
// version of a LocalAudioTrack
258
scoped_refptr<AudioTrack> audio_track_impl(
259
AudioTrack::CreateLocal(kAudioTrackLabel, NULL));
260
scoped_refptr<MockLocalAudioTrack> mock_audiotrack(
261
new talk_base::RefCountedObject<MockLocalAudioTrack>(audio_track_impl,
262
signaling_thread_.get()));
263
audio_track_ = AudioTrackProxy::CreateLocal(mock_audiotrack,
264
signaling_thread_.get());
266
ASSERT_TRUE(audio_track_.get() != NULL);
267
EXPECT_EQ(MediaStreamTrackInterface::kInitializing, audio_track_->state());
275
// Set the ready state on the signaling thread.
276
// State can only be changed on the signaling thread.
277
void SetReadyState(MediaStreamInterface* stream,
278
MediaStreamInterface::ReadyState new_state) {
279
ReadyStateMessageData state(stream, new_state);
280
signaling_thread_->Send(this, MSG_SET_READYSTATE, &state);
283
// Set the track state on the signaling thread.
284
// State can only be changed on the signaling thread.
285
void SetTrackState(MediaStreamTrackInterface* track,
286
MediaStreamTrackInterface::TrackState new_state) {
287
TrackStateMessageData state(track, new_state);
288
signaling_thread_->Send(this, MSG_SET_TRACKSTATE, &state);
291
talk_base::scoped_ptr<talk_base::Thread> signaling_thread_;
292
scoped_refptr<LocalMediaStreamInterface> stream_;
293
scoped_refptr<LocalVideoTrackInterface> video_track_;
294
scoped_refptr<LocalAudioTrackInterface> audio_track_;
297
// Implements talk_base::MessageHandler.
298
virtual void OnMessage(talk_base::Message* msg) {
299
switch (msg->message_id) {
300
case MSG_SET_READYSTATE: {
301
ReadyStateMessageData* state =
302
static_cast<ReadyStateMessageData*>(msg->pdata);
303
state->stream_->set_ready_state(state->ready_state_);
306
case MSG_SET_TRACKSTATE: {
307
TrackStateMessageData* state =
308
static_cast<TrackStateMessageData*>(msg->pdata);
309
state->track_->set_state(state->state_);
318
TEST_F(MediaStreamTest, CreateLocalStream) {
319
EXPECT_TRUE(stream_->AddTrack(video_track_));
320
EXPECT_TRUE(stream_->AddTrack(audio_track_));
322
ASSERT_EQ(1u, stream_->video_tracks()->count());
323
ASSERT_EQ(1u, stream_->audio_tracks()->count());
325
// Verify the video track.
326
scoped_refptr<webrtc::MediaStreamTrackInterface> track(
327
stream_->video_tracks()->at(0));
328
EXPECT_EQ(0, track->label().compare(kVideoTrackLabel));
329
EXPECT_TRUE(track->enabled());
331
// Verify the audio track.
332
track = stream_->audio_tracks()->at(0);
333
EXPECT_EQ(0, track->label().compare(kAudioTrackLabel));
334
EXPECT_TRUE(track->enabled());
337
TEST_F(MediaStreamTest, ChangeStreamState) {
338
MockObserver observer(signaling_thread_.get());
339
stream_->RegisterObserver(&observer);
341
EXPECT_CALL(observer, DoOnChanged())
343
SetReadyState(stream_, MediaStreamInterface::kLive);
345
EXPECT_EQ(MediaStreamInterface::kLive, stream_->ready_state());
346
// It should not be possible to add
347
// streams when the state has changed to live.
348
EXPECT_FALSE(stream_->AddTrack(audio_track_));
349
EXPECT_EQ(0u, stream_->audio_tracks()->count());
352
TEST_F(MediaStreamTest, ChangeVideoTrack) {
353
MockObserver observer(signaling_thread_.get());
354
video_track_->RegisterObserver(&observer);
356
EXPECT_CALL(observer, DoOnChanged())
358
video_track_->set_enabled(false);
359
EXPECT_FALSE(video_track_->state());
361
EXPECT_CALL(observer, DoOnChanged())
363
SetTrackState(video_track_, MediaStreamTrackInterface::kLive);
364
EXPECT_EQ(MediaStreamTrackInterface::kLive, video_track_->state());
366
EXPECT_CALL(observer, DoOnChanged())
368
scoped_refptr<VideoRendererWrapperInterface> renderer(
369
CreateVideoRenderer(NULL));
370
video_track_->SetRenderer(renderer.get());
371
EXPECT_TRUE(renderer.get() == video_track_->GetRenderer());
374
TEST_F(MediaStreamTest, ChangeAudioTrack) {
375
MockObserver observer(signaling_thread_.get());
376
audio_track_->RegisterObserver(&observer);
378
EXPECT_CALL(observer, DoOnChanged())
380
audio_track_->set_enabled(false);
381
EXPECT_FALSE(audio_track_->enabled());
383
EXPECT_CALL(observer, DoOnChanged())
385
SetTrackState(audio_track_, MediaStreamTrackInterface::kLive);
386
EXPECT_EQ(MediaStreamTrackInterface::kLive, audio_track_->state());
389
} // namespace webrtc