blob: 1265b40ec4d21065ca36a1c5acc8278309e1ef79 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2015 The Chromium Authors
juncaif70c51172017-02-10 23:49:172// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/bluetooth/bluetooth_allowed_devices.h"
6
7#include <string>
8#include <vector>
9
Lei Zhangde197672021-04-29 08:11:2410#include "base/containers/contains.h"
juncaif70c51172017-02-10 23:49:1711#include "base/logging.h"
juncaif70c51172017-02-10 23:49:1712#include "base/strings/string_util.h"
13#include "content/browser/bluetooth/bluetooth_blocklist.h"
juncaif70c51172017-02-10 23:49:1714
15using device::BluetoothUUID;
16
17namespace content {
18
19BluetoothAllowedDevices::BluetoothAllowedDevices() {}
20BluetoothAllowedDevices::BluetoothAllowedDevices(
21 const BluetoothAllowedDevices& other) = default;
22BluetoothAllowedDevices::~BluetoothAllowedDevices() {}
23
Ovidio Henriquez0e8ab7072019-05-31 21:38:0724const blink::WebBluetoothDeviceId& BluetoothAllowedDevices::AddDevice(
juncaif70c51172017-02-10 23:49:1725 const std::string& device_address,
26 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options) {
Doug Turner10051df2019-01-17 02:21:5527 auto& device_id = AddDevice(device_address);
28 AddUnionOfServicesTo(options, &device_id_to_services_map_[device_id]);
Ovidio Henriquezbbc7853c2020-09-17 22:36:5629 AddManufacturerDataTo(options, &device_id_to_manufacturers_map_[device_id]);
Doug Turner10051df2019-01-17 02:21:5530
31 // Currently, devices that are added with WebBluetoothRequestDeviceOptionsPtr
32 // |options| come from RequestDevice() and therefore have the ablity to be
33 // connected to.
34 device_id_to_connectable_map_[device_id] = true;
35
36 return device_id;
37}
38
Ovidio Henriquez0e8ab7072019-05-31 21:38:0739const blink::WebBluetoothDeviceId& BluetoothAllowedDevices::AddDevice(
Doug Turner10051df2019-01-17 02:21:5540 const std::string& device_address) {
juncaif70c51172017-02-10 23:49:1741 DVLOG(1) << "Adding a device to Map of Allowed Devices.";
42
43 auto id_iter = device_address_to_id_map_.find(device_address);
44 if (id_iter != device_address_to_id_map_.end()) {
45 DVLOG(1) << "Device already in map of allowed devices.";
juncaif70c51172017-02-10 23:49:1746 return device_address_to_id_map_[device_address];
47 }
Ovidio Henriquez0e8ab7072019-05-31 21:38:0748 const blink::WebBluetoothDeviceId device_id = GenerateUniqueDeviceId();
juncaif70c51172017-02-10 23:49:1749 DVLOG(1) << "Id generated for device: " << device_id;
50
51 device_address_to_id_map_[device_address] = device_id;
52 device_id_to_address_map_[device_id] = device_address;
juncaif70c51172017-02-10 23:49:1753
54 CHECK(device_id_set_.insert(device_id).second);
55
56 return device_address_to_id_map_[device_address];
57}
58
59void BluetoothAllowedDevices::RemoveDevice(const std::string& device_address) {
Ovidio Henriquez0e8ab7072019-05-31 21:38:0760 const blink::WebBluetoothDeviceId* device_id_ptr =
61 GetDeviceId(device_address);
juncaif70c51172017-02-10 23:49:1762 DCHECK(device_id_ptr != nullptr);
63
64 // We make a copy because we are going to remove the original value from its
65 // map.
Ovidio Henriquez0e8ab7072019-05-31 21:38:0766 blink::WebBluetoothDeviceId device_id = *device_id_ptr;
juncaif70c51172017-02-10 23:49:1767
68 // 1. Remove from all three maps.
69 CHECK(device_address_to_id_map_.erase(device_address));
70 CHECK(device_id_to_address_map_.erase(device_id));
71 CHECK(device_id_to_services_map_.erase(device_id));
72
Doug Turner10051df2019-01-17 02:21:5573 // Not all devices are connectable.
74 device_id_to_connectable_map_.erase(device_id);
75
juncaif70c51172017-02-10 23:49:1776 // 2. Remove from set of ids.
77 CHECK(device_id_set_.erase(device_id));
78}
79
Ovidio Henriquez0e8ab7072019-05-31 21:38:0780const blink::WebBluetoothDeviceId* BluetoothAllowedDevices::GetDeviceId(
juncaif70c51172017-02-10 23:49:1781 const std::string& device_address) {
82 auto id_iter = device_address_to_id_map_.find(device_address);
83 if (id_iter == device_address_to_id_map_.end()) {
84 return nullptr;
85 }
86 return &(id_iter->second);
87}
88
89const std::string& BluetoothAllowedDevices::GetDeviceAddress(
Ovidio Henriquez0e8ab7072019-05-31 21:38:0790 const blink::WebBluetoothDeviceId& device_id) {
juncaif70c51172017-02-10 23:49:1791 auto id_iter = device_id_to_address_map_.find(device_id);
juncaif70c51172017-02-10 23:49:1792 return id_iter == device_id_to_address_map_.end() ? base::EmptyString()
93 : id_iter->second;
94}
95
96bool BluetoothAllowedDevices::IsAllowedToAccessAtLeastOneService(
Ovidio Henriquez0e8ab7072019-05-31 21:38:0797 const blink::WebBluetoothDeviceId& device_id) const {
juncaif70c51172017-02-10 23:49:1798 auto id_iter = device_id_to_services_map_.find(device_id);
juncaif70c51172017-02-10 23:49:1799 return id_iter == device_id_to_services_map_.end() ? false
100 : !id_iter->second.empty();
101}
102
103bool BluetoothAllowedDevices::IsAllowedToAccessService(
Ovidio Henriquez0e8ab7072019-05-31 21:38:07104 const blink::WebBluetoothDeviceId& device_id,
juncaif70c51172017-02-10 23:49:17105 const BluetoothUUID& service_uuid) const {
Ovidio Henriquezbbc7853c2020-09-17 22:36:56106 if (BluetoothBlocklist::Get().IsExcluded(service_uuid))
juncaif70c51172017-02-10 23:49:17107 return false;
juncaif70c51172017-02-10 23:49:17108
109 auto id_iter = device_id_to_services_map_.find(device_id);
juncaif70c51172017-02-10 23:49:17110 return id_iter == device_id_to_services_map_.end()
111 ? false
Jan Wilken Dörrie77c581a2019-06-07 16:25:06112 : base::Contains(id_iter->second, service_uuid);
juncaif70c51172017-02-10 23:49:17113}
114
Doug Turner10051df2019-01-17 02:21:55115bool BluetoothAllowedDevices::IsAllowedToGATTConnect(
Ovidio Henriquez0e8ab7072019-05-31 21:38:07116 const blink::WebBluetoothDeviceId& device_id) const {
Doug Turner10051df2019-01-17 02:21:55117 auto id_iter = device_id_to_connectable_map_.find(device_id);
118 if (id_iter == device_id_to_connectable_map_.end())
119 return false;
120 return id_iter->second;
121}
122
Ovidio Henriquezbbc7853c2020-09-17 22:36:56123bool BluetoothAllowedDevices::IsAllowedToAccessManufacturerData(
124 const blink::WebBluetoothDeviceId& device_id,
125 const uint16_t manufacturer_code) const {
126 auto id_iter = device_id_to_manufacturers_map_.find(device_id);
127 return id_iter == device_id_to_manufacturers_map_.end()
128 ? false
129 : base::Contains(id_iter->second, manufacturer_code);
130}
131
Ovidio Henriquez0e8ab7072019-05-31 21:38:07132blink::WebBluetoothDeviceId BluetoothAllowedDevices::GenerateUniqueDeviceId() {
133 blink::WebBluetoothDeviceId device_id = blink::WebBluetoothDeviceId::Create();
Jan Wilken Dörrie77c581a2019-06-07 16:25:06134 while (base::Contains(device_id_set_, device_id)) {
juncaif70c51172017-02-10 23:49:17135 LOG(WARNING) << "Generated repeated id.";
Ovidio Henriquez0e8ab7072019-05-31 21:38:07136 device_id = blink::WebBluetoothDeviceId::Create();
juncaif70c51172017-02-10 23:49:17137 }
138 return device_id;
139}
140
141void BluetoothAllowedDevices::AddUnionOfServicesTo(
142 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options,
143 std::unordered_set<BluetoothUUID, device::BluetoothUUIDHash>*
144 unionOfServices) {
145 if (options->filters) {
146 for (const auto& filter : options->filters.value()) {
Ovidio Henriquezbbc7853c2020-09-17 22:36:56147 if (!filter->services)
juncaif70c51172017-02-10 23:49:17148 continue;
juncaif70c51172017-02-10 23:49:17149
Ovidio Henriquezbbc7853c2020-09-17 22:36:56150 for (const BluetoothUUID& uuid : filter->services.value())
juncaif70c51172017-02-10 23:49:17151 unionOfServices->insert(uuid);
juncaif70c51172017-02-10 23:49:17152 }
153 }
154
Ovidio Henriquezbbc7853c2020-09-17 22:36:56155 for (const BluetoothUUID& uuid : options->optional_services)
juncaif70c51172017-02-10 23:49:17156 unionOfServices->insert(uuid);
Ovidio Henriquezbbc7853c2020-09-17 22:36:56157}
158
159void BluetoothAllowedDevices::AddManufacturerDataTo(
160 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options,
161 base::flat_set<uint16_t>* manufacturer_codes) {
162 for (const uint16_t manufacturer_code : options->optional_manufacturer_data)
163 manufacturer_codes->insert(manufacturer_code);
juncaif70c51172017-02-10 23:49:17164}
165
166} // namespace content