Index: content/browser/bluetooth/bluetooth_allowed_devices_map.cc |
diff --git a/content/browser/bluetooth/bluetooth_allowed_devices_map.cc b/content/browser/bluetooth/bluetooth_allowed_devices_map.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3069ea1714aab2cfb99fe559c180f75044ae959e |
--- /dev/null |
+++ b/content/browser/bluetooth/bluetooth_allowed_devices_map.cc |
@@ -0,0 +1,146 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/browser/bluetooth/bluetooth_allowed_devices_map.h" |
+ |
+#include <vector> |
+ |
+#include "base/base64.h" |
+#include "base/logging.h" |
+#include "base/stl_util.h" |
+#include "base/strings/string_util.h" |
+#include "content/common/bluetooth/bluetooth_scan_filter.h" |
+#include "crypto/random.h" |
+#include "device/bluetooth/bluetooth_uuid.h" |
+ |
+using device::BluetoothUUID; |
+ |
+namespace content { |
+ |
+namespace { |
+std::string GetBase64Id() { |
+ std::string bytes(16 /* 128bits */, '\0'); |
+ |
+ crypto::RandBytes(base::WriteInto(&bytes /* str */, |
+ bytes.size() + 1 /* length_with_null */), |
palmer
2016/01/13 22:52:06
Possible performance nit: Will the call to |WriteI
ortuno
2016/01/14 02:44:58
Done.
|
+ bytes.size()); |
+ |
+ base::Base64Encode(bytes, &bytes); |
+ |
+ return bytes; |
+} |
+} // namespace |
+ |
+BluetoothAllowedDevicesMap::BluetoothAllowedDevicesMap() {} |
+BluetoothAllowedDevicesMap::~BluetoothAllowedDevicesMap() {} |
+ |
+const std::string& BluetoothAllowedDevicesMap::AddDevice( |
+ const std::string& origin, |
+ const std::string& device_address, |
+ const std::vector<BluetoothScanFilter>& filters, |
+ const std::vector<BluetoothUUID>& optional_services) { |
+ VLOG(1) << "Adding a device to Map of Allowed Devices."; |
+ |
+ if (ContainsKey(origin_to_device_address_to_id_map_[origin], |
+ device_address)) { |
+ VLOG(1) << "Device already in map of allowed devices."; |
+ return origin_to_device_address_to_id_map_[origin][device_address]; |
+ } |
+ const std::string device_id = GenerateDeviceId(origin); |
+ VLOG(1) << "Id generated for device: " << device_id; |
+ |
+ origin_to_device_address_to_id_map_[origin][device_address] = device_id; |
+ origin_to_device_id_to_address_map_[origin][device_id] = device_address; |
+ origin_to_device_id_to_services_map_[origin][device_id] = |
+ UnionOfServices(filters, optional_services); |
+ |
+ return origin_to_device_address_to_id_map_[origin][device_address]; |
+} |
+ |
+void BluetoothAllowedDevicesMap::RemoveDevice( |
+ const std::string& origin, |
+ const std::string& device_address) { |
+ const std::string device_id = GetDeviceId(origin, device_address); |
+ if (device_id.empty()) { |
palmer
2016/01/13 22:52:06
Could this be a DCHECK? Do we expect it to happen
ortuno
2016/01/14 02:44:58
Done.
|
+ return; |
+ } |
+ |
+ // 1. Remove from all three maps. |
+ CHECK(origin_to_device_address_to_id_map_[origin].erase(device_address)); |
+ CHECK(origin_to_device_id_to_address_map_[origin].erase(device_id)); |
+ CHECK(origin_to_device_id_to_services_map_[origin].erase(device_id)); |
+ |
+ // 2. Remove empty map for origin. |
+ if (origin_to_device_address_to_id_map_[origin].empty()) { |
+ CHECK(origin_to_device_address_to_id_map_.erase(origin)); |
+ CHECK(origin_to_device_id_to_address_map_.erase(origin)); |
+ CHECK(origin_to_device_id_to_services_map_.erase(origin)); |
+ } |
+} |
+ |
+const std::string& BluetoothAllowedDevicesMap::GetDeviceId( |
+ const std::string& origin, |
+ const std::string& device_address) { |
+ auto address_map_iter = origin_to_device_address_to_id_map_.find(origin); |
+ if (address_map_iter == origin_to_device_address_to_id_map_.end()) { |
+ return base::EmptyString(); |
+ } |
+ |
+ const DeviceAddressToIdMap& device_address_to_id_map = |
palmer
2016/01/13 22:52:06
Nit: this could be const auto&.
ortuno
2016/01/14 02:44:58
Done. Also done in the next function.
|
+ address_map_iter->second; |
+ |
+ auto id_iter = device_address_to_id_map.find(device_address); |
+ if (id_iter == device_address_to_id_map.end()) { |
+ return base::EmptyString(); |
+ } |
+ return id_iter->second; |
+} |
+ |
+const std::string& BluetoothAllowedDevicesMap::GetDeviceAddress( |
+ const std::string& origin, |
+ const std::string& device_id) { |
+ auto id_map_iter = origin_to_device_id_to_address_map_.find(origin); |
+ if (id_map_iter == origin_to_device_id_to_address_map_.end()) { |
+ return base::EmptyString(); |
+ } |
+ |
+ const DeviceIdToAddressMap& device_id_to_address_map = id_map_iter->second; |
+ |
+ auto id_iter = device_id_to_address_map.find(device_id); |
+ if (id_iter == device_id_to_address_map.end()) { |
palmer
2016/01/13 22:52:06
Nit: Potentially clearer code:
return id_iter
ortuno
2016/01/14 02:44:58
Done.
|
+ return base::EmptyString(); |
+ } |
+ return id_iter->second; |
+} |
+ |
+std::string BluetoothAllowedDevicesMap::GenerateDeviceId( |
+ const std::string& origin) { |
+ std::string device_id = GetBase64Id(); |
+ auto id_map_iter = origin_to_device_id_to_address_map_.find(origin); |
+ if (id_map_iter == origin_to_device_id_to_address_map_.end()) { |
+ return device_id; |
+ } |
+ while (ContainsKey(id_map_iter->second, device_id)) { |
+ LOG(WARNING) << "Generated repeated id."; |
+ device_id = GetBase64Id(); |
+ } |
+ return device_id; |
+} |
+ |
+std::set<std::string> BluetoothAllowedDevicesMap::UnionOfServices( |
+ const std::vector<BluetoothScanFilter>& filters, |
+ const std::vector<BluetoothUUID>& optional_services) { |
+ std::set<std::string> unionOfServices; |
+ for (const BluetoothScanFilter& filter : filters) { |
palmer
2016/01/13 22:52:06
Nit: Could use const auto& here.
ortuno
2016/01/14 02:44:58
Done. I kept the other ones as is because filter.s
|
+ for (const BluetoothUUID& uuid : filter.services) { |
+ unionOfServices.insert(uuid.canonical_value()); |
+ } |
+ } |
+ for (const BluetoothUUID& uuid : optional_services) { |
+ unionOfServices.insert(uuid.canonical_value()); |
+ } |
+ return unionOfServices; |
+} |
+ |
+} // namespace content |