bluetooth_chooser.cc 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Copyright (c) 2016 GitHub, 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/lib/bluetooth_chooser.h"
  5. #include "shell/common/gin_converters/callback_converter.h"
  6. #include "shell/common/gin_helper/dictionary.h"
  7. namespace gin {
  8. template <>
  9. struct Converter<electron::BluetoothChooser::DeviceInfo> {
  10. static v8::Local<v8::Value> ToV8(
  11. v8::Isolate* isolate,
  12. const electron::BluetoothChooser::DeviceInfo& val) {
  13. gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
  14. dict.Set("deviceName", val.device_name);
  15. dict.Set("deviceId", val.device_id);
  16. return gin::ConvertToV8(isolate, dict);
  17. }
  18. };
  19. } // namespace gin
  20. namespace electron {
  21. namespace {
  22. const int kMaxScanRetries = 5;
  23. void OnDeviceChosen(const content::BluetoothChooser::EventHandler& handler,
  24. const std::string& device_id) {
  25. if (device_id.empty()) {
  26. handler.Run(content::BluetoothChooser::Event::CANCELLED, device_id);
  27. } else {
  28. handler.Run(content::BluetoothChooser::Event::SELECTED, device_id);
  29. }
  30. }
  31. } // namespace
  32. BluetoothChooser::BluetoothChooser(api::WebContents* contents,
  33. const EventHandler& event_handler)
  34. : api_web_contents_(contents), event_handler_(event_handler) {}
  35. BluetoothChooser::~BluetoothChooser() = default;
  36. void BluetoothChooser::SetAdapterPresence(AdapterPresence presence) {
  37. switch (presence) {
  38. case AdapterPresence::ABSENT:
  39. case AdapterPresence::POWERED_OFF:
  40. event_handler_.Run(Event::CANCELLED, "");
  41. break;
  42. case AdapterPresence::POWERED_ON:
  43. break;
  44. }
  45. }
  46. void BluetoothChooser::ShowDiscoveryState(DiscoveryState state) {
  47. switch (state) {
  48. case DiscoveryState::FAILED_TO_START:
  49. event_handler_.Run(Event::CANCELLED, "");
  50. break;
  51. case DiscoveryState::IDLE:
  52. if (device_map_.empty()) {
  53. auto event =
  54. ++num_retries_ > kMaxScanRetries ? Event::CANCELLED : Event::RESCAN;
  55. event_handler_.Run(event, "");
  56. } else {
  57. bool prevent_default = api_web_contents_->Emit(
  58. "select-bluetooth-device", GetDeviceList(),
  59. base::BindOnce(&OnDeviceChosen, event_handler_));
  60. if (!prevent_default) {
  61. auto it = device_map_.begin();
  62. auto device_id = it->first;
  63. event_handler_.Run(Event::SELECTED, device_id);
  64. }
  65. }
  66. break;
  67. case DiscoveryState::DISCOVERING:
  68. break;
  69. }
  70. }
  71. void BluetoothChooser::AddOrUpdateDevice(const std::string& device_id,
  72. bool should_update_name,
  73. const base::string16& device_name,
  74. bool is_gatt_connected,
  75. bool is_paired,
  76. int signal_strength_level) {
  77. bool changed = false;
  78. auto entry = device_map_.find(device_id);
  79. if (entry == device_map_.end()) {
  80. device_map_[device_id] = device_name;
  81. changed = true;
  82. } else if (should_update_name) {
  83. entry->second = device_name;
  84. changed = true;
  85. }
  86. if (changed) {
  87. // Emit a select-bluetooth-device handler to allow for user to listen for
  88. // bluetooth device found.
  89. bool prevent_default = api_web_contents_->Emit(
  90. "select-bluetooth-device", GetDeviceList(),
  91. base::BindOnce(&OnDeviceChosen, event_handler_));
  92. // If emit not implimented select first device that matches the filters
  93. // provided.
  94. if (!prevent_default) {
  95. event_handler_.Run(Event::SELECTED, device_id);
  96. }
  97. }
  98. }
  99. std::vector<electron::BluetoothChooser::DeviceInfo>
  100. BluetoothChooser::GetDeviceList() {
  101. std::vector<electron::BluetoothChooser::DeviceInfo> vec;
  102. vec.reserve(device_map_.size());
  103. for (const auto& it : device_map_) {
  104. DeviceInfo info = {it.first, it.second};
  105. vec.push_back(info);
  106. }
  107. return vec;
  108. }
  109. } // namespace electron