Compare commits

...

1 Commits

Author SHA1 Message Date
Keeley Hammond
51eeed3aa3 Revert "fix: bluetooth crash in select-bluetooth-device event (#46782)"
This reverts commit 5dab95335b.
2025-05-22 10:31:09 -07:00
2 changed files with 40 additions and 42 deletions

View File

@@ -25,6 +25,19 @@ struct Converter<electron::BluetoothChooser::DeviceInfo> {
namespace electron { namespace electron {
namespace {
void OnDeviceChosen(const content::BluetoothChooser::EventHandler& handler,
const std::string& device_id) {
if (device_id.empty()) {
handler.Run(content::BluetoothChooserEvent::CANCELLED, device_id);
} else {
handler.Run(content::BluetoothChooserEvent::SELECTED, device_id);
}
}
} // namespace
BluetoothChooser::BluetoothChooser(api::WebContents* contents, BluetoothChooser::BluetoothChooser(api::WebContents* contents,
const EventHandler& event_handler) const EventHandler& event_handler)
: api_web_contents_(contents), event_handler_(event_handler) {} : api_web_contents_(contents), event_handler_(event_handler) {}
@@ -36,12 +49,13 @@ BluetoothChooser::~BluetoothChooser() {
void BluetoothChooser::SetAdapterPresence(AdapterPresence presence) { void BluetoothChooser::SetAdapterPresence(AdapterPresence presence) {
switch (presence) { switch (presence) {
case AdapterPresence::ABSENT: case AdapterPresence::ABSENT:
NOTREACHED();
case AdapterPresence::POWERED_OFF: case AdapterPresence::POWERED_OFF:
event_handler_.Run(content::BluetoothChooserEvent::CANCELLED, ""); // Chrome currently directs the user to system preferences
break; // to grant bluetooth permission for this case, should we
// do something similar ?
// https://chromium-review.googlesource.com/c/chromium/src/+/2617129
case AdapterPresence::UNAUTHORIZED: case AdapterPresence::UNAUTHORIZED:
event_handler_.Run(content::BluetoothChooserEvent::DENIED_PERMISSION, ""); event_handler_.Run(content::BluetoothChooserEvent::CANCELLED, "");
break; break;
case AdapterPresence::POWERED_ON: case AdapterPresence::POWERED_ON:
rescan_ = true; rescan_ = true;
@@ -60,27 +74,25 @@ void BluetoothChooser::ShowDiscoveryState(DiscoveryState state) {
refreshing_ = false; refreshing_ = false;
idle_state = true; idle_state = true;
break; break;
// The first time this state fires is due to a rescan triggering so we
// set a flag to ignore devices - the second time this state fires
// we are now safe to pick a device.
case DiscoveryState::DISCOVERING: case DiscoveryState::DISCOVERING:
// The first time this state fires is due to a rescan triggering so set a
// flag to ignore devices
if (rescan_ && !refreshing_) { if (rescan_ && !refreshing_) {
refreshing_ = true; refreshing_ = true;
} else { } else {
// The second time this state fires we are now safe to pick a device
refreshing_ = false; refreshing_ = false;
} }
break; break;
} }
bool prevent_default = bool prevent_default =
api_web_contents_->Emit("select-bluetooth-device", GetDeviceList(), api_web_contents_->Emit("select-bluetooth-device", GetDeviceList(),
base::BindOnce(&BluetoothChooser::OnDeviceChosen, base::BindOnce(&OnDeviceChosen, event_handler_));
weak_ptr_factory_.GetWeakPtr()));
if (!prevent_default && idle_state) { if (!prevent_default && idle_state) {
if (device_id_to_name_map_.empty()) { if (device_map_.empty()) {
event_handler_.Run(content::BluetoothChooserEvent::CANCELLED, ""); event_handler_.Run(content::BluetoothChooserEvent::CANCELLED, "");
} else { } else {
auto it = device_id_to_name_map_.begin(); auto it = device_map_.begin();
auto device_id = it->first; auto device_id = it->first;
event_handler_.Run(content::BluetoothChooserEvent::SELECTED, device_id); event_handler_.Run(content::BluetoothChooserEvent::SELECTED, device_id);
} }
@@ -93,47 +105,38 @@ void BluetoothChooser::AddOrUpdateDevice(const std::string& device_id,
bool is_gatt_connected, bool is_gatt_connected,
bool is_paired, bool is_paired,
int signal_strength_level) { int signal_strength_level) {
// Don't fire an event during refresh. if (refreshing_) {
if (refreshing_) // If the list of bluetooth devices is currently being generated don't fire
// an event
return; return;
}
// Emit a select-bluetooth-device handler to allow for user to listen for auto [iter, changed] = device_map_.try_emplace(device_id, device_name);
// bluetooth device found. If there's no listener in place, then select the
// first device that matches the filters provided.
auto [iter, changed] =
device_id_to_name_map_.try_emplace(device_id, device_name);
if (!changed && should_update_name) { if (!changed && should_update_name) {
iter->second = device_name; iter->second = device_name;
changed = true; changed = true;
} }
if (changed) { if (changed) {
// Emit a select-bluetooth-device handler to allow for user to listen for
// bluetooth device found.
bool prevent_default = api_web_contents_->Emit( bool prevent_default = api_web_contents_->Emit(
"select-bluetooth-device", GetDeviceList(), "select-bluetooth-device", GetDeviceList(),
base::BindOnce(&BluetoothChooser::OnDeviceChosen, base::BindOnce(&OnDeviceChosen, event_handler_));
weak_ptr_factory_.GetWeakPtr()));
if (!prevent_default) // If emit not implemented select first device that matches the filters
// provided.
if (!prevent_default) {
event_handler_.Run(content::BluetoothChooserEvent::SELECTED, device_id); event_handler_.Run(content::BluetoothChooserEvent::SELECTED, device_id);
} }
}
void BluetoothChooser::OnDeviceChosen(const std::string& device_id) {
if (event_handler_.is_null())
return;
if (device_id.empty()) {
event_handler_.Run(content::BluetoothChooserEvent::CANCELLED, device_id);
} else {
event_handler_.Run(content::BluetoothChooserEvent::SELECTED, device_id);
} }
} }
std::vector<electron::BluetoothChooser::DeviceInfo> std::vector<electron::BluetoothChooser::DeviceInfo>
BluetoothChooser::GetDeviceList() { BluetoothChooser::GetDeviceList() {
std::vector<electron::BluetoothChooser::DeviceInfo> vec; std::vector<electron::BluetoothChooser::DeviceInfo> vec;
vec.reserve(device_id_to_name_map_.size()); vec.reserve(device_map_.size());
for (const auto& [device_id, device_name] : device_id_to_name_map_) for (const auto& [device_id, device_name] : device_map_)
vec.emplace_back(device_id, device_name); vec.emplace_back(device_id, device_name);
return vec; return vec;
} }

View File

@@ -5,14 +5,13 @@
#ifndef ELECTRON_SHELL_BROWSER_LIB_BLUETOOTH_CHOOSER_H_ #ifndef ELECTRON_SHELL_BROWSER_LIB_BLUETOOTH_CHOOSER_H_
#define ELECTRON_SHELL_BROWSER_LIB_BLUETOOTH_CHOOSER_H_ #define ELECTRON_SHELL_BROWSER_LIB_BLUETOOTH_CHOOSER_H_
#include <map>
#include <string> #include <string>
#include <vector> #include <vector>
#include "base/memory/raw_ptr.h" #include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/bluetooth_chooser.h" #include "content/public/browser/bluetooth_chooser.h"
#include "shell/browser/api/electron_api_web_contents.h" #include "shell/browser/api/electron_api_web_contents.h"
#include "third_party/abseil-cpp/absl/container/flat_hash_map.h"
namespace electron { namespace electron {
@@ -40,18 +39,14 @@ class BluetoothChooser : public content::BluetoothChooser {
bool is_gatt_connected, bool is_gatt_connected,
bool is_paired, bool is_paired,
int signal_strength_level) override; int signal_strength_level) override;
void OnDeviceChosen(const std::string& device_id);
std::vector<DeviceInfo> GetDeviceList(); std::vector<DeviceInfo> GetDeviceList();
private: private:
absl::flat_hash_map<std::string, std::u16string> device_id_to_name_map_; std::map<std::string, std::u16string> device_map_;
raw_ptr<api::WebContents> api_web_contents_; raw_ptr<api::WebContents> api_web_contents_;
EventHandler event_handler_; EventHandler event_handler_;
bool refreshing_ = false; bool refreshing_ = false;
bool rescan_ = false; bool rescan_ = false;
base::WeakPtrFactory<BluetoothChooser> weak_ptr_factory_{this};
}; };
} // namespace electron } // namespace electron