Ignore non-active fullscreen windows for shelf state.
[chromium-blink-merge.git] / content / browser / renderer_host / media / desktop_capture_device_unittest.cc
blobea94cc20198999317c4eeebce5c39796c01afc78
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.
5 #include "content/browser/renderer_host/media/desktop_capture_device.h"
7 #include "base/basictypes.h"
8 #include "base/sequenced_task_runner.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "base/test/test_timeouts.h"
11 #include "base/threading/sequenced_worker_pool.h"
12 #include "base/time/time.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
16 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
17 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
19 using ::testing::_;
20 using ::testing::AnyNumber;
21 using ::testing::DoAll;
22 using ::testing::Expectation;
23 using ::testing::InvokeWithoutArgs;
24 using ::testing::SaveArg;
26 namespace content {
28 namespace {
30 MATCHER_P2(EqualsCaptureCapability, width, height, "") {
31 return arg.width == width && arg.height == height;
34 const int kTestFrameWidth1 = 100;
35 const int kTestFrameHeight1 = 100;
36 const int kTestFrameWidth2 = 200;
37 const int kTestFrameHeight2 = 150;
39 const int kFrameRate = 30;
41 class MockDeviceClient : public media::VideoCaptureDevice::Client {
42 public:
43 MOCK_METHOD2(ReserveOutputBuffer,
44 scoped_refptr<Buffer>(media::VideoFrame::Format format,
45 const gfx::Size& dimensions));
46 MOCK_METHOD0(OnError, void());
47 MOCK_METHOD7(OnIncomingCapturedFrame,
48 void(const uint8* data,
49 int length,
50 base::Time timestamp,
51 int rotation,
52 bool flip_vert,
53 bool flip_horiz,
54 const media::VideoCaptureFormat& frame_format));
55 MOCK_METHOD5(OnIncomingCapturedBuffer,
56 void(const scoped_refptr<Buffer>& buffer,
57 media::VideoFrame::Format format,
58 const gfx::Size& dimensions,
59 base::Time timestamp,
60 int frame_rate));
63 // DesktopFrame wrapper that flips wrapped frame upside down by inverting
64 // stride.
65 class InvertedDesktopFrame : public webrtc::DesktopFrame {
66 public:
67 // Takes ownership of |frame|.
68 InvertedDesktopFrame(webrtc::DesktopFrame* frame)
69 : webrtc::DesktopFrame(
70 frame->size(), -frame->stride(),
71 frame->data() + (frame->size().height() - 1) * frame->stride(),
72 frame->shared_memory()),
73 original_frame_(frame) {
74 set_dpi(frame->dpi());
75 set_capture_time_ms(frame->capture_time_ms());
76 mutable_updated_region()->Swap(frame->mutable_updated_region());
78 virtual ~InvertedDesktopFrame() {}
80 private:
81 scoped_ptr<webrtc::DesktopFrame> original_frame_;
83 DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame);
86 // TODO(sergeyu): Move this to a separate file where it can be reused.
87 class FakeScreenCapturer : public webrtc::ScreenCapturer {
88 public:
89 FakeScreenCapturer()
90 : callback_(NULL),
91 frame_index_(0),
92 generate_inverted_frames_(false) {
94 virtual ~FakeScreenCapturer() {}
96 void set_generate_inverted_frames(bool generate_inverted_frames) {
97 generate_inverted_frames_ = generate_inverted_frames;
100 // VideoFrameCapturer interface.
101 virtual void Start(Callback* callback) OVERRIDE {
102 callback_ = callback;
105 virtual void Capture(const webrtc::DesktopRegion& region) OVERRIDE {
106 webrtc::DesktopSize size;
107 if (frame_index_ % 2 == 0) {
108 size = webrtc::DesktopSize(kTestFrameWidth1, kTestFrameHeight1);
109 } else {
110 size = webrtc::DesktopSize(kTestFrameWidth2, kTestFrameHeight2);
112 frame_index_++;
114 webrtc::DesktopFrame* frame = new webrtc::BasicDesktopFrame(size);
115 if (generate_inverted_frames_)
116 frame = new InvertedDesktopFrame(frame);
117 callback_->OnCaptureCompleted(frame);
120 virtual void SetMouseShapeObserver(
121 MouseShapeObserver* mouse_shape_observer) OVERRIDE {
124 private:
125 Callback* callback_;
126 int frame_index_;
127 bool generate_inverted_frames_;
130 class DesktopCaptureDeviceTest : public testing::Test {
131 public:
132 virtual void SetUp() OVERRIDE {
133 worker_pool_ = new base::SequencedWorkerPool(3, "TestCaptureThread");
136 protected:
137 scoped_refptr<base::SequencedWorkerPool> worker_pool_;
140 } // namespace
142 // There is currently no screen capturer implementation for ozone. So disable
143 // the test that uses a real screen-capturer instead of FakeScreenCapturer.
144 // http://crbug.com/260318
145 #if defined(USE_OZONE)
146 #define MAYBE_Capture DISABLED_Capture
147 #else
148 #define MAYBE_Capture Capture
149 #endif
150 TEST_F(DesktopCaptureDeviceTest, MAYBE_Capture) {
151 scoped_ptr<webrtc::DesktopCapturer> capturer(
152 webrtc::ScreenCapturer::Create());
153 DesktopCaptureDevice capture_device(
154 worker_pool_->GetSequencedTaskRunner(worker_pool_->GetSequenceToken()),
155 capturer.Pass());
156 media::VideoCaptureFormat format;
157 base::WaitableEvent done_event(false, false);
158 int frame_size;
160 scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
161 EXPECT_CALL(*client, OnError()).Times(0);
162 EXPECT_CALL(*client, OnIncomingCapturedFrame(_, _, _, _, _, _, _))
163 .WillRepeatedly(
164 DoAll(SaveArg<1>(&frame_size),
165 SaveArg<6>(&format),
166 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
168 media::VideoCaptureParams capture_params;
169 capture_params.requested_format.frame_size.SetSize(640, 480);
170 capture_params.requested_format.frame_rate = kFrameRate;
171 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
172 capture_params.allow_resolution_change = false;
173 capture_device.AllocateAndStart(
174 capture_params, client.PassAs<media::VideoCaptureDevice::Client>());
175 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
176 capture_device.StopAndDeAllocate();
178 EXPECT_GT(format.frame_size.width(), 0);
179 EXPECT_GT(format.frame_size.height(), 0);
180 EXPECT_EQ(kFrameRate, format.frame_rate);
181 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format);
183 EXPECT_EQ(format.frame_size.GetArea() * 4, frame_size);
184 worker_pool_->FlushForTesting();
187 // Verify that frames are flipped when the capturer generates inverted frames.
188 TEST_F(DesktopCaptureDeviceTest, InvertedFrame) {
189 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer();
190 mock_capturer->set_generate_inverted_frames(true);
192 DesktopCaptureDevice capture_device(
193 worker_pool_->GetSequencedTaskRunner(worker_pool_->GetSequenceToken()),
194 scoped_ptr<webrtc::DesktopCapturer>(mock_capturer));
195 base::WaitableEvent done_event(false, false);
197 scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
198 EXPECT_CALL(*client, OnError()).Times(0);
200 // Expect that |flop_vert| is set to true.
201 EXPECT_CALL(*client, OnIncomingCapturedFrame(_, _, _, _, true, false, _))
202 .WillRepeatedly(
203 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal));
205 media::VideoCaptureParams capture_params;
206 capture_params.requested_format.frame_size.SetSize(640, 480);
207 capture_params.requested_format.frame_rate = kFrameRate;
208 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
209 capture_params.allow_resolution_change = false;
210 capture_device.AllocateAndStart(
211 capture_params, client.PassAs<media::VideoCaptureDevice::Client>());
212 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
213 capture_device.StopAndDeAllocate();
215 worker_pool_->FlushForTesting();
218 // Test that screen capturer behaves correctly if the source frame size changes
219 // but the caller cannot cope with variable resolution output.
220 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeConstantResolution) {
221 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer();
223 DesktopCaptureDevice capture_device(
224 worker_pool_->GetSequencedTaskRunner(worker_pool_->GetSequenceToken()),
225 scoped_ptr<webrtc::DesktopCapturer>(mock_capturer));
227 media::VideoCaptureFormat format;
228 base::WaitableEvent done_event(false, false);
229 int frame_size;
231 scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
232 EXPECT_CALL(*client, OnError()).Times(0);
233 EXPECT_CALL(*client, OnIncomingCapturedFrame(_, _, _, _, false, false, _))
234 .WillRepeatedly(
235 DoAll(SaveArg<1>(&frame_size),
236 SaveArg<6>(&format),
237 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
239 media::VideoCaptureParams capture_params;
240 capture_params.requested_format.frame_size.SetSize(kTestFrameWidth1,
241 kTestFrameHeight1);
242 capture_params.requested_format.frame_rate = kFrameRate;
243 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
244 capture_params.allow_resolution_change = false;
246 capture_device.AllocateAndStart(
247 capture_params, client.PassAs<media::VideoCaptureDevice::Client>());
249 // Capture at least two frames, to ensure that the source frame size has
250 // changed while capturing.
251 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
252 done_event.Reset();
253 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
255 capture_device.StopAndDeAllocate();
257 EXPECT_EQ(kTestFrameWidth1, format.frame_size.width());
258 EXPECT_EQ(kTestFrameHeight1, format.frame_size.height());
259 EXPECT_EQ(kFrameRate, format.frame_rate);
260 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format);
262 EXPECT_EQ(format.frame_size.GetArea() * 4, frame_size);
263 worker_pool_->FlushForTesting();
266 // Test that screen capturer behaves correctly if the source frame size changes
267 // and the caller can cope with variable resolution output.
268 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeVariableResolution) {
269 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer();
271 DesktopCaptureDevice capture_device(
272 worker_pool_->GetSequencedTaskRunner(worker_pool_->GetSequenceToken()),
273 scoped_ptr<webrtc::DesktopCapturer>(mock_capturer));
275 media::VideoCaptureFormat format;
276 base::WaitableEvent done_event(false, false);
278 scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
279 EXPECT_CALL(*client, OnError()).Times(0);
280 EXPECT_CALL(*client, OnIncomingCapturedFrame(_, _, _, _, _, _, _))
281 .WillRepeatedly(
282 DoAll(SaveArg<6>(&format),
283 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
285 media::VideoCaptureParams capture_params;
286 capture_params.requested_format.frame_size.SetSize(kTestFrameWidth2,
287 kTestFrameHeight2);
288 capture_params.requested_format.frame_rate = kFrameRate;
289 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
290 capture_params.allow_resolution_change = false;
292 capture_device.AllocateAndStart(
293 capture_params, client.PassAs<media::VideoCaptureDevice::Client>());
295 // Capture at least three frames, to ensure that the source frame size has
296 // changed at least twice while capturing.
297 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
298 done_event.Reset();
299 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
300 done_event.Reset();
301 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
303 capture_device.StopAndDeAllocate();
305 EXPECT_EQ(kTestFrameWidth1, format.frame_size.width());
306 EXPECT_EQ(kTestFrameHeight1, format.frame_size.height());
307 EXPECT_EQ(kFrameRate, format.frame_rate);
308 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format);
309 worker_pool_->FlushForTesting();
312 } // namespace content