| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "content/browser/browser_thread_impl.h" | 9 #include "content/browser/browser_thread_impl.h" |
| 10 #include "content/browser/mock_content_browser_client.h" |
| 10 #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h" | 11 #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h" |
| 11 #include "content/browser/renderer_host/media/media_stream_manager.h" | 12 #include "content/browser/renderer_host/media/media_stream_manager.h" |
| 13 #include "content/browser/renderer_host/media/mock_media_observer.h" |
| 12 #include "content/browser/renderer_host/media/video_capture_manager.h" | 14 #include "content/browser/renderer_host/media/video_capture_manager.h" |
| 13 #include "content/common/media/media_stream_messages.h" | 15 #include "content/common/media/media_stream_messages.h" |
| 14 #include "content/common/media/media_stream_options.h" | 16 #include "content/common/media/media_stream_options.h" |
| 15 #include "content/test/mock_resource_context.h" | 17 #include "content/test/mock_resource_context.h" |
| 18 #include "content/test/test_content_client.h" |
| 16 #include "ipc/ipc_message_macros.h" | 19 #include "ipc/ipc_message_macros.h" |
| 17 #include "media/audio/audio_manager.h" | 20 #include "media/audio/audio_manager.h" |
| 18 #include "net/url_request/url_request_context.h" | 21 #include "net/url_request/url_request_context.h" |
| 19 #include "testing/gmock/include/gmock/gmock.h" | 22 #include "testing/gmock/include/gmock/gmock.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 24 |
| 22 using ::testing::_; | 25 using ::testing::_; |
| 23 using ::testing::DeleteArg; | 26 using ::testing::DeleteArg; |
| 24 using ::testing::DoAll; | 27 using ::testing::DoAll; |
| 25 using ::testing::Return; | 28 using ::testing::Return; |
| 29 |
| 26 using content::BrowserThread; | 30 using content::BrowserThread; |
| 27 | |
| 28 using content::BrowserThreadImpl; | 31 using content::BrowserThreadImpl; |
| 29 | 32 |
| 30 const int kProcessId = 5; | 33 const int kProcessId = 5; |
| 31 const int kRenderId = 6; | 34 const int kRenderId = 6; |
| 32 const int kPageRequestId = 7; | 35 const int kPageRequestId = 7; |
| 33 | 36 |
| 34 namespace media_stream { | 37 namespace media_stream { |
| 35 | 38 |
| 36 class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost { | 39 class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost, |
| 40 public content::MockContentBrowserClient { |
| 37 public: | 41 public: |
| 38 MockMediaStreamDispatcherHost(content::ResourceContext* resource_context, | 42 MockMediaStreamDispatcherHost(content::ResourceContext* resource_context, |
| 39 MessageLoop* message_loop, | 43 MessageLoop* message_loop, |
| 40 media::AudioManager* audio_manager) | 44 media::AudioManager* audio_manager) |
| 41 : MediaStreamDispatcherHost(resource_context, kProcessId, audio_manager), | 45 : MediaStreamDispatcherHost(resource_context, kProcessId, audio_manager), |
| 42 message_loop_(message_loop) {} | 46 message_loop_(message_loop) {} |
| 43 | 47 |
| 44 // A list of mock methods. | 48 // A list of mock methods. |
| 45 MOCK_METHOD4(OnStreamGenerated, | 49 MOCK_METHOD4(OnStreamGenerated, |
| 46 void(int routing_id, int request_id, int audio_array_size, | 50 void(int routing_id, int request_id, int audio_array_size, |
| 47 int video_array_size)); | 51 int video_array_size)); |
| 48 MOCK_METHOD2(OnStreamGenerationFailed, void(int routing_id, int request_id)); | 52 MOCK_METHOD2(OnStreamGenerationFailed, void(int routing_id, int request_id)); |
| 49 MOCK_METHOD2(OnAudioDeviceFailed, void(int routing_id, int index)); | 53 MOCK_METHOD2(OnAudioDeviceFailed, void(int routing_id, int index)); |
| 50 MOCK_METHOD2(OnVideoDeviceFailed, void(int routing_id, int index)); | 54 MOCK_METHOD2(OnVideoDeviceFailed, void(int routing_id, int index)); |
| 55 MOCK_METHOD0(GetMediaObserver, content::MediaObserver*()); |
| 51 | 56 |
| 52 // Accessor to private functions. | 57 // Accessor to private functions. |
| 53 void OnGenerateStream(int page_request_id, const StreamOptions& components) { | 58 void OnGenerateStream(int page_request_id, const StreamOptions& components) { |
| 54 MediaStreamDispatcherHost::OnGenerateStream(kRenderId, | 59 MediaStreamDispatcherHost::OnGenerateStream(kRenderId, |
| 55 page_request_id, | 60 page_request_id, |
| 56 components, | 61 components, |
| 57 std::string()); | 62 std::string()); |
| 58 } | 63 } |
| 59 void OnStopGeneratedStream(const std::string& label) { | 64 void OnStopGeneratedStream(const std::string& label) { |
| 60 MediaStreamDispatcherHost::OnStopGeneratedStream(kRenderId, label); | 65 MediaStreamDispatcherHost::OnStopGeneratedStream(kRenderId, label); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 OnVideoDeviceFailed(msg.routing_id(), index); | 138 OnVideoDeviceFailed(msg.routing_id(), index); |
| 134 video_devices_.erase(video_devices_.begin() + index); | 139 video_devices_.erase(video_devices_.begin() + index); |
| 135 message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | 140 message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 136 } | 141 } |
| 137 | 142 |
| 138 MessageLoop* message_loop_; | 143 MessageLoop* message_loop_; |
| 139 }; | 144 }; |
| 140 | 145 |
| 141 class MediaStreamDispatcherHostTest : public testing::Test { | 146 class MediaStreamDispatcherHostTest : public testing::Test { |
| 142 public: | 147 public: |
| 148 MediaStreamDispatcherHostTest() : old_client_(NULL), |
| 149 old_browser_client_(NULL) {} |
| 150 |
| 143 void WaitForResult() { | 151 void WaitForResult() { |
| 144 message_loop_->Run(); | 152 message_loop_->Run(); |
| 145 } | 153 } |
| 146 | 154 |
| 147 protected: | 155 protected: |
| 148 virtual void SetUp() { | 156 virtual void SetUp() { |
| 149 message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO)); | 157 message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO)); |
| 150 // ResourceContext must be created on UI thread. | 158 // ResourceContext must be created on UI thread. |
| 151 ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, | 159 ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, |
| 152 message_loop_.get())); | 160 message_loop_.get())); |
| 153 // MediaStreamManager must be created and called on IO thread. | 161 // MediaStreamManager must be created and called on IO thread. |
| 154 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO, | 162 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO, |
| 155 message_loop_.get())); | 163 message_loop_.get())); |
| 156 | 164 |
| 157 audio_manager_.reset(media::AudioManager::Create()); | 165 audio_manager_.reset(media::AudioManager::Create()); |
| 158 | 166 |
| 167 // Create our own media observer. |
| 168 media_observer_.reset(new MockMediaObserver()); |
| 169 |
| 159 // Make sure we use fake devices to avoid long delays. | 170 // Make sure we use fake devices to avoid long delays. |
| 160 MediaStreamManager::GetForResourceContext( | 171 MediaStreamManager::GetForResourceContext( |
| 161 &resource_context_, audio_manager_.get())->UseFakeDevice(); | 172 &resource_context_, audio_manager_.get())->UseFakeDevice(); |
| 162 | 173 |
| 163 host_ = new MockMediaStreamDispatcherHost( | 174 host_ = new MockMediaStreamDispatcherHost( |
| 164 &resource_context_, message_loop_.get(), audio_manager_.get()); | 175 &resource_context_, message_loop_.get(), audio_manager_.get()); |
| 176 |
| 177 // Use the fake content client and browser. |
| 178 old_client_ = content::GetContentClient(); |
| 179 old_browser_client_ = content::GetContentClient()->browser(); |
| 180 content_client_.reset(new TestContentClient); |
| 181 content::SetContentClient(content_client_.get()); |
| 182 content_client_->set_browser(host_); |
| 165 } | 183 } |
| 166 | 184 |
| 167 virtual void TearDown() { | 185 virtual void TearDown() { |
| 168 // Needed to make sure the manager finishes all tasks on its own thread. | 186 // Needed to make sure the manager finishes all tasks on its own thread. |
| 169 SyncWithVideoCaptureManagerThread(); | 187 SyncWithVideoCaptureManagerThread(); |
| 188 |
| 189 // Recover the old browser client and content client. |
| 190 content::GetContentClient()->set_browser(old_browser_client_); |
| 191 content::SetContentClient(old_client_); |
| 192 content_client_.reset(); |
| 170 } | 193 } |
| 171 | 194 |
| 172 // Called on the VideoCaptureManager thread. | 195 // Called on the VideoCaptureManager thread. |
| 173 static void PostQuitMessageLoop(MessageLoop* message_loop) { | 196 static void PostQuitMessageLoop(MessageLoop* message_loop) { |
| 174 message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | 197 message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 175 } | 198 } |
| 176 | 199 |
| 177 // Called on the main thread. | 200 // Called on the main thread. |
| 178 static void PostQuitOnVideoCaptureManagerThread( | 201 static void PostQuitOnVideoCaptureManagerThread( |
| 179 MessageLoop* message_loop, | 202 MessageLoop* message_loop, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 197 &resource_context_, audio_manager_.get()))); | 220 &resource_context_, audio_manager_.get()))); |
| 198 message_loop_->Run(); | 221 message_loop_->Run(); |
| 199 } | 222 } |
| 200 | 223 |
| 201 scoped_refptr<MockMediaStreamDispatcherHost> host_; | 224 scoped_refptr<MockMediaStreamDispatcherHost> host_; |
| 202 scoped_ptr<MessageLoop> message_loop_; | 225 scoped_ptr<MessageLoop> message_loop_; |
| 203 scoped_ptr<BrowserThreadImpl> ui_thread_; | 226 scoped_ptr<BrowserThreadImpl> ui_thread_; |
| 204 scoped_ptr<BrowserThreadImpl> io_thread_; | 227 scoped_ptr<BrowserThreadImpl> io_thread_; |
| 205 scoped_ptr<media::AudioManager> audio_manager_; | 228 scoped_ptr<media::AudioManager> audio_manager_; |
| 206 content::MockResourceContext resource_context_; | 229 content::MockResourceContext resource_context_; |
| 230 content::ContentClient* old_client_; |
| 231 content::ContentBrowserClient* old_browser_client_; |
| 232 scoped_ptr<content::ContentClient> content_client_; |
| 233 scoped_ptr<MockMediaObserver> media_observer_; |
| 207 }; | 234 }; |
| 208 | 235 |
| 209 TEST_F(MediaStreamDispatcherHostTest, GenerateStream) { | 236 TEST_F(MediaStreamDispatcherHostTest, GenerateStream) { |
| 210 StreamOptions options(false, true); | 237 StreamOptions options(false, true); |
| 211 | 238 |
| 239 EXPECT_CALL(*host_, GetMediaObserver()) |
| 240 .WillRepeatedly(Return(media_observer_.get())); |
| 212 EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId, 0, 1)); | 241 EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId, 0, 1)); |
| 213 host_->OnGenerateStream(kPageRequestId, options); | 242 host_->OnGenerateStream(kPageRequestId, options); |
| 214 | 243 |
| 244 EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesOpened(_, _, _)); |
| 245 EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesClosed(_, _, _)); |
| 246 |
| 215 WaitForResult(); | 247 WaitForResult(); |
| 216 | 248 |
| 217 std::string label = host_->label_; | 249 std::string label = host_->label_; |
| 218 | 250 |
| 219 EXPECT_EQ(host_->audio_devices_.size(), 0u); | 251 EXPECT_EQ(host_->audio_devices_.size(), 0u); |
| 220 EXPECT_EQ(host_->video_devices_.size(), 1u); | 252 EXPECT_EQ(host_->video_devices_.size(), 1u); |
| 221 EXPECT_EQ(host_->NumberOfStreams(), 1u); | 253 EXPECT_EQ(host_->NumberOfStreams(), 1u); |
| 222 | 254 |
| 223 host_->OnStopGeneratedStream(label); | 255 host_->OnStopGeneratedStream(label); |
| 224 EXPECT_EQ(host_->NumberOfStreams(), 0u); | 256 EXPECT_EQ(host_->NumberOfStreams(), 0u); |
| 225 } | 257 } |
| 226 | 258 |
| 227 TEST_F(MediaStreamDispatcherHostTest, GenerateThreeStreams) { | 259 TEST_F(MediaStreamDispatcherHostTest, GenerateThreeStreams) { |
| 228 // This test opens three video capture devices. Two fake devices exists and it | 260 // This test opens three video capture devices. Two fake devices exists and it |
| 229 // is expected the last call to |Open()| will open the first device again, but | 261 // is expected the last call to |Open()| will open the first device again, but |
| 230 // with a different label. | 262 // with a different label. |
| 231 StreamOptions options(false, true); | 263 StreamOptions options(false, true); |
| 232 | 264 |
| 233 // Generate first stream. | 265 // Generate first stream. |
| 266 EXPECT_CALL(*host_, GetMediaObserver()) |
| 267 .WillRepeatedly(Return(media_observer_.get())); |
| 234 EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId, 0, 1)); | 268 EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId, 0, 1)); |
| 235 host_->OnGenerateStream(kPageRequestId, options); | 269 host_->OnGenerateStream(kPageRequestId, options); |
| 236 | 270 |
| 271 EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesOpened(_, _, _)); |
| 272 |
| 237 WaitForResult(); | 273 WaitForResult(); |
| 238 | 274 |
| 239 // Check the latest generated stream. | 275 // Check the latest generated stream. |
| 240 EXPECT_EQ(host_->audio_devices_.size(), 0u); | 276 EXPECT_EQ(host_->audio_devices_.size(), 0u); |
| 241 EXPECT_EQ(host_->video_devices_.size(), 1u); | 277 EXPECT_EQ(host_->video_devices_.size(), 1u); |
| 242 std::string label1 = host_->label_; | 278 std::string label1 = host_->label_; |
| 243 std::string device_id1 = host_->video_devices_.front().device_id; | 279 std::string device_id1 = host_->video_devices_.front().device_id; |
| 244 | 280 |
| 245 // Check that we now have one opened streams. | 281 // Check that we now have one opened streams. |
| 246 EXPECT_EQ(host_->NumberOfStreams(), 1u); | 282 EXPECT_EQ(host_->NumberOfStreams(), 1u); |
| 247 | 283 |
| 248 // Generate second stream. | 284 // Generate second stream. |
| 249 EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1)); | 285 EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1)); |
| 250 host_->OnGenerateStream(kPageRequestId+1, options); | 286 host_->OnGenerateStream(kPageRequestId+1, options); |
| 251 | 287 |
| 288 EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesOpened(_, _, _)); |
| 289 |
| 252 WaitForResult(); | 290 WaitForResult(); |
| 253 | 291 |
| 254 // Check the latest generated stream. | 292 // Check the latest generated stream. |
| 255 EXPECT_EQ(host_->audio_devices_.size(), 0u); | 293 EXPECT_EQ(host_->audio_devices_.size(), 0u); |
| 256 EXPECT_EQ(host_->video_devices_.size(), 1u); | 294 EXPECT_EQ(host_->video_devices_.size(), 1u); |
| 257 std::string label2 = host_->label_; | 295 std::string label2 = host_->label_; |
| 258 std::string device_id2 = host_->video_devices_.front().device_id; | 296 std::string device_id2 = host_->video_devices_.front().device_id; |
| 259 EXPECT_NE(device_id1, device_id2); | 297 EXPECT_NE(device_id1, device_id2); |
| 260 EXPECT_NE(label1, label2); | 298 EXPECT_NE(label1, label2); |
| 261 | 299 |
| 262 // Check that we now have two opened streams. | 300 // Check that we now have two opened streams. |
| 263 EXPECT_EQ(host_->NumberOfStreams(), 2u); | 301 EXPECT_EQ(host_->NumberOfStreams(), 2u); |
| 264 | 302 |
| 265 // Generate third stream. | 303 // Generate third stream. |
| 266 EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId + 2, 0, 1)); | 304 EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId + 2, 0, 1)); |
| 267 host_->OnGenerateStream(kPageRequestId+2, options); | 305 host_->OnGenerateStream(kPageRequestId+2, options); |
| 268 | 306 |
| 307 EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesOpened(_, _, _)); |
| 308 EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesClosed(_, _, _)) |
| 309 .Times(3); |
| 310 |
| 269 WaitForResult(); | 311 WaitForResult(); |
| 270 | 312 |
| 271 // Check the latest generated stream. | 313 // Check the latest generated stream. |
| 272 EXPECT_EQ(host_->audio_devices_.size(), 0u); | 314 EXPECT_EQ(host_->audio_devices_.size(), 0u); |
| 273 EXPECT_EQ(host_->video_devices_.size(), 1u); | 315 EXPECT_EQ(host_->video_devices_.size(), 1u); |
| 274 std::string label3 = host_->label_; | 316 std::string label3 = host_->label_; |
| 275 std::string device_id3 = host_->video_devices_.front().device_id; | 317 std::string device_id3 = host_->video_devices_.front().device_id; |
| 276 EXPECT_EQ(device_id1, device_id3); | 318 EXPECT_EQ(device_id1, device_id3); |
| 277 EXPECT_NE(device_id2, device_id3); | 319 EXPECT_NE(device_id2, device_id3); |
| 278 EXPECT_NE(label1, label3); | 320 EXPECT_NE(label1, label3); |
| 279 EXPECT_NE(label2, label3); | 321 EXPECT_NE(label2, label3); |
| 280 | 322 |
| 281 // Check that we now have three opened streams. | 323 // Check that we now have three opened streams. |
| 282 EXPECT_EQ(host_->NumberOfStreams(), 3u); | 324 EXPECT_EQ(host_->NumberOfStreams(), 3u); |
| 283 | 325 |
| 284 host_->OnStopGeneratedStream(label1); | 326 host_->OnStopGeneratedStream(label1); |
| 285 host_->OnStopGeneratedStream(label2); | 327 host_->OnStopGeneratedStream(label2); |
| 286 host_->OnStopGeneratedStream(label3); | 328 host_->OnStopGeneratedStream(label3); |
| 287 EXPECT_EQ(host_->NumberOfStreams(), 0u); | 329 EXPECT_EQ(host_->NumberOfStreams(), 0u); |
| 288 } | 330 } |
| 289 | 331 |
| 290 TEST_F(MediaStreamDispatcherHostTest, FailDevice) { | 332 TEST_F(MediaStreamDispatcherHostTest, FailDevice) { |
| 291 StreamOptions options(false, true); | 333 StreamOptions options(false, true); |
| 292 | 334 |
| 335 EXPECT_CALL(*host_, GetMediaObserver()) |
| 336 .WillRepeatedly(Return(media_observer_.get())); |
| 293 EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId, 0, 1)); | 337 EXPECT_CALL(*host_, OnStreamGenerated(kRenderId, kPageRequestId, 0, 1)); |
| 294 host_->OnGenerateStream(kPageRequestId, options); | 338 host_->OnGenerateStream(kPageRequestId, options); |
| 339 EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesOpened(_, _, _)); |
| 295 WaitForResult(); | 340 WaitForResult(); |
| 296 std::string label = host_->label_; | 341 std::string label = host_->label_; |
| 297 | 342 |
| 298 EXPECT_EQ(host_->audio_devices_.size(), 0u); | 343 EXPECT_EQ(host_->audio_devices_.size(), 0u); |
| 299 EXPECT_EQ(host_->video_devices_.size(), 1u); | 344 EXPECT_EQ(host_->video_devices_.size(), 1u); |
| 300 EXPECT_EQ(host_->NumberOfStreams(), 1u); | 345 EXPECT_EQ(host_->NumberOfStreams(), 1u); |
| 301 | 346 |
| 302 EXPECT_CALL(*host_, OnVideoDeviceFailed(kRenderId, 0)); | 347 EXPECT_CALL(*host_, OnVideoDeviceFailed(kRenderId, 0)); |
| 303 int session_id = host_->video_devices_[0].session_id; | 348 int session_id = host_->video_devices_[0].session_id; |
| 304 MediaStreamManager::GetForResourceContext( | 349 MediaStreamManager::GetForResourceContext( |
| 305 &resource_context_, audio_manager_.get())-> | 350 &resource_context_, audio_manager_.get())-> |
| 306 video_capture_manager()->Error(session_id); | 351 video_capture_manager()->Error(session_id); |
| 307 WaitForResult(); | 352 WaitForResult(); |
| 308 EXPECT_EQ(host_->video_devices_.size(), 0u); | 353 EXPECT_EQ(host_->video_devices_.size(), 0u); |
| 309 EXPECT_EQ(host_->NumberOfStreams(), 1u); | 354 EXPECT_EQ(host_->NumberOfStreams(), 1u); |
| 310 | 355 |
| 311 // TODO(perkj): test audio device failure? | 356 // TODO(perkj): test audio device failure? |
| 312 | 357 |
| 313 host_->OnStopGeneratedStream(label); | 358 host_->OnStopGeneratedStream(label); |
| 314 EXPECT_EQ(host_->NumberOfStreams(), 0u); | 359 EXPECT_EQ(host_->NumberOfStreams(), 0u); |
| 315 } | 360 } |
| 316 | 361 |
| 317 }; // namespace media_stream | 362 }; // namespace media_stream |
| OLD | NEW |