| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <string> |
| |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/message_loop/message_loop.h" |
| #include "content/common/media/media_stream_messages.h" |
| #include "content/public/common/media_stream_request.h" |
| #include "content/renderer/media/media_stream_dispatcher.h" |
| #include "content/renderer/media/media_stream_dispatcher_eventhandler.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| |
| namespace content { |
| namespace { |
| |
| const int kRouteId = 0; |
| const int kAudioSessionId = 3; |
| const int kVideoSessionId = 5; |
| const int kRequestId1 = 10; |
| const int kRequestId2 = 20; |
| const int kRequestId3 = 30; |
| const int kRequestId4 = 40; |
| static const char kLabel[] = "test"; |
| |
| const MediaStreamType kAudioType = MEDIA_DEVICE_AUDIO_CAPTURE; |
| const MediaStreamType kVideoType = MEDIA_DEVICE_VIDEO_CAPTURE; |
| const MediaStreamType kNoAudioType = MEDIA_NO_SERVICE; |
| |
| class MockMediaStreamDispatcherEventHandler |
| : public MediaStreamDispatcherEventHandler, |
| public base::SupportsWeakPtr<MockMediaStreamDispatcherEventHandler> { |
| public: |
| MockMediaStreamDispatcherEventHandler() |
| : request_id_(-1) {} |
| |
| virtual void OnStreamGenerated( |
| int request_id, |
| const std::string &label, |
| const StreamDeviceInfoArray& audio_device_array, |
| const StreamDeviceInfoArray& video_device_array) OVERRIDE { |
| request_id_ = request_id; |
| label_ = label; |
| } |
| |
| virtual void OnStreamGenerationFailed(int request_id) OVERRIDE { |
| request_id_ = request_id; |
| } |
| |
| virtual void OnStopGeneratedStream(const std::string& label) OVERRIDE { |
| label_ = label; |
| } |
| |
| virtual void OnDevicesEnumerated( |
| int request_id, |
| const StreamDeviceInfoArray& device_array) OVERRIDE { |
| request_id_ = request_id; |
| } |
| |
| virtual void OnDevicesEnumerationFailed(int request_id) OVERRIDE { |
| request_id_ = request_id; |
| } |
| |
| virtual void OnDeviceOpened( |
| int request_id, |
| const std::string& label, |
| const StreamDeviceInfo& video_device) OVERRIDE { |
| request_id_ = request_id; |
| label_ = label; |
| } |
| |
| virtual void OnDeviceOpenFailed(int request_id) OVERRIDE { |
| request_id_ = request_id; |
| } |
| |
| int request_id_; |
| std::string label_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MockMediaStreamDispatcherEventHandler); |
| }; |
| |
| } // namespace |
| |
| TEST(MediaStreamDispatcherTest, BasicStream) { |
| scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); |
| scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL)); |
| scoped_ptr<MockMediaStreamDispatcherEventHandler> |
| handler(new MockMediaStreamDispatcherEventHandler); |
| StreamOptions components(kAudioType, kVideoType); |
| GURL security_origin; |
| |
| int ipc_request_id1 = dispatcher->next_ipc_id_; |
| dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(), |
| components, security_origin); |
| int ipc_request_id2 = dispatcher->next_ipc_id_; |
| EXPECT_NE(ipc_request_id1, ipc_request_id2); |
| dispatcher->GenerateStream(kRequestId2, handler.get()->AsWeakPtr(), |
| components, security_origin); |
| EXPECT_EQ(dispatcher->requests_.size(), size_t(2)); |
| |
| StreamDeviceInfoArray audio_device_array(1); |
| StreamDeviceInfo audio_device_info; |
| audio_device_info.device.name = "Microphone"; |
| audio_device_info.device.type = kAudioType; |
| audio_device_info.session_id = kAudioSessionId; |
| audio_device_array[0] = audio_device_info; |
| |
| StreamDeviceInfoArray video_device_array(1); |
| StreamDeviceInfo video_device_info; |
| video_device_info.device.name = "Camera"; |
| video_device_info.device.type = kVideoType; |
| video_device_info.session_id = kVideoSessionId; |
| video_device_array[0] = video_device_info; |
| |
| // Complete the creation of stream1. |
| std::string stream_label1 = std::string("stream1"); |
| dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated( |
| kRouteId, ipc_request_id1, stream_label1, |
| audio_device_array, video_device_array)); |
| EXPECT_EQ(handler->request_id_, kRequestId1); |
| EXPECT_EQ(handler->label_, stream_label1); |
| |
| // Complete the creation of stream2. |
| std::string stream_label2 = std::string("stream2"); |
| dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated( |
| kRouteId, ipc_request_id2, stream_label2, |
| audio_device_array, video_device_array)); |
| EXPECT_EQ(handler->request_id_, kRequestId2); |
| EXPECT_EQ(handler->label_, stream_label2); |
| |
| EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); |
| EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(2)); |
| |
| // Check the session_id of stream2. |
| EXPECT_EQ(dispatcher->audio_session_id(stream_label2, 0), kAudioSessionId); |
| EXPECT_EQ(dispatcher->video_session_id(stream_label2, 0), kVideoSessionId); |
| |
| |
| // Stop audio. |
| dispatcher->StopStreamDevice(audio_device_info); |
| EXPECT_EQ(dispatcher->audio_session_id(stream_label1, 0), |
| StreamDeviceInfo::kNoId); |
| |
| // Stop video. |
| dispatcher->StopStreamDevice(video_device_info); |
| EXPECT_EQ(dispatcher->video_session_id(stream_label1, 0), |
| StreamDeviceInfo::kNoId); |
| |
| EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); |
| |
| // Verify that the request has been completed. |
| EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); |
| EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); |
| } |
| |
| TEST(MediaStreamDispatcherTest, BasicStreamForDevice) { |
| static const char kDeviceId[] = "/dev/video0"; |
| |
| scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); |
| scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL)); |
| scoped_ptr<MockMediaStreamDispatcherEventHandler> |
| handler(new MockMediaStreamDispatcherEventHandler); |
| StreamOptions components(kNoAudioType, kVideoType); |
| components.audio_device_id = kDeviceId; |
| components.video_device_id = kDeviceId; |
| GURL security_origin; |
| |
| int ipc_request_id1 = dispatcher->next_ipc_id_; |
| dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(), |
| components, security_origin); |
| int ipc_request_id2 = dispatcher->next_ipc_id_; |
| EXPECT_NE(ipc_request_id1, ipc_request_id2); |
| dispatcher->GenerateStream(kRequestId2, handler.get()->AsWeakPtr(), |
| components, security_origin); |
| EXPECT_EQ(dispatcher->requests_.size(), size_t(2)); |
| |
| // No audio requested. |
| StreamDeviceInfoArray audio_device_array; |
| |
| StreamDeviceInfoArray video_device_array(1); |
| StreamDeviceInfo video_device_info; |
| video_device_info.device.name = "Fake Video Capture Device"; |
| video_device_info.device.type = kVideoType; |
| video_device_info.session_id = kVideoSessionId; |
| video_device_array[0] = video_device_info; |
| |
| // Complete the creation of stream1. |
| std::string stream_label1 = std::string("stream1"); |
| dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated( |
| kRouteId, ipc_request_id1, stream_label1, |
| audio_device_array, video_device_array)); |
| EXPECT_EQ(handler->request_id_, kRequestId1); |
| EXPECT_EQ(handler->label_, stream_label1); |
| |
| // Complete the creation of stream2. |
| std::string stream_label2 = std::string("stream2"); |
| dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated( |
| kRouteId, ipc_request_id2, stream_label2, |
| audio_device_array, video_device_array)); |
| EXPECT_EQ(handler->request_id_, kRequestId2); |
| EXPECT_EQ(handler->label_, stream_label2); |
| |
| EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); |
| EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(2)); |
| |
| // Check the session_id of stream2. |
| EXPECT_EQ(dispatcher->video_session_id(stream_label2, 0), kVideoSessionId); |
| |
| // Stop video. |
| dispatcher->StopStreamDevice(video_device_info); |
| EXPECT_EQ(dispatcher->video_session_id(stream_label1, 0), |
| StreamDeviceInfo::kNoId); |
| |
| EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); |
| |
| // Verify that the request has been completed. |
| EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); |
| EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); |
| } |
| |
| TEST(MediaStreamDispatcherTest, BasicVideoDevice) { |
| scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); |
| scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL)); |
| scoped_ptr<MockMediaStreamDispatcherEventHandler> |
| handler1(new MockMediaStreamDispatcherEventHandler); |
| scoped_ptr<MockMediaStreamDispatcherEventHandler> |
| handler2(new MockMediaStreamDispatcherEventHandler); |
| GURL security_origin; |
| |
| int ipc_request_id1 = dispatcher->next_ipc_id_; |
| dispatcher->EnumerateDevices( |
| kRequestId1, handler1.get()->AsWeakPtr(), |
| kVideoType, |
| security_origin); |
| int ipc_request_id2 = dispatcher->next_ipc_id_; |
| EXPECT_NE(ipc_request_id1, ipc_request_id2); |
| dispatcher->EnumerateDevices( |
| kRequestId2, handler2.get()->AsWeakPtr(), |
| kVideoType, |
| security_origin); |
| EXPECT_EQ(dispatcher->video_enumeration_state_.requests.size(), size_t(2)); |
| |
| StreamDeviceInfoArray video_device_array(1); |
| StreamDeviceInfo video_device_info; |
| video_device_info.device.name = "Camera"; |
| video_device_info.device.id = "device_path"; |
| video_device_info.device.type = kVideoType; |
| video_device_info.session_id = kVideoSessionId; |
| video_device_array[0] = video_device_info; |
| |
| // Complete the enumeration request and all requesters should receive reply. |
| dispatcher->OnMessageReceived(MediaStreamMsg_DevicesEnumerated( |
| kRouteId, ipc_request_id1, kLabel, video_device_array)); |
| EXPECT_EQ(handler1->request_id_, kRequestId1); |
| EXPECT_EQ(handler2->request_id_, kRequestId2); |
| |
| EXPECT_EQ(dispatcher->video_enumeration_state_.requests.size(), size_t(2)); |
| EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); |
| |
| int ipc_request_id3 = dispatcher->next_ipc_id_; |
| dispatcher->OpenDevice(kRequestId3, handler1.get()->AsWeakPtr(), |
| video_device_info.device.id, |
| kVideoType, |
| security_origin); |
| int ipc_request_id4 = dispatcher->next_ipc_id_; |
| EXPECT_NE(ipc_request_id3, ipc_request_id4); |
| dispatcher->OpenDevice(kRequestId4, handler1.get()->AsWeakPtr(), |
| video_device_info.device.id, |
| kVideoType, |
| security_origin); |
| EXPECT_EQ(dispatcher->requests_.size(), size_t(2)); |
| |
| // Complete the OpenDevice of request 1. |
| std::string stream_label1 = std::string("stream1"); |
| dispatcher->OnMessageReceived(MediaStreamMsg_DeviceOpened( |
| kRouteId, ipc_request_id3, stream_label1, video_device_info)); |
| EXPECT_EQ(handler1->request_id_, kRequestId3); |
| |
| // Complete the OpenDevice of request 2. |
| std::string stream_label2 = std::string("stream2"); |
| dispatcher->OnMessageReceived(MediaStreamMsg_DeviceOpened( |
| kRouteId, ipc_request_id4, stream_label2, video_device_info)); |
| EXPECT_EQ(handler1->request_id_, kRequestId4); |
| |
| EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); |
| EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(2)); |
| |
| // Check the video_session_id. |
| EXPECT_EQ(dispatcher->video_session_id(stream_label1, 0), kVideoSessionId); |
| EXPECT_EQ(dispatcher->video_session_id(stream_label2, 0), kVideoSessionId); |
| |
| // Close the device from request 2. |
| dispatcher->CloseDevice(stream_label2); |
| EXPECT_EQ(dispatcher->video_session_id(stream_label2, 0), |
| StreamDeviceInfo::kNoId); |
| |
| // Close the device from request 1. |
| dispatcher->CloseDevice(stream_label1); |
| EXPECT_EQ(dispatcher->video_session_id(stream_label1, 0), |
| StreamDeviceInfo::kNoId); |
| EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); |
| |
| // Verify that the request have been completed. |
| EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); |
| EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); |
| } |
| |
| TEST(MediaStreamDispatcherTest, TestFailure) { |
| scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); |
| scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL)); |
| scoped_ptr<MockMediaStreamDispatcherEventHandler> |
| handler(new MockMediaStreamDispatcherEventHandler); |
| StreamOptions components(kAudioType, kVideoType); |
| GURL security_origin; |
| |
| // Test failure when creating a stream. |
| int ipc_request_id1 = dispatcher->next_ipc_id_; |
| dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(), |
| components, security_origin); |
| dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerationFailed( |
| kRouteId, ipc_request_id1)); |
| |
| // Verify that the request have been completed. |
| EXPECT_EQ(handler->request_id_, kRequestId1); |
| EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); |
| |
| // Create a new stream. |
| ipc_request_id1 = dispatcher->next_ipc_id_; |
| dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(), |
| components, security_origin); |
| |
| StreamDeviceInfoArray audio_device_array(1); |
| StreamDeviceInfo audio_device_info; |
| audio_device_info.device.name = "Microphone"; |
| audio_device_info.device.type = kAudioType; |
| audio_device_info.session_id = kAudioSessionId; |
| audio_device_array[0] = audio_device_info; |
| |
| StreamDeviceInfoArray video_device_array(1); |
| StreamDeviceInfo video_device_info; |
| video_device_info.device.name = "Camera"; |
| video_device_info.device.type = kVideoType; |
| video_device_info.session_id = kVideoSessionId; |
| video_device_array[0] = video_device_info; |
| |
| // Complete the creation of stream1. |
| std::string stream_label1 = std::string("stream1"); |
| dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated( |
| kRouteId, ipc_request_id1, stream_label1, |
| audio_device_array, video_device_array)); |
| EXPECT_EQ(handler->request_id_, kRequestId1); |
| EXPECT_EQ(handler->label_, stream_label1); |
| EXPECT_EQ(dispatcher->video_session_id(stream_label1, 0), kVideoSessionId); |
| } |
| |
| TEST(MediaStreamDispatcherTest, CancelGenerateStream) { |
| scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); |
| scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL)); |
| scoped_ptr<MockMediaStreamDispatcherEventHandler> |
| handler(new MockMediaStreamDispatcherEventHandler); |
| StreamOptions components(kAudioType, kVideoType); |
| int ipc_request_id1 = dispatcher->next_ipc_id_; |
| |
| dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(), |
| components, GURL()); |
| dispatcher->GenerateStream(kRequestId2, handler.get()->AsWeakPtr(), |
| components, GURL()); |
| |
| EXPECT_EQ(2u, dispatcher->requests_.size()); |
| dispatcher->CancelGenerateStream(kRequestId2, handler.get()->AsWeakPtr()); |
| EXPECT_EQ(1u, dispatcher->requests_.size()); |
| |
| // Complete the creation of stream1. |
| StreamDeviceInfo audio_device_info; |
| audio_device_info.device.name = "Microphone"; |
| audio_device_info.device.type = kAudioType; |
| audio_device_info.session_id = kAudioSessionId; |
| StreamDeviceInfoArray audio_device_array(1); |
| audio_device_array[0] = audio_device_info; |
| |
| StreamDeviceInfo video_device_info; |
| video_device_info.device.name = "Camera"; |
| video_device_info.device.type = kVideoType; |
| video_device_info.session_id = kVideoSessionId; |
| StreamDeviceInfoArray video_device_array(1); |
| video_device_array[0] = video_device_info; |
| |
| std::string stream_label1 = "stream1"; |
| dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated( |
| kRouteId, ipc_request_id1, stream_label1, |
| audio_device_array, video_device_array)); |
| EXPECT_EQ(handler->request_id_, kRequestId1); |
| EXPECT_EQ(handler->label_, stream_label1); |
| EXPECT_EQ(0u, dispatcher->requests_.size()); |
| } |
| |
| } // namespace content |