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 "content/common/media/media_stream_options.h"
      7 #include "content/renderer/media/media_stream_extra_data.h"
      8 #include "content/renderer/media/media_stream_source_extra_data.h"
      9 #include "content/renderer/media/mock_media_stream_dependency_factory.h"
     10 #include "content/renderer/media/mock_web_rtc_peer_connection_handler_client.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 #include "third_party/WebKit/public/platform/WebMediaConstraints.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/WebRTCPeerConnectionHandler.h"
     17 #include "third_party/WebKit/public/platform/WebVector.h"
     18 #include "third_party/libjingle/source/talk/app/webrtc/videosourceinterface.h"
     19 
     20 namespace content {
     21 
     22 class MediaSourceCreatedObserver {
     23  public:
     24   MediaSourceCreatedObserver()
     25      : result_(false),
     26        description_(NULL) {
     27   }
     28 
     29   void OnCreateNativeSourcesComplete(
     30       WebKit::WebMediaStream* description,
     31       bool request_succeeded) {
     32     result_ = request_succeeded;
     33     description_ = description;
     34   }
     35 
     36   WebKit::WebMediaStream* description() const {
     37     return description_;
     38   }
     39   bool result() const { return result_; }
     40 
     41  private:
     42   bool result_;
     43   WebKit::WebMediaStream* description_;
     44 };
     45 
     46 class MediaStreamDependencyFactoryTest : public ::testing::Test {
     47  public:
     48   virtual void SetUp() {
     49     dependency_factory_.reset(new MockMediaStreamDependencyFactory());
     50   }
     51 
     52   virtual void TearDown() OVERRIDE {
     53     // TODO(tommyw): Remove this once WebKit::MediaStreamSource::Owner has been
     54     // implemented to fully avoid a circular dependency.
     55     for (size_t i = 0; i < audio_sources_.size(); ++i)
     56       audio_sources_[i].setExtraData(NULL);
     57 
     58     for (size_t i = 0; i < video_sources_.size(); ++i)
     59       video_sources_[i].setExtraData(NULL);
     60   }
     61 
     62   WebKit::WebMediaStream CreateWebKitMediaStream(bool audio, bool video) {
     63     WebKit::WebVector<WebKit::WebMediaStreamSource> audio_sources(
     64         audio ? static_cast<size_t>(1) : 0);
     65     WebKit::WebVector<WebKit::WebMediaStreamSource> video_sources(
     66         video ? static_cast<size_t>(1) : 0);
     67 
     68     if (audio) {
     69       StreamDeviceInfo info;
     70       info.device.type = content::MEDIA_DEVICE_AUDIO_CAPTURE;
     71       info.device.name = "audio";
     72       info.device.sample_rate = 0;
     73       info.device.channel_layout = 0;
     74       info.session_id = 99;
     75       audio_sources[0].initialize("audio",
     76                                   WebKit::WebMediaStreamSource::TypeAudio,
     77                                   "audio");
     78       audio_sources[0].setExtraData(
     79           new MediaStreamSourceExtraData(info, audio_sources[0]));
     80       audio_sources_.assign(audio_sources);
     81     }
     82     if (video) {
     83       StreamDeviceInfo info;
     84       info.device.type = content::MEDIA_DEVICE_VIDEO_CAPTURE;
     85       info.device.name = "video";
     86       info.session_id = 98;
     87       video_sources[0].initialize("video",
     88                                   WebKit::WebMediaStreamSource::TypeVideo,
     89                                   "video");
     90       video_sources[0].setExtraData(
     91           new MediaStreamSourceExtraData(info, video_sources[0]));
     92       video_sources_.assign(video_sources);
     93     }
     94     WebKit::WebMediaStream stream_desc;
     95     WebKit::WebVector<WebKit::WebMediaStreamTrack> audio_track_vector(
     96         audio_sources.size());
     97     for (size_t i = 0; i < audio_track_vector.size(); ++i) {
     98       audio_track_vector[i].initialize(audio_sources[i].id(),
     99                                        audio_sources[i]);
    100     }
    101 
    102     WebKit::WebVector<WebKit::WebMediaStreamTrack> video_track_vector(
    103         video_sources.size());
    104     for (size_t i = 0; i < video_track_vector.size(); ++i) {
    105       video_track_vector[i].initialize(video_sources[i].id(),
    106                                        video_sources[i]);
    107     }
    108 
    109     stream_desc.initialize("media stream", audio_track_vector,
    110                            video_track_vector);
    111     return stream_desc;
    112   }
    113 
    114   void CreateNativeSources(WebKit::WebMediaStream* descriptor) {
    115     static const int kRenderViewId = 1;
    116 
    117     MediaSourceCreatedObserver observer;
    118     WebKit::WebMediaConstraints audio_constraints;
    119     dependency_factory_->CreateNativeMediaSources(
    120         kRenderViewId,
    121         WebKit::WebMediaConstraints(),
    122         WebKit::WebMediaConstraints(),
    123         descriptor,
    124         base::Bind(
    125             &MediaSourceCreatedObserver::OnCreateNativeSourcesComplete,
    126             base::Unretained(&observer)));
    127 
    128     EXPECT_FALSE(observer.result());
    129     // Change the state of the created source to live. This should trigger
    130     // MediaSourceCreatedObserver::OnCreateNativeSourcesComplete
    131     if (dependency_factory_->last_video_source()) {
    132       dependency_factory_->last_audio_source()->SetLive();
    133       dependency_factory_->last_video_source()->SetLive();
    134     }
    135     EXPECT_TRUE(observer.result());
    136     EXPECT_TRUE(observer.description() == descriptor);
    137   }
    138 
    139   void VerifyMediaStream(const WebKit::WebMediaStream& stream_desc,
    140                          size_t num_audio_tracks,
    141                          size_t num_video_tracks) {
    142     content::MediaStreamExtraData* extra_data =
    143         static_cast<content::MediaStreamExtraData*>(stream_desc.extraData());
    144     ASSERT_TRUE(extra_data && extra_data->stream().get());
    145     EXPECT_TRUE(extra_data->is_local());
    146     EXPECT_EQ(num_audio_tracks, extra_data->stream()->GetAudioTracks().size());
    147     EXPECT_EQ(num_video_tracks, extra_data->stream()->GetVideoTracks().size());
    148   }
    149 
    150  protected:
    151   scoped_ptr<MockMediaStreamDependencyFactory> dependency_factory_;
    152   WebKit::WebVector<WebKit::WebMediaStreamSource> audio_sources_;
    153   WebKit::WebVector<WebKit::WebMediaStreamSource> video_sources_;
    154 };
    155 
    156 TEST_F(MediaStreamDependencyFactoryTest, CreateRTCPeerConnectionHandler) {
    157   MockWebRTCPeerConnectionHandlerClient client_jsep;
    158   scoped_ptr<WebKit::WebRTCPeerConnectionHandler> pc_handler(
    159       dependency_factory_->CreateRTCPeerConnectionHandler(&client_jsep));
    160   EXPECT_TRUE(pc_handler.get() != NULL);
    161 }
    162 
    163 TEST_F(MediaStreamDependencyFactoryTest, CreateNativeMediaStream) {
    164   WebKit::WebMediaStream stream_desc = CreateWebKitMediaStream(true, true);
    165   CreateNativeSources(&stream_desc);
    166 
    167   dependency_factory_->CreateNativeLocalMediaStream(&stream_desc);
    168   VerifyMediaStream(stream_desc, 1, 1);
    169 }
    170 
    171 // Test that we don't crash if a MediaStream is created in WebKit with unknown
    172 // sources. This can for example happen if a MediaStream is created with
    173 // remote tracks.
    174 TEST_F(MediaStreamDependencyFactoryTest, CreateNativeMediaStreamWithoutSource) {
    175   // Create a WebKit MediaStream description.
    176   WebKit::WebMediaStreamSource audio_source;
    177   audio_source.initialize("audio source",
    178                           WebKit::WebMediaStreamSource::TypeAudio,
    179                           "something");
    180   WebKit::WebMediaStreamSource video_source;
    181   video_source.initialize("video source",
    182                           WebKit::WebMediaStreamSource::TypeVideo,
    183                           "something");
    184 
    185   WebKit::WebVector<WebKit::WebMediaStreamTrack> audio_tracks(
    186       static_cast<size_t>(1));
    187   audio_tracks[0].initialize(audio_source.id(), audio_source);
    188   WebKit::WebVector<WebKit::WebMediaStreamTrack> video_tracks(
    189       static_cast<size_t>(1));
    190   video_tracks[0].initialize(video_source.id(), video_source);
    191 
    192   WebKit::WebMediaStream stream_desc;
    193   stream_desc.initialize("new stream", audio_tracks, video_tracks);
    194 
    195   EXPECT_TRUE(dependency_factory_->EnsurePeerConnectionFactory());
    196   dependency_factory_->CreateNativeLocalMediaStream(&stream_desc);
    197   VerifyMediaStream(stream_desc, 0, 0);
    198 }
    199 
    200 TEST_F(MediaStreamDependencyFactoryTest, AddAndRemoveNativeTrack) {
    201   WebKit::WebMediaStream stream_desc = CreateWebKitMediaStream(true, true);
    202   CreateNativeSources(&stream_desc);
    203 
    204   dependency_factory_->CreateNativeLocalMediaStream(&stream_desc);
    205   VerifyMediaStream(stream_desc, 1, 1);
    206 
    207   WebKit::WebVector<WebKit::WebMediaStreamTrack> audio_tracks;
    208   stream_desc.audioTracks(audio_tracks);
    209   EXPECT_TRUE(dependency_factory_->RemoveNativeMediaStreamTrack(
    210       stream_desc, audio_tracks[0]));
    211   VerifyMediaStream(stream_desc, 0, 1);
    212 
    213   EXPECT_TRUE(dependency_factory_->AddNativeMediaStreamTrack(
    214       stream_desc, audio_tracks[0]));
    215   VerifyMediaStream(stream_desc, 1, 1);
    216 
    217   WebKit::WebVector<WebKit::WebMediaStreamTrack> video_tracks;
    218   stream_desc.videoTracks(video_tracks);
    219   EXPECT_TRUE(dependency_factory_->RemoveNativeMediaStreamTrack(
    220       stream_desc, video_tracks[0]));
    221   VerifyMediaStream(stream_desc, 1, 0);
    222 
    223   EXPECT_TRUE(dependency_factory_->AddNativeMediaStreamTrack(
    224       stream_desc, video_tracks[0]));
    225   VerifyMediaStream(stream_desc, 1, 1);
    226 }
    227 
    228 }  // namespace content
    229