Add tests for FullScreenPowerPointHandler
These tests check if string manipulation is handled correctly by the
FullScreenPowerPointHandler class.
Bug: chromium:409473386
Change-Id: I2dad1627918a4ee240813de72013b8b18ec4d5ac
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/387880
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Palak Agarwal <agpalak@google.com>
Reviewed-by: Elad Alon <eladalon@webrtc.org>
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#44763}
diff --git a/modules/desktop_capture/BUILD.gn b/modules/desktop_capture/BUILD.gn
index f00de0c..a49c24f 100644
--- a/modules/desktop_capture/BUILD.gn
+++ b/modules/desktop_capture/BUILD.gn
@@ -170,6 +170,7 @@
"win/cursor_unittest.cc",
"win/cursor_unittest_resources.h",
"win/cursor_unittest_resources.rc",
+ "win/full_screen_win_application_handler_unittest.cc",
"win/screen_capture_utils_unittest.cc",
"win/screen_capturer_win_directx_unittest.cc",
"win/test_support/test_window.cc",
diff --git a/modules/desktop_capture/win/full_screen_win_application_handler.cc b/modules/desktop_capture/win/full_screen_win_application_handler.cc
index 88ab8f6..fa15b3e 100644
--- a/modules/desktop_capture/win/full_screen_win_application_handler.cc
+++ b/modules/desktop_capture/win/full_screen_win_application_handler.cc
@@ -38,23 +38,27 @@
WCHAR buffer[kMaxClassNameLength];
const int length = ::GetClassNameW(window, buffer, kMaxClassNameLength);
- if (length <= 0)
+ if (length <= 0) {
return false;
+ }
- if (static_cast<size_t>(length) != classNameLength)
+ if (static_cast<size_t>(length) != classNameLength) {
return false;
+ }
return wcsncmp(buffer, class_name, classNameLength) == 0;
}
std::string WindowText(HWND window) {
size_t len = ::GetWindowTextLength(window);
- if (len == 0)
+ if (len == 0) {
return std::string();
+ }
std::vector<wchar_t> buffer(len + 1, 0);
size_t copied = ::GetWindowTextW(window, buffer.data(), buffer.size());
- if (copied == 0)
+ if (copied == 0) {
return std::string();
+ }
return webrtc::ToUtf8(buffer.data(), copied);
}
@@ -66,8 +70,9 @@
std::wstring FileNameFromPath(const std::wstring& path) {
auto found = path.rfind(L"\\");
- if (found == std::string::npos)
+ if (found == std::string::npos) {
return path;
+ }
return path.substr(found + 1);
}
@@ -88,111 +93,101 @@
});
return result;
}
+} // namespace
-class FullScreenPowerPointHandler : public FullScreenApplicationHandler {
- public:
- explicit FullScreenPowerPointHandler(DesktopCapturer::SourceId sourceId)
- : FullScreenApplicationHandler(sourceId) {}
+FullScreenPowerPointHandler::FullScreenPowerPointHandler(
+ DesktopCapturer::SourceId sourceId)
+ : FullScreenApplicationHandler(sourceId) {}
- ~FullScreenPowerPointHandler() override {}
-
- DesktopCapturer::SourceId FindFullScreenWindow(
- const DesktopCapturer::SourceList& window_list,
- int64_t timestamp) const override {
- if (!UseHeuristicFullscreenPowerPointWindows()) {
- return 0;
- }
-
- if (window_list.empty())
- return 0;
-
- HWND original_window = reinterpret_cast<HWND>(GetSourceId());
- if (GetWindowType(original_window) != WindowType::kEditor)
- return 0;
-
- DesktopCapturer::SourceList powerpoint_windows = GetProcessWindows(
- window_list, WindowProcessId(original_window), original_window);
-
- // No relevant window with the same process id as the `original_window` was
- // found.
- if (powerpoint_windows.empty())
- return 0;
-
- const std::string original_document_title =
- GetDocumentTitleFromEditor(original_window);
- for (const auto& source : powerpoint_windows) {
- HWND window = reinterpret_cast<HWND>(source.id);
-
- // Looking for fullscreen slide show window for the corresponding editor
- // document
- if (GetWindowType(window) == WindowType::kSlideShow &&
- GetDocumentTitleFromSlideShow(window) == original_document_title) {
- return source.id;
- }
- }
+DesktopCapturer::SourceId FullScreenPowerPointHandler::FindFullScreenWindow(
+ const DesktopCapturer::SourceList& window_list,
+ int64_t timestamp) const {
+ if (!UseHeuristicFullscreenPowerPointWindows() || window_list.empty()) {
return 0;
}
- private:
- enum class WindowType { kEditor, kSlideShow, kOther };
-
- WindowType GetWindowType(HWND window) const {
- if (IsEditorWindow(window))
- return WindowType::kEditor;
- else if (IsSlideShowWindow(window))
- return WindowType::kSlideShow;
- else
- return WindowType::kOther;
+ HWND original_window = reinterpret_cast<HWND>(GetSourceId());
+ if (GetWindowType(original_window) != WindowType::kEditor) {
+ return 0;
}
- constexpr static char kDocumentTitleSeparator = '-';
+ DesktopCapturer::SourceList powerpoint_windows = GetProcessWindows(
+ window_list, WindowProcessId(original_window), original_window);
- // This function extracts the title from the editor. It needs to be
- // updated everytime PowerPoint changes its editor title format. Currently, it
- // supports editor title in the format "Window - Title - PowerPoint".
- std::string GetDocumentTitleFromEditor(HWND window) const {
- std::string title = WindowText(window);
- return std::string(
- absl::StripAsciiWhitespace(absl::string_view(title).substr(
- 0, title.rfind(kDocumentTitleSeparator))));
+ // No relevant windows with the same process id as the `original_window` were
+ // found.
+ if (powerpoint_windows.empty()) {
+ return 0;
}
- // This function extracts the title from the slideshow when PowerPoint goes
- // fullscreen. This function needs to be updated whenever PowerPoint changes
- // its title format. Currently, it supports Fullscreen titles of the format
- // "PowerPoint Slide Show - [Window - Title]" or "PowerPoint Slide Show -
- // Window - Title".
- std::string GetDocumentTitleFromSlideShow(HWND window) const {
- std::string title = WindowText(window);
- auto position = title.find(kDocumentTitleSeparator);
- if (position != std::string::npos) {
- title = std::string(absl::StripAsciiWhitespace(
- absl::string_view(title).substr(position + 1, std::wstring::npos)));
+ const std::string original_document_title =
+ GetDocumentTitleFromEditor(original_window);
+ for (const auto& source : powerpoint_windows) {
+ HWND window = reinterpret_cast<HWND>(source.id);
+
+ // Looking for fullscreen slide show window for the corresponding editor
+ // document.
+ if (GetWindowType(window) == WindowType::kSlideShow &&
+ GetDocumentTitleFromSlideShow(window) == original_document_title) {
+ return source.id;
}
+ }
+ return 0;
+}
- auto left_bracket_pos = title.find("[");
- auto right_bracket_pos = title.rfind("]");
- if (left_bracket_pos == std::string::npos ||
- right_bracket_pos == std::string::npos ||
- right_bracket_pos <= left_bracket_pos) {
- return title;
- }
-
- return std::string(absl::StripAsciiWhitespace(title.substr(
- left_bracket_pos + 1, right_bracket_pos - left_bracket_pos - 1)));
+FullScreenPowerPointHandler::WindowType
+FullScreenPowerPointHandler::GetWindowType(HWND window) const {
+ if (IsEditorWindow(window)) {
+ return WindowType::kEditor;
+ } else if (IsSlideShowWindow(window)) {
+ return WindowType::kSlideShow;
}
- bool IsEditorWindow(HWND window) const {
- return CheckWindowClassName(window, L"PPTFrameClass");
+ return WindowType::kOther;
+}
+
+constexpr static char kDocumentTitleSeparator = '-';
+
+std::string FullScreenPowerPointHandler::GetDocumentTitleFromEditor(
+ HWND window) const {
+ std::string title = WindowText(window);
+ return std::string(absl::StripAsciiWhitespace(absl::string_view(title).substr(
+ 0, title.rfind(kDocumentTitleSeparator))));
+}
+
+std::string FullScreenPowerPointHandler::GetDocumentTitleFromSlideShow(
+ HWND window) const {
+ std::string title = WindowText(window);
+ size_t position = title.find(kDocumentTitleSeparator);
+ if (position != std::string::npos) {
+ title = absl::StripAsciiWhitespace(
+ absl::string_view(title).substr(position + 1, std::wstring::npos));
}
- bool IsSlideShowWindow(HWND window) const {
- const LONG style = ::GetWindowLong(window, GWL_STYLE);
- const bool min_box = WS_MINIMIZEBOX & style;
- const bool max_box = WS_MAXIMIZEBOX & style;
- return !min_box && !max_box;
+ size_t left_bracket_pos = title.find("[");
+ size_t right_bracket_pos = title.rfind("]");
+ if (left_bracket_pos == std::string::npos ||
+ right_bracket_pos == std::string::npos ||
+ right_bracket_pos <= left_bracket_pos) {
+ return title;
}
-};
+
+ return std::string(absl::StripAsciiWhitespace(title.substr(
+ left_bracket_pos + 1, right_bracket_pos - left_bracket_pos - 1)));
+}
+
+bool FullScreenPowerPointHandler::IsEditorWindow(HWND window) const {
+ return CheckWindowClassName(window, L"PPTFrameClass");
+}
+
+bool FullScreenPowerPointHandler::IsSlideShowWindow(HWND window) const {
+ // TODO(https://crbug.com/409473386): Change this to use GetWindowLongPtr
+ // instead as recommended in the MS Windows API.
+ // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowlongptra
+ const bool has_minimize_or_maximize_buttons =
+ ::GetWindowLong(window, GWL_STYLE) & (WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
+ return !has_minimize_or_maximize_buttons;
+}
class OpenOfficeApplicationHandler : public FullScreenApplicationHandler {
public:
@@ -202,8 +197,9 @@
DesktopCapturer::SourceId FindFullScreenWindow(
const DesktopCapturer::SourceList& window_list,
int64_t timestamp) const override {
- if (window_list.empty())
+ if (window_list.empty()) {
return 0;
+ }
DWORD process_id = WindowProcessId(reinterpret_cast<HWND>(GetSourceId()));
@@ -235,8 +231,9 @@
return IsSlideShowWindow(x);
});
- if (slide_show_window == app_windows.end())
+ if (slide_show_window == app_windows.end()) {
return 0;
+ }
return slide_show_window->id;
}
@@ -266,22 +263,22 @@
DWORD process_id = WindowProcessId(window_id);
HANDLE process =
::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id);
- if (process == NULL)
+ if (process == NULL) {
return L"";
+ }
DWORD path_len = MAX_PATH;
WCHAR path[MAX_PATH];
std::wstring result;
- if (::QueryFullProcessImageNameW(process, 0, path, &path_len))
+ if (::QueryFullProcessImageNameW(process, 0, path, &path_len)) {
result = std::wstring(path, path_len);
- else
+ } else {
RTC_LOG_GLE(LS_ERROR) << "QueryFullProcessImageName failed.";
+ }
::CloseHandle(process);
return result;
}
-} // namespace
-
std::unique_ptr<FullScreenApplicationHandler>
CreateFullScreenWinApplicationHandler(DesktopCapturer::SourceId source_id) {
std::unique_ptr<FullScreenApplicationHandler> result;
diff --git a/modules/desktop_capture/win/full_screen_win_application_handler.h b/modules/desktop_capture/win/full_screen_win_application_handler.h
index 286e8e5..706e96e 100644
--- a/modules/desktop_capture/win/full_screen_win_application_handler.h
+++ b/modules/desktop_capture/win/full_screen_win_application_handler.h
@@ -14,9 +14,42 @@
#include <memory>
#include "modules/desktop_capture/full_screen_application_handler.h"
+#include "modules/desktop_capture/win/window_capture_utils.h"
namespace webrtc {
+class FullScreenPowerPointHandler : public FullScreenApplicationHandler {
+ public:
+ enum class WindowType { kEditor, kSlideShow, kOther };
+
+ explicit FullScreenPowerPointHandler(DesktopCapturer::SourceId sourceId);
+
+ ~FullScreenPowerPointHandler() override {}
+
+ DesktopCapturer::SourceId FindFullScreenWindow(
+ const DesktopCapturer::SourceList& window_list,
+ int64_t timestamp) const override;
+
+ private:
+ WindowType GetWindowType(HWND window) const;
+
+ // This function extracts the title from the editor. It needs to be
+ // updated every time PowerPoint changes its editor title format. Currently,
+ // it supports editor title in the format "Window - Title - PowerPoint".
+ std::string GetDocumentTitleFromEditor(HWND window) const;
+
+ // This function extracts the title from the slideshow when PowerPoint goes
+ // fullscreen. This function needs to be updated whenever PowerPoint changes
+ // its title format. Currently, it supports Fullscreen titles of the format
+ // "PowerPoint Slide Show - [Window - Title]" or "PowerPoint Slide Show -
+ // Window - Title".
+ std::string GetDocumentTitleFromSlideShow(HWND window) const;
+
+ bool IsEditorWindow(HWND window) const;
+
+ bool IsSlideShowWindow(HWND window) const;
+};
+
std::unique_ptr<FullScreenApplicationHandler>
CreateFullScreenWinApplicationHandler(DesktopCapturer::SourceId sourceId);
diff --git a/modules/desktop_capture/win/full_screen_win_application_handler_unittest.cc b/modules/desktop_capture/win/full_screen_win_application_handler_unittest.cc
new file mode 100644
index 0000000..1fcd13b
--- /dev/null
+++ b/modules/desktop_capture/win/full_screen_win_application_handler_unittest.cc
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2025 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "modules/desktop_capture/win/full_screen_win_application_handler.h"
+
+#include <vector>
+
+#include "modules/desktop_capture/win/test_support/test_window.h"
+#include "modules/desktop_capture/win/window_capture_utils.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+WindowInfo CreateTestWindow(const WCHAR* window_title,
+ const WCHAR* window_class) {
+ return CreateTestWindow(window_title, /*height=*/240, /*width=*/320,
+ /*extended_styles=*/0, window_class);
+}
+
+class FullScreenWinApplicationHandlerTest : public ::testing::Test {
+ public:
+ void CreateEditorWindow(const WCHAR* title,
+ const WCHAR* window_class = L"PPTFrameClass") {
+ editor_window_info_ = CreateTestWindow(title, window_class);
+ full_screen_ppt_handler_ = std::make_unique<FullScreenPowerPointHandler>(
+ reinterpret_cast<DesktopCapturer::SourceId>(editor_window_info_.hwnd));
+ }
+
+ HWND CreateSlideShowWindow(const WCHAR* title) {
+ slide_show_window_info_ =
+ CreateTestWindow(title, /*window_class=*/L"screenClass");
+ return slide_show_window_info_.hwnd;
+ }
+
+ // FindFullScreenWindow returns a non-zero value when a full screen slide show
+ // is found. It returns NULL when it fails to find a corresponding full screen
+ // slide show.
+ HWND FindFullScreenWindow() {
+ DesktopCapturer::SourceList window_list;
+ EXPECT_TRUE(GetWindowList(GetWindowListFlags::kNone, &window_list));
+ EXPECT_GT(window_list.size(), 0u); // Otherwise, faulty test.
+
+ return reinterpret_cast<HWND>(
+ full_screen_ppt_handler_->FindFullScreenWindow(window_list,
+ /*timestamp=*/0));
+ }
+
+ void TearDown() override {
+ DestroyTestWindow(editor_window_info_);
+ DestroyTestWindow(slide_show_window_info_);
+ }
+
+ protected:
+ WindowInfo editor_window_info_;
+ WindowInfo slide_show_window_info_;
+ std::unique_ptr<FullScreenPowerPointHandler> full_screen_ppt_handler_;
+};
+
+TEST_F(FullScreenWinApplicationHandlerTest, FullScreenWindowFoundForEditor) {
+ CreateEditorWindow(L"My - Title - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My - Title]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorTitleHasExtraSpaces) {
+ CreateEditorWindow(L"My Title - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My Title ]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+// This can happen in older PowerPoint versions, where full screen slide show
+// title did not had brackets around the document name.
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenSlideShowTitleHasNoBrackets) {
+ CreateEditorWindow(L"My - Title - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - My - Title");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorTitleHasUnevenlySpacedDashes) {
+ CreateEditorWindow(L"My -Test - Title - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My -Test - Title]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorTitleHasMatchingBrackets) {
+ CreateEditorWindow(L"[My - Title] - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [[My - Title]]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorTitleHasAFrontRightBracket) {
+ CreateEditorWindow(L"[My - Title - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [[My - Title]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorTitleHasABackRightBracket) {
+ CreateEditorWindow(L"My - Title[ - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My - Title[]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorTitleHasAFrontLeftBracket) {
+ CreateEditorWindow(L"]My - Title - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - []My - Title]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorTitleHasABackLeftBracket) {
+ CreateEditorWindow(L"My - Title] - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My - Title]]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorTitleHasMismatchingBrackets) {
+ CreateEditorWindow(L"]My - Title[ - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - []My - Title[]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorTitleHasOnlyLeftBrackets) {
+ CreateEditorWindow(L"[[My - Title[ - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [[[My - Title[]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorTitleHasOnlyRightBrackets) {
+ CreateEditorWindow(L"]My - Title]] - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - []My - Title]]]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorTitleHasNestedBrackets) {
+ CreateEditorWindow(L"[[My - Title]] - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [[[My - Title]]]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorTitleHasNestedBracketsInFront) {
+ CreateEditorWindow(L"[[My] - Title] - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [[[My] - Title]]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorTitleHasNestedBracketsInBack) {
+ CreateEditorWindow(L"[My - [Title]] - PowerPoint");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [[My - [Title]]]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenEditorWindowHasNoPowerPointInTitle) {
+ CreateEditorWindow(L"My - Title - Power");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My - Title]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowFoundWhenSlideShowWindowHasNoPowerPointInTitle) {
+ CreateEditorWindow(L"My - Title - PowerPoint");
+ HWND slide_show = CreateSlideShowWindow(L"Slide Show - [My - Title]");
+
+ EXPECT_EQ(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowNotFoundWhenEditorWindowHasWrongWindowClass) {
+ // Create editor window with class name "WrongClass" instead of
+ // "PPTFrameClass".
+ CreateEditorWindow(L"My - Title - PowerPoint",
+ /*window_class=*/L"WrongClass");
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My - Title]");
+
+ EXPECT_NE(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowNotFoundWhenFullScreenPPTHandlerUsesSlideShowWindow) {
+ CreateEditorWindow(L"My - Title - PowerPoint");
+
+ // Create FullScreenPowerPointHandler using the slide show WindowInfo.
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My - Title]");
+ full_screen_ppt_handler_.reset(new FullScreenPowerPointHandler(
+ reinterpret_cast<DesktopCapturer::SourceId>(slide_show)));
+
+ EXPECT_NE(FindFullScreenWindow(), slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ CorrectFullScreenWindowFoundWhenMultipleSlideShowsHaveSimilarTitles) {
+ CreateEditorWindow(L"My - Title - PowerPoint");
+ HWND correct_slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My - Title]");
+ std::vector<HWND> wrong_slide_shows = {
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My - Title]"),
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My Title]"),
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My Title -]")};
+
+ ASSERT_THAT(wrong_slide_shows,
+ testing::Not(testing::Contains(correct_slide_show)));
+ EXPECT_EQ(FindFullScreenWindow(), correct_slide_show);
+}
+
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowsFoundWhenMultipleEditorsAndSlideShowsExist) {
+ std::vector<WindowInfo> editors = {
+ CreateTestWindow(L"My - Title - PowerPoint",
+ /*window_class=*/L"PPTFrameClass"),
+ CreateTestWindow(L"[[My Title] - PowerPoint",
+ /*window_class=*/L"PPTFrameClass"),
+ CreateTestWindow(L"My Ttile - PowerPoint",
+ /*window_class=*/L"PPTFrameClass")};
+
+ std::vector<std::unique_ptr<FullScreenPowerPointHandler>> handlers;
+ for (auto& editor : editors) {
+ handlers.push_back(std::make_unique<FullScreenPowerPointHandler>(
+ reinterpret_cast<DesktopCapturer::SourceId>(editor.hwnd)));
+ }
+
+ std::vector<HWND> slide_shows = {
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My - Title]"),
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [[[My Title]]"),
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My Ttile]")};
+
+ DesktopCapturer::SourceList window_list;
+ EXPECT_TRUE(GetWindowList(GetWindowListFlags::kNone, &window_list));
+ EXPECT_GT(window_list.size(), 0u);
+
+ for (size_t count = 0; count < handlers.size(); count++) {
+ EXPECT_EQ(reinterpret_cast<HWND>(
+ handlers[count]->FindFullScreenWindow(window_list,
+ /*timestamp=*/0)),
+ slide_shows[count]);
+ }
+}
+
+} // namespace webrtc
diff --git a/modules/desktop_capture/win/test_support/test_window.cc b/modules/desktop_capture/win/test_support/test_window.cc
index c07ff74..2b7d132 100644
--- a/modules/desktop_capture/win/test_support/test_window.cc
+++ b/modules/desktop_capture/win/test_support/test_window.cc
@@ -13,7 +13,6 @@
namespace webrtc {
namespace {
-const WCHAR kWindowClass[] = L"DesktopCaptureTestWindowClass";
const int kWindowHeight = 200;
const int kWindowWidth = 300;
@@ -42,7 +41,8 @@
WindowInfo CreateTestWindow(const WCHAR* window_title,
const int height,
const int width,
- const LONG extended_styles) {
+ const LONG extended_styles,
+ const WCHAR* window_class) {
WindowInfo info;
::GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
@@ -55,19 +55,20 @@
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.hInstance = info.window_instance;
wcex.lpfnWndProc = &WindowProc;
- wcex.lpszClassName = kWindowClass;
+ wcex.lpszClassName = window_class;
info.window_class = ::RegisterClassExW(&wcex);
// Use the default height and width if the caller did not supply the optional
// height and width parameters, or if they supplied invalid values.
int window_height = height <= 0 ? kWindowHeight : height;
int window_width = width <= 0 ? kWindowWidth : width;
- info.hwnd =
- ::CreateWindowExW(extended_styles, kWindowClass, window_title,
- WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
- window_width, window_height, /*parent_window=*/nullptr,
- /*menu_bar=*/nullptr, info.window_instance,
- /*additional_params=*/nullptr);
+ info.hwnd = ::CreateWindowExW(
+ extended_styles, window_class, window_title,
+ (window_class == kWindowClass) ? WS_OVERLAPPEDWINDOW : WS_OVERLAPPED,
+ CW_USEDEFAULT, CW_USEDEFAULT, window_width, window_height,
+ /*parent_window=*/nullptr,
+ /*menu_bar=*/nullptr, info.window_instance,
+ /*additional_params=*/nullptr);
::ShowWindow(info.hwnd, SW_SHOWNORMAL);
::UpdateWindow(info.hwnd);
diff --git a/modules/desktop_capture/win/test_support/test_window.h b/modules/desktop_capture/win/test_support/test_window.h
index b055da7..a30d453 100644
--- a/modules/desktop_capture/win/test_support/test_window.h
+++ b/modules/desktop_capture/win/test_support/test_window.h
@@ -25,6 +25,8 @@
const uint8_t kTestWindowGValue = 99;
const uint8_t kTestWindowBValue = 12;
+const WCHAR kWindowClass[] = L"DesktopCaptureTestWindowClass";
+
struct WindowInfo {
HWND hwnd;
HINSTANCE window_instance;
@@ -34,7 +36,8 @@
WindowInfo CreateTestWindow(const WCHAR* window_title,
int height = 0,
int width = 0,
- LONG extended_styles = 0);
+ LONG extended_styles = 0,
+ const WCHAR* window_class = kWindowClass);
void ResizeTestWindow(HWND hwnd, int width, int height);