Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc

Issue 10662049: Move the device enumerate/open/close work to device thread from IO thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: moved MediaStream to BrowserMainloop and addressed all the comments from Tommi and Magnus. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/renderer_host/media/audio_input_device_manager.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"
12 #include "content/browser/renderer_host/media/mock_media_observer.h" 13 #include "content/browser/renderer_host/media/mock_media_observer.h"
13 #include "content/browser/renderer_host/media/video_capture_manager.h" 14 #include "content/browser/renderer_host/media/video_capture_manager.h"
14 #include "content/common/media/media_stream_messages.h" 15 #include "content/common/media/media_stream_messages.h"
15 #include "content/common/media/media_stream_options.h" 16 #include "content/common/media/media_stream_options.h"
16 #include "content/public/test/mock_resource_context.h" 17 #include "content/public/test/mock_resource_context.h"
17 #include "content/test/test_content_browser_client.h" 18 #include "content/test/test_content_browser_client.h"
18 #include "content/test/test_content_client.h" 19 #include "content/test/test_content_client.h"
19 #include "ipc/ipc_message_macros.h" 20 #include "ipc/ipc_message_macros.h"
(...skipping 12 matching lines...) Expand all
32 33
33 const int kProcessId = 5; 34 const int kProcessId = 5;
34 const int kRenderId = 6; 35 const int kRenderId = 6;
35 const int kPageRequestId = 7; 36 const int kPageRequestId = 7;
36 37
37 namespace media_stream { 38 namespace media_stream {
38 39
39 class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost, 40 class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
40 public content::TestContentBrowserClient { 41 public content::TestContentBrowserClient {
41 public: 42 public:
42 MockMediaStreamDispatcherHost(content::ResourceContext* resource_context, 43 MockMediaStreamDispatcherHost(MessageLoop* message_loop,
43 MessageLoop* message_loop, 44 MediaStreamManager* manager)
44 media::AudioManager* audio_manager) 45 : MediaStreamDispatcherHost(kProcessId),
45 : MediaStreamDispatcherHost(resource_context, kProcessId, audio_manager), 46 message_loop_(message_loop),
46 message_loop_(message_loop) {} 47 manager_(manager) {}
47 48
48 // A list of mock methods. 49 // A list of mock methods.
49 MOCK_METHOD4(OnStreamGenerated, 50 MOCK_METHOD4(OnStreamGenerated,
50 void(int routing_id, int request_id, int audio_array_size, 51 void(int routing_id, int request_id, int audio_array_size,
51 int video_array_size)); 52 int video_array_size));
52 MOCK_METHOD2(OnStreamGenerationFailed, void(int routing_id, int request_id)); 53 MOCK_METHOD2(OnStreamGenerationFailed, void(int routing_id, int request_id));
53 MOCK_METHOD2(OnAudioDeviceFailed, void(int routing_id, int index)); 54 MOCK_METHOD2(OnAudioDeviceFailed, void(int routing_id, int index));
54 MOCK_METHOD2(OnVideoDeviceFailed, void(int routing_id, int index)); 55 MOCK_METHOD2(OnVideoDeviceFailed, void(int routing_id, int index));
55 MOCK_METHOD0(GetMediaObserver, content::MediaObserver*()); 56 MOCK_METHOD0(GetMediaObserver, content::MediaObserver*());
56 57
(...skipping 16 matching lines...) Expand all
73 std::string label_; 74 std::string label_;
74 StreamDeviceInfoArray audio_devices_; 75 StreamDeviceInfoArray audio_devices_;
75 StreamDeviceInfoArray video_devices_; 76 StreamDeviceInfoArray video_devices_;
76 77
77 private: 78 private:
78 virtual ~MockMediaStreamDispatcherHost() {} 79 virtual ~MockMediaStreamDispatcherHost() {}
79 80
80 // This method is used to dispatch IPC messages to the renderer. We intercept 81 // This method is used to dispatch IPC messages to the renderer. We intercept
81 // these messages here and dispatch to our mock methods to verify the 82 // these messages here and dispatch to our mock methods to verify the
82 // conversation between this object and the renderer. 83 // conversation between this object and the renderer.
83 virtual bool Send(IPC::Message* message) { 84 virtual bool Send(IPC::Message* message) OVERRIDE {
84 CHECK(message); 85 CHECK(message);
85 86
86 // In this method we dispatch the messages to the according handlers as if 87 // In this method we dispatch the messages to the according handlers as if
87 // we are the renderer. 88 // we are the renderer.
88 bool handled = true; 89 bool handled = true;
89 IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost, *message) 90 IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost, *message)
90 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated, OnStreamGenerated) 91 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated, OnStreamGenerated)
91 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed, 92 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed,
92 OnStreamGenerationFailed) 93 OnStreamGenerationFailed)
93 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_VideoDeviceFailed, 94 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_VideoDeviceFailed,
94 OnVideoDeviceFailed) 95 OnVideoDeviceFailed)
95 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_AudioDeviceFailed, 96 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_AudioDeviceFailed,
96 OnAudioDeviceFailed) 97 OnAudioDeviceFailed)
97 IPC_MESSAGE_UNHANDLED(handled = false) 98 IPC_MESSAGE_UNHANDLED(handled = false)
98 IPC_END_MESSAGE_MAP() 99 IPC_END_MESSAGE_MAP()
99 EXPECT_TRUE(handled); 100 EXPECT_TRUE(handled);
100 101
101 delete message; 102 delete message;
102 return true; 103 return true;
103 } 104 }
104 105
106 // Use our own MediaStreamManager.
107 virtual MediaStreamManager* GetManager() OVERRIDE {
108 return manager_;
109 }
110
105 // These handler methods do minimal things and delegate to the mock methods. 111 // These handler methods do minimal things and delegate to the mock methods.
106 void OnStreamGenerated( 112 void OnStreamGenerated(
107 const IPC::Message& msg, 113 const IPC::Message& msg,
108 int request_id, 114 int request_id,
109 std::string label, 115 std::string label,
110 StreamDeviceInfoArray audio_device_list, 116 StreamDeviceInfoArray audio_device_list,
111 StreamDeviceInfoArray video_device_list) { 117 StreamDeviceInfoArray video_device_list) {
112 OnStreamGenerated(msg.routing_id(), request_id, audio_device_list.size(), 118 OnStreamGenerated(msg.routing_id(), request_id, audio_device_list.size(),
113 video_device_list.size()); 119 video_device_list.size());
114 // Notify that the event have occured. 120 // Notify that the event have occured.
(...skipping 19 matching lines...) Expand all
134 140
135 void OnVideoDeviceFailed(const IPC::Message& msg, 141 void OnVideoDeviceFailed(const IPC::Message& msg,
136 std::string label, 142 std::string label,
137 int index) { 143 int index) {
138 OnVideoDeviceFailed(msg.routing_id(), index); 144 OnVideoDeviceFailed(msg.routing_id(), index);
139 video_devices_.erase(video_devices_.begin() + index); 145 video_devices_.erase(video_devices_.begin() + index);
140 message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); 146 message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
141 } 147 }
142 148
143 MessageLoop* message_loop_; 149 MessageLoop* message_loop_;
150 MediaStreamManager* manager_;
144 }; 151 };
145 152
146 class MediaStreamDispatcherHostTest : public testing::Test { 153 class MediaStreamDispatcherHostTest : public testing::Test {
147 public: 154 public:
148 MediaStreamDispatcherHostTest() : old_client_(NULL), 155 MediaStreamDispatcherHostTest() : old_client_(NULL),
149 old_browser_client_(NULL) {} 156 old_browser_client_(NULL) {}
157 virtual ~MediaStreamDispatcherHostTest() {}
150 158
151 void WaitForResult() { 159 void WaitForResult() {
152 message_loop_->Run(); 160 message_loop_->Run();
153 } 161 }
154 162
155 protected: 163 protected:
156 virtual void SetUp() { 164 virtual void SetUp() OVERRIDE {
165 // MediaStreamManager must be created and called on IO thread.
157 message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO)); 166 message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
158 // ResourceContext must be created on UI thread.
159 ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI,
160 message_loop_.get()));
161 // MediaStreamManager must be created and called on IO thread.
162 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO, 167 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
163 message_loop_.get())); 168 message_loop_.get()));
164 169
165 audio_manager_.reset(media::AudioManager::Create());
166
167 // Create our own media observer. 170 // Create our own media observer.
168 media_observer_.reset(new MockMediaObserver()); 171 media_observer_.reset(new MockMediaObserver());
169 172
173 // Create our own MediaStreamManager.
174 audio_manager_.reset(media::AudioManager::Create());
175 scoped_refptr<media_stream::AudioInputDeviceManager>
176 audio_input_device_manager(
177 new media_stream::AudioInputDeviceManager(audio_manager_.get()));
178 scoped_refptr<media_stream::VideoCaptureManager> video_capture_manager(
179 new media_stream::VideoCaptureManager());
180 media_stream_manager_.reset(new media_stream::MediaStreamManager(
181 audio_input_device_manager, video_capture_manager));
170 // Make sure we use fake devices to avoid long delays. 182 // Make sure we use fake devices to avoid long delays.
171 MediaStreamManager::GetForResourceContext( 183 media_stream_manager_->UseFakeDevice();
tommi (sloooow) - chröme 2012/07/04 13:46:48 I think this is a good example of how great this c
no longer working on chromium 2012/07/04 14:31:39 True, thanks for all the good ideas. I will add a
172 &resource_context_, audio_manager_.get())->UseFakeDevice();
173 184
174 host_ = new MockMediaStreamDispatcherHost( 185 host_ = new MockMediaStreamDispatcherHost(message_loop_.get(),
175 &resource_context_, message_loop_.get(), audio_manager_.get()); 186 media_stream_manager_.get());
176 187
177 // Use the fake content client and browser. 188 // Use the fake content client and browser.
178 old_client_ = content::GetContentClient(); 189 old_client_ = content::GetContentClient();
179 old_browser_client_ = content::GetContentClient()->browser(); 190 old_browser_client_ = content::GetContentClient()->browser();
180 content_client_.reset(new TestContentClient); 191 content_client_.reset(new TestContentClient);
181 content::SetContentClient(content_client_.get()); 192 content::SetContentClient(content_client_.get());
182 content_client_->set_browser_for_testing(host_); 193 content_client_->set_browser_for_testing(host_);
183 } 194 }
184 195
185 virtual void TearDown() { 196 virtual void TearDown() OVERRIDE {
186 // Needed to make sure the manager finishes all tasks on its own thread. 197 message_loop_->RunAllPending();
187 SyncWithVideoCaptureManagerThread();
188 198
189 // Recover the old browser client and content client. 199 // Recover the old browser client and content client.
190 content::GetContentClient()->set_browser_for_testing(old_browser_client_); 200 content::GetContentClient()->set_browser_for_testing(old_browser_client_);
191 content::SetContentClient(old_client_); 201 content::SetContentClient(old_client_);
192 content_client_.reset(); 202 content_client_.reset();
193 } 203 }
194 204
195 // Called on the VideoCaptureManager thread.
196 static void PostQuitMessageLoop(MessageLoop* message_loop) {
197 message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
198 }
199
200 // Called on the main thread.
201 static void PostQuitOnVideoCaptureManagerThread(
202 MessageLoop* message_loop,
203 media_stream::MediaStreamManager* media_stream_manager) {
204 media_stream_manager->video_capture_manager()->GetMessageLoop()->
205 PostTask(FROM_HERE,
206 base::Bind(&PostQuitMessageLoop, message_loop));
207 }
208
209 // SyncWithVideoCaptureManagerThread() waits until all pending tasks on the
210 // video_capture_manager thread are executed while also processing pending
211 // task in message_loop_ on the current thread. It is used to synchronize
212 // with the video capture manager thread when we are stopping a video
213 // capture device.
214 void SyncWithVideoCaptureManagerThread() {
215 message_loop_->PostTask(
216 FROM_HERE,
217 base::Bind(&PostQuitOnVideoCaptureManagerThread,
218 message_loop_.get(),
219 MediaStreamManager::GetForResourceContext(
220 &resource_context_, audio_manager_.get())));
221 message_loop_->Run();
222 }
223
224 scoped_refptr<MockMediaStreamDispatcherHost> host_; 205 scoped_refptr<MockMediaStreamDispatcherHost> host_;
225 scoped_ptr<MessageLoop> message_loop_; 206 scoped_ptr<MessageLoop> message_loop_;
226 scoped_ptr<BrowserThreadImpl> ui_thread_;
227 scoped_ptr<BrowserThreadImpl> io_thread_; 207 scoped_ptr<BrowserThreadImpl> io_thread_;
228 scoped_ptr<media::AudioManager> audio_manager_; 208 scoped_ptr<media::AudioManager> audio_manager_;
229 content::MockResourceContext resource_context_; 209 scoped_ptr<MediaStreamManager> media_stream_manager_;
230 content::ContentClient* old_client_; 210 content::ContentClient* old_client_;
231 content::ContentBrowserClient* old_browser_client_; 211 content::ContentBrowserClient* old_browser_client_;
232 scoped_ptr<content::ContentClient> content_client_; 212 scoped_ptr<content::ContentClient> content_client_;
233 scoped_ptr<MockMediaObserver> media_observer_; 213 scoped_ptr<MockMediaObserver> media_observer_;
234 }; 214 };
235 215
236 TEST_F(MediaStreamDispatcherHostTest, GenerateStream) { 216 TEST_F(MediaStreamDispatcherHostTest, GenerateStream) {
237 StreamOptions options(false, true); 217 StreamOptions options(false, true);
238 218
239 EXPECT_CALL(*host_, GetMediaObserver()) 219 EXPECT_CALL(*host_, GetMediaObserver())
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesOpened(_, _, _)); 319 EXPECT_CALL(*media_observer_.get(), OnCaptureDevicesOpened(_, _, _));
340 WaitForResult(); 320 WaitForResult();
341 std::string label = host_->label_; 321 std::string label = host_->label_;
342 322
343 EXPECT_EQ(host_->audio_devices_.size(), 0u); 323 EXPECT_EQ(host_->audio_devices_.size(), 0u);
344 EXPECT_EQ(host_->video_devices_.size(), 1u); 324 EXPECT_EQ(host_->video_devices_.size(), 1u);
345 EXPECT_EQ(host_->NumberOfStreams(), 1u); 325 EXPECT_EQ(host_->NumberOfStreams(), 1u);
346 326
347 EXPECT_CALL(*host_, OnVideoDeviceFailed(kRenderId, 0)); 327 EXPECT_CALL(*host_, OnVideoDeviceFailed(kRenderId, 0));
348 int session_id = host_->video_devices_[0].session_id; 328 int session_id = host_->video_devices_[0].session_id;
349 MediaStreamManager::GetForResourceContext( 329 media_stream_manager_->video_capture_manager()->Error(session_id);
350 &resource_context_, audio_manager_.get())->
351 video_capture_manager()->Error(session_id);
352 WaitForResult(); 330 WaitForResult();
353 EXPECT_EQ(host_->video_devices_.size(), 0u); 331 EXPECT_EQ(host_->video_devices_.size(), 0u);
354 EXPECT_EQ(host_->NumberOfStreams(), 1u); 332 EXPECT_EQ(host_->NumberOfStreams(), 1u);
355 333
356 // TODO(perkj): test audio device failure? 334 // TODO(perkj): test audio device failure?
357 335
358 host_->OnStopGeneratedStream(label); 336 host_->OnStopGeneratedStream(label);
359 EXPECT_EQ(host_->NumberOfStreams(), 0u); 337 EXPECT_EQ(host_->NumberOfStreams(), 0u);
360 } 338 }
361 339
362 }; // namespace media_stream 340 }; // namespace media_stream
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698