OLD | NEW |
| (Empty) |
1 // Copyright 2013 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 "chrome/browser/media/desktop_media_picker_model.h" | |
6 | |
7 #include "base/message_loop/message_loop.h" | |
8 #include "base/strings/utf_string_conversions.h" | |
9 #include "base/synchronization/lock.h" | |
10 #include "content/public/test/test_browser_thread.h" | |
11 #include "testing/gmock/include/gmock/gmock.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | |
14 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" | |
15 #include "third_party/webrtc/modules/desktop_capture/window_capturer.h" | |
16 | |
17 using testing::_; | |
18 using testing::DoAll; | |
19 | |
20 namespace { | |
21 | |
22 class MockObserver : public DesktopMediaPickerModel::Observer { | |
23 public: | |
24 MOCK_METHOD1(OnSourceAdded, void(int index)); | |
25 MOCK_METHOD1(OnSourceRemoved, void(int index)); | |
26 MOCK_METHOD1(OnSourceNameChanged, void(int index)); | |
27 MOCK_METHOD1(OnSourceThumbnailChanged, void(int index)); | |
28 }; | |
29 | |
30 class FakeScreenCapturer : public webrtc::ScreenCapturer { | |
31 public: | |
32 FakeScreenCapturer() {} | |
33 virtual ~FakeScreenCapturer() {} | |
34 | |
35 // webrtc::ScreenCapturer implementation. | |
36 virtual void Start(Callback* callback) OVERRIDE { | |
37 callback_ = callback; | |
38 } | |
39 | |
40 virtual void Capture(const webrtc::DesktopRegion& region) OVERRIDE { | |
41 DCHECK(callback_); | |
42 webrtc::DesktopFrame* frame = | |
43 new webrtc::BasicDesktopFrame(webrtc::DesktopSize(10, 10)); | |
44 memset(frame->data(), 0, frame->stride() * frame->size().height()); | |
45 callback_->OnCaptureCompleted(frame); | |
46 } | |
47 | |
48 virtual void SetMouseShapeObserver( | |
49 MouseShapeObserver* mouse_shape_observer) OVERRIDE { | |
50 NOTIMPLEMENTED(); | |
51 } | |
52 | |
53 protected: | |
54 Callback* callback_; | |
55 | |
56 DISALLOW_COPY_AND_ASSIGN(FakeScreenCapturer); | |
57 }; | |
58 | |
59 class FakeWindowCapturer : public webrtc::WindowCapturer { | |
60 public: | |
61 FakeWindowCapturer() | |
62 : callback_(NULL) { | |
63 } | |
64 virtual ~FakeWindowCapturer() {} | |
65 | |
66 void SetWindowList(const WindowList& list) { | |
67 base::AutoLock lock(window_list_lock_); | |
68 window_list_ = list; | |
69 } | |
70 | |
71 // Sets |value| thats going to be used to memset() content of the frames | |
72 // generated for |window_id|. By default generated frames are set to zeros. | |
73 void SetNextFrameValue(WindowId window_id, int8_t value) { | |
74 base::AutoLock lock(frame_values_lock_); | |
75 frame_values_[window_id] = value; | |
76 } | |
77 | |
78 // webrtc::WindowCapturer implementation. | |
79 virtual void Start(Callback* callback) OVERRIDE { | |
80 callback_ = callback; | |
81 } | |
82 | |
83 virtual void Capture(const webrtc::DesktopRegion& region) OVERRIDE { | |
84 DCHECK(callback_); | |
85 | |
86 base::AutoLock lock(frame_values_lock_); | |
87 | |
88 std::map<WindowId, int8_t>::iterator it = | |
89 frame_values_.find(selected_window_id_); | |
90 int8_t value = (it != frame_values_.end()) ? it->second : 0; | |
91 webrtc::DesktopFrame* frame = | |
92 new webrtc::BasicDesktopFrame(webrtc::DesktopSize(10, 10)); | |
93 memset(frame->data(), value, frame->stride() * frame->size().height()); | |
94 callback_->OnCaptureCompleted(frame); | |
95 } | |
96 | |
97 virtual bool GetWindowList(WindowList* windows) OVERRIDE { | |
98 base::AutoLock lock(window_list_lock_); | |
99 *windows = window_list_; | |
100 return true; | |
101 } | |
102 | |
103 virtual bool SelectWindow(WindowId id) OVERRIDE { | |
104 selected_window_id_ = id; | |
105 return true; | |
106 } | |
107 | |
108 private: | |
109 Callback* callback_; | |
110 WindowList window_list_; | |
111 base::Lock window_list_lock_; | |
112 | |
113 WindowId selected_window_id_; | |
114 | |
115 // Frames to be captured per window. | |
116 std::map<WindowId, int8_t> frame_values_; | |
117 base::Lock frame_values_lock_; | |
118 | |
119 DISALLOW_COPY_AND_ASSIGN(FakeWindowCapturer); | |
120 }; | |
121 | |
122 class DesktopMediaPickerModelTest : public testing::Test { | |
123 public: | |
124 DesktopMediaPickerModelTest() | |
125 : window_capturer_(NULL), | |
126 ui_thread_(content::BrowserThread::UI, | |
127 &message_loop_) { | |
128 } | |
129 | |
130 void CreateWithDefaultCapturers() { | |
131 window_capturer_ = new FakeWindowCapturer(); | |
132 model_.reset(new DesktopMediaPickerModelImpl( | |
133 scoped_ptr<webrtc::ScreenCapturer>(new FakeScreenCapturer()), | |
134 scoped_ptr<webrtc::WindowCapturer>(window_capturer_))); | |
135 | |
136 // Set update period to reduce the time it takes to run tests. | |
137 model_->SetUpdatePeriod(base::TimeDelta::FromMilliseconds(0)); | |
138 } | |
139 | |
140 protected: | |
141 // Must be listed before |model_|, so it's destroyed last. | |
142 MockObserver observer_; | |
143 | |
144 // Owned by |model_|; | |
145 FakeWindowCapturer* window_capturer_; | |
146 | |
147 scoped_ptr<DesktopMediaPickerModelImpl> model_; | |
148 | |
149 base::MessageLoop message_loop_; | |
150 content::TestBrowserThread ui_thread_; | |
151 | |
152 DISALLOW_COPY_AND_ASSIGN(DesktopMediaPickerModelTest); | |
153 }; | |
154 | |
155 ACTION_P2(CheckListSize, model, expected_list_size) { | |
156 EXPECT_EQ(expected_list_size, model->source_count()); | |
157 } | |
158 | |
159 ACTION_P(QuitMessageLoop, message_loop) { | |
160 message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); | |
161 } | |
162 | |
163 TEST_F(DesktopMediaPickerModelTest, InitialSourceList) { | |
164 CreateWithDefaultCapturers(); | |
165 | |
166 webrtc::WindowCapturer::WindowList list; | |
167 webrtc::WindowCapturer::Window window; | |
168 window.id = 0; | |
169 window.title = "Test window"; | |
170 list.push_back(window); | |
171 window_capturer_->SetWindowList(list); | |
172 | |
173 { | |
174 testing::InSequence dummy; | |
175 EXPECT_CALL(observer_, OnSourceAdded(0)) | |
176 .WillOnce(CheckListSize(model_.get(), 1)); | |
177 EXPECT_CALL(observer_, OnSourceAdded(1)) | |
178 .WillOnce(CheckListSize(model_.get(), 2)); | |
179 EXPECT_CALL(observer_, OnSourceThumbnailChanged(0)); | |
180 EXPECT_CALL(observer_, OnSourceThumbnailChanged(1)) | |
181 .WillOnce(QuitMessageLoop(&message_loop_)); | |
182 } | |
183 model_->StartUpdating(&observer_); | |
184 | |
185 message_loop_.Run(); | |
186 | |
187 EXPECT_EQ(model_->source(0).id.type, content::DesktopMediaID::TYPE_SCREEN); | |
188 EXPECT_EQ(model_->source(0).id.id, 0); | |
189 EXPECT_EQ(model_->source(1).id.type, content::DesktopMediaID::TYPE_WINDOW); | |
190 EXPECT_EQ(model_->source(1).id.id, 0); | |
191 EXPECT_EQ(model_->source(1).name, UTF8ToUTF16(window.title)); | |
192 } | |
193 | |
194 // Verifies that the window specified with SetViewDialogWindowId() is filtered | |
195 // from the results. | |
196 TEST_F(DesktopMediaPickerModelTest, Filtering) { | |
197 CreateWithDefaultCapturers(); | |
198 | |
199 webrtc::WindowCapturer::WindowList list; | |
200 webrtc::WindowCapturer::Window window; | |
201 | |
202 window.id = 0; | |
203 window.title = "Test window"; | |
204 list.push_back(window); | |
205 | |
206 window.id = 1; | |
207 list.push_back(window); | |
208 | |
209 window_capturer_->SetWindowList(list); | |
210 | |
211 { | |
212 testing::InSequence dummy; | |
213 EXPECT_CALL(observer_, OnSourceAdded(0)) | |
214 .WillOnce(CheckListSize(model_.get(), 1)); | |
215 EXPECT_CALL(observer_, OnSourceAdded(1)) | |
216 .WillOnce(CheckListSize(model_.get(), 2)); | |
217 EXPECT_CALL(observer_, OnSourceThumbnailChanged(0)); | |
218 EXPECT_CALL(observer_, OnSourceThumbnailChanged(1)) | |
219 .WillOnce(QuitMessageLoop(&message_loop_)); | |
220 } | |
221 | |
222 model_->SetViewDialogWindowId(0); | |
223 | |
224 model_->StartUpdating(&observer_); | |
225 message_loop_.Run(); | |
226 | |
227 EXPECT_EQ(model_->source(0).id.type, content::DesktopMediaID::TYPE_SCREEN); | |
228 EXPECT_EQ(model_->source(0).id.id, 0); | |
229 EXPECT_EQ(model_->source(1).id.type, content::DesktopMediaID::TYPE_WINDOW); | |
230 EXPECT_EQ(model_->source(1).id.id, 1); | |
231 EXPECT_EQ(model_->source(1).name, UTF8ToUTF16(window.title)); | |
232 } | |
233 | |
234 TEST_F(DesktopMediaPickerModelTest, WindowsOnly) { | |
235 window_capturer_ = new FakeWindowCapturer(); | |
236 model_.reset(new DesktopMediaPickerModelImpl( | |
237 scoped_ptr<webrtc::ScreenCapturer>(), | |
238 scoped_ptr<webrtc::WindowCapturer>(window_capturer_))); | |
239 | |
240 webrtc::WindowCapturer::WindowList list; | |
241 webrtc::WindowCapturer::Window window; | |
242 window.id = 0; | |
243 window.title = "Test window"; | |
244 list.push_back(window); | |
245 window_capturer_->SetWindowList(list); | |
246 | |
247 { | |
248 testing::InSequence dummy; | |
249 EXPECT_CALL(observer_, OnSourceAdded(0)) | |
250 .WillOnce(CheckListSize(model_.get(), 1)); | |
251 EXPECT_CALL(observer_, OnSourceThumbnailChanged(0)) | |
252 .WillOnce(QuitMessageLoop(&message_loop_)); | |
253 } | |
254 model_->StartUpdating(&observer_); | |
255 | |
256 message_loop_.Run(); | |
257 | |
258 EXPECT_EQ(model_->source(0).id.type, content::DesktopMediaID::TYPE_WINDOW); | |
259 } | |
260 | |
261 TEST_F(DesktopMediaPickerModelTest, ScreenOnly) { | |
262 model_.reset(new DesktopMediaPickerModelImpl( | |
263 scoped_ptr<webrtc::ScreenCapturer>(new FakeScreenCapturer), | |
264 scoped_ptr<webrtc::WindowCapturer>())); | |
265 | |
266 { | |
267 testing::InSequence dummy; | |
268 EXPECT_CALL(observer_, OnSourceAdded(0)) | |
269 .WillOnce(CheckListSize(model_.get(), 1)); | |
270 EXPECT_CALL(observer_, OnSourceThumbnailChanged(0)) | |
271 .WillOnce(QuitMessageLoop(&message_loop_)); | |
272 } | |
273 model_->StartUpdating(&observer_); | |
274 | |
275 message_loop_.Run(); | |
276 | |
277 EXPECT_EQ(model_->source(0).id.type, content::DesktopMediaID::TYPE_SCREEN); | |
278 } | |
279 | |
280 TEST_F(DesktopMediaPickerModelTest, AddWindow) { | |
281 CreateWithDefaultCapturers(); | |
282 | |
283 webrtc::WindowCapturer::WindowList list; | |
284 webrtc::WindowCapturer::Window window; | |
285 window.id = 1; | |
286 window.title = "Test window 1"; | |
287 list.push_back(window); | |
288 window_capturer_->SetWindowList(list); | |
289 | |
290 { | |
291 testing::InSequence dummy; | |
292 EXPECT_CALL(observer_, OnSourceAdded(0)) | |
293 .WillOnce(CheckListSize(model_.get(), 1)); | |
294 EXPECT_CALL(observer_, OnSourceAdded(1)) | |
295 .WillOnce(CheckListSize(model_.get(), 2)); | |
296 EXPECT_CALL(observer_, OnSourceThumbnailChanged(0)); | |
297 EXPECT_CALL(observer_, OnSourceThumbnailChanged(1)) | |
298 .WillOnce(QuitMessageLoop(&message_loop_)); | |
299 } | |
300 model_->StartUpdating(&observer_); | |
301 | |
302 message_loop_.Run(); | |
303 | |
304 testing::Mock::VerifyAndClearExpectations(&observer_); | |
305 | |
306 EXPECT_CALL(observer_, OnSourceAdded(1)) | |
307 .WillOnce(DoAll(CheckListSize(model_.get(), 3), | |
308 QuitMessageLoop(&message_loop_))); | |
309 | |
310 window.id = 0; | |
311 window.title = "Test window 0"; | |
312 list.push_back(window); | |
313 window_capturer_->SetWindowList(list); | |
314 | |
315 message_loop_.Run(); | |
316 | |
317 EXPECT_EQ(model_->source(1).id.type, content::DesktopMediaID::TYPE_WINDOW); | |
318 EXPECT_EQ(model_->source(1).id.id, 0); | |
319 } | |
320 | |
321 TEST_F(DesktopMediaPickerModelTest, RemoveWindow) { | |
322 CreateWithDefaultCapturers(); | |
323 | |
324 webrtc::WindowCapturer::WindowList list; | |
325 webrtc::WindowCapturer::Window window; | |
326 window.id = 0; | |
327 window.title = "Test window 0"; | |
328 list.push_back(window); | |
329 window.id = 1; | |
330 window.title = "Test window 1"; | |
331 list.push_back(window); | |
332 window_capturer_->SetWindowList(list); | |
333 | |
334 { | |
335 testing::InSequence dummy; | |
336 EXPECT_CALL(observer_, OnSourceAdded(0)) | |
337 .WillOnce(CheckListSize(model_.get(), 1)); | |
338 EXPECT_CALL(observer_, OnSourceAdded(1)) | |
339 .WillOnce(CheckListSize(model_.get(), 2)); | |
340 EXPECT_CALL(observer_, OnSourceAdded(2)) | |
341 .WillOnce(CheckListSize(model_.get(), 3)); | |
342 EXPECT_CALL(observer_, OnSourceThumbnailChanged(0)); | |
343 EXPECT_CALL(observer_, OnSourceThumbnailChanged(1)); | |
344 EXPECT_CALL(observer_, OnSourceThumbnailChanged(2)) | |
345 .WillOnce(QuitMessageLoop(&message_loop_)); | |
346 } | |
347 model_->StartUpdating(&observer_); | |
348 | |
349 message_loop_.Run(); | |
350 | |
351 testing::Mock::VerifyAndClearExpectations(&observer_); | |
352 | |
353 EXPECT_CALL(observer_, OnSourceRemoved(1)) | |
354 .WillOnce(DoAll(CheckListSize(model_.get(), 2), | |
355 QuitMessageLoop(&message_loop_))); | |
356 | |
357 list.erase(list.begin()); | |
358 window_capturer_->SetWindowList(list); | |
359 | |
360 message_loop_.Run(); | |
361 } | |
362 | |
363 TEST_F(DesktopMediaPickerModelTest, UpdateTitle) { | |
364 CreateWithDefaultCapturers(); | |
365 | |
366 webrtc::WindowCapturer::WindowList list; | |
367 webrtc::WindowCapturer::Window window; | |
368 window.id = 0; | |
369 window.title = "Test window"; | |
370 list.push_back(window); | |
371 window_capturer_->SetWindowList(list); | |
372 | |
373 { | |
374 testing::InSequence dummy; | |
375 EXPECT_CALL(observer_, OnSourceAdded(0)) | |
376 .WillOnce(CheckListSize(model_.get(), 1)); | |
377 EXPECT_CALL(observer_, OnSourceAdded(1)) | |
378 .WillOnce(CheckListSize(model_.get(), 2)); | |
379 EXPECT_CALL(observer_, OnSourceThumbnailChanged(0)); | |
380 EXPECT_CALL(observer_, OnSourceThumbnailChanged(1)) | |
381 .WillOnce(QuitMessageLoop(&message_loop_)); | |
382 } | |
383 model_->StartUpdating(&observer_); | |
384 | |
385 message_loop_.Run(); | |
386 | |
387 testing::Mock::VerifyAndClearExpectations(&observer_); | |
388 | |
389 EXPECT_CALL(observer_, OnSourceNameChanged(1)) | |
390 .WillOnce(QuitMessageLoop(&message_loop_)); | |
391 | |
392 const std::string kTestTitle = "New Title"; | |
393 | |
394 list[0].title = kTestTitle; | |
395 window_capturer_->SetWindowList(list); | |
396 | |
397 message_loop_.Run(); | |
398 | |
399 EXPECT_EQ(model_->source(1).name, base::UTF8ToUTF16(kTestTitle)); | |
400 } | |
401 | |
402 TEST_F(DesktopMediaPickerModelTest, UpdateThumbnail) { | |
403 CreateWithDefaultCapturers(); | |
404 | |
405 webrtc::WindowCapturer::WindowList list; | |
406 webrtc::WindowCapturer::Window window; | |
407 window.id = 0; | |
408 window.title = "Test window 1"; | |
409 list.push_back(window); | |
410 window.id = 1; | |
411 window.title = "Test window 2"; | |
412 list.push_back(window); | |
413 window_capturer_->SetWindowList(list); | |
414 | |
415 { | |
416 testing::InSequence dummy; | |
417 EXPECT_CALL(observer_, OnSourceAdded(0)) | |
418 .WillOnce(CheckListSize(model_.get(), 1)); | |
419 EXPECT_CALL(observer_, OnSourceAdded(1)) | |
420 .WillOnce(CheckListSize(model_.get(), 2)); | |
421 EXPECT_CALL(observer_, OnSourceAdded(2)) | |
422 .WillOnce(CheckListSize(model_.get(), 3)); | |
423 EXPECT_CALL(observer_, OnSourceThumbnailChanged(0)); | |
424 EXPECT_CALL(observer_, OnSourceThumbnailChanged(1)); | |
425 EXPECT_CALL(observer_, OnSourceThumbnailChanged(2)) | |
426 .WillOnce(QuitMessageLoop(&message_loop_)); | |
427 } | |
428 model_->StartUpdating(&observer_); | |
429 | |
430 message_loop_.Run(); | |
431 | |
432 testing::Mock::VerifyAndClearExpectations(&observer_); | |
433 | |
434 EXPECT_CALL(observer_, OnSourceThumbnailChanged(1)) | |
435 .WillOnce(QuitMessageLoop(&message_loop_)); | |
436 | |
437 // Update frame for the window and verify that we get notification about it. | |
438 window_capturer_->SetNextFrameValue(0, 1); | |
439 | |
440 message_loop_.Run(); | |
441 } | |
442 | |
443 } // namespace | |
OLD | NEW |