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