electron_bluetooth_delegate.cc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // Copyright (c) 2020 Microsoft, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/browser/bluetooth/electron_bluetooth_delegate.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "base/strings/string_util.h"
  8. #include "base/strings/utf_string_conversions.h"
  9. #include "content/public/browser/browser_context.h"
  10. #include "content/public/browser/render_frame_host.h"
  11. #include "content/public/browser/web_contents.h"
  12. #include "device/bluetooth/bluetooth_device.h"
  13. #include "device/bluetooth/public/cpp/bluetooth_uuid.h"
  14. #include "shell/browser/api/electron_api_web_contents.h"
  15. #include "shell/browser/electron_permission_manager.h"
  16. #include "shell/browser/lib/bluetooth_chooser.h"
  17. #include "shell/common/gin_converters/frame_converter.h"
  18. #include "shell/common/gin_helper/dictionary.h"
  19. #include "third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h"
  20. #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom.h"
  21. using blink::WebBluetoothDeviceId;
  22. using content::RenderFrameHost;
  23. using content::WebContents;
  24. using device::BluetoothUUID;
  25. namespace gin {
  26. template <>
  27. struct Converter<content::BluetoothDelegate::PairingKind> {
  28. static v8::Local<v8::Value> ToV8(
  29. v8::Isolate* isolate,
  30. content::BluetoothDelegate::PairingKind pairing_kind) {
  31. switch (pairing_kind) {
  32. case content::BluetoothDelegate::PairingKind::kConfirmOnly:
  33. return StringToV8(isolate, "confirm");
  34. case content::BluetoothDelegate::PairingKind::kConfirmPinMatch:
  35. return StringToV8(isolate, "confirmPin");
  36. case content::BluetoothDelegate::PairingKind::kProvidePin:
  37. return StringToV8(isolate, "providePin");
  38. default:
  39. return StringToV8(isolate, "unknown");
  40. }
  41. }
  42. };
  43. } // namespace gin
  44. namespace electron {
  45. ElectronBluetoothDelegate::ElectronBluetoothDelegate() = default;
  46. ElectronBluetoothDelegate::~ElectronBluetoothDelegate() = default;
  47. std::unique_ptr<content::BluetoothChooser>
  48. ElectronBluetoothDelegate::RunBluetoothChooser(
  49. content::RenderFrameHost* frame,
  50. const content::BluetoothChooser::EventHandler& event_handler) {
  51. auto* api_web_contents =
  52. api::WebContents::From(content::WebContents::FromRenderFrameHost(frame));
  53. return std::make_unique<BluetoothChooser>(api_web_contents, event_handler);
  54. }
  55. // The following methods are not currently called in Electron.
  56. std::unique_ptr<content::BluetoothScanningPrompt>
  57. ElectronBluetoothDelegate::ShowBluetoothScanningPrompt(
  58. content::RenderFrameHost* frame,
  59. const content::BluetoothScanningPrompt::EventHandler& event_handler) {
  60. NOTIMPLEMENTED();
  61. return nullptr;
  62. }
  63. WebBluetoothDeviceId ElectronBluetoothDelegate::GetWebBluetoothDeviceId(
  64. RenderFrameHost* frame,
  65. const std::string& device_address) {
  66. NOTIMPLEMENTED();
  67. return WebBluetoothDeviceId::Create();
  68. }
  69. std::string ElectronBluetoothDelegate::GetDeviceAddress(
  70. RenderFrameHost* frame,
  71. const WebBluetoothDeviceId& device_id) {
  72. NOTIMPLEMENTED();
  73. return "";
  74. }
  75. WebBluetoothDeviceId ElectronBluetoothDelegate::AddScannedDevice(
  76. RenderFrameHost* frame,
  77. const std::string& device_address) {
  78. NOTIMPLEMENTED();
  79. return WebBluetoothDeviceId::Create();
  80. }
  81. WebBluetoothDeviceId ElectronBluetoothDelegate::GrantServiceAccessPermission(
  82. RenderFrameHost* frame,
  83. const device::BluetoothDevice* device,
  84. const blink::mojom::WebBluetoothRequestDeviceOptions* options) {
  85. NOTIMPLEMENTED();
  86. return WebBluetoothDeviceId::Create();
  87. }
  88. bool ElectronBluetoothDelegate::HasDevicePermission(
  89. RenderFrameHost* frame,
  90. const WebBluetoothDeviceId& device_id) {
  91. NOTIMPLEMENTED();
  92. return true;
  93. }
  94. void ElectronBluetoothDelegate::RevokeDevicePermissionWebInitiated(
  95. RenderFrameHost* frame,
  96. const WebBluetoothDeviceId& device_id) {
  97. NOTIMPLEMENTED();
  98. }
  99. bool ElectronBluetoothDelegate::MayUseBluetooth(RenderFrameHost* frame) {
  100. return true;
  101. }
  102. bool ElectronBluetoothDelegate::IsAllowedToAccessService(
  103. RenderFrameHost* frame,
  104. const WebBluetoothDeviceId& device_id,
  105. const BluetoothUUID& service) {
  106. NOTIMPLEMENTED();
  107. return true;
  108. }
  109. bool ElectronBluetoothDelegate::IsAllowedToAccessAtLeastOneService(
  110. RenderFrameHost* frame,
  111. const WebBluetoothDeviceId& device_id) {
  112. NOTIMPLEMENTED();
  113. return true;
  114. }
  115. bool ElectronBluetoothDelegate::IsAllowedToAccessManufacturerData(
  116. RenderFrameHost* frame,
  117. const WebBluetoothDeviceId& device_id,
  118. uint16_t manufacturer_code) {
  119. NOTIMPLEMENTED();
  120. return true;
  121. }
  122. void ElectronBluetoothDelegate::AddFramePermissionObserver(
  123. FramePermissionObserver* observer) {
  124. NOTIMPLEMENTED();
  125. }
  126. void ElectronBluetoothDelegate::RemoveFramePermissionObserver(
  127. FramePermissionObserver* observer) {
  128. NOTIMPLEMENTED();
  129. }
  130. std::vector<blink::mojom::WebBluetoothDevicePtr>
  131. ElectronBluetoothDelegate::GetPermittedDevices(
  132. content::RenderFrameHost* frame) {
  133. std::vector<blink::mojom::WebBluetoothDevicePtr> permitted_devices;
  134. NOTIMPLEMENTED();
  135. return permitted_devices;
  136. }
  137. void ElectronBluetoothDelegate::ShowDevicePairPrompt(
  138. content::RenderFrameHost* frame,
  139. const std::u16string& device_identifier,
  140. PairPromptCallback callback,
  141. PairingKind pairing_kind,
  142. const std::optional<std::u16string>& pin) {
  143. auto* web_contents = content::WebContents::FromRenderFrameHost(frame);
  144. if (web_contents) {
  145. auto* permission_manager = static_cast<ElectronPermissionManager*>(
  146. web_contents->GetBrowserContext()->GetPermissionControllerDelegate());
  147. v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
  148. v8::HandleScope scope(isolate);
  149. auto details = gin_helper::Dictionary::CreateEmpty(isolate);
  150. details.Set("deviceId", device_identifier);
  151. details.Set("pairingKind", pairing_kind);
  152. details.SetGetter("frame", frame);
  153. if (pin.has_value()) {
  154. details.Set("pin", pin.value());
  155. }
  156. permission_manager->CheckBluetoothDevicePair(
  157. details,
  158. base::BindOnce(&ElectronBluetoothDelegate::OnDevicePairPromptResponse,
  159. weak_factory_.GetWeakPtr(), std::move(callback)));
  160. }
  161. }
  162. void ElectronBluetoothDelegate::OnDevicePairPromptResponse(
  163. PairPromptCallback callback,
  164. base::Value::Dict response) {
  165. BluetoothDelegate::PairPromptResult result;
  166. if (response.FindBool("confirmed").value_or(false)) {
  167. result.result_code = BluetoothDelegate::PairPromptStatus::kSuccess;
  168. } else {
  169. result.result_code = BluetoothDelegate::PairPromptStatus::kCancelled;
  170. }
  171. const std::string* pin = response.FindString("pin");
  172. if (pin) {
  173. std::u16string trimmed_input = base::UTF8ToUTF16(*pin);
  174. base::TrimWhitespace(trimmed_input, base::TRIM_ALL, &trimmed_input);
  175. result.pin = base::UTF16ToUTF8(trimmed_input);
  176. }
  177. std::move(callback).Run(result);
  178. }
  179. } // namespace electron