1 /****************************************************************************** 2 * 3 * Copyright 2020 Google, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 #pragma once 20 21 #include <mutex> 22 #include <string> 23 #include <thread> 24 #include <unordered_set> 25 26 #include "common/lru_cache.h" 27 #include "hci/address.h" 28 29 namespace bluetooth { 30 namespace common { 31 32 class MetricIdManager { 33 public: 34 using Callback = std::function<bool(const hci::Address& address, const int id)>; 35 36 static const size_t kMaxNumUnpairedDevicesInMemory; 37 static const size_t kMaxNumPairedDevicesInMemory; 38 39 static const int kMinId; 40 static const int kMaxId; 41 42 ~MetricIdManager(); 43 44 /** 45 * Get the instance of singleton 46 * 47 * @return MetricIdManager& 48 */ 49 static MetricIdManager& GetInstance(); 50 51 /** 52 * Initialize the allocator 53 * 54 * @param paired_device_map map from mac_address to id already saved 55 * in the disk before init 56 * @param save_id_callback a callback that will be called after successfully 57 * saving id for a paired device 58 * @param forget_device_callback a callback that will be called after 59 * successful id deletion for forgotten device, 60 * @return true if successfully initialized 61 */ 62 bool Init( 63 const std::unordered_map<hci::Address, int>& paired_device_map, 64 Callback save_id_callback, 65 Callback forget_device_callback); 66 67 /** 68 * Close the allocator. should be called when Bluetooth process is killed 69 * 70 * @return true if successfully close 71 */ 72 bool Close(); 73 74 /** 75 * Check if no id saved in memory 76 * 77 * @return true if no id is saved 78 */ 79 bool IsEmpty() const; 80 81 /** 82 * Allocate an id for a scanned device, or return the id if there is already 83 * one 84 * 85 * @param mac_address mac address of Bluetooth device 86 * @return the id of device 87 */ 88 int AllocateId(const hci::Address& mac_address); 89 90 /** 91 * Save the id for a paired device 92 * 93 * @param mac_address mac address of Bluetooth device 94 * @return true if save successfully 95 */ 96 bool SaveDevice(const hci::Address& mac_address); 97 98 /** 99 * Delete the id for a device to be forgotten 100 * 101 * @param mac_address mac address of Bluetooth device 102 */ 103 void ForgetDevice(const hci::Address& mac_address); 104 105 /** 106 * Check if an id is valid. 107 * The id should be less than or equal to kMaxId and bigger than or equal to 108 * kMinId 109 * 110 * @param mac_address mac address of Bluetooth device 111 * @return true if delete successfully 112 */ 113 static bool IsValidId(const int id); 114 115 protected: 116 // Singleton 117 MetricIdManager(); 118 119 private: 120 mutable std::mutex id_allocator_mutex_; 121 122 LruCache<hci::Address, int> paired_device_cache_; 123 LruCache<hci::Address, int> temporary_device_cache_; 124 std::unordered_set<int> id_set_; 125 126 int next_id_{kMinId}; 127 bool initialized_{false}; 128 Callback save_id_callback_; 129 Callback forget_device_callback_; 130 131 void ForgetDevicePostprocess(const hci::Address& mac_address, 132 const int id); 133 134 // delete copy constructor for singleton 135 MetricIdManager(MetricIdManager const&) = delete; 136 MetricIdManager& operator=(MetricIdManager const&) = delete; 137 }; 138 139 } // namespace common 140 } // namespace bluetooth 141