blob: 1d2375e80059b27c00207d204104287a4fe1d732 [file] [log] [blame]
Zijie He77b7a1d2017-09-01 15:51:14 -07001/*
2 * Copyright (c) 2017 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/desktop_capture/window_finder.h"
Zijie He77b7a1d2017-09-01 15:51:14 -070012
13#include <stdint.h>
14
15#include <memory>
16
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/desktop_capture/desktop_geometry.h"
18#include "modules/desktop_capture/screen_drawer.h"
19#include "rtc_base/logging.h"
20#include "test/gtest.h"
Zijie He77b7a1d2017-09-01 15:51:14 -070021
22#if defined(USE_X11)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "modules/desktop_capture/x11/shared_x_display.h"
24#include "modules/desktop_capture/x11/x_atom_cache.h"
25#include "rtc_base/ptr_util.h"
Zijie He77b7a1d2017-09-01 15:51:14 -070026#endif
27
28#if defined(WEBRTC_WIN)
29#include <windows.h>
30
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "modules/desktop_capture/window_finder_win.h"
32#include "modules/desktop_capture/win/window_capture_utils.h"
Zijie He77b7a1d2017-09-01 15:51:14 -070033#endif
34
35namespace webrtc {
36
37namespace {
38
39#if defined(WEBRTC_WIN)
40// ScreenDrawerWin does not have a message loop, so it's unresponsive to user
41// inputs. WindowFinderWin cannot detect this kind of unresponsive windows.
42// Instead, console window is used to test WindowFinderWin.
43TEST(WindowFinderTest, FindConsoleWindow) {
44 // Creates a ScreenDrawer to avoid this test from conflicting with
45 // ScreenCapturerIntegrationTest: both tests require its window to be in
46 // foreground.
47 //
48 // In ScreenCapturer related tests, this is controlled by
49 // ScreenDrawer, which has a global lock to ensure only one ScreenDrawer
50 // window is active. So even we do not use ScreenDrawer for Windows test,
51 // creating an instance can block ScreenCapturer related tests until this test
52 // finishes.
53 //
54 // Usually the test framework should take care of this "isolated test"
55 // requirement, but unfortunately WebRTC trybots do not support this.
56 std::unique_ptr<ScreenDrawer> drawer = ScreenDrawer::Create();
57 const int kMaxSize = 10000;
58 // Enlarges current console window.
59 system("mode 1000,1000");
60 const HWND console_window = GetConsoleWindow();
61 MoveWindow(console_window, 0, 0, kMaxSize, kMaxSize, true);
62
63 // Brings console window to top.
64 SetWindowPos(
65 console_window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
66 BringWindowToTop(console_window);
67
68 WindowFinderWin finder;
69 for (int i = 0; i < kMaxSize; i++) {
70 const DesktopVector spot(i, i);
71 const HWND id = reinterpret_cast<HWND>(finder.GetWindowUnderPoint(spot));
72 if (id == console_window) {
73 return;
74 }
75 }
76
77 FAIL();
78}
79
80#else
81TEST(WindowFinderTest, FindDrawerWindow) {
82 WindowFinder::Options options;
83#if defined(USE_X11)
84 std::unique_ptr<XAtomCache> cache;
85 const auto shared_x_display = SharedXDisplay::CreateDefault();
86 if (shared_x_display) {
87 cache = rtc::MakeUnique<XAtomCache>(shared_x_display->display());
88 options.cache = cache.get();
89 }
90#endif
91 std::unique_ptr<WindowFinder> finder = WindowFinder::Create(options);
92 if (!finder) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010093 RTC_LOG(LS_WARNING)
94 << "No WindowFinder implementation for current platform.";
Zijie He77b7a1d2017-09-01 15:51:14 -070095 return;
96 }
97
98 std::unique_ptr<ScreenDrawer> drawer = ScreenDrawer::Create();
99 if (!drawer) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100100 RTC_LOG(LS_WARNING)
101 << "No ScreenDrawer implementation for current platform.";
Zijie He77b7a1d2017-09-01 15:51:14 -0700102 return;
103 }
104
105 if (drawer->window_id() == kNullWindowId) {
106 // TODO(zijiehe): WindowFinderTest can use a dedicated window without
107 // relying on ScreenDrawer.
Mirko Bonadei675513b2017-11-09 11:09:25 +0100108 RTC_LOG(LS_WARNING)
109 << "ScreenDrawer implementation for current platform does "
110 "create a window.";
Zijie He77b7a1d2017-09-01 15:51:14 -0700111 return;
112 }
113
114 // ScreenDrawer may not be able to bring the window to the top. So we test
115 // several spots, at least one of them should succeed.
116 const DesktopRect region = drawer->DrawableRegion();
117 if (region.is_empty()) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100118 RTC_LOG(LS_WARNING)
119 << "ScreenDrawer::DrawableRegion() is too small for the "
120 "WindowFinderTest.";
Zijie He77b7a1d2017-09-01 15:51:14 -0700121 return;
122 }
123
124 for (int i = 0; i < region.width(); i++) {
125 const DesktopVector spot(
126 region.left() + i, region.top() + i * region.height() / region.width());
127 const WindowId id = finder->GetWindowUnderPoint(spot);
128 if (id == drawer->window_id()) {
129 return;
130 }
131 }
132
133 FAIL();
134}
135#endif
136
137TEST(WindowFinderTest, ShouldReturnNullWindowIfSpotIsOutOfScreen) {
138 WindowFinder::Options options;
139#if defined(USE_X11)
140 std::unique_ptr<XAtomCache> cache;
141 const auto shared_x_display = SharedXDisplay::CreateDefault();
142 if (shared_x_display) {
143 cache = rtc::MakeUnique<XAtomCache>(shared_x_display->display());
144 options.cache = cache.get();
145 }
146#endif
147 std::unique_ptr<WindowFinder> finder = WindowFinder::Create(options);
148 if (!finder) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100149 RTC_LOG(LS_WARNING)
150 << "No WindowFinder implementation for current platform.";
Zijie He77b7a1d2017-09-01 15:51:14 -0700151 return;
152 }
153
154 ASSERT_EQ(kNullWindowId, finder->GetWindowUnderPoint(
155 DesktopVector(INT16_MAX, INT16_MAX)));
156 ASSERT_EQ(kNullWindowId, finder->GetWindowUnderPoint(
157 DesktopVector(INT16_MAX, INT16_MIN)));
158 ASSERT_EQ(kNullWindowId, finder->GetWindowUnderPoint(
159 DesktopVector(INT16_MIN, INT16_MAX)));
160 ASSERT_EQ(kNullWindowId, finder->GetWindowUnderPoint(
161 DesktopVector(INT16_MIN, INT16_MIN)));
162}
163
164} // namespace
165
166} // namespace webrtc