feat: implement systemPreferences.getMediaAccessStatus() on Windows (#24275)
This commit is contained in:
parent
5b80556da2
commit
9b4572de44
5 changed files with 75 additions and 6 deletions
|
@ -416,7 +416,7 @@ This API itself will not protect your user data; rather, it is a mechanism to al
|
|||
|
||||
Returns `Boolean` - `true` if the current process is a trusted accessibility client and `false` if it is not.
|
||||
|
||||
### `systemPreferences.getMediaAccessStatus(mediaType)` _macOS_
|
||||
### `systemPreferences.getMediaAccessStatus(mediaType)` _Windows_ _macOS_
|
||||
|
||||
* `mediaType` String - Can be `microphone`, `camera` or `screen`.
|
||||
|
||||
|
@ -426,6 +426,9 @@ This user consent was not required on macOS 10.13 High Sierra or lower so this m
|
|||
macOS 10.14 Mojave or higher requires consent for `microphone` and `camera` access.
|
||||
macOS 10.15 Catalina or higher requires consent for `screen` access.
|
||||
|
||||
Windows 10 has a global setting controlling `microphone` and `camera` access for all win32 applications.
|
||||
It will always return `granted` for `screen` and for all media types on older versions of Windows.
|
||||
|
||||
### `systemPreferences.askForMediaAccess(mediaType)` _macOS_
|
||||
|
||||
* `mediaType` String - the type of media being requested; can be `microphone`, `camera`.
|
||||
|
|
|
@ -73,6 +73,8 @@ void SystemPreferences::BuildPrototype(
|
|||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
.SetMethod("getColor", &SystemPreferences::GetColor)
|
||||
.SetMethod("getAccentColor", &SystemPreferences::GetAccentColor)
|
||||
.SetMethod("getMediaAccessStatus",
|
||||
&SystemPreferences::GetMediaAccessStatus)
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
@ -112,8 +114,6 @@ void SystemPreferences::BuildPrototype(
|
|||
.SetMethod("promptTouchID", &SystemPreferences::PromptTouchID)
|
||||
.SetMethod("isTrustedAccessibilityClient",
|
||||
&SystemPreferences::IsTrustedAccessibilityClient)
|
||||
.SetMethod("getMediaAccessStatus",
|
||||
&SystemPreferences::GetMediaAccessStatus)
|
||||
.SetMethod("askForMediaAccess", &SystemPreferences::AskForMediaAccess)
|
||||
#endif
|
||||
.SetMethod("isInvertedColorScheme",
|
||||
|
|
|
@ -49,6 +49,8 @@ class SystemPreferences : public gin_helper::EventEmitter<SystemPreferences>
|
|||
std::string GetAccentColor();
|
||||
std::string GetColor(gin_helper::ErrorThrower thrower,
|
||||
const std::string& color);
|
||||
std::string GetMediaAccessStatus(const std::string& media_type,
|
||||
gin_helper::Arguments* args);
|
||||
#endif
|
||||
#if defined(OS_WIN)
|
||||
bool IsAeroGlassEnabled();
|
||||
|
@ -99,8 +101,6 @@ class SystemPreferences : public gin_helper::EventEmitter<SystemPreferences>
|
|||
|
||||
static bool IsTrustedAccessibilityClient(bool prompt);
|
||||
|
||||
std::string GetMediaAccessStatus(const std::string& media_type,
|
||||
gin_helper::Arguments* args);
|
||||
v8::Local<v8::Promise> AskForMediaAccess(v8::Isolate* isolate,
|
||||
const std::string& media_type);
|
||||
|
||||
|
|
|
@ -3,10 +3,13 @@
|
|||
// found in the LICENSE file.
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <windows.devices.enumeration.h>
|
||||
#include <wrl/client.h>
|
||||
#include <iomanip>
|
||||
|
||||
#include "shell/browser/api/electron_api_system_preferences.h"
|
||||
|
||||
#include "base/win/core_winrt_util.h"
|
||||
#include "base/win/wrapped_window_proc.h"
|
||||
#include "shell/common/color_util.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
|
@ -20,6 +23,51 @@ namespace {
|
|||
const wchar_t kSystemPreferencesWindowClass[] =
|
||||
L"Electron_SystemPreferencesHostWindow";
|
||||
|
||||
using ABI::Windows::Devices::Enumeration::DeviceAccessStatus;
|
||||
using ABI::Windows::Devices::Enumeration::DeviceClass;
|
||||
using ABI::Windows::Devices::Enumeration::IDeviceAccessInformation;
|
||||
using ABI::Windows::Devices::Enumeration::IDeviceAccessInformationStatics;
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
DeviceAccessStatus GetDeviceAccessStatus(DeviceClass device_class) {
|
||||
ComPtr<IDeviceAccessInformationStatics> dev_access_info_statics;
|
||||
HRESULT hr = base::win::GetActivationFactory<
|
||||
IDeviceAccessInformationStatics,
|
||||
RuntimeClass_Windows_Devices_Enumeration_DeviceAccessInformation>(
|
||||
&dev_access_info_statics);
|
||||
if (FAILED(hr)) {
|
||||
VLOG(1) << "IDeviceAccessInformationStatics failed: " << hr;
|
||||
return DeviceAccessStatus::DeviceAccessStatus_Allowed;
|
||||
}
|
||||
|
||||
ComPtr<IDeviceAccessInformation> dev_access_info;
|
||||
hr = dev_access_info_statics->CreateFromDeviceClass(device_class,
|
||||
&dev_access_info);
|
||||
if (FAILED(hr)) {
|
||||
VLOG(1) << "IDeviceAccessInformation failed: " << hr;
|
||||
return DeviceAccessStatus::DeviceAccessStatus_Allowed;
|
||||
}
|
||||
|
||||
auto status = DeviceAccessStatus::DeviceAccessStatus_Unspecified;
|
||||
dev_access_info->get_CurrentStatus(&status);
|
||||
return status;
|
||||
}
|
||||
|
||||
std::string ConvertDeviceAccessStatus(DeviceAccessStatus value) {
|
||||
switch (value) {
|
||||
case DeviceAccessStatus::DeviceAccessStatus_Unspecified:
|
||||
return "not-determined";
|
||||
case DeviceAccessStatus::DeviceAccessStatus_Allowed:
|
||||
return "granted";
|
||||
case DeviceAccessStatus::DeviceAccessStatus_DeniedBySystem:
|
||||
return "restricted";
|
||||
case DeviceAccessStatus::DeviceAccessStatus_DeniedByUser:
|
||||
return "denied";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace api {
|
||||
|
@ -117,6 +165,24 @@ std::string SystemPreferences::GetColor(gin_helper::ErrorThrower thrower,
|
|||
return ToRGBHex(color_utils::GetSysSkColor(id));
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetMediaAccessStatus(
|
||||
const std::string& media_type,
|
||||
gin_helper::Arguments* args) {
|
||||
if (media_type == "camera") {
|
||||
return ConvertDeviceAccessStatus(
|
||||
GetDeviceAccessStatus(DeviceClass::DeviceClass_VideoCapture));
|
||||
} else if (media_type == "microphone") {
|
||||
return ConvertDeviceAccessStatus(
|
||||
GetDeviceAccessStatus(DeviceClass::DeviceClass_AudioCapture));
|
||||
} else if (media_type == "screen") {
|
||||
return ConvertDeviceAccessStatus(
|
||||
DeviceAccessStatus::DeviceAccessStatus_Allowed);
|
||||
} else {
|
||||
args->ThrowError("Invalid media type");
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
void SystemPreferences::InitializeWindow() {
|
||||
invertered_color_scheme_ = IsInvertedColorScheme();
|
||||
high_contrast_color_scheme_ = IsHighContrastColorScheme();
|
||||
|
|
|
@ -269,7 +269,7 @@ describe('systemPreferences module', () => {
|
|||
});
|
||||
});
|
||||
|
||||
ifdescribe(process.platform === 'darwin')('systemPreferences.getMediaAccessStatus(mediaType)', () => {
|
||||
ifdescribe(['win32', 'darwin'].includes(process.platform))('systemPreferences.getMediaAccessStatus(mediaType)', () => {
|
||||
const statuses = ['not-determined', 'granted', 'denied', 'restricted', 'unknown'];
|
||||
|
||||
it('returns an access status for a camera access request', () => {
|
||||
|
|
Loading…
Add table
Reference in a new issue