commit 1f592a0365b84aa854df299d2445f81d9f59b380
parent 4e0347938c2ab39a8a98b7356d91372c668eddba
Author: Michael Froman <mfroman@mozilla.com>
Date: Wed, 15 Oct 2025 11:12:11 -0500
Bug 1993083 - Vendor libwebrtc from 7cba6c495d
Upstream commit: https://webrtc.googlesource.com/src/+/7cba6c495d05fb7317c53af642d5769b581ea089
Fix heuristic when slide show exists while selecting what to share
Bug: chromium:409473386
Change-Id: If2d359d0b881a240298abcf222601a93a180e528
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/400681
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Palak Agarwal <agpalak@google.com>
Cr-Commit-Position: refs/heads/main@{#45238}
Diffstat:
10 files changed, 130 insertions(+), 17 deletions(-)
diff --git a/third_party/libwebrtc/README.mozilla.last-vendor b/third_party/libwebrtc/README.mozilla.last-vendor
@@ -1,4 +1,4 @@
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc
-libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-15T16:11:01.783444+00:00.
+libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-15T16:12:02.404352+00:00.
# base of lastest vendoring
-11e550580a
+7cba6c495d
diff --git a/third_party/libwebrtc/modules/desktop_capture/full_screen_application_handler.h b/third_party/libwebrtc/modules/desktop_capture/full_screen_application_handler.h
@@ -51,6 +51,9 @@ class FullScreenApplicationHandler {
return use_heuristic_fullscreen_powerpoint_windows_;
}
+ virtual void SetSlideShowCreationStateForTest(
+ bool fullscreen_slide_show_started_after_capture_start) {}
+
private:
// `use_heuristic_fullscreen_powerpoint_windows_` is used to implement a
// killswitch.
diff --git a/third_party/libwebrtc/modules/desktop_capture/full_screen_window_detector.cc b/third_party/libwebrtc/modules/desktop_capture/full_screen_window_detector.cc
@@ -115,12 +115,15 @@ void FullScreenWindowDetector::CreateApplicationHandlerIfNeeded(
}
void FullScreenWindowDetector::CreateFullScreenApplicationHandlerForTest(
- DesktopCapturer::SourceId source_id) {
+ DesktopCapturer::SourceId source_id,
+ bool fullscreen_slide_show_started_after_capture_start) {
if (app_handler_) {
return;
}
#if defined(WEBRTC_WIN)
app_handler_ = std::make_unique<FullScreenPowerPointHandler>(source_id);
+ app_handler_->SetSlideShowCreationStateForTest(
+ fullscreen_slide_show_started_after_capture_start);
#endif
}
diff --git a/third_party/libwebrtc/modules/desktop_capture/full_screen_window_detector.h b/third_party/libwebrtc/modules/desktop_capture/full_screen_window_detector.h
@@ -76,7 +76,8 @@ class FullScreenWindowDetector
// Used for tests.
void CreateFullScreenApplicationHandlerForTest(
- DesktopCapturer::SourceId source_id);
+ DesktopCapturer::SourceId source_id,
+ bool fullscreen_slide_show_started_after_capture_start);
protected:
std::unique_ptr<FullScreenApplicationHandler> app_handler_;
diff --git a/third_party/libwebrtc/modules/desktop_capture/win/full_screen_win_application_handler.cc b/third_party/libwebrtc/modules/desktop_capture/win/full_screen_win_application_handler.cc
@@ -109,6 +109,7 @@ DesktopCapturer::SourceList GetProcessWindows(
FullScreenPowerPointHandler::FullScreenPowerPointHandler(
DesktopCapturer::SourceId sourceId)
: FullScreenApplicationHandler(sourceId),
+ was_slide_show_created_after_capture_started_(false),
full_screen_detector_result_(FullScreenDetectorResult::kUnknown) {}
DesktopCapturer::SourceId FullScreenPowerPointHandler::FindFullScreenWindow(
@@ -129,13 +130,16 @@ DesktopCapturer::SourceId FullScreenPowerPointHandler::FindFullScreenWindow(
// No relevant windows with the same process id as the `original_window` were
// found.
if (powerpoint_windows.empty()) {
+ was_slide_show_created_after_capture_started_ = true;
return 0;
}
+ bool do_same_title_editors_exist = false;
+ bool does_slide_show_exist = false;
DesktopCapturer::SourceId full_screen_slide_show_id = 0;
const std::string original_document_title =
GetDocumentTitleFromEditor(original_window);
- auto result = FullScreenDetectorResult::kUnknown;
+ auto result = full_screen_detector_result_;
for (const auto& source : powerpoint_windows) {
HWND window = reinterpret_cast<HWND>(source.id);
@@ -144,18 +148,32 @@ DesktopCapturer::SourceId FullScreenPowerPointHandler::FindFullScreenWindow(
// slide show.
if (GetWindowType(window) == WindowType::kEditor &&
GetDocumentTitleFromEditor(window) == original_document_title) {
+ do_same_title_editors_exist = true;
result = FullScreenDetectorResult::kFailureDueToSameTitleWindows;
- return 0;
}
// Looking for fullscreen slide show window for the corresponding editor
// document.
if (GetWindowType(window) == WindowType::kSlideShow &&
GetDocumentTitleFromSlideShow(window) == original_document_title) {
- result = FullScreenDetectorResult::kSuccess;
+ does_slide_show_exist = true;
full_screen_slide_show_id = source.id;
}
}
+ if (does_slide_show_exist) {
+ if (!was_slide_show_created_after_capture_started_) {
+ full_screen_slide_show_id = 0;
+ result = FullScreenDetectorResult::kFailureDueToSlideShowWasNotChosen;
+ } else if (do_same_title_editors_exist) {
+ full_screen_slide_show_id = 0;
+ result = FullScreenDetectorResult::kFailureDueToSameTitleWindows;
+ } else {
+ result = FullScreenDetectorResult::kSuccess;
+ }
+ } else {
+ was_slide_show_created_after_capture_started_ = true;
+ }
+
if (full_screen_detector_result_ != result) {
full_screen_detector_result_ = result;
RecordFullScreenDetectorResult(result);
@@ -163,6 +181,12 @@ DesktopCapturer::SourceId FullScreenPowerPointHandler::FindFullScreenWindow(
return full_screen_slide_show_id;
}
+void FullScreenPowerPointHandler::SetSlideShowCreationStateForTest(
+ bool fullscreen_slide_show_started_after_capture_start) {
+ was_slide_show_created_after_capture_started_ =
+ fullscreen_slide_show_started_after_capture_start;
+}
+
FullScreenPowerPointHandler::WindowType
FullScreenPowerPointHandler::GetWindowType(HWND window) const {
if (IsEditorWindow(window)) {
diff --git a/third_party/libwebrtc/modules/desktop_capture/win/full_screen_win_application_handler.h b/third_party/libwebrtc/modules/desktop_capture/win/full_screen_win_application_handler.h
@@ -26,7 +26,8 @@ enum class FullScreenDetectorResult {
kUnknown = 0,
kSuccess = 1,
kFailureDueToSameTitleWindows = 2,
- kMaxValue = kFailureDueToSameTitleWindows
+ kFailureDueToSlideShowWasNotChosen = 3,
+ kMaxValue = kFailureDueToSlideShowWasNotChosen
};
namespace webrtc {
@@ -43,6 +44,9 @@ class FullScreenPowerPointHandler : public FullScreenApplicationHandler {
const DesktopCapturer::SourceList& window_list,
int64_t timestamp) const override;
+ void SetSlideShowCreationStateForTest(
+ bool fullscreen_slide_show_started_after_capture_start) override;
+
private:
WindowType GetWindowType(HWND window) const;
@@ -62,6 +66,8 @@ class FullScreenPowerPointHandler : public FullScreenApplicationHandler {
bool IsSlideShowWindow(HWND window) const;
+ mutable bool was_slide_show_created_after_capture_started_;
+
mutable FullScreenDetectorResult full_screen_detector_result_;
};
diff --git a/third_party/libwebrtc/modules/desktop_capture/win/full_screen_win_application_handler_unittest.cc b/third_party/libwebrtc/modules/desktop_capture/win/full_screen_win_application_handler_unittest.cc
@@ -27,11 +27,15 @@ WindowInfo CreateTestWindow(const WCHAR* window_title,
class FullScreenWinApplicationHandlerTest : public ::testing::Test {
public:
- void CreateEditorWindow(const WCHAR* title,
- const WCHAR* window_class = L"PPTFrameClass") {
+ void CreateEditorWindow(
+ const WCHAR* title,
+ const WCHAR* window_class = L"PPTFrameClass",
+ bool fullscreen_slide_show_started_after_capture_start = true) {
editor_window_info_ = CreateTestWindow(title, window_class);
full_screen_ppt_handler_ = std::make_unique<FullScreenPowerPointHandler>(
reinterpret_cast<DesktopCapturer::SourceId>(editor_window_info_.hwnd));
+ full_screen_ppt_handler_->SetSlideShowCreationStateForTest(
+ fullscreen_slide_show_started_after_capture_start);
}
HWND CreateSlideShowWindow(const WCHAR* title) {
@@ -270,8 +274,11 @@ TEST_F(FullScreenWinApplicationHandlerTest,
std::vector<std::unique_ptr<FullScreenPowerPointHandler>> handlers;
for (auto& editor : editors) {
- handlers.push_back(std::make_unique<FullScreenPowerPointHandler>(
- reinterpret_cast<DesktopCapturer::SourceId>(editor.hwnd)));
+ auto handler = std::make_unique<FullScreenPowerPointHandler>(
+ reinterpret_cast<DesktopCapturer::SourceId>(editor.hwnd));
+ handler->SetSlideShowCreationStateForTest(
+ /*fullscreen_slide_show_started_after_capture_start=*/true);
+ handlers.push_back(std::move(handler));
}
std::vector<HWND> slide_shows = {
@@ -307,4 +314,16 @@ TEST_F(FullScreenWinApplicationHandlerTest,
DestroyTestWindow(second_editor_window_info);
}
+TEST_F(FullScreenWinApplicationHandlerTest,
+ FullScreenWindowNotFoundWhenSlideShowWasCreatedBefore) {
+ const WCHAR* editor_title = L"My - Title - PowerPoint";
+ CreateEditorWindow(
+ editor_title, /*window_class=*/L"PPTFrameClass",
+ /*fullscreen_slide_show_started_after_capture_start=*/false);
+ HWND slide_show =
+ CreateSlideShowWindow(L"PowerPoint Slide Show - [My - Title]");
+
+ EXPECT_NE(FindFullScreenWindow(), slide_show);
+ EXPECT_EQ(FindFullScreenWindow(), reinterpret_cast<HWND>(0));
+}
} // namespace webrtc
diff --git a/third_party/libwebrtc/modules/desktop_capture/win/wgc_capturer_win.cc b/third_party/libwebrtc/modules/desktop_capture/win/wgc_capturer_win.cc
@@ -462,12 +462,13 @@ bool WgcCapturerWin::IsSourceBeingCaptured(DesktopCapturer::SourceId id) {
void WgcCapturerWin::SetUpFullScreenDetectorForTest(
bool use_heuristic,
- DesktopCapturer::SourceId source_id) {
+ DesktopCapturer::SourceId source_id,
+ bool fullscreen_slide_show_started_after_capture_start) {
if (full_screen_window_detector_) {
full_screen_window_detector_->SetUseHeuristicFullscreenPowerPointWindows(
/*use_heuristic_fullscreen_powerpoint_windows=*/true, use_heuristic);
full_screen_window_detector_->CreateFullScreenApplicationHandlerForTest(
- source_id);
+ source_id, fullscreen_slide_show_started_after_capture_start);
}
}
diff --git a/third_party/libwebrtc/modules/desktop_capture/win/wgc_capturer_win.h b/third_party/libwebrtc/modules/desktop_capture/win/wgc_capturer_win.h
@@ -113,8 +113,10 @@ class WgcCapturerWin : public DesktopCapturer {
// Used in WgcCapturerTests.
bool IsSourceBeingCaptured(SourceId id);
- void SetUpFullScreenDetectorForTest(bool use_heuristic,
- DesktopCapturer::SourceId source_id);
+ void SetUpFullScreenDetectorForTest(
+ bool use_heuristic,
+ DesktopCapturer::SourceId source_id,
+ bool fullscreen_slide_show_started_after_capture_start = true);
private:
typedef HRESULT(WINAPI* CreateDispatcherQueueControllerFunc)(
diff --git a/third_party/libwebrtc/modules/desktop_capture/win/wgc_capturer_win_unittest.cc b/third_party/libwebrtc/modules/desktop_capture/win/wgc_capturer_win_unittest.cc
@@ -54,6 +54,12 @@ constexpr int kSourceClosed = 1;
constexpr char kCaptureTimeHistogram[] =
"WebRTC.DesktopCapture.Win.WgcCapturerFrameTime";
+constexpr char kFullScreenDetectorResult[] =
+ "WebRTC.Screenshare.FullScreenDetectorResult";
+constexpr int detector_result_success = 1;
+constexpr int detector_result_failure_same_title_windows = 2;
+constexpr int detector_result_failure_slide_show_not_chosen = 3;
+
constexpr char kCaptureFullscreenDetectorHistogram[] =
"WebRTC.Screenshare.DesktopCapturerFullscreenDetector";
@@ -622,7 +628,8 @@ TEST_F(WgcCapturerFullScreenDetectorTest, SlideShowNotFoundByDefaultConfig) {
EXPECT_EQ(metrics::NumEvents(kCaptureFullscreenDetectorHistogram, true), 0);
}
-TEST_F(WgcCapturerFullScreenDetectorTest, CorrectSlideShowFoundForEditor) {
+TEST_F(WgcCapturerFullScreenDetectorTest,
+ CorrectSlideShowFoundForEditorWhenSlideShowCreatedAfter) {
wgc_capturer_->SetUpFullScreenDetectorForTest(
/*use_heuristic=*/true,
reinterpret_cast<DesktopCapturer::SourceId>(editor_window_.hwnd));
@@ -638,6 +645,38 @@ TEST_F(WgcCapturerFullScreenDetectorTest, CorrectSlideShowFoundForEditor) {
reinterpret_cast<DesktopCapturer::SourceId>(slide_show_window_.hwnd)));
EXPECT_EQ(metrics::NumEvents(kCaptureFullscreenDetectorHistogram, true), 1);
+ EXPECT_EQ(
+ metrics::NumEvents(kFullScreenDetectorResult, detector_result_success),
+ 1);
+ EXPECT_EQ(metrics::NumEvents(kFullScreenDetectorResult,
+ detector_result_failure_slide_show_not_chosen),
+ 0);
+}
+
+TEST_F(WgcCapturerFullScreenDetectorTest,
+ SlideShowNotFoundForEditorWhenSlideShowCreatedBefore) {
+ wgc_capturer_->SetUpFullScreenDetectorForTest(
+ /*use_heuristic=*/true,
+ reinterpret_cast<DesktopCapturer::SourceId>(editor_window_.hwnd),
+ /*fullscreen_slide_show_started_after_capture_start=*/false);
+
+ EXPECT_TRUE(wgc_capturer_->SelectSource(
+ reinterpret_cast<DesktopCapturer::SourceId>(editor_window_.hwnd)));
+ wgc_capturer_->Start(this);
+ DoCapture();
+
+ EXPECT_TRUE(wgc_capturer_->IsSourceBeingCaptured(
+ reinterpret_cast<DesktopCapturer::SourceId>(editor_window_.hwnd)));
+ EXPECT_FALSE(wgc_capturer_->IsSourceBeingCaptured(
+ reinterpret_cast<DesktopCapturer::SourceId>(slide_show_window_.hwnd)));
+
+ EXPECT_EQ(metrics::NumEvents(kCaptureFullscreenDetectorHistogram, true), 0);
+ EXPECT_EQ(
+ metrics::NumEvents(kFullScreenDetectorResult, detector_result_success),
+ 0);
+ EXPECT_EQ(metrics::NumEvents(kFullScreenDetectorResult,
+ detector_result_failure_slide_show_not_chosen),
+ 1);
}
TEST_F(WgcCapturerFullScreenDetectorTest, LoggedOnlyOnce) {
@@ -656,6 +695,9 @@ TEST_F(WgcCapturerFullScreenDetectorTest, LoggedOnlyOnce) {
EXPECT_TRUE(wgc_capturer_->IsSourceBeingCaptured(
reinterpret_cast<DesktopCapturer::SourceId>(slide_show_window_.hwnd)));
EXPECT_EQ(metrics::NumEvents(kCaptureFullscreenDetectorHistogram, true), 1);
+ EXPECT_EQ(
+ metrics::NumEvents(kFullScreenDetectorResult, detector_result_success),
+ 1);
}
TEST_F(WgcCapturerFullScreenDetectorTest,
@@ -676,6 +718,12 @@ TEST_F(WgcCapturerFullScreenDetectorTest,
EXPECT_FALSE(wgc_capturer_->IsSourceBeingCaptured(
reinterpret_cast<DesktopCapturer::SourceId>(slide_show_window_.hwnd)));
EXPECT_EQ(metrics::NumEvents(kCaptureFullscreenDetectorHistogram, true), 0);
+ EXPECT_EQ(
+ metrics::NumEvents(kFullScreenDetectorResult, detector_result_success),
+ 0);
+ EXPECT_EQ(metrics::NumEvents(kFullScreenDetectorResult,
+ detector_result_failure_same_title_windows),
+ 1);
}
TEST_F(WgcCapturerFullScreenDetectorTest,
@@ -697,6 +745,12 @@ TEST_F(WgcCapturerFullScreenDetectorTest,
EXPECT_TRUE(wgc_capturer_->IsSourceBeingCaptured(
reinterpret_cast<DesktopCapturer::SourceId>(slide_show_window_.hwnd)));
EXPECT_EQ(metrics::NumEvents(kCaptureFullscreenDetectorHistogram, true), 0);
+ EXPECT_EQ(
+ metrics::NumEvents(kFullScreenDetectorResult, detector_result_success),
+ 0);
+ EXPECT_EQ(metrics::NumEvents(kFullScreenDetectorResult,
+ detector_result_failure_slide_show_not_chosen),
+ 0);
}
} // namespace webrtc