diff --git a/docs/api/session.md b/docs/api/session.md index f61b412693629..b0cf756eeb877 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -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: @@ -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` - Resolves when the operation is complete. diff --git a/shell/browser/api/electron_api_session.cc b/shell/browser/api/electron_api_session.cc index 499d40259783b..1615cc2d828cd 100644 --- a/shell/browser/api/electron_api_session.cc +++ b/shell/browser/api/electron_api_session.cc @@ -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", diff --git a/shell/browser/electron_permission_manager.cc b/shell/browser/electron_permission_manager.cc index f1e50aebc70e2..a5e059ead9485 100644 --- a/shell/browser/electron_permission_manager.cc +++ b/shell/browser/electron_permission_manager.cc @@ -8,6 +8,7 @@ #include #include +#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" @@ -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, diff --git a/shell/browser/electron_permission_manager.h b/shell/browser/electron_permission_manager.h index 1d9d49e5eab50..9191855fb8b87 100644 --- a/shell/browser/electron_permission_manager.h +++ b/shell/browser/electron_permission_manager.h @@ -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; @@ -38,6 +39,7 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate { base::OnceCallback; using StatusesCallback = base::OnceCallback&)>; + using PairCallback = base::OnceCallback; using RequestHandler = base::RepeatingCallback&)>; - using BluetoothPairingHandler = base::RepeatingCallback( - const v8::Local&)>; + using BluetoothPairingHandler = + base::RepeatingCallback; // Handler to dispatch permission requests in JS. void SetPermissionRequestHandler(const RequestHandler& handler); @@ -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,