Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / browser / media / capture / desktop_capture_device_unittest.cc
1 // Copyright (c) 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 "content/browser/media/capture/desktop_capture_device.h"
6
7 #include <string>
8
9 #include "base/basictypes.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "base/test/test_timeouts.h"
12 #include "base/time/time.h"
13 #include "content/public/test/test_browser_thread_bundle.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
17 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
18 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
19
20 using ::testing::_;
21 using ::testing::AnyNumber;
22 using ::testing::DoAll;
23 using ::testing::Expectation;
24 using ::testing::InvokeWithoutArgs;
25 using ::testing::SaveArg;
26
27 namespace content {
28
29 namespace {
30
31 MATCHER_P2(EqualsCaptureCapability, width, height, "") {
32   return arg.width == width && arg.height == height;
33 }
34
35 const int kTestFrameWidth1 = 100;
36 const int kTestFrameHeight1 = 100;
37 const int kTestFrameWidth2 = 200;
38 const int kTestFrameHeight2 = 150;
39
40 const int kFrameRate = 30;
41
42 class MockDeviceClient : public media::VideoCaptureDevice::Client {
43  public:
44   MOCK_METHOD2(ReserveOutputBuffer,
45                scoped_refptr<Buffer>(media::VideoFrame::Format format,
46                                      const gfx::Size& dimensions));
47   MOCK_METHOD1(OnError, void(const std::string& reason));
48   MOCK_METHOD5(OnIncomingCapturedData,
49                void(const uint8* data,
50                     int length,
51                     const media::VideoCaptureFormat& frame_format,
52                     int rotation,
53                     base::TimeTicks timestamp));
54   MOCK_METHOD4(OnIncomingCapturedVideoFrame,
55                void(const scoped_refptr<Buffer>& buffer,
56                     const media::VideoCaptureFormat& buffer_format,
57                     const scoped_refptr<media::VideoFrame>& frame,
58                     base::TimeTicks timestamp));
59 };
60
61 // DesktopFrame wrapper that flips wrapped frame upside down by inverting
62 // stride.
63 class InvertedDesktopFrame : public webrtc::DesktopFrame {
64  public:
65   // Takes ownership of |frame|.
66   explicit InvertedDesktopFrame(webrtc::DesktopFrame* frame)
67       : webrtc::DesktopFrame(
68             frame->size(),
69             -frame->stride(),
70             frame->data() + (frame->size().height() - 1) * frame->stride(),
71             frame->shared_memory()),
72         original_frame_(frame) {
73     set_dpi(frame->dpi());
74     set_capture_time_ms(frame->capture_time_ms());
75     mutable_updated_region()->Swap(frame->mutable_updated_region());
76   }
77   ~InvertedDesktopFrame() override {}
78
79  private:
80   scoped_ptr<webrtc::DesktopFrame> original_frame_;
81
82   DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame);
83 };
84
85 // TODO(sergeyu): Move this to a separate file where it can be reused.
86 class FakeScreenCapturer : public webrtc::ScreenCapturer {
87  public:
88   FakeScreenCapturer()
89       : callback_(NULL),
90         frame_index_(0),
91         generate_inverted_frames_(false) {
92   }
93   ~FakeScreenCapturer() override {}
94
95   void set_generate_inverted_frames(bool generate_inverted_frames) {
96     generate_inverted_frames_ = generate_inverted_frames;
97   }
98
99   // VideoFrameCapturer interface.
100   void Start(Callback* callback) override { callback_ = callback; }
101
102   void Capture(const webrtc::DesktopRegion& region) override {
103     webrtc::DesktopSize size;
104     if (frame_index_ % 2 == 0) {
105       size = webrtc::DesktopSize(kTestFrameWidth1, kTestFrameHeight1);
106     } else {
107       size = webrtc::DesktopSize(kTestFrameWidth2, kTestFrameHeight2);
108     }
109     frame_index_++;
110
111     webrtc::DesktopFrame* frame = new webrtc::BasicDesktopFrame(size);
112     if (generate_inverted_frames_)
113       frame = new InvertedDesktopFrame(frame);
114     callback_->OnCaptureCompleted(frame);
115   }
116
117   void SetMouseShapeObserver(
118       MouseShapeObserver* mouse_shape_observer) override {}
119
120   bool GetScreenList(ScreenList* screens) override { return false; }
121
122   bool SelectScreen(webrtc::ScreenId id) override { return false; }
123
124  private:
125   Callback* callback_;
126   int frame_index_;
127   bool generate_inverted_frames_;
128 };
129
130 }  // namespace
131
132 class DesktopCaptureDeviceTest : public testing::Test {
133  public:
134   void CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer> capturer) {
135     capture_device_.reset(
136         new DesktopCaptureDevice(capturer.Pass(), DesktopMediaID::TYPE_SCREEN));
137   }
138
139  protected:
140   scoped_ptr<DesktopCaptureDevice> capture_device_;
141 };
142
143 // There is currently no screen capturer implementation for ozone. So disable
144 // the test that uses a real screen-capturer instead of FakeScreenCapturer.
145 // http://crbug.com/260318
146 #if defined(USE_OZONE)
147 #define MAYBE_Capture DISABLED_Capture
148 #else
149 #define MAYBE_Capture Capture
150 #endif
151 TEST_F(DesktopCaptureDeviceTest, MAYBE_Capture) {
152   scoped_ptr<webrtc::DesktopCapturer> capturer(
153       webrtc::ScreenCapturer::Create());
154   CreateScreenCaptureDevice(capturer.Pass());
155
156   media::VideoCaptureFormat format;
157   base::WaitableEvent done_event(false, false);
158   int frame_size;
159
160   scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
161   EXPECT_CALL(*client, OnError(_)).Times(0);
162   EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
163       DoAll(SaveArg<1>(&frame_size),
164             SaveArg<2>(&format),
165             InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
166
167   media::VideoCaptureParams capture_params;
168   capture_params.requested_format.frame_size.SetSize(640, 480);
169   capture_params.requested_format.frame_rate = kFrameRate;
170   capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
171   capture_device_->AllocateAndStart(capture_params, client.Pass());
172   EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
173   capture_device_->StopAndDeAllocate();
174
175   EXPECT_GT(format.frame_size.width(), 0);
176   EXPECT_GT(format.frame_size.height(), 0);
177   EXPECT_EQ(kFrameRate, format.frame_rate);
178   EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format);
179
180   EXPECT_EQ(format.frame_size.GetArea() * 4, frame_size);
181 }
182
183 // Test that screen capturer behaves correctly if the source frame size changes
184 // but the caller cannot cope with variable resolution output.
185 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeConstantResolution) {
186   FakeScreenCapturer* mock_capturer = new FakeScreenCapturer();
187
188   CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer));
189
190   media::VideoCaptureFormat format;
191   base::WaitableEvent done_event(false, false);
192   int frame_size;
193
194   scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
195   EXPECT_CALL(*client, OnError(_)).Times(0);
196   EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
197       DoAll(SaveArg<1>(&frame_size),
198             SaveArg<2>(&format),
199             InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
200
201   media::VideoCaptureParams capture_params;
202   capture_params.requested_format.frame_size.SetSize(kTestFrameWidth1,
203                                                      kTestFrameHeight1);
204   capture_params.requested_format.frame_rate = kFrameRate;
205   capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
206
207   capture_device_->AllocateAndStart(capture_params, client.Pass());
208
209   // Capture at least two frames, to ensure that the source frame size has
210   // changed while capturing.
211   EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
212   done_event.Reset();
213   EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
214
215   capture_device_->StopAndDeAllocate();
216
217   EXPECT_EQ(kTestFrameWidth1, format.frame_size.width());
218   EXPECT_EQ(kTestFrameHeight1, format.frame_size.height());
219   EXPECT_EQ(kFrameRate, format.frame_rate);
220   EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format);
221
222   EXPECT_EQ(format.frame_size.GetArea() * 4, frame_size);
223 }
224
225 // Test that screen capturer behaves correctly if the source frame size changes
226 // and the caller can cope with variable resolution output.
227 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeVariableResolution) {
228   FakeScreenCapturer* mock_capturer = new FakeScreenCapturer();
229
230   CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer));
231
232   media::VideoCaptureFormat format;
233   base::WaitableEvent done_event(false, false);
234
235   scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
236   EXPECT_CALL(*client, OnError(_)).Times(0);
237   EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
238       DoAll(SaveArg<2>(&format),
239             InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
240
241   media::VideoCaptureParams capture_params;
242   capture_params.requested_format.frame_size.SetSize(kTestFrameWidth2,
243                                                      kTestFrameHeight2);
244   capture_params.requested_format.frame_rate = kFrameRate;
245   capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
246
247   capture_device_->AllocateAndStart(
248       capture_params, client.Pass());
249
250   // Capture at least three frames, to ensure that the source frame size has
251   // changed at least twice while capturing.
252   EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
253   done_event.Reset();
254   EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
255   done_event.Reset();
256   EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
257
258   capture_device_->StopAndDeAllocate();
259
260   EXPECT_EQ(kTestFrameWidth1, format.frame_size.width());
261   EXPECT_EQ(kTestFrameHeight1, format.frame_size.height());
262   EXPECT_EQ(kFrameRate, format.frame_rate);
263   EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format);
264 }
265
266 }  // namespace content