Commit 15fd27f4 authored by Guido Urdaneta's avatar Guido Urdaneta Committed by Commit Bot

[Screen Capture] Update heuristic to determine system permission in Catalina

The old heuristic checked that the title of all windows was readable, but
it failed in some corner cases where an application creates a window whose
title cannot be read even with screen capture permissions.
The new heuristic checks that the title of at least one normal, dock or status
window running on another process is readable, which is less susceptible to
failures.

Drive-by: return SYSTEM_PERMISSION_DENIED instead of PERMISSION_DENIED when
the system permission check fails in getDisplayMedia().

Bug: 993692
Change-Id: Ie127d1e2d6bd29dd8885b0c461bdab838559fcb8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1871885
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#708260}
parent 59a80ba8
......@@ -210,7 +210,7 @@ void DisplayMediaAccessHandler::OnPickerDialogResults(
system_media_permissions::CheckSystemScreenCapturePermission() !=
system_media_permissions::SystemPermission::kAllowed) {
request_result =
blink::mojom::MediaStreamRequestResult::PERMISSION_DENIED;
blink::mojom::MediaStreamRequestResult::SYSTEM_PERMISSION_DENIED;
}
#endif
if (request_result == blink::mojom::MediaStreamRequestResult::OK) {
......
......@@ -166,27 +166,46 @@ void RequestSystemMediaCapturePermission(NSString* media_type,
}
// Heuristic to check screen capture permission on macOS 10.15.
// See https://crbug.com/993692#c3.
// Screen Capture is considered allowed if the name of at least one normal,
// dock or status window running on another process is visible.
// See https://crbug.com/993692.
bool IsScreenCaptureAllowed() {
if (@available(macOS 10.15, *)) {
if (!base::FeatureList::IsEnabled(
features::kMacSystemScreenCapturePermissionCheck)) {
return true;
}
base::ScopedCFTypeRef<CFArrayRef> window_list(CGWindowListCopyWindowInfo(
kCGWindowListOptionOnScreenOnly, kCGNullWindowID));
NSUInteger num_windows = CFArrayGetCount(window_list);
NSUInteger num_windows_with_name = 0;
for (NSDictionary* dict in base::mac::CFToNSCast(window_list.get())) {
if ([dict objectForKey:base::mac::CFToNSCast(kCGWindowName)]) {
num_windows_with_name++;
} else {
// No kCGWindowName detected implies no permission.
break;
int current_pid = [[NSProcessInfo processInfo] processIdentifier];
for (NSDictionary* window in base::mac::CFToNSCast(window_list.get())) {
NSNumber* window_pid =
[window objectForKey:base::mac::CFToNSCast(kCGWindowOwnerPID)];
if (!window_pid || [window_pid integerValue] == current_pid)
continue;
NSString* window_name =
[window objectForKey:base::mac::CFToNSCast(kCGWindowName)];
if (!window_name)
continue;
NSNumber* layer =
[window objectForKey:base::mac::CFToNSCast(kCGWindowLayer)];
if (!layer)
continue;
NSInteger layer_integer = [layer integerValue];
if (layer_integer == CGWindowLevelForKey(kCGNormalWindowLevelKey) ||
layer_integer == CGWindowLevelForKey(kCGDockWindowLevelKey) ||
layer_integer == CGWindowLevelForKey(kCGStatusWindowLevelKey)) {
return true;
}
}
return num_windows == num_windows_with_name;
return false;
}
// Screen capture is always allowed in older macOS versions.
return true;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment