- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / media / desktop_media_picker_model_unittest.cc
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