electron_bluetooth_delegate.cc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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 "build/build_config.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::IsAllowedToAccessService(
  100. RenderFrameHost* frame,
  101. const WebBluetoothDeviceId& device_id,
  102. const BluetoothUUID& service) {
  103. NOTIMPLEMENTED();
  104. return true;
  105. }
  106. bool ElectronBluetoothDelegate::IsAllowedToAccessAtLeastOneService(
  107. RenderFrameHost* frame,
  108. const WebBluetoothDeviceId& device_id) {
  109. NOTIMPLEMENTED();
  110. return true;
  111. }
  112. bool ElectronBluetoothDelegate::IsAllowedToAccessManufacturerData(
  113. RenderFrameHost* frame,
  114. const WebBluetoothDeviceId& device_id,
  115. uint16_t manufacturer_code) {
  116. NOTIMPLEMENTED();
  117. return true;
  118. }
  119. void ElectronBluetoothDelegate::AddFramePermissionObserver(
  120. FramePermissionObserver* observer) {
  121. NOTIMPLEMENTED();
  122. }
  123. void ElectronBluetoothDelegate::RemoveFramePermissionObserver(
  124. FramePermissionObserver* observer) {
  125. NOTIMPLEMENTED();
  126. }
  127. std::vector<blink::mojom::WebBluetoothDevicePtr>
  128. ElectronBluetoothDelegate::GetPermittedDevices(
  129. content::RenderFrameHost* frame) {
  130. std::vector<blink::mojom::WebBluetoothDevicePtr> permitted_devices;
  131. NOTIMPLEMENTED();
  132. return permitted_devices;
  133. }
  134. void ElectronBluetoothDelegate::ShowDevicePairPrompt(
  135. content::RenderFrameHost* frame,
  136. const std::u16string& device_identifier,
  137. PairPromptCallback callback,
  138. PairingKind pairing_kind,
  139. const absl::optional<std::u16string>& pin) {
  140. auto* web_contents = content::WebContents::FromRenderFrameHost(frame);
  141. if (web_contents) {
  142. auto* permission_manager = static_cast<ElectronPermissionManager*>(
  143. web_contents->GetBrowserContext()->GetPermissionControllerDelegate());
  144. v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
  145. v8::HandleScope scope(isolate);
  146. gin_helper::Dictionary details =
  147. gin_helper::Dictionary::CreateEmpty(isolate);
  148. details.Set("deviceId", device_identifier);
  149. details.Set("pairingKind", pairing_kind);
  150. details.SetGetter("frame", frame);
  151. if (pin.has_value()) {
  152. details.Set("pin", pin.value());
  153. }
  154. permission_manager->CheckBluetoothDevicePair(
  155. details, base::AdaptCallbackForRepeating(base::BindOnce(
  156. &ElectronBluetoothDelegate::OnDevicePairPromptResponse,
  157. weak_factory_.GetWeakPtr(), std::move(callback))));
  158. }
  159. }
  160. void ElectronBluetoothDelegate::OnDevicePairPromptResponse(
  161. PairPromptCallback callback,
  162. base::Value::Dict response) {
  163. BluetoothDelegate::PairPromptResult result;
  164. if (response.FindBool("confirmed").value_or(false)) {
  165. result.result_code = BluetoothDelegate::PairPromptStatus::kSuccess;
  166. } else {
  167. result.result_code = BluetoothDelegate::PairPromptStatus::kCancelled;
  168. }
  169. const std::string* pin = response.FindString("pin");
  170. if (pin) {
  171. std::u16string trimmed_input = base::UTF8ToUTF16(*pin);
  172. base::TrimWhitespace(trimmed_input, base::TRIM_ALL, &trimmed_input);
  173. result.pin = base::UTF16ToUTF8(trimmed_input);
  174. }
  175. std::move(callback).Run(result);
  176. }
  177. } // namespace electron