Skip to content

Commit

Permalink
Remove 10.13, 10.14 support from media permissions
Browse files Browse the repository at this point in the history
These macOS releases are no longer supported by Chromium.

Bug: 1410851
Change-Id: I30919613d6ca6398bf8ac8a12afcffa712cbb6ce
Include-Ci-Only-Tests: true
Cq-Include-Trybots: luci.chrome.try:mac-chrome
Validate-Test-Flakiness: skip
Low-Coverage-Reason: Doing core refactoring across all of Chromium; I do not own this code
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4632022
Commit-Queue: Avi Drissman <avi@chromium.org>
Auto-Submit: Avi Drissman <avi@chromium.org>
Reviewed-by: Gary Kacmarcik <garykac@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1161580}
  • Loading branch information
Avi Drissman authored and Chromium LUCI CQ committed Jun 23, 2023
1 parent 14da5e8 commit 025a588
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ void PermissionBubbleMediaAccessHandler::OnAccessRequestResponse(
if (system_audio_permission == SystemPermission::kNotDetermined) {
// Using WeakPtr since callback can come at any time and we might be
// destroyed.
system_media_permissions::RequestSystemAudioCapturePermisson(
system_media_permissions::RequestSystemAudioCapturePermission(
base::BindOnce(&PermissionBubbleMediaAccessHandler::
OnAccessRequestResponseForBinding,
weak_factory_.GetWeakPtr(), web_contents, request_id,
Expand All @@ -424,7 +424,7 @@ void PermissionBubbleMediaAccessHandler::OnAccessRequestResponse(
if (system_video_permission == SystemPermission::kNotDetermined) {
// Using WeakPtr since callback can come at any time and we might be
// destroyed.
system_media_permissions::RequestSystemVideoCapturePermisson(
system_media_permissions::RequestSystemVideoCapturePermission(
base::BindOnce(&PermissionBubbleMediaAccessHandler::
OnAccessRequestResponseForBinding,
weak_factory_.GetWeakPtr(), web_contents, request_id,
Expand Down
22 changes: 8 additions & 14 deletions chrome/browser/media/webrtc/system_media_capture_permissions_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,19 @@ enum class SystemPermission {
kMaxValue = kAllowed
};

// On 10.14 and above: returns the system permission.
// On 10.13 and below: returns |SystemPermission::kAllowed|, since there are no
// system media capture permissions.
// Returns the system permission to capture audio or video.
SystemPermission CheckSystemAudioCapturePermission();
SystemPermission CheckSystemVideoCapturePermission();

// On 10.15 and above: returns the system permission.
// On 10.14 and below: returns |SystemPermission::kAllowed|, since there are no
// system screen capture permissions.
// Returns the system permission to capture the screen.
SystemPermission CheckSystemScreenCapturePermission();

// On 10.14 and above: requests system permission and returns. When requesting
// permission, the OS will show a user dialog and respond asynchronously. At the
// response, |callback| is posted as a reply on the requesting thread.
// Note: these functions should really never be called for pre-10.14 since one
// would normally check the permission first, and only call this if it's not
// determined.
void RequestSystemAudioCapturePermisson(base::OnceClosure callback);
void RequestSystemVideoCapturePermisson(base::OnceClosure callback);
// Requests the system permission to capture audio or video. This call
// immediately returns. When requesting permission, the OS will show a user
// dialog and respond asynchronously. At the response, |callback| is posted as a
// reply on the requesting thread.
void RequestSystemAudioCapturePermission(base::OnceClosure callback);
void RequestSystemVideoCapturePermission(base::OnceClosure callback);

// Sets the wrapper object for OS calls. For test mocking purposes.
void SetMediaAuthorizationWrapperForTesting(MediaAuthorizationWrapper* wrapper);
Expand Down
88 changes: 32 additions & 56 deletions chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,19 @@ bool UsingFakeMediaDevices() {
~MediaAuthorizationWrapperImpl() override = default;

NSInteger AuthorizationStatusForMediaType(AVMediaType media_type) override {
if (@available(macOS 10.14, *)) {
return [AVCaptureDevice authorizationStatusForMediaType:media_type];
} else {
CHECK(false);
return 0;
}
return [AVCaptureDevice authorizationStatusForMediaType:media_type];
}

void RequestAccessForMediaType(AVMediaType media_type,
base::OnceClosure callback) override {
if (@available(macOS 10.14, *)) {
__block base::OnceClosure block_callback = std::move(callback);
__block scoped_refptr<base::SequencedTaskRunner> requesting_thread =
base::SequencedTaskRunner::GetCurrentDefault();
[AVCaptureDevice requestAccessForMediaType:media_type
completionHandler:^(BOOL granted) {
requesting_thread->PostTask(
FROM_HERE, std::move(block_callback));
}];
} else {
CHECK(false);
}
__block base::OnceClosure block_callback = std::move(callback);
__block scoped_refptr<base::SequencedTaskRunner> requesting_thread =
base::SequencedTaskRunner::GetCurrentDefault();
[AVCaptureDevice requestAccessForMediaType:media_type
completionHandler:^(BOOL granted) {
requesting_thread->PostTask(
FROM_HERE, std::move(block_callback));
}];
}
};

Expand All @@ -85,37 +76,28 @@ void RequestAccessForMediaType(AVMediaType media_type,
}

NSInteger MediaAuthorizationStatus(AVMediaType media_type) {
if (@available(macOS 10.14, *)) {
return GetMediaAuthorizationWrapper().AuthorizationStatusForMediaType(
media_type);
}

CHECK(false);
return 0;
return GetMediaAuthorizationWrapper().AuthorizationStatusForMediaType(
media_type);
}

SystemPermission CheckSystemMediaCapturePermission(AVMediaType media_type) {
if (UsingFakeMediaDevices())
if (UsingFakeMediaDevices()) {
return SystemPermission::kAllowed;

if (@available(macOS 10.14, *)) {
NSInteger auth_status = MediaAuthorizationStatus(media_type);
switch (auth_status) {
case AVAuthorizationStatusNotDetermined:
return SystemPermission::kNotDetermined;
case AVAuthorizationStatusRestricted:
return SystemPermission::kRestricted;
case AVAuthorizationStatusDenied:
return SystemPermission::kDenied;
case AVAuthorizationStatusAuthorized:
return SystemPermission::kAllowed;
default:
NOTREACHED_NORETURN();
}
}

// On pre-10.14, there are no system permissions, so we return allowed.
return SystemPermission::kAllowed;
NSInteger auth_status = MediaAuthorizationStatus(media_type);
switch (auth_status) {
case AVAuthorizationStatusNotDetermined:
return SystemPermission::kNotDetermined;
case AVAuthorizationStatusRestricted:
return SystemPermission::kRestricted;
case AVAuthorizationStatusDenied:
return SystemPermission::kDenied;
case AVAuthorizationStatusAuthorized:
return SystemPermission::kAllowed;
default:
NOTREACHED_NORETURN();
}
}

void RequestSystemMediaCapturePermission(AVMediaType media_type,
Expand All @@ -126,20 +108,14 @@ void RequestSystemMediaCapturePermission(AVMediaType media_type,
return;
}

if (@available(macOS 10.14, *)) {
GetMediaAuthorizationWrapper().RequestAccessForMediaType(
media_type, std::move(callback));
} else {
CHECK(false);
}
GetMediaAuthorizationWrapper().RequestAccessForMediaType(media_type,
std::move(callback));
}

bool IsScreenCaptureAllowed() {
if (@available(macOS 10.15, *)) {
if (!base::FeatureList::IsEnabled(
features::kMacSystemScreenCapturePermissionCheck)) {
return true;
}
if (!base::FeatureList::IsEnabled(
features::kMacSystemScreenCapturePermissionCheck)) {
return true;
}

bool allowed = ui::IsScreenCaptureAllowed();
Expand All @@ -162,11 +138,11 @@ SystemPermission CheckSystemScreenCapturePermission() {
: SystemPermission::kDenied;
}

void RequestSystemAudioCapturePermisson(base::OnceClosure callback) {
void RequestSystemAudioCapturePermission(base::OnceClosure callback) {
RequestSystemMediaCapturePermission(AVMediaTypeAudio, std::move(callback));
}

void RequestSystemVideoCapturePermisson(base::OnceClosure callback) {
void RequestSystemVideoCapturePermission(base::OnceClosure callback) {
RequestSystemMediaCapturePermission(AVMediaTypeVideo, std::move(callback));
}

Expand Down
49 changes: 19 additions & 30 deletions remoting/host/mac/permission_utils.mm
Original file line number Diff line number Diff line change
Expand Up @@ -113,19 +113,16 @@ void ShowScreenRecordingPermissionDialog() {
namespace remoting::mac {

bool CanInjectInput() {
if (!base::mac::IsAtLeastOS10_14()) {
return true;
}
return AXIsProcessTrusted();
}

bool CanRecordScreen() {
return ui::IsScreenCaptureAllowed();
}

// MacOs 10.14+ requires an additional runtime permission for injecting input
// using CGEventPost (we use this in our input injector for Mac). This method
// will request that the user enable this permission for us if they are on an
// macOS requires an additional runtime permission for injecting input using
// CGEventPost (we use this in our input injector for Mac). This method will
// request that the user enable this permission for us if they are on an
// affected version and the permission has not already been approved.
void PromptUserForAccessibilityPermissionIfNeeded(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
Expand All @@ -140,10 +137,9 @@ void PromptUserForAccessibilityPermissionIfNeeded(
base::BindOnce(&ShowAccessibilityPermissionDialog));
}

// MacOs 10.15+ requires an additional runtime permission for capturing the
// screen. This method will request that the user enable this permission for
// us if they are on an affected version and the permission has not already
// been approved.
// macOS requires an additional runtime permission for capturing the screen.
// This method will request that the user enable this permission for us if they
// are on an affected version and the permission has not already been approved.
void PromptUserForScreenRecordingPermissionIfNeeded(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
if (CanRecordScreen()) {
Expand All @@ -164,29 +160,22 @@ void PromptUserToChangeTrustStateIfNeeded(
}

bool CanCaptureAudio() {
if (@available(macOS 10.14, *)) {
NSInteger auth_status =
[AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
return auth_status == AVAuthorizationStatusAuthorized;
}
return true;
NSInteger auth_status =
[AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
return auth_status == AVAuthorizationStatusAuthorized;
}

void RequestAudioCapturePermission(base::OnceCallback<void(bool)> callback) {
if (@available(macOS 10.14, *)) {
auto task_runner = base::SequencedTaskRunner::GetCurrentDefault();
__block auto block_callback = std::move(callback);
[AVCaptureDevice
requestAccessForMediaType:AVMediaTypeAudio
completionHandler:^(BOOL granted) {
task_runner->PostTask(
FROM_HERE,
base::BindOnce(std::move(block_callback), granted));
}];
return;
}
// CanCaptureAudio() returns true for older OSes.
NOTREACHED();
auto task_runner = base::SequencedTaskRunner::GetCurrentDefault();
__block auto block_callback = std::move(callback);
[AVCaptureDevice
requestAccessForMediaType:AVMediaTypeAudio
completionHandler:^(BOOL granted) {
task_runner->PostTask(
FROM_HERE,
base::BindOnce(std::move(block_callback), granted));
}];
return;
}

} // namespace remoting::mac
6 changes: 3 additions & 3 deletions ui/base/cocoa/permissions_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

namespace ui {

// Starting on macOS 10.15, the ability to screen capture is restricted and
// requires a permission authorization. This function returns `true` if screen
// capture permission was already granted by the user and `false` if it was not.
// The ability to screen capture is restricted and requires a permission
// authorization. This function returns `true` if screen capture permission was
// already granted by the user and `false` if it was not.
COMPONENT_EXPORT(UI_BASE) bool IsScreenCaptureAllowed();

// Explicitly request from the user permission to capture the screen. Returns
Expand Down
48 changes: 20 additions & 28 deletions ui/base/cocoa/permissions_utils.mm
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
bool IsScreenCaptureAllowed() {
if (@available(macOS 11.0, *)) {
return CGPreflightScreenCaptureAccess();
} else if (@available(macOS 10.15, *)) {
} else {
// Screen Capture is considered allowed if the name of at least one normal
// or dock window running on another process is visible.
// See https://crbug.com/993692.
Expand Down Expand Up @@ -59,16 +59,13 @@ bool IsScreenCaptureAllowed() {
}
}
return false;
} else {
// Screen capture is always allowed in older macOS versions.
return true;
}
}

bool TryPromptUserForScreenCapture() {
if (@available(macOS 11.0, *)) {
return CGRequestScreenCaptureAccess();
} else if (@available(macOS 10.15, *)) {
} else {
// On 10.15+, macOS will show the permissions prompt for Screen Recording
// if we request to create a display stream and our application is not
// in the applications list in System permissions. Stream creation will
Expand All @@ -80,33 +77,28 @@ bool TryPromptUserForScreenCapture() {
IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef){
}));
return stream != nullptr;
} else {
// Screen capture is always allowed in older macOS versions.
return true;
}
}

void WarmScreenCapture() {
if (@available(macOS 10.15, *)) {
// WarmScreenCapture() is meant to be called during early startup. Since the
// calls to warm the cache may block, execute them off the main thread so we
// don't hold up startup. To be effective these calls need to run before
// Chrome is updated. Running them off the main thread technically opens us
// to a race condition, however updating happens way later so this is not a
// concern.
base::ThreadPool::PostTask(
FROM_HERE,
// Checking screen capture access hits the TCC.db and reads Chrome's
// code signature from disk, marking as MayBlock.
{base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce([] {
if (IsScreenCaptureAllowed()) {
base::ScopedCFTypeRef<CGImageRef>(CGWindowListCreateImage(
CGRectInfinite, kCGWindowListOptionOnScreenOnly,
kCGNullWindowID, kCGWindowImageDefault));
}
}));
}
// WarmScreenCapture() is meant to be called during early startup. Since the
// calls to warm the cache may block, execute them off the main thread so we
// don't hold up startup. To be effective these calls need to run before
// Chrome is updated. Running them off the main thread technically opens us
// to a race condition, however updating happens way later so this is not a
// concern.
base::ThreadPool::PostTask(
FROM_HERE,
// Checking screen capture access hits the TCC.db and reads Chrome's
// code signature from disk, marking as MayBlock.
{base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce([] {
if (IsScreenCaptureAllowed()) {
base::ScopedCFTypeRef<CGImageRef>(CGWindowListCreateImage(
CGRectInfinite, kCGWindowListOptionOnScreenOnly, kCGNullWindowID,
kCGWindowImageDefault));
}
}));
}

} // namespace ui

0 comments on commit 025a588

Please sign in to comment.