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(const std::unordered_map<hci::Address, int>& paired_device_map, 63 Callback save_id_callback, Callback forget_device_callback); 64 65 /** 66 * Close the allocator. should be called when Bluetooth process is killed 67 * 68 * @return true if successfully close 69 */ 70 bool Close(); 71 72 /** 73 * Check if no id saved in memory 74 * 75 * @return true if no id is saved 76 */ 77 bool IsEmpty() const; 78 79 /** 80 * Allocate an id for a scanned device, or return the id if there is already 81 * one 82 * 83 * @param mac_address mac address of Bluetooth device 84 * @return the id of device 85 */ 86 int AllocateId(const hci::Address& mac_address); 87 88 /** 89 * Save the id for a paired device 90 * 91 * @param mac_address mac address of Bluetooth device 92 * @return true if save successfully 93 */ 94 bool SaveDevice(const hci::Address& mac_address); 95 96 /** 97 * Delete the id for a device to be forgotten 98 * 99 * @param mac_address mac address of Bluetooth device 100 */ 101 void ForgetDevice(const hci::Address& mac_address); 102 103 /** 104 * Check if an id is valid. 105 * The id should be less than or equal to kMaxId and bigger than or equal to 106 * kMinId 107 * 108 * @param mac_address mac address of Bluetooth device 109 * @return true if delete successfully 110 */ 111 static bool IsValidId(const int id); 112 113 protected: 114 // Singleton 115 MetricIdManager(); 116 117 private: 118 mutable std::mutex id_allocator_mutex_; 119 120 LruCache<hci::Address, int> paired_device_cache_; 121 LruCache<hci::Address, int> temporary_device_cache_; 122 std::unordered_set<int> id_set_; 123 124 int next_id_{kMinId}; 125 bool initialized_{false}; 126 Callback save_id_callback_; 127 Callback forget_device_callback_; 128 129 void ForgetDevicePostprocess(const hci::Address& mac_address, const int id); 130 131 // delete copy constructor for singleton 132 MetricIdManager(MetricIdManager const&) = delete; 133 MetricIdManager& operator=(MetricIdManager const&) = delete; 134 }; 135 136 } // namespace common 137 } // namespace bluetooth 138