Home | History | Annotate | Download | only in media
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/memory/scoped_ptr.h"
      6 #include "base/strings/utf_string_conversions.h"
      7 #include "content/renderer/media/media_stream_extra_data.h"
      8 #include "content/renderer/media/media_stream_impl.h"
      9 #include "content/renderer/media/mock_media_stream_dependency_factory.h"
     10 #include "content/renderer/media/mock_media_stream_dispatcher.h"
     11 #include "content/renderer/media/video_capture_impl_manager.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 #include "third_party/WebKit/public/platform/WebMediaStream.h"
     14 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
     15 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
     16 #include "third_party/WebKit/public/platform/WebString.h"
     17 #include "third_party/WebKit/public/platform/WebVector.h"
     18 
     19 namespace content {
     20 
     21 class MediaStreamImplUnderTest : public MediaStreamImpl {
     22  public:
     23   enum RequestState {
     24     REQUEST_NOT_STARTED,
     25     REQUEST_NOT_COMPLETE,
     26     REQUEST_SUCCEEDED,
     27     REQUEST_FAILED,
     28   };
     29 
     30   MediaStreamImplUnderTest(MediaStreamDispatcher* media_stream_dispatcher,
     31                            MediaStreamDependencyFactory* dependency_factory)
     32       : MediaStreamImpl(NULL, media_stream_dispatcher, dependency_factory),
     33         state_(REQUEST_NOT_STARTED) {
     34   }
     35 
     36   void RequestUserMedia() {
     37     WebKit::WebUserMediaRequest user_media_request;
     38     state_ = REQUEST_NOT_COMPLETE;
     39     requestUserMedia(user_media_request);
     40   }
     41 
     42   virtual void CompleteGetUserMediaRequest(
     43       const WebKit::WebMediaStream& stream,
     44       WebKit::WebUserMediaRequest* request_info,
     45       bool request_succeeded) OVERRIDE {
     46     last_generated_stream_ = stream;
     47     state_ = request_succeeded ? REQUEST_SUCCEEDED : REQUEST_FAILED;
     48   }
     49 
     50   virtual WebKit::WebMediaStream GetMediaStream(
     51       const GURL& url) OVERRIDE {
     52     return last_generated_stream_;
     53   }
     54 
     55   using MediaStreamImpl::OnLocalMediaStreamStop;
     56 
     57   const WebKit::WebMediaStream& last_generated_stream() {
     58     return last_generated_stream_;
     59   }
     60 
     61   RequestState request_state() const { return state_; }
     62 
     63  private:
     64   WebKit::WebMediaStream last_generated_stream_;
     65   RequestState state_;
     66 };
     67 
     68 class MediaStreamImplTest : public ::testing::Test {
     69  public:
     70   virtual void SetUp() {
     71     // Create our test object.
     72     ms_dispatcher_.reset(new MockMediaStreamDispatcher());
     73     dependency_factory_.reset(new MockMediaStreamDependencyFactory());
     74     ms_impl_.reset(new MediaStreamImplUnderTest(ms_dispatcher_.get(),
     75                                                 dependency_factory_.get()));
     76   }
     77 
     78   WebKit::WebMediaStream RequestLocalMediaStream() {
     79     ms_impl_->RequestUserMedia();
     80     FakeMediaStreamDispatcherComplete();
     81     ChangeVideoSourceStateToLive();
     82     ChangeAudioSourceStateToLive();
     83 
     84     EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_SUCCEEDED,
     85               ms_impl_->request_state());
     86 
     87     WebKit::WebMediaStream desc = ms_impl_->last_generated_stream();
     88     content::MediaStreamExtraData* extra_data =
     89         static_cast<content::MediaStreamExtraData*>(desc.extraData());
     90     if (!extra_data || !extra_data->stream().get()) {
     91       ADD_FAILURE();
     92       return desc;
     93     }
     94 
     95     EXPECT_EQ(1u, extra_data->stream()->GetAudioTracks().size());
     96     EXPECT_EQ(1u, extra_data->stream()->GetVideoTracks().size());
     97     EXPECT_NE(extra_data->stream()->GetAudioTracks()[0]->id(),
     98               extra_data->stream()->GetVideoTracks()[0]->id());
     99     return desc;
    100   }
    101 
    102   void FakeMediaStreamDispatcherComplete() {
    103     ms_impl_->OnStreamGenerated(ms_dispatcher_->request_id(),
    104                                 ms_dispatcher_->stream_label(),
    105                                 ms_dispatcher_->audio_array(),
    106                                 ms_dispatcher_->video_array());
    107   }
    108 
    109   void ChangeVideoSourceStateToLive() {
    110     if (dependency_factory_->last_video_source() != NULL) {
    111       dependency_factory_->last_video_source()->SetLive();
    112     }
    113   }
    114 
    115   void ChangeAudioSourceStateToLive() {
    116     if (dependency_factory_->last_audio_source() != NULL) {
    117       dependency_factory_->last_audio_source()->SetLive();
    118     }
    119   }
    120 
    121   void ChangeVideoSourceStateToEnded() {
    122     if (dependency_factory_->last_video_source() != NULL) {
    123       dependency_factory_->last_video_source()->SetEnded();
    124     }
    125   }
    126 
    127   void ChangeAudioSourceStateToEnded() {
    128     if (dependency_factory_->last_audio_source() != NULL) {
    129       dependency_factory_->last_audio_source()->SetEnded();
    130     }
    131   }
    132 
    133  protected:
    134   scoped_ptr<MockMediaStreamDispatcher> ms_dispatcher_;
    135   scoped_ptr<MediaStreamImplUnderTest> ms_impl_;
    136   scoped_ptr<MockMediaStreamDependencyFactory> dependency_factory_;
    137 };
    138 
    139 TEST_F(MediaStreamImplTest, LocalMediaStream) {
    140   // Test a stream with both audio and video.
    141   WebKit::WebMediaStream mixed_desc = RequestLocalMediaStream();
    142 
    143   // Test a stream with audio only.
    144   WebKit::WebMediaStream audio_desc = RequestLocalMediaStream();
    145 
    146   // Test a stream with video only.
    147   WebKit::WebMediaStream video_desc = RequestLocalMediaStream();
    148 
    149   // Stop generated local streams.
    150   ms_impl_->OnLocalMediaStreamStop(mixed_desc.id().utf8());
    151   EXPECT_EQ(1, ms_dispatcher_->stop_stream_counter());
    152   ms_impl_->OnLocalMediaStreamStop(audio_desc.id().utf8());
    153   EXPECT_EQ(2, ms_dispatcher_->stop_stream_counter());
    154 
    155   // Test that the MediaStreams are deleted if the owning WebFrame is deleted.
    156   // In the unit test the owning frame is NULL.
    157   ms_impl_->FrameWillClose(NULL);
    158   EXPECT_EQ(3, ms_dispatcher_->stop_stream_counter());
    159 }
    160 
    161 // This test what happens if a source to a MediaSteam fails to start.
    162 TEST_F(MediaStreamImplTest, MediaSourceFailToStart) {
    163   ms_impl_->RequestUserMedia();
    164   FakeMediaStreamDispatcherComplete();
    165   ChangeVideoSourceStateToEnded();
    166   ChangeAudioSourceStateToEnded();
    167   EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_FAILED,
    168             ms_impl_->request_state());
    169   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
    170   EXPECT_EQ(1, ms_dispatcher_->stop_stream_counter());
    171 }
    172 
    173 // This test what happens if MediaStreamImpl is deleted while the sources of a
    174 // MediaStream is being started.
    175 TEST_F(MediaStreamImplTest, MediaStreamImplShutDown) {
    176   ms_impl_->RequestUserMedia();
    177   FakeMediaStreamDispatcherComplete();
    178   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
    179   EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
    180             ms_impl_->request_state());
    181   ms_impl_.reset();
    182   ChangeAudioSourceStateToLive();
    183   ChangeVideoSourceStateToLive();
    184 }
    185 
    186 // This test what happens if the WebFrame is closed while the MediaStream is
    187 // being generated by the MediaStreamDispatcher.
    188 TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingStream) {
    189   ms_impl_->RequestUserMedia();
    190   ms_impl_->FrameWillClose(NULL);
    191   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
    192   EXPECT_EQ(0, ms_dispatcher_->stop_stream_counter());
    193   ChangeAudioSourceStateToLive();
    194   ChangeVideoSourceStateToLive();
    195   EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
    196             ms_impl_->request_state());
    197 }
    198 
    199 // This test what happens if the WebFrame is closed while the sources are being
    200 // started by MediaStreamDependencyFactory.
    201 TEST_F(MediaStreamImplTest, ReloadFrameWhileGeneratingSources) {
    202   ms_impl_->RequestUserMedia();
    203   FakeMediaStreamDispatcherComplete();
    204   EXPECT_EQ(0, ms_dispatcher_->stop_stream_counter());
    205   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
    206   ms_impl_->FrameWillClose(NULL);
    207   EXPECT_EQ(1, ms_dispatcher_->stop_stream_counter());
    208   ChangeAudioSourceStateToLive();
    209   ChangeVideoSourceStateToLive();
    210   EXPECT_EQ(MediaStreamImplUnderTest::REQUEST_NOT_COMPLETE,
    211             ms_impl_->request_state());
    212 }
    213 
    214 // This test what happens if stop is called on a stream after the frame has
    215 // been reloaded.
    216 TEST_F(MediaStreamImplTest, StopStreamAfterReload) {
    217   WebKit::WebMediaStream mixed_desc = RequestLocalMediaStream();
    218   EXPECT_EQ(0, ms_dispatcher_->stop_stream_counter());
    219   EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
    220   ms_impl_->FrameWillClose(NULL);
    221   EXPECT_EQ(1, ms_dispatcher_->stop_stream_counter());
    222   ms_impl_->OnLocalMediaStreamStop(mixed_desc.id().utf8());
    223   EXPECT_EQ(1, ms_dispatcher_->stop_stream_counter());
    224 }
    225 
    226 }  // namespace content
    227