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

Side by Side Diff: chrome/browser/media/native_desktop_media_list_unittest.cc

Issue 2307083002: Cleanup: move WebRTC related files from chrome/browser/media to chrome/browser/media/webrtc/ (Closed)
Patch Set: Removed file wrongly resuscitated during rebase Created 4 years, 3 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
OLDNEW
(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/native_desktop_media_list.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <vector>
11
12 #include "base/location.h"
13 #include "base/macros.h"
14 #include "base/run_loop.h"
15 #include "base/single_thread_task_runner.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/synchronization/lock.h"
18 #include "chrome/browser/media/desktop_media_list_observer.h"
19 #include "content/public/test/test_browser_thread.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
23 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
24 #include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
25 #include "ui/aura/window.h"
26 #include "ui/aura/window_tree_host.h"
27 #include "ui/views/test/views_test_base.h"
28 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
29 #include "ui/views/widget/widget.h"
30
31 using content::DesktopMediaID;
32 using testing::_;
33 using testing::DoAll;
34
35 namespace {
36
37 // Aura window capture unit tests are not stable in linux. crbug.com/602494 and
38 // crbug.com/603823.
39 #if defined(OS_WIN)
40 #define ENABLE_AURA_WINDOW_TESTS
41 #endif
42
43 static const int kDefaultWindowCount = 2;
44 #if defined(ENABLE_AURA_WINDOW_TESTS)
45 static const int kDefaultAuraCount = 1;
46 #else
47 static const int kDefaultAuraCount = 0;
48 #endif
49
50 class MockObserver : public DesktopMediaListObserver {
51 public:
52 MOCK_METHOD2(OnSourceAdded, void(DesktopMediaList* list, int index));
53 MOCK_METHOD2(OnSourceRemoved, void(DesktopMediaList* list, int index));
54 MOCK_METHOD3(OnSourceMoved,
55 void(DesktopMediaList* list, int old_index, int new_index));
56 MOCK_METHOD2(OnSourceNameChanged, void(DesktopMediaList* list, int index));
57 MOCK_METHOD2(OnSourceThumbnailChanged,
58 void(DesktopMediaList* list, int index));
59 };
60
61 class FakeScreenCapturer : public webrtc::ScreenCapturer {
62 public:
63 FakeScreenCapturer() {}
64 ~FakeScreenCapturer() override {}
65
66 // webrtc::ScreenCapturer implementation.
67 void Start(Callback* callback) override { callback_ = callback; }
68
69 void Capture(const webrtc::DesktopRegion& region) override {
70 DCHECK(callback_);
71 std::unique_ptr<webrtc::DesktopFrame> frame(
72 new webrtc::BasicDesktopFrame(webrtc::DesktopSize(10, 10)));
73 memset(frame->data(), 0, frame->stride() * frame->size().height());
74 callback_->OnCaptureResult(webrtc::DesktopCapturer::Result::SUCCESS,
75 std::move(frame));
76 }
77
78 bool GetScreenList(ScreenList* screens) override {
79 webrtc::ScreenCapturer::Screen screen;
80 screen.id = 0;
81 screens->push_back(screen);
82 return true;
83 }
84
85 bool SelectScreen(webrtc::ScreenId id) override {
86 EXPECT_EQ(0, id);
87 return true;
88 }
89
90 protected:
91 Callback* callback_;
92
93 DISALLOW_COPY_AND_ASSIGN(FakeScreenCapturer);
94 };
95
96 class FakeWindowCapturer : public webrtc::WindowCapturer {
97 public:
98 FakeWindowCapturer()
99 : callback_(NULL) {
100 }
101 ~FakeWindowCapturer() override {}
102
103 void SetWindowList(const WindowList& list) {
104 base::AutoLock lock(window_list_lock_);
105 window_list_ = list;
106 }
107
108 // Sets |value| thats going to be used to memset() content of the frames
109 // generated for |window_id|. By default generated frames are set to zeros.
110 void SetNextFrameValue(WindowId window_id, int8_t value) {
111 base::AutoLock lock(frame_values_lock_);
112 frame_values_[window_id] = value;
113 }
114
115 // webrtc::WindowCapturer implementation.
116 void Start(Callback* callback) override { callback_ = callback; }
117
118 void Capture(const webrtc::DesktopRegion& region) override {
119 DCHECK(callback_);
120
121 base::AutoLock lock(frame_values_lock_);
122
123 std::map<WindowId, int8_t>::iterator it =
124 frame_values_.find(selected_window_id_);
125 int8_t value = (it != frame_values_.end()) ? it->second : 0;
126 std::unique_ptr<webrtc::DesktopFrame> frame(
127 new webrtc::BasicDesktopFrame(webrtc::DesktopSize(10, 10)));
128 memset(frame->data(), value, frame->stride() * frame->size().height());
129 callback_->OnCaptureResult(webrtc::DesktopCapturer::Result::SUCCESS,
130 std::move(frame));
131 }
132
133 bool GetWindowList(WindowList* windows) override {
134 base::AutoLock lock(window_list_lock_);
135 *windows = window_list_;
136 return true;
137 }
138
139 bool SelectWindow(WindowId id) override {
140 selected_window_id_ = id;
141 return true;
142 }
143
144 bool BringSelectedWindowToFront() override { return true; }
145
146 private:
147 Callback* callback_;
148 WindowList window_list_;
149 base::Lock window_list_lock_;
150
151 WindowId selected_window_id_;
152
153 // Frames to be captured per window.
154 std::map<WindowId, int8_t> frame_values_;
155 base::Lock frame_values_lock_;
156
157 DISALLOW_COPY_AND_ASSIGN(FakeWindowCapturer);
158 };
159
160 } // namespace
161
162 ACTION_P2(CheckListSize, model, expected_list_size) {
163 EXPECT_EQ(expected_list_size, model->GetSourceCount());
164 }
165
166 ACTION_P(QuitMessageLoop, message_loop) {
167 message_loop->task_runner()->PostTask(
168 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
169 }
170
171 class NativeDesktopMediaListTest : public views::ViewsTestBase {
172 public:
173 NativeDesktopMediaListTest()
174 : ui_thread_(content::BrowserThread::UI, message_loop()) {}
175
176 void TearDown() override {
177 for (size_t i = 0; i < desktop_widgets_.size(); i++)
178 desktop_widgets_[i].reset();
179
180 ViewsTestBase::TearDown();
181 }
182
183 void CreateWithCapturers(bool screen, bool window) {
184 webrtc::ScreenCapturer* screen_capturer = nullptr;
185 if (screen)
186 screen_capturer = new FakeScreenCapturer();
187
188 if (window)
189 window_capturer_ = new FakeWindowCapturer();
190 else
191 window_capturer_ = nullptr;
192
193 model_.reset(new NativeDesktopMediaList(
194 std::unique_ptr<webrtc::ScreenCapturer>(screen_capturer),
195 std::unique_ptr<webrtc::WindowCapturer>(window_capturer_)));
196
197 // Set update period to reduce the time it takes to run tests.
198 model_->SetUpdatePeriod(base::TimeDelta::FromMilliseconds(20));
199 }
200
201 void AddNativeWindow(int id) {
202 webrtc::WindowCapturer::Window window;
203 window.id = id;
204 window.title = "Test window";
205 window_list_.push_back(window);
206 }
207
208 #if defined(USE_AURA)
209 std::unique_ptr<views::Widget> CreateDesktopWidget() {
210 std::unique_ptr<views::Widget> widget(new views::Widget);
211 views::Widget::InitParams params;
212 params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
213 params.accept_events = false;
214 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
215 params.native_widget = new views::DesktopNativeWidgetAura(widget.get());
216 params.bounds = gfx::Rect(0, 0, 20, 20);
217 widget->Init(params);
218 widget->Show();
219 return widget;
220 }
221
222 void AddAuraWindow() {
223 webrtc::WindowCapturer::Window window;
224 window.title = "Test window";
225 // Create a aura native widow through a widget.
226 desktop_widgets_.push_back(CreateDesktopWidget());
227 // Get the native window's id.
228 aura::Window* aura_window = desktop_widgets_.back()->GetNativeWindow();
229 gfx::AcceleratedWidget widget =
230 aura_window->GetHost()->GetAcceleratedWidget();
231 #if defined(OS_WIN)
232 window.id = reinterpret_cast<DesktopMediaID::Id>(widget);
233 #else
234 window.id = widget;
235 #endif
236 // Get the aura window's id.
237 DesktopMediaID aura_id = DesktopMediaID::RegisterAuraWindow(
238 DesktopMediaID::TYPE_WINDOW, aura_window);
239 native_aura_id_map_[window.id] = aura_id.aura_id;
240
241 window_list_.push_back(window);
242 }
243
244 void RemoveAuraWindow(int index) {
245 DCHECK_LT(index, static_cast<int>(desktop_widgets_.size()));
246
247 // Get the native window's id.
248 aura::Window* aura_window = desktop_widgets_[index]->GetNativeWindow();
249 gfx::AcceleratedWidget widget =
250 aura_window->GetHost()->GetAcceleratedWidget();
251 #if defined(OS_WIN)
252 int native_id = reinterpret_cast<DesktopMediaID::Id>(widget);
253 #else
254 int native_id = widget;
255 #endif
256 // Remove the widget and assoicate aura window.
257 desktop_widgets_.erase(desktop_widgets_.begin() + index);
258 // Remove the aura window from the window list.
259 size_t i;
260 for (i = 0; i < window_list_.size(); i++) {
261 if (window_list_[i].id == native_id)
262 break;
263 }
264 DCHECK_LT(i, window_list_.size());
265 window_list_.erase(window_list_.begin() + i);
266 native_aura_id_map_.erase(native_id);
267 }
268
269 #endif // defined(USE_AURA)
270
271 void AddWindowsAndVerify(bool screen,
272 size_t window_count,
273 size_t aura_count,
274 bool has_view_dialog) {
275 // Create model_.
276 CreateWithCapturers(screen, window_count > 0);
277
278 #if !defined(USE_AURA)
279 aura_count = 0;
280 #endif
281 if (aura_count >= window_count)
282 aura_count = window_count - 1;
283
284 if (window_count == 0)
285 has_view_dialog = false;
286
287 // Set up widows.
288 size_t aura_window_first_index = window_count - aura_count;
289 for (size_t i = 0; i < window_count; ++i) {
290 if (i < aura_window_first_index) {
291 AddNativeWindow(i + 1);
292 } else {
293 #if defined(USE_AURA)
294 AddAuraWindow();
295 #endif
296 }
297 }
298
299 if (window_capturer_)
300 window_capturer_->SetWindowList(window_list_);
301
302 // Set view dialog window ID as the first window id.
303 if (has_view_dialog) {
304 DesktopMediaID dialog_window_id(DesktopMediaID::TYPE_WINDOW,
305 window_list_[0].id);
306 model_->SetViewDialogWindowId(dialog_window_id);
307 window_count--;
308 aura_window_first_index--;
309 }
310
311 {
312 testing::InSequence dummy;
313 size_t source_count = screen ? window_count + 1 : window_count;
314 for (size_t i = 0; i < source_count; ++i) {
315 EXPECT_CALL(observer_, OnSourceAdded(model_.get(), i))
316 .WillOnce(CheckListSize(model_.get(), static_cast<int>(i + 1)));
317 }
318 for (size_t i = 0; i < source_count - 1; ++i) {
319 EXPECT_CALL(observer_, OnSourceThumbnailChanged(model_.get(), i));
320 }
321 EXPECT_CALL(observer_,
322 OnSourceThumbnailChanged(model_.get(), source_count - 1))
323 .WillOnce(QuitMessageLoop(message_loop()));
324 }
325 model_->StartUpdating(&observer_);
326 base::RunLoop().Run();
327
328 if (screen) {
329 EXPECT_EQ(model_->GetSource(0).id.type, DesktopMediaID::TYPE_SCREEN);
330 EXPECT_EQ(model_->GetSource(0).id.id, 0);
331 }
332
333 for (size_t i = 0; i < window_count; ++i) {
334 size_t source_index = screen ? i + 1 : i;
335 EXPECT_EQ(model_->GetSource(source_index).id.type,
336 DesktopMediaID::TYPE_WINDOW);
337 EXPECT_EQ(model_->GetSource(source_index).name,
338 base::UTF8ToUTF16("Test window"));
339 int index = has_view_dialog ? i + 1 : i;
340 int native_id = window_list_[index].id;
341 EXPECT_EQ(model_->GetSource(source_index).id.id, native_id);
342 #if defined(USE_AURA)
343 if (i >= aura_window_first_index)
344 EXPECT_EQ(model_->GetSource(source_index).id.aura_id,
345 native_aura_id_map_[native_id]);
346 #endif
347 }
348 testing::Mock::VerifyAndClearExpectations(&observer_);
349 }
350
351 protected:
352 // Must be listed before |model_|, so it's destroyed last.
353 MockObserver observer_;
354
355 // Owned by |model_|;
356 FakeWindowCapturer* window_capturer_;
357
358 webrtc::WindowCapturer::WindowList window_list_;
359 std::vector<std::unique_ptr<views::Widget>> desktop_widgets_;
360 std::map<DesktopMediaID::Id, DesktopMediaID::Id> native_aura_id_map_;
361 std::unique_ptr<NativeDesktopMediaList> model_;
362
363 content::TestBrowserThread ui_thread_;
364
365 DISALLOW_COPY_AND_ASSIGN(NativeDesktopMediaListTest);
366 };
367
368 TEST_F(NativeDesktopMediaListTest, WindowsOnly) {
369 AddWindowsAndVerify(false, kDefaultWindowCount, kDefaultAuraCount, false);
370 }
371
372 TEST_F(NativeDesktopMediaListTest, ScreenOnly) {
373 AddWindowsAndVerify(true, 0, 0, false);
374 }
375
376 // Verifies that the window specified with SetViewDialogWindowId() is filtered
377 // from the results.
378 TEST_F(NativeDesktopMediaListTest, Filtering) {
379 AddWindowsAndVerify(true, kDefaultWindowCount, kDefaultAuraCount, true);
380 }
381
382 TEST_F(NativeDesktopMediaListTest, AddNativeWindow) {
383 AddWindowsAndVerify(true, kDefaultWindowCount, kDefaultAuraCount, false);
384
385 const int index = kDefaultWindowCount + 1;
386 EXPECT_CALL(observer_, OnSourceAdded(model_.get(), index))
387 .WillOnce(DoAll(CheckListSize(model_.get(), index + 1),
388 QuitMessageLoop(message_loop())));
389
390 webrtc::WindowCapturer::Window window;
391 AddNativeWindow(index);
392 window_capturer_->SetWindowList(window_list_);
393
394 base::RunLoop().Run();
395
396 EXPECT_EQ(model_->GetSource(index).id.type, DesktopMediaID::TYPE_WINDOW);
397 EXPECT_EQ(model_->GetSource(index).id.id, index);
398 }
399
400 #if defined(ENABLE_AURA_WINDOW_TESTS)
401 TEST_F(NativeDesktopMediaListTest, AddAuraWindow) {
402 AddWindowsAndVerify(true, kDefaultWindowCount, kDefaultAuraCount, false);
403
404 const int index = kDefaultWindowCount + 1;
405 EXPECT_CALL(observer_, OnSourceAdded(model_.get(), index))
406 .WillOnce(DoAll(CheckListSize(model_.get(), index + 1),
407 QuitMessageLoop(message_loop())));
408
409 AddAuraWindow();
410 window_capturer_->SetWindowList(window_list_);
411
412 message_loop()->Run();
413
414 int native_id = window_list_.back().id;
415 EXPECT_EQ(model_->GetSource(index).id.type, DesktopMediaID::TYPE_WINDOW);
416 EXPECT_EQ(model_->GetSource(index).id.id, native_id);
417 EXPECT_EQ(model_->GetSource(index).id.aura_id,
418 native_aura_id_map_[native_id]);
419 }
420 #endif // defined(ENABLE_AURA_WINDOW_TESTS)
421
422 TEST_F(NativeDesktopMediaListTest, RemoveNativeWindow) {
423 AddWindowsAndVerify(true, kDefaultWindowCount, kDefaultAuraCount, false);
424
425 EXPECT_CALL(observer_, OnSourceRemoved(model_.get(), 1))
426 .WillOnce(DoAll(CheckListSize(model_.get(), kDefaultWindowCount),
427 QuitMessageLoop(message_loop())));
428
429 window_list_.erase(window_list_.begin());
430 window_capturer_->SetWindowList(window_list_);
431
432 base::RunLoop().Run();
433 }
434
435 #if defined(ENABLE_AURA_WINDOW_TESTS)
436 TEST_F(NativeDesktopMediaListTest, RemoveAuraWindow) {
437 AddWindowsAndVerify(true, kDefaultWindowCount, kDefaultAuraCount, false);
438
439 int aura_window_start_index = kDefaultWindowCount - kDefaultAuraCount + 1;
440 EXPECT_CALL(observer_, OnSourceRemoved(model_.get(), aura_window_start_index))
441 .WillOnce(DoAll(CheckListSize(model_.get(), kDefaultWindowCount),
442 QuitMessageLoop(message_loop())));
443
444 RemoveAuraWindow(0);
445 window_capturer_->SetWindowList(window_list_);
446
447 message_loop()->Run();
448 }
449 #endif // defined(ENABLE_AURA_WINDOW_TESTS)
450
451 TEST_F(NativeDesktopMediaListTest, RemoveAllWindows) {
452 AddWindowsAndVerify(true, kDefaultWindowCount, kDefaultAuraCount, false);
453
454 testing::InSequence seq;
455 for (int i = 0; i < kDefaultWindowCount - 1; i++) {
456 EXPECT_CALL(observer_, OnSourceRemoved(model_.get(), 1))
457 .WillOnce(CheckListSize(model_.get(), kDefaultWindowCount - i));
458 }
459 EXPECT_CALL(observer_, OnSourceRemoved(model_.get(), 1))
460 .WillOnce(DoAll(CheckListSize(model_.get(), 1),
461 QuitMessageLoop(message_loop())));
462
463 window_list_.clear();
464 window_capturer_->SetWindowList(window_list_);
465
466 base::RunLoop().Run();
467 }
468
469 TEST_F(NativeDesktopMediaListTest, UpdateTitle) {
470 AddWindowsAndVerify(true, kDefaultWindowCount, kDefaultAuraCount, false);
471
472 EXPECT_CALL(observer_, OnSourceNameChanged(model_.get(), 1))
473 .WillOnce(QuitMessageLoop(message_loop()));
474
475 const std::string kTestTitle = "New Title";
476 window_list_[0].title = kTestTitle;
477 window_capturer_->SetWindowList(window_list_);
478
479 base::RunLoop().Run();
480
481 EXPECT_EQ(model_->GetSource(1).name, base::UTF8ToUTF16(kTestTitle));
482 }
483
484 TEST_F(NativeDesktopMediaListTest, UpdateThumbnail) {
485 AddWindowsAndVerify(true, kDefaultWindowCount, kDefaultAuraCount, false);
486
487 // Aura windows' thumbnails may unpredictably change over time.
488 for (size_t i = kDefaultWindowCount - kDefaultAuraCount;
489 i < kDefaultWindowCount; ++i) {
490 EXPECT_CALL(observer_, OnSourceThumbnailChanged(model_.get(), i + 1))
491 .Times(testing::AnyNumber());
492 }
493
494 EXPECT_CALL(observer_, OnSourceThumbnailChanged(model_.get(), 1))
495 .WillOnce(QuitMessageLoop(message_loop()));
496
497 // Update frame for the window and verify that we get notification about it.
498 window_capturer_->SetNextFrameValue(1, 10);
499
500 base::RunLoop().Run();
501 }
502
503 TEST_F(NativeDesktopMediaListTest, MoveWindow) {
504 AddWindowsAndVerify(true, kDefaultWindowCount, kDefaultAuraCount, false);
505
506 EXPECT_CALL(observer_, OnSourceMoved(model_.get(), 2, 1))
507 .WillOnce(DoAll(CheckListSize(model_.get(), kDefaultWindowCount + 1),
508 QuitMessageLoop(message_loop())));
509
510 // Swap the two windows.
511 webrtc::WindowCapturer::Window temp = window_list_[0];
512 window_list_[0] = window_list_[1];
513 window_list_[1] = temp;
514 window_capturer_->SetWindowList(window_list_);
515
516 base::RunLoop().Run();
517 }
OLDNEW
« no previous file with comments | « chrome/browser/media/native_desktop_media_list.cc ('k') | chrome/browser/media/output_protection_proxy.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698