xref: /aosp_15_r20/external/webrtc/modules/desktop_capture/screen_capturer_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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 <memory>
12 
13 #include "modules/desktop_capture/desktop_capture_options.h"
14 #include "modules/desktop_capture/desktop_capturer.h"
15 #include "modules/desktop_capture/desktop_frame.h"
16 #include "modules/desktop_capture/desktop_region.h"
17 #include "modules/desktop_capture/mock_desktop_capturer_callback.h"
18 #include "rtc_base/logging.h"
19 #include "test/gmock.h"
20 #include "test/gtest.h"
21 
22 #if defined(WEBRTC_WIN)
23 #include "modules/desktop_capture/win/screen_capturer_win_directx.h"
24 #endif  // defined(WEBRTC_WIN)
25 
26 using ::testing::_;
27 
28 const int kTestSharedMemoryId = 123;
29 
30 namespace webrtc {
31 
32 class ScreenCapturerTest : public ::testing::Test {
33  public:
SetUp()34   void SetUp() override {
35     capturer_ = DesktopCapturer::CreateScreenCapturer(
36         DesktopCaptureOptions::CreateDefault());
37     ASSERT_TRUE(capturer_);
38   }
39 
40  protected:
41 #if defined(WEBRTC_WIN)
42   // Enable allow_directx_capturer in DesktopCaptureOptions, but let
43   // DesktopCapturer::CreateScreenCapturer to decide whether a DirectX capturer
44   // should be used.
MaybeCreateDirectxCapturer()45   void MaybeCreateDirectxCapturer() {
46     DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
47     options.set_allow_directx_capturer(true);
48     capturer_ = DesktopCapturer::CreateScreenCapturer(options);
49   }
50 
CreateDirectxCapturer()51   bool CreateDirectxCapturer() {
52     if (!ScreenCapturerWinDirectx::IsSupported()) {
53       RTC_LOG(LS_WARNING) << "Directx capturer is not supported";
54       return false;
55     }
56 
57     MaybeCreateDirectxCapturer();
58     return true;
59   }
60 
CreateMagnifierCapturer()61   void CreateMagnifierCapturer() {
62     DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
63     options.set_allow_use_magnification_api(true);
64     capturer_ = DesktopCapturer::CreateScreenCapturer(options);
65   }
66 #endif  // defined(WEBRTC_WIN)
67 
68   std::unique_ptr<DesktopCapturer> capturer_;
69   MockDesktopCapturerCallback callback_;
70 };
71 
72 class FakeSharedMemory : public SharedMemory {
73  public:
FakeSharedMemory(char * buffer,size_t size)74   FakeSharedMemory(char* buffer, size_t size)
75       : SharedMemory(buffer, size, 0, kTestSharedMemoryId), buffer_(buffer) {}
~FakeSharedMemory()76   ~FakeSharedMemory() override { delete[] buffer_; }
77 
78   FakeSharedMemory(const FakeSharedMemory&) = delete;
79   FakeSharedMemory& operator=(const FakeSharedMemory&) = delete;
80 
81  private:
82   char* buffer_;
83 };
84 
85 class FakeSharedMemoryFactory : public SharedMemoryFactory {
86  public:
FakeSharedMemoryFactory()87   FakeSharedMemoryFactory() {}
~FakeSharedMemoryFactory()88   ~FakeSharedMemoryFactory() override {}
89 
90   FakeSharedMemoryFactory(const FakeSharedMemoryFactory&) = delete;
91   FakeSharedMemoryFactory& operator=(const FakeSharedMemoryFactory&) = delete;
92 
CreateSharedMemory(size_t size)93   std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override {
94     return std::unique_ptr<SharedMemory>(
95         new FakeSharedMemory(new char[size], size));
96   }
97 };
98 
ACTION_P(SaveUniquePtrArg,dest)99 ACTION_P(SaveUniquePtrArg, dest) {
100   *dest = std::move(*arg1);
101 }
102 
103 // TODO(bugs.webrtc.org/12950): Re-enable when libc++ issue is fixed.
104 #if defined(WEBRTC_LINUX) && defined(MEMORY_SANITIZER)
105 #define MAYBE_GetScreenListAndSelectScreen DISABLED_GetScreenListAndSelectScreen
106 #else
107 #define MAYBE_GetScreenListAndSelectScreen GetScreenListAndSelectScreen
108 #endif
TEST_F(ScreenCapturerTest,MAYBE_GetScreenListAndSelectScreen)109 TEST_F(ScreenCapturerTest, MAYBE_GetScreenListAndSelectScreen) {
110   webrtc::DesktopCapturer::SourceList screens;
111   EXPECT_TRUE(capturer_->GetSourceList(&screens));
112   for (const auto& screen : screens) {
113     EXPECT_TRUE(capturer_->SelectSource(screen.id));
114   }
115 }
116 
117 // Flaky on Linux. See: crbug.com/webrtc/7830
118 #if defined(WEBRTC_LINUX)
119 #define MAYBE_StartCapturer DISABLED_StartCaptuerer
120 #else
121 #define MAYBE_StartCapturer StartCapturer
122 #endif
TEST_F(ScreenCapturerTest,MAYBE_StartCapturer)123 TEST_F(ScreenCapturerTest, MAYBE_StartCapturer) {
124   capturer_->Start(&callback_);
125 }
126 
127 #if defined(WEBRTC_LINUX)
128 #define MAYBE_Capture DISABLED_Capture
129 #else
130 #define MAYBE_Capture Capture
131 #endif
TEST_F(ScreenCapturerTest,MAYBE_Capture)132 TEST_F(ScreenCapturerTest, MAYBE_Capture) {
133   // Assume that Start() treats the screen as invalid initially.
134   std::unique_ptr<DesktopFrame> frame;
135   EXPECT_CALL(callback_,
136               OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
137       .WillOnce(SaveUniquePtrArg(&frame));
138 
139   capturer_->Start(&callback_);
140   capturer_->CaptureFrame();
141 
142   ASSERT_TRUE(frame);
143   EXPECT_GT(frame->size().width(), 0);
144   EXPECT_GT(frame->size().height(), 0);
145   EXPECT_GE(frame->stride(),
146             frame->size().width() * DesktopFrame::kBytesPerPixel);
147   EXPECT_TRUE(frame->shared_memory() == NULL);
148 
149   // Verify that the region contains whole screen.
150   EXPECT_FALSE(frame->updated_region().is_empty());
151   DesktopRegion::Iterator it(frame->updated_region());
152   ASSERT_TRUE(!it.IsAtEnd());
153   EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size())));
154   it.Advance();
155   EXPECT_TRUE(it.IsAtEnd());
156 }
157 
158 #if defined(WEBRTC_WIN)
159 
TEST_F(ScreenCapturerTest,UseSharedBuffers)160 TEST_F(ScreenCapturerTest, UseSharedBuffers) {
161   std::unique_ptr<DesktopFrame> frame;
162   EXPECT_CALL(callback_,
163               OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
164       .WillOnce(SaveUniquePtrArg(&frame));
165 
166   capturer_->Start(&callback_);
167   capturer_->SetSharedMemoryFactory(
168       std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory()));
169   capturer_->CaptureFrame();
170 
171   ASSERT_TRUE(frame);
172   ASSERT_TRUE(frame->shared_memory());
173   EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
174 }
175 
TEST_F(ScreenCapturerTest,UseMagnifier)176 TEST_F(ScreenCapturerTest, UseMagnifier) {
177   CreateMagnifierCapturer();
178   std::unique_ptr<DesktopFrame> frame;
179   EXPECT_CALL(callback_,
180               OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
181       .WillOnce(SaveUniquePtrArg(&frame));
182 
183   capturer_->Start(&callback_);
184   capturer_->CaptureFrame();
185   ASSERT_TRUE(frame);
186 }
187 
TEST_F(ScreenCapturerTest,UseDirectxCapturer)188 TEST_F(ScreenCapturerTest, UseDirectxCapturer) {
189   if (!CreateDirectxCapturer()) {
190     return;
191   }
192 
193   std::unique_ptr<DesktopFrame> frame;
194   EXPECT_CALL(callback_,
195               OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
196       .WillOnce(SaveUniquePtrArg(&frame));
197 
198   capturer_->Start(&callback_);
199   capturer_->CaptureFrame();
200   ASSERT_TRUE(frame);
201 }
202 
TEST_F(ScreenCapturerTest,UseDirectxCapturerWithSharedBuffers)203 TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) {
204   if (!CreateDirectxCapturer()) {
205     return;
206   }
207 
208   std::unique_ptr<DesktopFrame> frame;
209   EXPECT_CALL(callback_,
210               OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
211       .WillOnce(SaveUniquePtrArg(&frame));
212 
213   capturer_->Start(&callback_);
214   capturer_->SetSharedMemoryFactory(
215       std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory()));
216   capturer_->CaptureFrame();
217   ASSERT_TRUE(frame);
218   ASSERT_TRUE(frame->shared_memory());
219   EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
220 }
221 
222 #endif  // defined(WEBRTC_WIN)
223 
224 }  // namespace webrtc
225