Skip to content

Commit

Permalink
chore: add CheckBluetoothDevicePair
Browse files Browse the repository at this point in the history
  • Loading branch information
John Kleinschmidt committed Sep 19, 2022
1 parent 289d50c commit 61e9427
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 55 deletions.
115 changes: 62 additions & 53 deletions docs/api/session.md
Expand Up @@ -69,59 +69,6 @@ console.log(ses.getUserAgent())

The following events are available on instances of `Session`:

#### Event: 'bluetooth-pair-prompt' _Windows_ _Linux_

Returns:

* `event` Event
* `details` Object
* `deviceId` string
* `pairingKind` string - The type of pairing prompt being requested.
Value will be one of `confirm`, `confirmPin`, or `providePin`.
* `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 - If the `pairingKind` is `confirmPin`, this value will be
the pin value to verify.
* `callback` Function
* `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.

Emitted when a bluetooth device requires a response to pairing. This event
allows developers to handle devices that require additional validation for
pairing. When handling this event, `event.preventDefault()` should be called
to prevent the default behavior of cancelling this prompt.

```javascript
const { session } = require('electron')
session.defaultSession.on('bluetooth-pair-prompt', (event, details, callback) => {
event.preventDefault()
switch (details.pairingKind) {
case 'confirm': {
callback(confirm(`Do you want to connect to device ${details.deviceId}`))
break
}
case 'confirmPin': {
callback(confirm(`Does the pin ${details.pin} match the pin displayed on device ${details.deviceId}?`))
break
}
case 'providePin': {
callback(true, prompt(`Please provide a pin for ${details.deviceId}`))
}
}
})
```

#### Event: 'will-download'

Returns:
Expand Down Expand Up @@ -876,6 +823,68 @@ 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 - If the `pairingKind` is `confirmPin`, this value will be
the pin value to verify.
* `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 the handler which can be used to respond when a bluetooth device requires
a response to pairing. This handler allows developers to handle devices that
require additional validation for pairing.
To clear the handler, call `setBluetoothPairingHandler(null)`.
```javascript

const { session } = require('electron')

session.defaultSession.setBluetoothPairingHandler((details, callback) => {
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
}
}
}
callback(response)
})
```
#### `ses.clearHostResolverCache()`
Returns `Promise<void>` - Resolves when the operation is complete.
Expand Down
2 changes: 2 additions & 0 deletions shell/browser/api/electron_api_session.cc
Expand Up @@ -1233,6 +1233,8 @@ gin::ObjectTemplateBuilder Session::GetObjectTemplateBuilder(
&Session::SetDisplayMediaRequestHandler)
.SetMethod("setDevicePermissionHandler",
&Session::SetDevicePermissionHandler)
.SetMethod("setBluetoothPairingHandler",
&Session::SetBluetoothPairingHandler)
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
.SetMethod("clearAuthCache", &Session::ClearAuthCache)
.SetMethod("allowNTLMCredentialsForDomains",
Expand Down
13 changes: 13 additions & 0 deletions shell/browser/electron_permission_manager.cc
Expand Up @@ -8,6 +8,7 @@
#include <utility>
#include <vector>

#include "base/strings/string_util.h"
#include "base/values.h"
#include "content/browser/permissions/permission_util.h" // nogncheck
#include "content/public/browser/child_process_security_policy.h"
Expand Down Expand Up @@ -271,6 +272,18 @@ ElectronPermissionManager::SubscribePermissionStatusChange(
void ElectronPermissionManager::UnsubscribePermissionStatusChange(
SubscriptionId id) {}

void ElectronPermissionManager::CheckBluetoothDevicePair(
base::Value::Dict 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.Clone(), std::move(pair_callback));
}
}

bool ElectronPermissionManager::CheckPermissionWithDetails(
blink::PermissionType permission,
content::RenderFrameHost* render_frame_host,
Expand Down
9 changes: 7 additions & 2 deletions shell/browser/electron_permission_manager.h
Expand Up @@ -13,6 +13,7 @@
#include "content/public/browser/permission_controller_delegate.h"
#include "gin/dictionary.h"
#include "shell/browser/electron_browser_context.h"
#include "shell/common/gin_helper/dictionary.h"

namespace base {
class Value;
Expand All @@ -38,6 +39,7 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {
base::OnceCallback<void(blink::mojom::PermissionStatus)>;
using StatusesCallback = base::OnceCallback<void(
const std::vector<blink::mojom::PermissionStatus>&)>;
using PairCallback = base::OnceCallback<void(base::Value::Dict)>;
using RequestHandler = base::RepeatingCallback<void(content::WebContents*,
blink::PermissionType,
StatusCallback,
Expand All @@ -50,8 +52,8 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {

using DeviceCheckHandler =
base::RepeatingCallback<bool(const v8::Local<v8::Object>&)>;
using BluetoothPairingHandler = base::RepeatingCallback<v8::Local<v8::Object>(
const v8::Local<v8::Object>&)>;
using BluetoothPairingHandler =
base::RepeatingCallback<void(base::Value::Dict, PairCallback)>;

// Handler to dispatch permission requests in JS.
void SetPermissionRequestHandler(const RequestHandler& handler);
Expand Down Expand Up @@ -87,6 +89,9 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {
blink::PermissionType permission,
content::RenderFrameHost* render_frame_host) override;

void CheckBluetoothDevicePair(base::Value::Dict details,
PairCallback pair_callback) const;

bool CheckPermissionWithDetails(blink::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
Expand Down

0 comments on commit 61e9427

Please sign in to comment.