1/*
2 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/modules/desktop_capture/screen_capturer.h"
12
13#include "testing/gmock/include/gmock/gmock.h"
14#include "testing/gtest/include/gtest/gtest.h"
15#include "webrtc/modules/desktop_capture/desktop_capture_options.h"
16#include "webrtc/modules/desktop_capture/desktop_frame.h"
17#include "webrtc/modules/desktop_capture/desktop_region.h"
18#include "webrtc/modules/desktop_capture/screen_capturer_mock_objects.h"
19
20using ::testing::_;
21using ::testing::AnyNumber;
22using ::testing::Return;
23using ::testing::SaveArg;
24
25const int kTestSharedMemoryId = 123;
26
27namespace webrtc {
28
29class ScreenCapturerTest : public testing::Test {
30 public:
31  SharedMemory* CreateSharedMemory(size_t size);
32
33  virtual void SetUp() OVERRIDE {
34    capturer_.reset(
35        ScreenCapturer::Create(DesktopCaptureOptions::CreateDefault()));
36  }
37
38 protected:
39  scoped_ptr<ScreenCapturer> capturer_;
40  MockMouseShapeObserver mouse_observer_;
41  MockScreenCapturerCallback callback_;
42};
43
44class FakeSharedMemory : public SharedMemory {
45 public:
46  FakeSharedMemory(char* buffer, size_t size)
47    : SharedMemory(buffer, size, 0, kTestSharedMemoryId),
48      buffer_(buffer) {
49  }
50  virtual ~FakeSharedMemory() {
51    delete[] buffer_;
52  }
53 private:
54  char* buffer_;
55  DISALLOW_COPY_AND_ASSIGN(FakeSharedMemory);
56};
57
58SharedMemory* ScreenCapturerTest::CreateSharedMemory(size_t size) {
59  return new FakeSharedMemory(new char[size], size);
60}
61
62TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) {
63  webrtc::ScreenCapturer::ScreenList screens;
64  EXPECT_TRUE(capturer_->GetScreenList(&screens));
65  for(webrtc::ScreenCapturer::ScreenList::iterator it = screens.begin();
66      it != screens.end(); ++it) {
67    EXPECT_TRUE(capturer_->SelectScreen(it->id));
68  }
69}
70
71TEST_F(ScreenCapturerTest, StartCapturer) {
72  capturer_->SetMouseShapeObserver(&mouse_observer_);
73  capturer_->Start(&callback_);
74}
75
76TEST_F(ScreenCapturerTest, Capture) {
77  // Assume that Start() treats the screen as invalid initially.
78  DesktopFrame* frame = NULL;
79  EXPECT_CALL(callback_, OnCaptureCompleted(_))
80      .WillOnce(SaveArg<0>(&frame));
81  EXPECT_CALL(mouse_observer_, OnCursorShapeChangedPtr(_))
82      .Times(AnyNumber());
83
84  EXPECT_CALL(callback_, CreateSharedMemory(_))
85      .Times(AnyNumber())
86      .WillRepeatedly(Return(static_cast<SharedMemory*>(NULL)));
87
88  capturer_->Start(&callback_);
89  capturer_->Capture(DesktopRegion());
90
91  ASSERT_TRUE(frame);
92  EXPECT_GT(frame->size().width(), 0);
93  EXPECT_GT(frame->size().height(), 0);
94  EXPECT_GE(frame->stride(),
95            frame->size().width() * DesktopFrame::kBytesPerPixel);
96  EXPECT_TRUE(frame->shared_memory() == NULL);
97
98  // Verify that the region contains whole screen.
99  EXPECT_FALSE(frame->updated_region().is_empty());
100  DesktopRegion::Iterator it(frame->updated_region());
101  ASSERT_TRUE(!it.IsAtEnd());
102  EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size())));
103  it.Advance();
104  EXPECT_TRUE(it.IsAtEnd());
105
106  delete frame;
107}
108
109#if defined(WEBRTC_WIN)
110
111TEST_F(ScreenCapturerTest, UseSharedBuffers) {
112  DesktopFrame* frame = NULL;
113  EXPECT_CALL(callback_, OnCaptureCompleted(_))
114      .WillOnce(SaveArg<0>(&frame));
115  EXPECT_CALL(mouse_observer_, OnCursorShapeChangedPtr(_))
116      .Times(AnyNumber());
117
118  EXPECT_CALL(callback_, CreateSharedMemory(_))
119      .Times(AnyNumber())
120      .WillRepeatedly(Invoke(this, &ScreenCapturerTest::CreateSharedMemory));
121
122  capturer_->Start(&callback_);
123  capturer_->Capture(DesktopRegion());
124
125  ASSERT_TRUE(frame);
126  ASSERT_TRUE(frame->shared_memory());
127  EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
128
129  delete frame;
130}
131
132TEST_F(ScreenCapturerTest, UseMagnifier) {
133  DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
134  options.set_allow_use_magnification_api(true);
135  capturer_.reset(ScreenCapturer::Create(options));
136
137  DesktopFrame* frame = NULL;
138  EXPECT_CALL(callback_, OnCaptureCompleted(_)).WillOnce(SaveArg<0>(&frame));
139
140  capturer_->Start(&callback_);
141  capturer_->Capture(DesktopRegion());
142  ASSERT_TRUE(frame);
143  delete frame;
144}
145
146#endif  // defined(WEBRTC_WIN)
147
148}  // namespace webrtc
149