зеркало из https://github.com/electron/electron.git
feat: add media access APIs for macOS Mojave (#15624)
This commit is contained in:
Родитель
aa2b2f7c8f
Коммит
c31629ad98
1
BUILD.gn
1
BUILD.gn
|
@ -595,6 +595,7 @@ if (is_mac) {
|
|||
sources = filenames.framework_sources
|
||||
|
||||
libs = [
|
||||
"AVFoundation.framework",
|
||||
"Carbon.framework",
|
||||
"QuartzCore.framework",
|
||||
"Quartz.framework",
|
||||
|
|
|
@ -89,6 +89,9 @@ void SystemPreferences::BuildPrototype(
|
|||
&SystemPreferences::GetAppLevelAppearance)
|
||||
.SetMethod("setAppLevelAppearance",
|
||||
&SystemPreferences::SetAppLevelAppearance)
|
||||
.SetMethod("getMediaAccessStatus",
|
||||
&SystemPreferences::GetMediaAccessStatus)
|
||||
.SetMethod("askForMediaAccess", &SystemPreferences::AskForMediaAccess)
|
||||
#endif
|
||||
.SetMethod("isInvertedColorScheme",
|
||||
&SystemPreferences::IsInvertedColorScheme)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <string>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/values.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
@ -90,6 +91,13 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
|||
void RemoveUserDefault(const std::string& name);
|
||||
bool IsSwipeTrackingFromScrollEventsEnabled();
|
||||
|
||||
// TODO(codebytere): Write tests for these methods once we
|
||||
// are running tests on a Mojave machine
|
||||
std::string GetMediaAccessStatus(const std::string& media_type,
|
||||
mate::Arguments* args);
|
||||
v8::Local<v8::Promise> AskForMediaAccess(v8::Isolate* isolate,
|
||||
const std::string& media_type);
|
||||
|
||||
// TODO(MarshallOfSound): Write tests for these methods once we
|
||||
// are running tests on a Mojave machine
|
||||
v8::Local<v8::Value> GetEffectiveAppearance(v8::Isolate* isolate);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <map>
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
|
@ -78,6 +79,31 @@ int g_next_id = 0;
|
|||
// The map to convert |id| to |int|.
|
||||
std::map<int, id> g_id_map;
|
||||
|
||||
AVMediaType ParseMediaType(const std::string& media_type) {
|
||||
if (media_type == "camera") {
|
||||
return AVMediaTypeVideo;
|
||||
} else if (media_type == "microphone") {
|
||||
return AVMediaTypeAudio;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
std::string ConvertAuthorizationStatus(AVAuthorizationStatusMac status) {
|
||||
switch (status) {
|
||||
case AVAuthorizationStatusNotDeterminedMac:
|
||||
return "not-determined";
|
||||
case AVAuthorizationStatusRestrictedMac:
|
||||
return "restricted";
|
||||
case AVAuthorizationStatusDeniedMac:
|
||||
return "denied";
|
||||
case AVAuthorizationStatusAuthorizedMac:
|
||||
return "granted";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void SystemPreferences::PostNotification(
|
||||
|
@ -360,6 +386,47 @@ void SystemPreferences::SetUserDefault(const std::string& name,
|
|||
}
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetMediaAccessStatus(
|
||||
const std::string& media_type,
|
||||
mate::Arguments* args) {
|
||||
if (auto type = ParseMediaType(media_type)) {
|
||||
if (@available(macOS 10.14, *)) {
|
||||
return ConvertAuthorizationStatus(
|
||||
[AVCaptureDevice authorizationStatusForMediaType:type]);
|
||||
} else {
|
||||
// access always allowed pre-10.14 Mojave
|
||||
return ConvertAuthorizationStatus(AVAuthorizationStatusAuthorizedMac);
|
||||
}
|
||||
} else {
|
||||
args->ThrowError("Invalid media type");
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> SystemPreferences::AskForMediaAccess(
|
||||
v8::Isolate* isolate,
|
||||
const std::string& media_type) {
|
||||
scoped_refptr<util::Promise> promise = new util::Promise(isolate);
|
||||
|
||||
if (auto type = ParseMediaType(media_type)) {
|
||||
if (@available(macOS 10.14, *)) {
|
||||
[AVCaptureDevice requestAccessForMediaType:type
|
||||
completionHandler:^(BOOL granted) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
promise->Resolve(!!granted);
|
||||
});
|
||||
}];
|
||||
} else {
|
||||
// access always allowed pre-10.14 Mojave
|
||||
promise->Resolve(true);
|
||||
}
|
||||
} else {
|
||||
promise->RejectWithErrorMessage("Invalid media type");
|
||||
}
|
||||
|
||||
return promise->GetHandle();
|
||||
}
|
||||
|
||||
void SystemPreferences::RemoveUserDefault(const std::string& name) {
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults removeObjectForKey:base::SysUTF8ToNSString(name)];
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
#include "base/mac/scoped_nsobject.h"
|
||||
#include "base/mac/scoped_sending_event.h"
|
||||
|
||||
// Forward Declare Appareance APIs
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
// Forward Declare Appearance APIs
|
||||
@interface NSApplication (HighSierraSDK)
|
||||
@property(copy, readonly)
|
||||
NSAppearance* effectiveAppearance API_AVAILABLE(macosx(10.14));
|
||||
|
@ -14,6 +16,27 @@
|
|||
- (void)setAppearance:(NSAppearance*)appearance API_AVAILABLE(macosx(10.14));
|
||||
@end
|
||||
|
||||
// forward declare Access APIs
|
||||
typedef NSString* AVMediaType NS_EXTENSIBLE_STRING_ENUM;
|
||||
|
||||
AVF_EXPORT AVMediaType const AVMediaTypeVideo;
|
||||
AVF_EXPORT AVMediaType const AVMediaTypeAudio;
|
||||
|
||||
typedef NS_ENUM(NSInteger, AVAuthorizationStatusMac) {
|
||||
AVAuthorizationStatusNotDeterminedMac = 0,
|
||||
AVAuthorizationStatusRestrictedMac = 1,
|
||||
AVAuthorizationStatusDeniedMac = 2,
|
||||
AVAuthorizationStatusAuthorizedMac = 3,
|
||||
};
|
||||
|
||||
@interface AVCaptureDevice (MojaveSDK)
|
||||
+ (void)requestAccessForMediaType:(AVMediaType)mediaType
|
||||
completionHandler:(void (^)(BOOL granted))handler
|
||||
API_AVAILABLE(macosx(10.14));
|
||||
+ (AVAuthorizationStatusMac)authorizationStatusForMediaType:
|
||||
(AVMediaType)mediaType API_AVAILABLE(macosx(10.14));
|
||||
@end
|
||||
|
||||
extern "C" {
|
||||
#if !defined(MAC_OS_X_VERSION_10_14) || \
|
||||
MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_14
|
||||
|
|
|
@ -311,7 +311,6 @@ using `electron-packager` or `electron-forge` just set the `enableDarwinDarkMode
|
|||
packager option to `true`. See the [Electron Packager API](https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#darwindarkmodesupport)
|
||||
for more details.
|
||||
|
||||
|
||||
### `systemPreferences.getAppLevelAppearance()` _macOS_
|
||||
|
||||
Returns `String` | `null` - Can be `dark`, `light` or `unknown`.
|
||||
|
@ -326,3 +325,21 @@ You can use the `setAppLevelAppearance` API to set this value.
|
|||
|
||||
Sets the appearance setting for your application, this should override the
|
||||
system default and override the value of `getEffectiveAppearance`.
|
||||
|
||||
### `systemPreferences.getMediaAccessStatus(mediaType)` _macOS_
|
||||
|
||||
* `mediaType` String - `microphone` or `camera`.
|
||||
|
||||
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.
|
||||
|
||||
### `systemPreferences.askForMediaAccess(mediaType)` _macOS_
|
||||
|
||||
* `mediaType` String - the type of media being requested; can be `microphone`, `camera`.
|
||||
|
||||
Returns `Promise<Boolean>` - A promise that resolves with `true` if consent was granted and `false` if it was denied. If an invalid `mediaType` is passed, the promise will be rejected. If an access request was denied and later is changed through the System Preferences pane, a restart of the app will be required for the new permissions to take effect. If access has already been requested and denied, it _must_ be changed through the preference pane; an alert will not pop up and the promise will resolve with the existing access status.
|
||||
|
||||
**Important:** In order to properly leverage this API, you [must set](https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/requesting_authorization_for_media_capture_on_macos?language=objc) the `NSMicrophoneUsageDescription` and `NSCameraUsageDescription` strings in your app's `Info.plist` file. The values for these keys will be used to populate the permission dialogs so that the user will be properly informed as to the purpose of the permission request. See [Electron Application Distribution](https://electronjs.org/docs/tutorial/application-distribution#macos) for more information about how to set these in the context of Electron.
|
||||
|
||||
This user consent was not required until macOS 10.14 Mojave, so this method will always return `true` if your system is running 10.13 High Sierra or lower.
|
Загрузка…
Ссылка в новой задаче