Skip to content

Commit

Permalink
feat: implement systemPreferences.getMediaAccessStatus() on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
miniak committed Jun 24, 2020
1 parent acb64a2 commit d058966
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 6 deletions.
2 changes: 1 addition & 1 deletion docs/api/system-preferences.md
Expand Up @@ -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`.

Expand Down
4 changes: 2 additions & 2 deletions shell/browser/api/electron_api_system_preferences.cc
Expand Up @@ -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)
Expand Down Expand Up @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions shell/browser/api/electron_api_system_preferences.h
Expand Up @@ -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();
Expand Down Expand Up @@ -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);

Expand Down
67 changes: 67 additions & 0 deletions shell/browser/api/electron_api_system_preferences_win.cc
Expand Up @@ -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"
Expand All @@ -20,6 +23,52 @@ 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) {
auto status = DeviceAccessStatus::DeviceAccessStatus_Unspecified;

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 status;
}

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 status;
}

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 {
Expand Down Expand Up @@ -117,6 +166,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();
Expand Down
2 changes: 1 addition & 1 deletion spec-main/api-system-preferences-spec.ts
Expand Up @@ -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', () => {
Expand Down

0 comments on commit d058966

Please sign in to comment.