Skip to content

Commit

Permalink
fix: navigator.bluetooth.requestDevice crash (#27941)
Browse files Browse the repository at this point in the history
* fix: navigator.bluetooth.requestDevice crash

* update bluetooth test to handle bluetooth permission denied

(cherry picked from commit 1c7ca27)
  • Loading branch information
jkleinsc committed Mar 1, 2021
1 parent fb5822a commit 26c5cc2
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
15 changes: 15 additions & 0 deletions shell/browser/lib/bluetooth_chooser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ void BluetoothChooser::SetAdapterPresence(AdapterPresence presence) {
void BluetoothChooser::ShowDiscoveryState(DiscoveryState state) {
switch (state) {
case DiscoveryState::FAILED_TO_START:
refreshing_ = false;
event_handler_.Run(content::BluetoothChooserEvent::CANCELLED, "");
break;
case DiscoveryState::IDLE:
refreshing_ = false;
if (device_map_.empty()) {
auto event = ++num_retries_ > kMaxScanRetries
? content::BluetoothChooserEvent::CANCELLED
Expand All @@ -81,6 +83,14 @@ void BluetoothChooser::ShowDiscoveryState(DiscoveryState state) {
}
break;
case DiscoveryState::DISCOVERING:
// The first time this state fires is due to a rescan triggering so set a
// flag to ignore devices
if (!refreshing_) {
refreshing_ = true;
} else {
// The second time this state fires we are now safe to pick a device
refreshing_ = false;
}
break;
}
}
Expand All @@ -91,6 +101,11 @@ void BluetoothChooser::AddOrUpdateDevice(const std::string& device_id,
bool is_gatt_connected,
bool is_paired,
int signal_strength_level) {
if (refreshing_) {
// If the list of bluetooth devices is currently being generated don't fire
// an event
return;
}
bool changed = false;
auto entry = device_map_.find(device_id);
if (entry == device_map_.end()) {
Expand Down
1 change: 1 addition & 0 deletions shell/browser/lib/bluetooth_chooser.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class BluetoothChooser : public content::BluetoothChooser {
api::WebContents* api_web_contents_;
EventHandler event_handler_;
int num_retries_ = 0;
bool refreshing_ = false;

DISALLOW_COPY_AND_ASSIGN(BluetoothChooser);
};
Expand Down
21 changes: 21 additions & 0 deletions spec-main/chromium-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1530,3 +1530,24 @@ describe('navigator.clipboard', () => {
expect(clipboard).to.not.equal('Read permission denied.');
});
});

describe('navigator.bluetooth', () => {
let w: BrowserWindow;
before(async () => {
w = new BrowserWindow({
show: false,
webPreferences: {
enableBlinkFeatures: 'WebBluetooth'
}
});
await w.loadFile(path.join(fixturesPath, 'pages', 'blank.html'));
});

after(closeAllWindows);

it('can request bluetooth devices', async () => {
const bluetooth = await w.webContents.executeJavaScript(`
navigator.bluetooth.requestDevice({ acceptAllDevices: true}).then(device => "Found a device!").catch(err => err.message);`, true);
expect(bluetooth).to.be.oneOf(['Found a device!', 'Bluetooth adapter not available.', 'User cancelled the requestDevice() chooser.']);
});
});

0 comments on commit 26c5cc2

Please sign in to comment.