Add DesktopCaptureOption enumerate_current_process_windows to avoid hang

Enumerating windows owned by the current process on Windows has some
complications due to the GetWindowText*() APIs potentially causing a
deadlock. The APIs will send messages to the window's message loop, and
if the message loop is waiting on this operation we will enter a
deadlock.

I previously put in a mitigation for this [1] which brought the
incidence rate down by an order of magnitude, but we are still seeing
this issue fairly frequently.

So, I've added  DesktopCaptureOption enumerate_current_process_windows
which allows consumers to avoid this issue completely by ignoring
these potentially problematic windows.

By default the flag is set to true which equates with the current
behavior, consumers can set the flag to false to get the new behavior.

I've also updated all the capturers that enumerate windows on Windows
to respect the option.

[1] https://webrtc-review.googlesource.com/c/src/+/195365

Bug: chromium:1152841
Change-Id: I0e0d868957d6fbe1e607a440b3a909d005c93ccf
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/219380
Commit-Queue: Austin Orion <auorion@microsoft.com>
Reviewed-by: Joe Downing <joedow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#34191}
This commit is contained in:
Austin Orion
2021-06-01 09:49:15 -07:00
committed by WebRTC LUCI CQ
parent 803fdc4106
commit 78c73477c7
9 changed files with 99 additions and 29 deletions

View File

@ -78,6 +78,7 @@ enum GetWindowListFlags {
kNone = 0x00,
kIgnoreUntitled = 1 << 0,
kIgnoreUnresponsive = 1 << 1,
kIgnoreCurrentProcessWindows = 1 << 2,
};
// Retrieves the list of top-level windows on the screen.
@ -85,7 +86,8 @@ enum GetWindowListFlags {
// - Those that are invisible or minimized.
// - Program Manager & Start menu.
// - [with kIgnoreUntitled] windows with no title.
// - [with kIgnoreUnresponsive] windows that unresponsive.
// - [with kIgnoreUnresponsive] windows that are unresponsive.
// - [with kIgnoreCurrentProcessWindows] windows owned by the current process.
// - Any windows with extended styles that match |ex_style_filters|.
// Returns false if native APIs failed.
bool GetWindowList(int flags,
@ -115,6 +117,7 @@ class WindowCaptureHelperWin {
// extended window styles (e.g. WS_EX_TOOLWINDOW) and prevent windows that
// match from being included in |results|.
bool EnumerateCapturableWindows(DesktopCapturer::SourceList* results,
bool enumerate_current_process_windows,
LONG ex_style_filters = 0);
private: