Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / media / native_desktop_media_list_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/native_desktop_media_list.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 "chrome/browser/media/desktop_media_list_observer.h"
11 #include "content/public/test/test_browser_thread.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
15 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
16 #include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
17
18 using testing::_;
19 using testing::DoAll;
20
21 namespace {
22
23 class MockObserver : public DesktopMediaListObserver {
24  public:
25   MOCK_METHOD1(OnSourceAdded, void(int index));
26   MOCK_METHOD1(OnSourceRemoved, void(int index));
27   MOCK_METHOD2(OnSourceMoved, void(int old_index, int new_index));
28   MOCK_METHOD1(OnSourceNameChanged, void(int index));
29   MOCK_METHOD1(OnSourceThumbnailChanged, void(int index));
30 };
31
32 class FakeScreenCapturer : public webrtc::ScreenCapturer {
33  public:
34   FakeScreenCapturer() {}
35   ~FakeScreenCapturer() override {}
36
37   // webrtc::ScreenCapturer implementation.
38   void Start(Callback* callback) override { callback_ = callback; }
39
40   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   void SetMouseShapeObserver(
49       MouseShapeObserver* mouse_shape_observer) override {
50     NOTIMPLEMENTED();
51   }
52
53   bool GetScreenList(ScreenList* screens) override {
54     webrtc::ScreenCapturer::Screen screen;
55     screen.id = 0;
56     screens->push_back(screen);
57     return true;
58   }
59
60   bool SelectScreen(webrtc::ScreenId id) override {
61     EXPECT_EQ(0, id);
62     return true;
63   }
64
65  protected:
66   Callback* callback_;
67
68   DISALLOW_COPY_AND_ASSIGN(FakeScreenCapturer);
69 };
70
71 class FakeWindowCapturer : public webrtc::WindowCapturer {
72  public:
73   FakeWindowCapturer()
74       : callback_(NULL) {
75   }
76   ~FakeWindowCapturer() override {}
77
78   void SetWindowList(const WindowList& list) {
79     base::AutoLock lock(window_list_lock_);
80     window_list_ = list;
81   }
82
83   // Sets |value| thats going to be used to memset() content of the frames
84   // generated for |window_id|. By default generated frames are set to zeros.
85   void SetNextFrameValue(WindowId window_id, int8_t value) {
86     base::AutoLock lock(frame_values_lock_);
87     frame_values_[window_id] = value;
88   }
89
90   // webrtc::WindowCapturer implementation.
91   void Start(Callback* callback) override { callback_ = callback; }
92
93   void Capture(const webrtc::DesktopRegion& region) override {
94     DCHECK(callback_);
95
96     base::AutoLock lock(frame_values_lock_);
97
98     std::map<WindowId, int8_t>::iterator it =
99         frame_values_.find(selected_window_id_);
100     int8_t value = (it != frame_values_.end()) ? it->second : 0;
101     webrtc::DesktopFrame* frame =
102         new webrtc::BasicDesktopFrame(webrtc::DesktopSize(10, 10));
103     memset(frame->data(), value, frame->stride() * frame->size().height());
104     callback_->OnCaptureCompleted(frame);
105   }
106
107   bool GetWindowList(WindowList* windows) override {
108     base::AutoLock lock(window_list_lock_);
109     *windows = window_list_;
110     return true;
111   }
112
113   bool SelectWindow(WindowId id) override {
114     selected_window_id_ = id;
115     return true;
116   }
117
118   bool BringSelectedWindowToFront() override { return true; }
119
120  private:
121   Callback* callback_;
122   WindowList window_list_;
123   base::Lock window_list_lock_;
124
125   WindowId selected_window_id_;
126
127   // Frames to be captured per window.
128   std::map<WindowId, int8_t> frame_values_;
129   base::Lock frame_values_lock_;
130
131   DISALLOW_COPY_AND_ASSIGN(FakeWindowCapturer);
132 };
133
134 ACTION_P2(CheckListSize, model, expected_list_size) {
135   EXPECT_EQ(expected_list_size, model->GetSourceCount());
136 }
137
138 ACTION_P(QuitMessageLoop, message_loop) {
139   message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
140 }
141
142 class DesktopMediaListTest : public testing::Test {
143  public:
144   DesktopMediaListTest()
145       : window_capturer_(NULL),
146         ui_thread_(content::BrowserThread::UI,
147                    &message_loop_) {
148   }
149
150   void CreateWithDefaultCapturers() {
151     window_capturer_ = new FakeWindowCapturer();
152     model_.reset(new NativeDesktopMediaList(
153         scoped_ptr<webrtc::ScreenCapturer>(new FakeScreenCapturer()),
154         scoped_ptr<webrtc::WindowCapturer>(window_capturer_)));
155
156     // Set update period to reduce the time it takes to run tests.
157     model_->SetUpdatePeriod(base::TimeDelta::FromMilliseconds(0));
158   }
159
160   webrtc::WindowCapturer::WindowList AddWindowsAndVerify(
161       size_t count, bool window_only) {
162     webrtc::WindowCapturer::WindowList list;
163     for (size_t i = 0; i < count; ++i) {
164       webrtc::WindowCapturer::Window window;
165       window.id = i + 1;
166       window.title = "Test window";
167       list.push_back(window);
168     }
169     window_capturer_->SetWindowList(list);
170
171     {
172       testing::InSequence dummy;
173       size_t source_count = window_only ? count : count + 1;
174       for (size_t i = 0; i < source_count; ++i) {
175         EXPECT_CALL(observer_, OnSourceAdded(i))
176           .WillOnce(CheckListSize(model_.get(), static_cast<int>(i + 1)));
177       }
178       for (size_t i = 0; i < source_count - 1; ++i) {
179         EXPECT_CALL(observer_, OnSourceThumbnailChanged(i));
180       }
181       EXPECT_CALL(observer_, OnSourceThumbnailChanged(source_count - 1))
182         .WillOnce(QuitMessageLoop(&message_loop_));
183     }
184     model_->StartUpdating(&observer_);
185     message_loop_.Run();
186
187     for (size_t i = 0; i < count; ++i) {
188       size_t source_index = window_only ? i : i + 1;
189       EXPECT_EQ(model_->GetSource(source_index).id.type,
190                                   content::DesktopMediaID::TYPE_WINDOW);
191       EXPECT_EQ(model_->GetSource(source_index).id.id, static_cast<int>(i + 1));
192       EXPECT_EQ(model_->GetSource(source_index).name,
193                                   base::UTF8ToUTF16("Test window"));
194     }
195     testing::Mock::VerifyAndClearExpectations(&observer_);
196     return list;
197   }
198
199  protected:
200   // Must be listed before |model_|, so it's destroyed last.
201   MockObserver observer_;
202
203   // Owned by |model_|;
204   FakeWindowCapturer* window_capturer_;
205
206   scoped_ptr<NativeDesktopMediaList> model_;
207
208   base::MessageLoop message_loop_;
209   content::TestBrowserThread ui_thread_;
210
211   DISALLOW_COPY_AND_ASSIGN(DesktopMediaListTest);
212 };
213
214 TEST_F(DesktopMediaListTest, InitialSourceList) {
215   CreateWithDefaultCapturers();
216   webrtc::WindowCapturer::WindowList list = AddWindowsAndVerify(1, false);
217
218   EXPECT_EQ(model_->GetSource(0).id.type, content::DesktopMediaID::TYPE_SCREEN);
219   EXPECT_EQ(model_->GetSource(0).id.id, 0);
220 }
221
222 // Verifies that the window specified with SetViewDialogWindowId() is filtered
223 // from the results.
224 TEST_F(DesktopMediaListTest, Filtering) {
225   CreateWithDefaultCapturers();
226   webrtc::WindowCapturer::WindowList list = AddWindowsAndVerify(2, false);
227
228   EXPECT_EQ(model_->GetSource(0).id.type, content::DesktopMediaID::TYPE_SCREEN);
229   EXPECT_EQ(model_->GetSource(0).id.id, 0);
230 }
231
232 TEST_F(DesktopMediaListTest, WindowsOnly) {
233   window_capturer_ = new FakeWindowCapturer();
234   model_.reset(new NativeDesktopMediaList(
235       scoped_ptr<webrtc::ScreenCapturer>(),
236       scoped_ptr<webrtc::WindowCapturer>(window_capturer_)));
237   AddWindowsAndVerify(1, true);
238 }
239
240 TEST_F(DesktopMediaListTest, ScreenOnly) {
241   model_.reset(new NativeDesktopMediaList(
242       scoped_ptr<webrtc::ScreenCapturer>(new FakeScreenCapturer),
243       scoped_ptr<webrtc::WindowCapturer>()));
244
245   {
246     testing::InSequence dummy;
247     EXPECT_CALL(observer_, OnSourceAdded(0))
248       .WillOnce(CheckListSize(model_.get(), 1));
249     EXPECT_CALL(observer_, OnSourceThumbnailChanged(0))
250       .WillOnce(QuitMessageLoop(&message_loop_));
251   }
252   model_->StartUpdating(&observer_);
253
254   message_loop_.Run();
255
256   EXPECT_EQ(model_->GetSource(0).id.type, content::DesktopMediaID::TYPE_SCREEN);
257 }
258
259 TEST_F(DesktopMediaListTest, AddWindow) {
260   CreateWithDefaultCapturers();
261   webrtc::WindowCapturer::WindowList list = AddWindowsAndVerify(1, false);
262
263   EXPECT_CALL(observer_, OnSourceAdded(2))
264     .WillOnce(DoAll(CheckListSize(model_.get(), 3),
265                     QuitMessageLoop(&message_loop_)));
266
267   webrtc::WindowCapturer::Window window;
268   window.id = 0;
269   window.title = "Test window 0";
270   list.push_back(window);
271   window_capturer_->SetWindowList(list);
272
273   message_loop_.Run();
274
275   EXPECT_EQ(model_->GetSource(2).id.type, content::DesktopMediaID::TYPE_WINDOW);
276   EXPECT_EQ(model_->GetSource(2).id.id, 0);
277 }
278
279 TEST_F(DesktopMediaListTest, RemoveWindow) {
280   CreateWithDefaultCapturers();
281   webrtc::WindowCapturer::WindowList list = AddWindowsAndVerify(2, false);
282
283   EXPECT_CALL(observer_, OnSourceRemoved(2))
284     .WillOnce(DoAll(CheckListSize(model_.get(), 2),
285                     QuitMessageLoop(&message_loop_)));
286
287   list.erase(list.begin() + 1);
288   window_capturer_->SetWindowList(list);
289
290   message_loop_.Run();
291 }
292
293 TEST_F(DesktopMediaListTest, RemoveAllWindows) {
294   CreateWithDefaultCapturers();
295   webrtc::WindowCapturer::WindowList list = AddWindowsAndVerify(2, false);
296
297   testing::InSequence seq;
298   EXPECT_CALL(observer_, OnSourceRemoved(1))
299     .WillOnce(CheckListSize(model_.get(), 2));
300   EXPECT_CALL(observer_, OnSourceRemoved(1))
301     .WillOnce(DoAll(CheckListSize(model_.get(), 1),
302                     QuitMessageLoop(&message_loop_)));
303
304   list.erase(list.begin(), list.end());
305   window_capturer_->SetWindowList(list);
306
307   message_loop_.Run();
308 }
309
310 TEST_F(DesktopMediaListTest, UpdateTitle) {
311   CreateWithDefaultCapturers();
312   webrtc::WindowCapturer::WindowList list = AddWindowsAndVerify(1, false);
313
314   EXPECT_CALL(observer_, OnSourceNameChanged(1))
315     .WillOnce(QuitMessageLoop(&message_loop_));
316
317   const std::string kTestTitle = "New Title";
318
319   list[0].title = kTestTitle;
320   window_capturer_->SetWindowList(list);
321
322   message_loop_.Run();
323
324   EXPECT_EQ(model_->GetSource(1).name, base::UTF8ToUTF16(kTestTitle));
325 }
326
327 TEST_F(DesktopMediaListTest, UpdateThumbnail) {
328   CreateWithDefaultCapturers();
329   AddWindowsAndVerify(2, false);
330
331   EXPECT_CALL(observer_, OnSourceThumbnailChanged(1))
332     .WillOnce(QuitMessageLoop(&message_loop_));
333   // Update frame for the window and verify that we get notification about it.
334   window_capturer_->SetNextFrameValue(1, 1);
335
336   message_loop_.Run();
337 }
338
339 TEST_F(DesktopMediaListTest, MoveWindow) {
340   CreateWithDefaultCapturers();
341   webrtc::WindowCapturer::WindowList list = AddWindowsAndVerify(2, false);
342
343   EXPECT_CALL(observer_, OnSourceMoved(2, 1))
344     .WillOnce(DoAll(CheckListSize(model_.get(), 3),
345                     QuitMessageLoop(&message_loop_)));
346
347   // Swap the two windows.
348   webrtc::WindowCapturer::Window temp = list[0];
349   list[0] = list[1];
350   list[1] = temp;
351   window_capturer_->SetWindowList(list);
352
353   message_loop_.Run();
354 }
355
356 }  // namespace