blob: 234744e822488f244ae57eb1fc52b91b91f7dd80 [file] [log] [blame]
juncaif70c51172017-02-10 23:49:171// Copyright 2015 The Chromium Authors. All rights reserved.
2// 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"
Anton Bikineevf62d1bf2021-05-15 17:56:0714#include "third_party/abseil-cpp/absl/types/optional.h"
juncaif70c51172017-02-10 23:49:1715
16using device::BluetoothUUID;
17
18namespace content {
19
20BluetoothAllowedDevices::BluetoothAllowedDevices() {}
21BluetoothAllowedDevices::BluetoothAllowedDevices(
22 const BluetoothAllowedDevices& other) = default;
23BluetoothAllowedDevices::~BluetoothAllowedDevices() {}
24
Ovidio Henriquez0e8ab7072019-05-31 21:38:0725const blink::WebBluetoothDeviceId& BluetoothAllowedDevices::AddDevice(
juncaif70c51172017-02-10 23:49:1726 const std::string& device_address,
27 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options) {
Doug Turner10051df2019-01-17 02:21:5528 auto& device_id = AddDevice(device_address);
29 AddUnionOfServicesTo(options, &device_id_to_services_map_[device_id]);
Ovidio Henriquezbbc7853c2020-09-17 22:36:5630 AddManufacturerDataTo(options, &device_id_to_manufacturers_map_[device_id]);
Doug Turner10051df2019-01-17 02:21:5531
32 // Currently, devices that are added with WebBluetoothRequestDeviceOptionsPtr
33 // |options| come from RequestDevice() and therefore have the ablity to be
34 // connected to.
35 device_id_to_connectable_map_[device_id] = true;
36
37 return device_id;
38}
39
Ovidio Henriquez0e8ab7072019-05-31 21:38:0740const blink::WebBluetoothDeviceId& BluetoothAllowedDevices::AddDevice(
Doug Turner10051df2019-01-17 02:21:5541 const std::string& device_address) {
juncaif70c51172017-02-10 23:49:1742 DVLOG(1) << "Adding a device to Map of Allowed Devices.";
43
44 auto id_iter = device_address_to_id_map_.find(device_address);
45 if (id_iter != device_address_to_id_map_.end()) {
46 DVLOG(1) << "Device already in map of allowed devices.";
juncaif70c51172017-02-10 23:49:1747 return device_address_to_id_map_[device_address];
48 }
Ovidio Henriquez0e8ab7072019-05-31 21:38:0749 const blink::WebBluetoothDeviceId device_id = GenerateUniqueDeviceId();
juncaif70c51172017-02-10 23:49:1750 DVLOG(1) << "Id generated for device: " << device_id;
51
52 device_address_to_id_map_[device_address] = device_id;
53 device_id_to_address_map_[device_id] = device_address;
juncaif70c51172017-02-10 23:49:1754
55 CHECK(device_id_set_.insert(device_id).second);
56
57 return device_address_to_id_map_[device_address];
58}
59
60void BluetoothAllowedDevices::RemoveDevice(const std::string& device_address) {
Ovidio Henriquez0e8ab7072019-05-31 21:38:0761 const blink::WebBluetoothDeviceId* device_id_ptr =
62 GetDeviceId(device_address);
juncaif70c51172017-02-10 23:49:1763 DCHECK(device_id_ptr != nullptr);
64
65 // We make a copy because we are going to remove the original value from its
66 // map.
Ovidio Henriquez0e8ab7072019-05-31 21:38:0767 blink::WebBluetoothDeviceId device_id = *device_id_ptr;
juncaif70c51172017-02-10 23:49:1768
69 // 1. Remove from all three maps.
70 CHECK(device_address_to_id_map_.erase(device_address));
71 CHECK(device_id_to_address_map_.erase(device_id));
72 CHECK(device_id_to_services_map_.erase(device_id));
73
Doug Turner10051df2019-01-17 02:21:5574 // Not all devices are connectable.
75 device_id_to_connectable_map_.erase(device_id);
76
juncaif70c51172017-02-10 23:49:1777 // 2. Remove from set of ids.
78 CHECK(device_id_set_.erase(device_id));
79}
80
Ovidio Henriquez0e8ab7072019-05-31 21:38:0781const blink::WebBluetoothDeviceId* BluetoothAllowedDevices::GetDeviceId(
juncaif70c51172017-02-10 23:49:1782 const std::string& device_address) {
83 auto id_iter = device_address_to_id_map_.find(device_address);
84 if (id_iter == device_address_to_id_map_.end()) {
85 return nullptr;
86 }
87 return &(id_iter->second);
88}
89
90const std::string& BluetoothAllowedDevices::GetDeviceAddress(
Ovidio Henriquez0e8ab7072019-05-31 21:38:0791 const blink::WebBluetoothDeviceId& device_id) {
juncaif70c51172017-02-10 23:49:1792 auto id_iter = device_id_to_address_map_.find(device_id);
juncaif70c51172017-02-10 23:49:1793 return id_iter == device_id_to_address_map_.end() ? base::EmptyString()
94 : id_iter->second;
95}
96
97bool BluetoothAllowedDevices::IsAllowedToAccessAtLeastOneService(
Ovidio Henriquez0e8ab7072019-05-31 21:38:0798 const blink::WebBluetoothDeviceId& device_id) const {
juncaif70c51172017-02-10 23:49:1799 auto id_iter = device_id_to_services_map_.find(device_id);
juncaif70c51172017-02-10 23:49:17100 return id_iter == device_id_to_services_map_.end() ? false
101 : !id_iter->second.empty();
102}
103
104bool BluetoothAllowedDevices::IsAllowedToAccessService(
Ovidio Henriquez0e8ab7072019-05-31 21:38:07105 const blink::WebBluetoothDeviceId& device_id,
juncaif70c51172017-02-10 23:49:17106 const BluetoothUUID& service_uuid) const {
Ovidio Henriquezbbc7853c2020-09-17 22:36:56107 if (BluetoothBlocklist::Get().IsExcluded(service_uuid))
juncaif70c51172017-02-10 23:49:17108 return false;
juncaif70c51172017-02-10 23:49:17109
110 auto id_iter = device_id_to_services_map_.find(device_id);
juncaif70c51172017-02-10 23:49:17111 return id_iter == device_id_to_services_map_.end()
112 ? false
Jan Wilken Dörrie77c581a2019-06-07 16:25:06113 : base::Contains(id_iter->second, service_uuid);
juncaif70c51172017-02-10 23:49:17114}
115
Doug Turner10051df2019-01-17 02:21:55116bool BluetoothAllowedDevices::IsAllowedToGATTConnect(
Ovidio Henriquez0e8ab7072019-05-31 21:38:07117 const blink::WebBluetoothDeviceId& device_id) const {
Doug Turner10051df2019-01-17 02:21:55118 auto id_iter = device_id_to_connectable_map_.find(device_id);
119 if (id_iter == device_id_to_connectable_map_.end())
120 return false;
121 return id_iter->second;
122}
123
Ovidio Henriquezbbc7853c2020-09-17 22:36:56124bool BluetoothAllowedDevices::IsAllowedToAccessManufacturerData(
125 const blink::WebBluetoothDeviceId& device_id,
126 const uint16_t manufacturer_code) const {
127 auto id_iter = device_id_to_manufacturers_map_.find(device_id);
128 return id_iter == device_id_to_manufacturers_map_.end()
129 ? false
130 : base::Contains(id_iter->second, manufacturer_code);
131}
132
Ovidio Henriquez0e8ab7072019-05-31 21:38:07133blink::WebBluetoothDeviceId BluetoothAllowedDevices::GenerateUniqueDeviceId() {
134 blink::WebBluetoothDeviceId device_id = blink::WebBluetoothDeviceId::Create();
Jan Wilken Dörrie77c581a2019-06-07 16:25:06135 while (base::Contains(device_id_set_, device_id)) {
juncaif70c51172017-02-10 23:49:17136 LOG(WARNING) << "Generated repeated id.";
Ovidio Henriquez0e8ab7072019-05-31 21:38:07137 device_id = blink::WebBluetoothDeviceId::Create();
juncaif70c51172017-02-10 23:49:17138 }
139 return device_id;
140}
141
142void BluetoothAllowedDevices::AddUnionOfServicesTo(
143 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options,
144 std::unordered_set<BluetoothUUID, device::BluetoothUUIDHash>*
145 unionOfServices) {
146 if (options->filters) {
147 for (const auto& filter : options->filters.value()) {
Ovidio Henriquezbbc7853c2020-09-17 22:36:56148 if (!filter->services)
juncaif70c51172017-02-10 23:49:17149 continue;
juncaif70c51172017-02-10 23:49:17150
Ovidio Henriquezbbc7853c2020-09-17 22:36:56151 for (const BluetoothUUID& uuid : filter->services.value())
juncaif70c51172017-02-10 23:49:17152 unionOfServices->insert(uuid);
juncaif70c51172017-02-10 23:49:17153 }
154 }
155
Ovidio Henriquezbbc7853c2020-09-17 22:36:56156 for (const BluetoothUUID& uuid : options->optional_services)
juncaif70c51172017-02-10 23:49:17157 unionOfServices->insert(uuid);
Ovidio Henriquezbbc7853c2020-09-17 22:36:56158}
159
160void BluetoothAllowedDevices::AddManufacturerDataTo(
161 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options,
162 base::flat_set<uint16_t>* manufacturer_codes) {
163 for (const uint16_t manufacturer_code : options->optional_manufacturer_data)
164 manufacturer_codes->insert(manufacturer_code);
juncaif70c51172017-02-10 23:49:17165}
166
167} // namespace content