Save errno for logging before potentially overwriting it.
[chromium-blink-merge.git] / content / browser / renderer_host / media / screen_capture_device_unittest.cc
blob6a2cf2b1a0597e59409631a4b6d5d238019e979c
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/screen_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.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::DoAll;
21 using ::testing::InvokeWithoutArgs;
22 using ::testing::SaveArg;
24 namespace content {
26 namespace {
28 const int kTestFrameWidth1 = 100;
29 const int kTestFrameHeight1 = 100;
30 const int kTestFrameWidth2 = 200;
31 const int kTestFrameHeight2 = 150;
32 const int kBufferSize = kTestFrameWidth2 * kTestFrameHeight2 * 4;
34 const int kFrameRate = 30;
36 class MockFrameObserver : public media::VideoCaptureDevice::EventHandler {
37 public:
38 MOCK_METHOD0(ReserveOutputBuffer, scoped_refptr<media::VideoFrame>());
39 MOCK_METHOD0(OnError, void());
40 MOCK_METHOD1(OnFrameInfo, void(const media::VideoCaptureCapability& info));
41 MOCK_METHOD6(OnIncomingCapturedFrame, void(const uint8* data,
42 int length,
43 base::Time timestamp,
44 int rotation,
45 bool flip_vert,
46 bool flip_horiz));
47 MOCK_METHOD2(OnIncomingCapturedVideoFrame,
48 void(const scoped_refptr<media::VideoFrame>& frame,
49 base::Time timestamp));
52 // TODO(sergeyu): Move this to a separate file where it can be reused.
53 class FakeScreenCapturer : public webrtc::ScreenCapturer {
54 public:
55 FakeScreenCapturer()
56 : callback_(NULL),
57 frame_index_(0) {
59 virtual ~FakeScreenCapturer() {}
61 // VideoFrameCapturer interface.
62 virtual void Start(Callback* callback) OVERRIDE {
63 callback_ = callback;
66 virtual void Capture(const webrtc::DesktopRegion& region) OVERRIDE {
67 webrtc::DesktopSize size;
68 if (frame_index_ % 2 == 0) {
69 size = webrtc::DesktopSize(kTestFrameWidth1, kTestFrameHeight1);
70 } else {
71 size = webrtc::DesktopSize(kTestFrameWidth2, kTestFrameHeight2);
73 frame_index_++;
74 callback_->OnCaptureCompleted(new webrtc::BasicDesktopFrame(size));
77 virtual void SetMouseShapeObserver(
78 MouseShapeObserver* mouse_shape_observer) OVERRIDE {
81 private:
82 Callback* callback_;
83 int frame_index_;
86 class ScreenCaptureDeviceTest : public testing::Test {
87 public:
88 virtual void SetUp() OVERRIDE {
89 worker_pool_ = new base::SequencedWorkerPool(3, "TestCaptureThread");
92 protected:
93 scoped_refptr<base::SequencedWorkerPool> worker_pool_;
96 } // namespace
98 TEST_F(ScreenCaptureDeviceTest, Capture) {
99 ScreenCaptureDevice capture_device(
100 worker_pool_->GetSequencedTaskRunner(worker_pool_->GetSequenceToken()));
101 media::VideoCaptureCapability caps;
102 base::WaitableEvent done_event(false, false);
103 int frame_size;
105 MockFrameObserver frame_observer;
106 EXPECT_CALL(frame_observer, OnFrameInfo(_))
107 .WillOnce(SaveArg<0>(&caps));
108 EXPECT_CALL(frame_observer, OnError())
109 .Times(0);
110 EXPECT_CALL(frame_observer, OnIncomingCapturedFrame(_, _, _, _, _, _))
111 .WillRepeatedly(DoAll(
112 SaveArg<1>(&frame_size),
113 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
115 capture_device.Allocate(640, 480, kFrameRate, &frame_observer);
116 capture_device.Start();
117 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
118 capture_device.Stop();
119 capture_device.DeAllocate();
121 EXPECT_GT(caps.width, 0);
122 EXPECT_GT(caps.height, 0);
123 EXPECT_EQ(kFrameRate, caps.frame_rate);
124 EXPECT_EQ(media::VideoCaptureCapability::kARGB, caps.color);
125 EXPECT_FALSE(caps.interlaced);
127 EXPECT_EQ(caps.width * caps.height * 4, frame_size);
130 // Test that screen capturer can handle resolution change without crashing.
131 TEST_F(ScreenCaptureDeviceTest, ScreenResolutionChange) {
132 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer();
134 ScreenCaptureDevice capture_device(
135 worker_pool_->GetSequencedTaskRunner(worker_pool_->GetSequenceToken()));
136 capture_device.SetScreenCapturerForTest(
137 scoped_ptr<webrtc::ScreenCapturer>(mock_capturer));
139 media::VideoCaptureCapability caps;
140 base::WaitableEvent done_event(false, false);
141 int frame_size;
143 MockFrameObserver frame_observer;
144 EXPECT_CALL(frame_observer, OnFrameInfo(_))
145 .WillOnce(SaveArg<0>(&caps));
146 EXPECT_CALL(frame_observer, OnError())
147 .Times(0);
148 EXPECT_CALL(frame_observer, OnIncomingCapturedFrame(_, _, _, _, _, _))
149 .WillRepeatedly(DoAll(
150 SaveArg<1>(&frame_size),
151 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
153 capture_device.Allocate(kTestFrameWidth1, kTestFrameHeight1,
154 kFrameRate, &frame_observer);
155 capture_device.Start();
156 // Capture first frame.
157 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
158 done_event.Reset();
159 // Capture second frame.
160 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
161 capture_device.Stop();
162 capture_device.DeAllocate();
164 EXPECT_EQ(kTestFrameWidth1, caps.width);
165 EXPECT_EQ(kTestFrameHeight1, caps.height);
166 EXPECT_EQ(kFrameRate, caps.frame_rate);
167 EXPECT_EQ(media::VideoCaptureCapability::kARGB, caps.color);
168 EXPECT_FALSE(caps.interlaced);
170 EXPECT_EQ(caps.width * caps.height * 4, frame_size);
173 } // namespace content