diff --git a/chromium_src/BUILD.gn b/chromium_src/BUILD.gn index 2447e121082e9..274721155b5f6 100644 --- a/chromium_src/BUILD.gn +++ b/chromium_src/BUILD.gn @@ -32,6 +32,8 @@ static_library("chrome") { "//chrome/browser/icon_loader_win.cc", "//chrome/browser/icon_manager.cc", "//chrome/browser/icon_manager.h", + "//chrome/browser/media/webrtc/system_media_capture_permissions_mac.h", + "//chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm", "//chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc", "//chrome/browser/net/chrome_mojo_proxy_resolver_factory.h", "//chrome/browser/net/proxy_config_monitor.cc", diff --git a/docs/api/desktop-capturer.md b/docs/api/desktop-capturer.md index f8e12d04d0788..bf376ce46a9a0 100644 --- a/docs/api/desktop-capturer.md +++ b/docs/api/desktop-capturer.md @@ -91,7 +91,11 @@ The `desktopCapturer` module has the following methods: Returns `Promise` - Resolves with an array of [`DesktopCapturerSource`](structures/desktop-capturer-source.md) objects, each `DesktopCapturerSource` represents a screen or an individual window that can be captured. +**Note** Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher, +which can detected by [`systemPreferences.getMediaAccessStatus`]. + [`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia +[`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-macos ## Caveats diff --git a/docs/api/system-preferences.md b/docs/api/system-preferences.md index 38672a4512818..9a8047ddc7993 100644 --- a/docs/api/system-preferences.md +++ b/docs/api/system-preferences.md @@ -434,11 +434,13 @@ Returns `Boolean` - `true` if the current process is a trusted accessibility cli ### `systemPreferences.getMediaAccessStatus(mediaType)` _macOS_ -* `mediaType` String - `microphone` or `camera`. +* `mediaType` String - `microphone`, `camera` or `screen`. Returns `String` - Can be `not-determined`, `granted`, `denied`, `restricted` or `unknown`. -This user consent was not required until macOS 10.14 Mojave, so this method will always return `granted` if your system is running 10.13 High Sierra or lower. +This user consent was not required on macOS 10.13 High Sierra or lower so this method will always return `granted`. +macOS 10.14 Mojave or higher requires consent for `microphone` and `camera` access. +macOS 10.15 Catalina or higher requires consent for `screen` access. ### `systemPreferences.askForMediaAccess(mediaType)` _macOS_ diff --git a/shell/browser/api/atom_api_system_preferences_mac.mm b/shell/browser/api/atom_api_system_preferences_mac.mm index 179202d77ef04..dc50f820bf320 100644 --- a/shell/browser/api/atom_api_system_preferences_mac.mm +++ b/shell/browser/api/atom_api_system_preferences_mac.mm @@ -21,6 +21,7 @@ #include "base/strings/sys_string_conversions.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/values.h" +#include "chrome/browser/media/webrtc/system_media_capture_permissions_mac.h" #include "net/base/mac/url_conversions.h" #include "shell/browser/mac/atom_application.h" #include "shell/browser/mac/dict_util.h" @@ -103,6 +104,23 @@ AVMediaType ParseMediaType(const std::string& media_type) { } } +std::string ConvertSystemPermission( + system_media_permissions::SystemPermission value) { + using SystemPermission = system_media_permissions::SystemPermission; + switch (value) { + case SystemPermission::kNotDetermined: + return "not-determined"; + case SystemPermission::kRestricted: + return "restricted"; + case SystemPermission::kDenied: + return "denied"; + case SystemPermission::kAllowed: + return "granted"; + default: + return "unknown"; + } +} + } // namespace void SystemPreferences::PostNotification(const std::string& name, @@ -574,24 +592,15 @@ AVMediaType ParseMediaType(const std::string& media_type) { std::string SystemPreferences::GetMediaAccessStatus( const std::string& media_type, gin_helper::Arguments* args) { - if (auto type = ParseMediaType(media_type)) { - if (@available(macOS 10.14, *)) { - switch ([AVCaptureDevice authorizationStatusForMediaType:type]) { - case AVAuthorizationStatusNotDetermined: - return "not-determined"; - case AVAuthorizationStatusRestricted: - return "restricted"; - case AVAuthorizationStatusDenied: - return "denied"; - case AVAuthorizationStatusAuthorized: - return "granted"; - default: - return "unknown"; - } - } else { - // access always allowed pre-10.14 Mojave - return "granted"; - } + if (media_type == "camera") { + return ConvertSystemPermission( + system_media_permissions::CheckSystemVideoCapturePermission()); + } else if (media_type == "microphone") { + return ConvertSystemPermission( + system_media_permissions::CheckSystemAudioCapturePermission()); + } else if (media_type == "screen") { + return ConvertSystemPermission( + system_media_permissions::CheckSystemScreenCapturePermission()); } else { args->ThrowError("Invalid media type"); return std::string(); diff --git a/spec-main/api-system-preferences-spec.ts b/spec-main/api-system-preferences-spec.ts index 57f87fa144507..ea0d53c528fab 100644 --- a/spec-main/api-system-preferences-spec.ts +++ b/spec-main/api-system-preferences-spec.ts @@ -246,6 +246,11 @@ describe('systemPreferences module', () => { const microphoneStatus = systemPreferences.getMediaAccessStatus('microphone') expect(statuses).to.include(microphoneStatus) }) + + it('returns an access status for a screen access request', () => { + const screenStatus = systemPreferences.getMediaAccessStatus('screen') + expect(statuses).to.include(screenStatus) + }) }) describe('systemPreferences.getAnimationSettings()', () => {