feat: add support for Web Bluetooth pin pairing (#35416)
* feat: add bluetooth pairing handler * Update docs/api/session.md Co-authored-by: Charles Kerr <charles@charleskerr.com> * Update docs/api/session.md Co-authored-by: Charles Kerr <charles@charleskerr.com> * docs: update based on review * Apply suggestions from code review Co-authored-by: Erick Zhao <erick@hotmail.ca> Co-authored-by: Charles Kerr <charles@charleskerr.com> * chore: update docs per review * chore: cleanup callback per review Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: Erick Zhao <erick@hotmail.ca>
This commit is contained in:
parent
f8077cc004
commit
697a219bcb
11 changed files with 234 additions and 6 deletions
|
@ -823,6 +823,71 @@ app.whenReady().then(() => {
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `ses.setBluetoothPairingHandler(handler)` _Windows_ _Linux_
|
||||||
|
|
||||||
|
* `handler` Function | null
|
||||||
|
* `details` Object
|
||||||
|
* `deviceId` string
|
||||||
|
* `pairingKind` string - The type of pairing prompt being requested.
|
||||||
|
One of the following values:
|
||||||
|
* `confirm`
|
||||||
|
This prompt is requesting confirmation that the Bluetooth device should
|
||||||
|
be paired.
|
||||||
|
* `confirmPin`
|
||||||
|
This prompt is requesting confirmation that the provided PIN matches the
|
||||||
|
pin displayed on the device.
|
||||||
|
* `providePin`
|
||||||
|
This prompt is requesting that a pin be provided for the device.
|
||||||
|
* `frame` [WebFrameMain](web-frame-main.md)
|
||||||
|
* `pin` string (optional) - The pin value to verify if `pairingKind` is `confirmPin`.
|
||||||
|
* `callback` Function
|
||||||
|
* `response` Object
|
||||||
|
* `confirmed` boolean - `false` should be passed in if the dialog is canceled.
|
||||||
|
If the `pairingKind` is `confirm` or `confirmPin`, this value should indicate
|
||||||
|
if the pairing is confirmed. If the `pairingKind` is `providePin` the value
|
||||||
|
should be `true` when a value is provided.
|
||||||
|
* `pin` string | null (optional) - When the `pairingKind` is `providePin`
|
||||||
|
this value should be the required pin for the Bluetooth device.
|
||||||
|
|
||||||
|
Sets a handler to respond to Bluetooth pairing requests. This handler
|
||||||
|
allows developers to handle devices that require additional validation
|
||||||
|
before pairing. When a handler is not defined, any pairing on Linux or Windows
|
||||||
|
that requires additional validation will be automatically cancelled.
|
||||||
|
macOS does not require a handler because macOS handles the pairing
|
||||||
|
automatically. To clear the handler, call `setBluetoothPairingHandler(null)`.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
|
||||||
|
const { app, BrowserWindow, ipcMain, session } = require('electron')
|
||||||
|
|
||||||
|
let bluetoothPinCallback = null
|
||||||
|
|
||||||
|
function createWindow () {
|
||||||
|
const mainWindow = new BrowserWindow({
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, 'preload.js')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen for an IPC message from the renderer to get the response for the Bluetooth pairing.
|
||||||
|
ipcMain.on('bluetooth-pairing-response', (event, response) => {
|
||||||
|
bluetoothPinCallback(response)
|
||||||
|
})
|
||||||
|
|
||||||
|
mainWindow.webContents.session.setBluetoothPairingHandler((details, callback) => {
|
||||||
|
bluetoothPinCallback = callback
|
||||||
|
// Send a IPC message to the renderer to prompt the user to confirm the pairing.
|
||||||
|
// Note that this will require logic in the renderer to handle this message and
|
||||||
|
// display a prompt to the user.
|
||||||
|
mainWindow.webContents.send('bluetooth-pairing-request', details)
|
||||||
|
})
|
||||||
|
|
||||||
|
app.whenReady().then(() => {
|
||||||
|
createWindow()
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
#### `ses.clearHostResolverCache()`
|
#### `ses.clearHostResolverCache()`
|
||||||
|
|
||||||
Returns `Promise<void>` - Resolves when the operation is complete.
|
Returns `Promise<void>` - Resolves when the operation is complete.
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
const {app, BrowserWindow} = require('electron')
|
const {app, BrowserWindow, ipcMain} = require('electron')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
function createWindow () {
|
function createWindow () {
|
||||||
const mainWindow = new BrowserWindow({
|
const mainWindow = new BrowserWindow({
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600
|
height: 600,
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, 'preload.js')
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
mainWindow.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
|
mainWindow.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
|
||||||
|
@ -14,6 +17,18 @@ function createWindow () {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Listen for a message from the renderer to get the response for the Bluetooth pairing.
|
||||||
|
ipcMain.on('bluetooth-pairing-response', (event, response) => {
|
||||||
|
bluetoothPinCallback(response)
|
||||||
|
})
|
||||||
|
|
||||||
|
mainWindow.webContents.session.setBluetoothPairingHandler((details, callback) => {
|
||||||
|
|
||||||
|
bluetoothPinCallback = callback
|
||||||
|
// Send a message to the renderer to prompt the user to confirm the pairing.
|
||||||
|
mainWindow.webContents.send('bluetooth-pairing-request', details)
|
||||||
|
})
|
||||||
|
|
||||||
mainWindow.loadFile('index.html')
|
mainWindow.loadFile('index.html')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
docs/fiddles/features/web-bluetooth/preload.js
Normal file
6
docs/fiddles/features/web-bluetooth/preload.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
const { contextBridge, ipcRenderer } = require('electron')
|
||||||
|
|
||||||
|
contextBridge.exposeInMainWorld('electronAPI', {
|
||||||
|
bluetoothPairingRequest: (callback) => ipcRenderer.on('bluetooth-pairing-request', callback),
|
||||||
|
bluetoothPairingResponse: (response) => ipcRenderer.send('bluetooth-pairing-respnse', response)
|
||||||
|
})
|
|
@ -5,4 +5,30 @@ async function testIt() {
|
||||||
document.getElementById('device-name').innerHTML = device.name || `ID: ${device.id}`
|
document.getElementById('device-name').innerHTML = device.name || `ID: ${device.id}`
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('clickme').addEventListener('click',testIt)
|
document.getElementById('clickme').addEventListener('click',testIt)
|
||||||
|
|
||||||
|
window.electronAPI.bluetoothPairingRequest((event, details) => {
|
||||||
|
const response = {}
|
||||||
|
|
||||||
|
switch (details.pairingKind) {
|
||||||
|
case 'confirm': {
|
||||||
|
response.confirmed = confirm(`Do you want to connect to device ${details.deviceId}?`)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'confirmPin': {
|
||||||
|
response.confirmed = confirm(`Does the pin ${details.pin} match the pin displayed on device ${details.deviceId}?`)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'providePin': {
|
||||||
|
const pin = prompt(`Please provide a pin for ${details.deviceId}.`)
|
||||||
|
if (pin) {
|
||||||
|
response.pin = pin
|
||||||
|
response.confirmed = true
|
||||||
|
} else {
|
||||||
|
response.confirmed = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.electronAPI.bluetoothPairingResponse(response)
|
||||||
|
})
|
|
@ -16,6 +16,10 @@ with bluetooth devices. In order to use this API in Electron, developers will
|
||||||
need to handle the [`select-bluetooth-device` event on the webContents](../api/web-contents.md#event-select-bluetooth-device)
|
need to handle the [`select-bluetooth-device` event on the webContents](../api/web-contents.md#event-select-bluetooth-device)
|
||||||
associated with the device request.
|
associated with the device request.
|
||||||
|
|
||||||
|
Additionally, [`ses.setBluetoothPairingHandler(handler)`](../api/session.md#sessetbluetoothpairinghandlerhandler-windows-linux)
|
||||||
|
can be used to handle pairing to bluetooth devices on Windows or Linux when
|
||||||
|
additional validation such as a pin is needed.
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
This example demonstrates an Electron application that automatically selects
|
This example demonstrates an Electron application that automatically selects
|
||||||
|
|
|
@ -674,6 +674,18 @@ void Session::SetDevicePermissionHandler(v8::Local<v8::Value> val,
|
||||||
permission_manager->SetDevicePermissionHandler(handler);
|
permission_manager->SetDevicePermissionHandler(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Session::SetBluetoothPairingHandler(v8::Local<v8::Value> val,
|
||||||
|
gin::Arguments* args) {
|
||||||
|
ElectronPermissionManager::BluetoothPairingHandler handler;
|
||||||
|
if (!(val->IsNull() || gin::ConvertFromV8(args->isolate(), val, &handler))) {
|
||||||
|
args->ThrowTypeError("Must pass null or function");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto* permission_manager = static_cast<ElectronPermissionManager*>(
|
||||||
|
browser_context()->GetPermissionControllerDelegate());
|
||||||
|
permission_manager->SetBluetoothPairingHandler(handler);
|
||||||
|
}
|
||||||
|
|
||||||
v8::Local<v8::Promise> Session::ClearHostResolverCache(gin::Arguments* args) {
|
v8::Local<v8::Promise> Session::ClearHostResolverCache(gin::Arguments* args) {
|
||||||
v8::Isolate* isolate = args->isolate();
|
v8::Isolate* isolate = args->isolate();
|
||||||
gin_helper::Promise<void> promise(isolate);
|
gin_helper::Promise<void> promise(isolate);
|
||||||
|
@ -1225,6 +1237,8 @@ gin::ObjectTemplateBuilder Session::GetObjectTemplateBuilder(
|
||||||
&Session::SetDisplayMediaRequestHandler)
|
&Session::SetDisplayMediaRequestHandler)
|
||||||
.SetMethod("setDevicePermissionHandler",
|
.SetMethod("setDevicePermissionHandler",
|
||||||
&Session::SetDevicePermissionHandler)
|
&Session::SetDevicePermissionHandler)
|
||||||
|
.SetMethod("setBluetoothPairingHandler",
|
||||||
|
&Session::SetBluetoothPairingHandler)
|
||||||
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
|
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
|
||||||
.SetMethod("clearAuthCache", &Session::ClearAuthCache)
|
.SetMethod("clearAuthCache", &Session::ClearAuthCache)
|
||||||
.SetMethod("allowNTLMCredentialsForDomains",
|
.SetMethod("allowNTLMCredentialsForDomains",
|
||||||
|
|
|
@ -105,6 +105,8 @@ class Session : public gin::Wrappable<Session>,
|
||||||
gin::Arguments* args);
|
gin::Arguments* args);
|
||||||
void SetDevicePermissionHandler(v8::Local<v8::Value> val,
|
void SetDevicePermissionHandler(v8::Local<v8::Value> val,
|
||||||
gin::Arguments* args);
|
gin::Arguments* args);
|
||||||
|
void SetBluetoothPairingHandler(v8::Local<v8::Value> val,
|
||||||
|
gin::Arguments* args);
|
||||||
v8::Local<v8::Promise> ClearHostResolverCache(gin::Arguments* args);
|
v8::Local<v8::Promise> ClearHostResolverCache(gin::Arguments* args);
|
||||||
v8::Local<v8::Promise> ClearAuthCache();
|
v8::Local<v8::Promise> ClearAuthCache();
|
||||||
void AllowNTLMCredentialsForDomains(const std::string& domains);
|
void AllowNTLMCredentialsForDomains(const std::string& domains);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "base/strings/string_util.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "build/build_config.h"
|
#include "build/build_config.h"
|
||||||
#include "content/public/browser/render_frame_host.h"
|
#include "content/public/browser/render_frame_host.h"
|
||||||
|
@ -14,7 +15,10 @@
|
||||||
#include "device/bluetooth/bluetooth_device.h"
|
#include "device/bluetooth/bluetooth_device.h"
|
||||||
#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
|
#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
|
||||||
#include "shell/browser/api/electron_api_web_contents.h"
|
#include "shell/browser/api/electron_api_web_contents.h"
|
||||||
|
#include "shell/browser/electron_permission_manager.h"
|
||||||
#include "shell/browser/lib/bluetooth_chooser.h"
|
#include "shell/browser/lib/bluetooth_chooser.h"
|
||||||
|
#include "shell/common/gin_converters/frame_converter.h"
|
||||||
|
#include "shell/common/gin_helper/dictionary.h"
|
||||||
#include "third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h"
|
#include "third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h"
|
||||||
#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom.h"
|
#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom.h"
|
||||||
|
|
||||||
|
@ -23,6 +27,28 @@ using content::RenderFrameHost;
|
||||||
using content::WebContents;
|
using content::WebContents;
|
||||||
using device::BluetoothUUID;
|
using device::BluetoothUUID;
|
||||||
|
|
||||||
|
namespace gin {
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<content::BluetoothDelegate::PairingKind> {
|
||||||
|
static v8::Local<v8::Value> ToV8(
|
||||||
|
v8::Isolate* isolate,
|
||||||
|
content::BluetoothDelegate::PairingKind pairing_kind) {
|
||||||
|
switch (pairing_kind) {
|
||||||
|
case content::BluetoothDelegate::PairingKind::kConfirmOnly:
|
||||||
|
return StringToV8(isolate, "confirm");
|
||||||
|
case content::BluetoothDelegate::PairingKind::kConfirmPinMatch:
|
||||||
|
return StringToV8(isolate, "confirmPin");
|
||||||
|
case content::BluetoothDelegate::PairingKind::kProvidePin:
|
||||||
|
return StringToV8(isolate, "providePin");
|
||||||
|
default:
|
||||||
|
return StringToV8(isolate, "unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gin
|
||||||
|
|
||||||
namespace electron {
|
namespace electron {
|
||||||
|
|
||||||
ElectronBluetoothDelegate::ElectronBluetoothDelegate() = default;
|
ElectronBluetoothDelegate::ElectronBluetoothDelegate() = default;
|
||||||
|
@ -136,9 +162,46 @@ void ElectronBluetoothDelegate::ShowDevicePairPrompt(
|
||||||
PairPromptCallback callback,
|
PairPromptCallback callback,
|
||||||
PairingKind pairing_kind,
|
PairingKind pairing_kind,
|
||||||
const absl::optional<std::u16string>& pin) {
|
const absl::optional<std::u16string>& pin) {
|
||||||
NOTIMPLEMENTED();
|
auto* web_contents = content::WebContents::FromRenderFrameHost(frame);
|
||||||
std::move(callback).Run(BluetoothDelegate::PairPromptResult(
|
if (web_contents) {
|
||||||
BluetoothDelegate::PairPromptStatus::kCancelled));
|
auto* permission_manager = static_cast<ElectronPermissionManager*>(
|
||||||
|
web_contents->GetBrowserContext()->GetPermissionControllerDelegate());
|
||||||
|
|
||||||
|
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||||
|
v8::HandleScope scope(isolate);
|
||||||
|
gin_helper::Dictionary details =
|
||||||
|
gin_helper::Dictionary::CreateEmpty(isolate);
|
||||||
|
details.Set("deviceId", device_identifier);
|
||||||
|
details.Set("pairingKind", pairing_kind);
|
||||||
|
details.SetGetter("frame", frame);
|
||||||
|
if (pin.has_value()) {
|
||||||
|
details.Set("pin", pin.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
permission_manager->CheckBluetoothDevicePair(
|
||||||
|
details, base::AdaptCallbackForRepeating(base::BindOnce(
|
||||||
|
&ElectronBluetoothDelegate::OnDevicePairPromptResponse,
|
||||||
|
weak_factory_.GetWeakPtr(), std::move(callback))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElectronBluetoothDelegate::OnDevicePairPromptResponse(
|
||||||
|
PairPromptCallback callback,
|
||||||
|
base::Value::Dict response) {
|
||||||
|
BluetoothDelegate::PairPromptResult result;
|
||||||
|
if (response.FindBool("confirmed").value_or(false)) {
|
||||||
|
result.result_code = BluetoothDelegate::PairPromptStatus::kSuccess;
|
||||||
|
} else {
|
||||||
|
result.result_code = BluetoothDelegate::PairPromptStatus::kCancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string* pin = response.FindString("pin");
|
||||||
|
if (pin) {
|
||||||
|
std::u16string trimmed_input = base::UTF8ToUTF16(*pin);
|
||||||
|
base::TrimWhitespace(trimmed_input, base::TRIM_ALL, &trimmed_input);
|
||||||
|
result.pin = base::UTF16ToUTF8(trimmed_input);
|
||||||
|
}
|
||||||
|
std::move(callback).Run(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "base/memory/weak_ptr.h"
|
||||||
#include "base/observer_list.h"
|
#include "base/observer_list.h"
|
||||||
#include "base/scoped_observation.h"
|
#include "base/scoped_observation.h"
|
||||||
#include "content/public/browser/bluetooth_delegate.h"
|
#include "content/public/browser/bluetooth_delegate.h"
|
||||||
|
@ -91,6 +92,12 @@ class ElectronBluetoothDelegate : public content::BluetoothDelegate {
|
||||||
void AddFramePermissionObserver(FramePermissionObserver* observer) override;
|
void AddFramePermissionObserver(FramePermissionObserver* observer) override;
|
||||||
void RemoveFramePermissionObserver(
|
void RemoveFramePermissionObserver(
|
||||||
FramePermissionObserver* observer) override;
|
FramePermissionObserver* observer) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OnDevicePairPromptResponse(PairPromptCallback callback,
|
||||||
|
base::Value::Dict response);
|
||||||
|
|
||||||
|
base::WeakPtrFactory<ElectronBluetoothDelegate> weak_factory_{this};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
|
@ -130,6 +130,11 @@ void ElectronPermissionManager::SetDevicePermissionHandler(
|
||||||
device_permission_handler_ = handler;
|
device_permission_handler_ = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ElectronPermissionManager::SetBluetoothPairingHandler(
|
||||||
|
const BluetoothPairingHandler& handler) {
|
||||||
|
bluetooth_pairing_handler_ = handler;
|
||||||
|
}
|
||||||
|
|
||||||
void ElectronPermissionManager::RequestPermission(
|
void ElectronPermissionManager::RequestPermission(
|
||||||
blink::PermissionType permission,
|
blink::PermissionType permission,
|
||||||
content::RenderFrameHost* render_frame_host,
|
content::RenderFrameHost* render_frame_host,
|
||||||
|
@ -276,6 +281,18 @@ ElectronPermissionManager::SubscribePermissionStatusChange(
|
||||||
void ElectronPermissionManager::UnsubscribePermissionStatusChange(
|
void ElectronPermissionManager::UnsubscribePermissionStatusChange(
|
||||||
SubscriptionId id) {}
|
SubscriptionId id) {}
|
||||||
|
|
||||||
|
void ElectronPermissionManager::CheckBluetoothDevicePair(
|
||||||
|
gin_helper::Dictionary details,
|
||||||
|
PairCallback pair_callback) const {
|
||||||
|
if (bluetooth_pairing_handler_.is_null()) {
|
||||||
|
base::Value::Dict response;
|
||||||
|
response.Set("confirmed", false);
|
||||||
|
std::move(pair_callback).Run(std::move(response));
|
||||||
|
} else {
|
||||||
|
bluetooth_pairing_handler_.Run(details, std::move(pair_callback));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ElectronPermissionManager::CheckPermissionWithDetails(
|
bool ElectronPermissionManager::CheckPermissionWithDetails(
|
||||||
blink::PermissionType permission,
|
blink::PermissionType permission,
|
||||||
content::RenderFrameHost* render_frame_host,
|
content::RenderFrameHost* render_frame_host,
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "content/public/browser/permission_controller_delegate.h"
|
#include "content/public/browser/permission_controller_delegate.h"
|
||||||
#include "gin/dictionary.h"
|
#include "gin/dictionary.h"
|
||||||
#include "shell/browser/electron_browser_context.h"
|
#include "shell/browser/electron_browser_context.h"
|
||||||
|
#include "shell/common/gin_helper/dictionary.h"
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
class Value;
|
class Value;
|
||||||
|
@ -38,6 +39,7 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {
|
||||||
base::OnceCallback<void(blink::mojom::PermissionStatus)>;
|
base::OnceCallback<void(blink::mojom::PermissionStatus)>;
|
||||||
using StatusesCallback = base::OnceCallback<void(
|
using StatusesCallback = base::OnceCallback<void(
|
||||||
const std::vector<blink::mojom::PermissionStatus>&)>;
|
const std::vector<blink::mojom::PermissionStatus>&)>;
|
||||||
|
using PairCallback = base::OnceCallback<void(base::Value::Dict)>;
|
||||||
using RequestHandler = base::RepeatingCallback<void(content::WebContents*,
|
using RequestHandler = base::RepeatingCallback<void(content::WebContents*,
|
||||||
blink::PermissionType,
|
blink::PermissionType,
|
||||||
StatusCallback,
|
StatusCallback,
|
||||||
|
@ -50,11 +52,14 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {
|
||||||
|
|
||||||
using DeviceCheckHandler =
|
using DeviceCheckHandler =
|
||||||
base::RepeatingCallback<bool(const v8::Local<v8::Object>&)>;
|
base::RepeatingCallback<bool(const v8::Local<v8::Object>&)>;
|
||||||
|
using BluetoothPairingHandler =
|
||||||
|
base::RepeatingCallback<void(gin_helper::Dictionary, PairCallback)>;
|
||||||
|
|
||||||
// Handler to dispatch permission requests in JS.
|
// Handler to dispatch permission requests in JS.
|
||||||
void SetPermissionRequestHandler(const RequestHandler& handler);
|
void SetPermissionRequestHandler(const RequestHandler& handler);
|
||||||
void SetPermissionCheckHandler(const CheckHandler& handler);
|
void SetPermissionCheckHandler(const CheckHandler& handler);
|
||||||
void SetDevicePermissionHandler(const DeviceCheckHandler& handler);
|
void SetDevicePermissionHandler(const DeviceCheckHandler& handler);
|
||||||
|
void SetBluetoothPairingHandler(const BluetoothPairingHandler& handler);
|
||||||
|
|
||||||
// content::PermissionControllerDelegate:
|
// content::PermissionControllerDelegate:
|
||||||
void RequestPermission(blink::PermissionType permission,
|
void RequestPermission(blink::PermissionType permission,
|
||||||
|
@ -81,6 +86,9 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {
|
||||||
base::Value::Dict details,
|
base::Value::Dict details,
|
||||||
StatusesCallback callback);
|
StatusesCallback callback);
|
||||||
|
|
||||||
|
void CheckBluetoothDevicePair(gin_helper::Dictionary details,
|
||||||
|
PairCallback pair_callback) const;
|
||||||
|
|
||||||
bool CheckPermissionWithDetails(blink::PermissionType permission,
|
bool CheckPermissionWithDetails(blink::PermissionType permission,
|
||||||
content::RenderFrameHost* render_frame_host,
|
content::RenderFrameHost* render_frame_host,
|
||||||
const GURL& requesting_origin,
|
const GURL& requesting_origin,
|
||||||
|
@ -147,6 +155,7 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {
|
||||||
RequestHandler request_handler_;
|
RequestHandler request_handler_;
|
||||||
CheckHandler check_handler_;
|
CheckHandler check_handler_;
|
||||||
DeviceCheckHandler device_permission_handler_;
|
DeviceCheckHandler device_permission_handler_;
|
||||||
|
BluetoothPairingHandler bluetooth_pairing_handler_;
|
||||||
|
|
||||||
PendingRequestsMap pending_requests_;
|
PendingRequestsMap pending_requests_;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue