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  void SetUp() override {
34    capturer_.reset(
35        ScreenCapturer::Create(DesktopCaptureOptions::CreateDefault()));
36  }
37
38 protected:
39  rtc::scoped_ptr<ScreenCapturer> capturer_;
40  MockScreenCapturerCallback callback_;
41};
42
43class FakeSharedMemory : public SharedMemory {
44 public:
45  FakeSharedMemory(char* buffer, size_t size)
46    : SharedMemory(buffer, size, 0, kTestSharedMemoryId),
47      buffer_(buffer) {
48  }
49  virtual ~FakeSharedMemory() {
50    delete[] buffer_;
51  }
52 private:
53  char* buffer_;
54  RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemory);
55};
56
57SharedMemory* ScreenCapturerTest::CreateSharedMemory(size_t size) {
58  return new FakeSharedMemory(new char[size], size);
59}
60
61TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) {
62  webrtc::ScreenCapturer::ScreenList screens;
63  EXPECT_TRUE(capturer_->GetScreenList(&screens));
64  for(webrtc::ScreenCapturer::ScreenList::iterator it = screens.begin();
65      it != screens.end(); ++it) {
66    EXPECT_TRUE(capturer_->SelectScreen(it->id));
67  }
68}
69
70TEST_F(ScreenCapturerTest, StartCapturer) {
71  capturer_->Start(&callback_);
72}
73
74TEST_F(ScreenCapturerTest, Capture) {
75  // Assume that Start() treats the screen as invalid initially.
76  DesktopFrame* frame = NULL;
77  EXPECT_CALL(callback_, OnCaptureCompleted(_))
78      .WillOnce(SaveArg<0>(&frame));
79
80  EXPECT_CALL(callback_, CreateSharedMemory(_))
81      .Times(AnyNumber())
82      .WillRepeatedly(Return(static_cast<SharedMemory*>(NULL)));
83
84  capturer_->Start(&callback_);
85  capturer_->Capture(DesktopRegion());
86
87  ASSERT_TRUE(frame);
88  EXPECT_GT(frame->size().width(), 0);
89  EXPECT_GT(frame->size().height(), 0);
90  EXPECT_GE(frame->stride(),
91            frame->size().width() * DesktopFrame::kBytesPerPixel);
92  EXPECT_TRUE(frame->shared_memory() == NULL);
93
94  // Verify that the region contains whole screen.
95  EXPECT_FALSE(frame->updated_region().is_empty());
96  DesktopRegion::Iterator it(frame->updated_region());
97  ASSERT_TRUE(!it.IsAtEnd());
98  EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size())));
99  it.Advance();
100  EXPECT_TRUE(it.IsAtEnd());
101
102  delete frame;
103}
104
105#if defined(WEBRTC_WIN)
106
107TEST_F(ScreenCapturerTest, UseSharedBuffers) {
108  DesktopFrame* frame = NULL;
109  EXPECT_CALL(callback_, OnCaptureCompleted(_))
110      .WillOnce(SaveArg<0>(&frame));
111
112  EXPECT_CALL(callback_, CreateSharedMemory(_))
113      .Times(AnyNumber())
114      .WillRepeatedly(Invoke(this, &ScreenCapturerTest::CreateSharedMemory));
115
116  capturer_->Start(&callback_);
117  capturer_->Capture(DesktopRegion());
118
119  ASSERT_TRUE(frame);
120  ASSERT_TRUE(frame->shared_memory());
121  EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
122
123  delete frame;
124}
125
126TEST_F(ScreenCapturerTest, UseMagnifier) {
127  DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
128  options.set_allow_use_magnification_api(true);
129  capturer_.reset(ScreenCapturer::Create(options));
130
131  DesktopFrame* frame = NULL;
132  EXPECT_CALL(callback_, OnCaptureCompleted(_)).WillOnce(SaveArg<0>(&frame));
133
134  capturer_->Start(&callback_);
135  capturer_->Capture(DesktopRegion());
136  ASSERT_TRUE(frame);
137  delete frame;
138}
139
140#endif  // defined(WEBRTC_WIN)
141
142}  // namespace webrtc
143