window_capture_utils_unittest.cc (5686B)
1 /* 2 * Copyright (c) 2020 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 "modules/desktop_capture/win/window_capture_utils.h" 12 13 #include <winuser.h> 14 15 #include <algorithm> 16 #include <memory> 17 #include <mutex> 18 19 #include "modules/desktop_capture/desktop_capturer.h" 20 #include "modules/desktop_capture/win/test_support/test_window.h" 21 #include "rtc_base/task_queue_for_test.h" 22 #include "rtc_base/thread.h" 23 #include "test/gtest.h" 24 25 namespace webrtc { 26 namespace { 27 28 constexpr char kWindowThreadName[] = "window_capture_utils_test_thread"; 29 const WCHAR kWindowTitle[] = L"Window Capture Utils Test"; 30 31 TEST(WindowCaptureUtilsTest, GetWindowList) { 32 WindowInfo info = CreateTestWindow(kWindowTitle); 33 DesktopCapturer::SourceList window_list; 34 ASSERT_TRUE(GetWindowList(GetWindowListFlags::kNone, &window_list)); 35 EXPECT_GT(window_list.size(), 0ULL); 36 EXPECT_NE(std::find_if(window_list.begin(), window_list.end(), 37 [&info](DesktopCapturer::Source window) { 38 return reinterpret_cast<HWND>(window.id) == 39 info.hwnd; 40 }), 41 window_list.end()); 42 DestroyTestWindow(info); 43 } 44 45 // Disable thread-safety-analysis in order to test unresponsive Windows. 46 #pragma clang diagnostic push 47 #pragma clang diagnostic ignored "-Wthread-safety-analysis" 48 49 std::unique_ptr<Thread> SetUpUnresponsiveWindow(std::mutex& mtx, 50 WindowInfo& info) { 51 std::unique_ptr<Thread> window_thread; 52 window_thread = Thread::Create(); 53 window_thread->SetName(kWindowThreadName, nullptr); 54 window_thread->Start(); 55 56 SendTask(window_thread.get(), [&] { info = CreateTestWindow(kWindowTitle); }); 57 58 // Intentionally create a deadlock to cause the window to become unresponsive. 59 mtx.lock(); 60 window_thread->PostTask([&mtx]() { 61 mtx.lock(); 62 mtx.unlock(); 63 }); 64 65 return window_thread; 66 } 67 68 TEST(WindowCaptureUtilsTest, IncludeUnresponsiveWindows) { 69 std::mutex mtx; 70 WindowInfo info; 71 std::unique_ptr<Thread> window_thread = SetUpUnresponsiveWindow(mtx, info); 72 73 EXPECT_FALSE(IsWindowResponding(info.hwnd)); 74 75 DesktopCapturer::SourceList window_list; 76 ASSERT_TRUE(GetWindowList(GetWindowListFlags::kNone, &window_list)); 77 EXPECT_GT(window_list.size(), 0ULL); 78 EXPECT_NE(std::find_if(window_list.begin(), window_list.end(), 79 [&info](DesktopCapturer::Source window) { 80 return reinterpret_cast<HWND>(window.id) == 81 info.hwnd; 82 }), 83 window_list.end()); 84 85 mtx.unlock(); 86 SendTask(window_thread.get(), [&info]() { DestroyTestWindow(info); }); 87 window_thread->Stop(); 88 } 89 90 TEST(WindowCaptureUtilsTest, IgnoreUnresponsiveWindows) { 91 std::mutex mtx; 92 WindowInfo info; 93 std::unique_ptr<Thread> window_thread = SetUpUnresponsiveWindow(mtx, info); 94 95 EXPECT_FALSE(IsWindowResponding(info.hwnd)); 96 97 DesktopCapturer::SourceList window_list; 98 ASSERT_TRUE( 99 GetWindowList(GetWindowListFlags::kIgnoreUnresponsive, &window_list)); 100 EXPECT_EQ(std::find_if(window_list.begin(), window_list.end(), 101 [&info](DesktopCapturer::Source window) { 102 return reinterpret_cast<HWND>(window.id) == 103 info.hwnd; 104 }), 105 window_list.end()); 106 107 mtx.unlock(); 108 SendTask(window_thread.get(), [&info]() { DestroyTestWindow(info); }); 109 window_thread->Stop(); 110 } 111 112 #pragma clang diagnostic pop 113 114 TEST(WindowCaptureUtilsTest, IncludeUntitledWindows) { 115 WindowInfo info = CreateTestWindow(L""); 116 DesktopCapturer::SourceList window_list; 117 ASSERT_TRUE(GetWindowList(GetWindowListFlags::kNone, &window_list)); 118 EXPECT_GT(window_list.size(), 0ULL); 119 EXPECT_NE(std::find_if(window_list.begin(), window_list.end(), 120 [&info](DesktopCapturer::Source window) { 121 return reinterpret_cast<HWND>(window.id) == 122 info.hwnd; 123 }), 124 window_list.end()); 125 DestroyTestWindow(info); 126 } 127 128 TEST(WindowCaptureUtilsTest, IgnoreUntitledWindows) { 129 WindowInfo info = CreateTestWindow(L""); 130 DesktopCapturer::SourceList window_list; 131 ASSERT_TRUE(GetWindowList(GetWindowListFlags::kIgnoreUntitled, &window_list)); 132 EXPECT_EQ(std::find_if(window_list.begin(), window_list.end(), 133 [&info](DesktopCapturer::Source window) { 134 return reinterpret_cast<HWND>(window.id) == 135 info.hwnd; 136 }), 137 window_list.end()); 138 DestroyTestWindow(info); 139 } 140 141 TEST(WindowCaptureUtilsTest, IgnoreCurrentProcessWindows) { 142 WindowInfo info = CreateTestWindow(kWindowTitle); 143 DesktopCapturer::SourceList window_list; 144 ASSERT_TRUE(GetWindowList(GetWindowListFlags::kIgnoreCurrentProcessWindows, 145 &window_list)); 146 EXPECT_EQ(std::find_if(window_list.begin(), window_list.end(), 147 [&info](DesktopCapturer::Source window) { 148 return reinterpret_cast<HWND>(window.id) == 149 info.hwnd; 150 }), 151 window_list.end()); 152 DestroyTestWindow(info); 153 } 154 155 } // namespace 156 } // namespace webrtc