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 #include "raw_address.h" 26 27 #include "lru.h" 28 29 namespace bluetooth { 30 31 namespace common { 32 33 class MetricIdAllocator { 34 public: 35 using Callback = std::function<bool(const RawAddress& address, const int id)>; 36 37 static const size_t kMaxNumUnpairedDevicesInMemory; 38 static const size_t kMaxNumPairedDevicesInMemory; 39 40 static const int kMinId; 41 static const int kMaxId; 42 43 ~MetricIdAllocator(); 44 45 /** 46 * Get the instance of singleton 47 * 48 * @return MetricIdAllocator& 49 */ 50 static MetricIdAllocator& GetInstance(); 51 52 /** 53 * Initialize the allocator 54 * 55 * @param paired_device_map map from mac_address to id already saved 56 * in the disk before init 57 * @param save_id_callback a callback that will be called after successfully 58 * saving id for a paired device 59 * @param forget_device_callback a callback that will be called after 60 * successful id deletion for forgotten device, 61 * @return true if successfully initialized 62 */ 63 bool Init(const std::unordered_map<RawAddress, int>& paired_device_map, 64 Callback save_id_callback, Callback forget_device_callback); 65 66 /** 67 * Close the allocator. should be called when Bluetooth process is killed 68 * 69 * @return true if successfully close 70 */ 71 bool Close(); 72 73 /** 74 * Check if no id saved in memory 75 * 76 * @return true if no id is saved 77 */ 78 bool IsEmpty() const; 79 80 /** 81 * Allocate an id for a scanned device, or return the id if there is already 82 * one 83 * 84 * @param mac_address mac address of Bluetooth device 85 * @return the id of device 86 */ 87 int AllocateId(const RawAddress& mac_address); 88 89 /** 90 * Save the id for a paired device 91 * 92 * @param mac_address mac address of Bluetooth device 93 * @return true if save successfully 94 */ 95 bool SaveDevice(const RawAddress& mac_address); 96 97 /** 98 * Delete the id for a device to be forgotten 99 * 100 * @param mac_address mac address of Bluetooth device 101 */ 102 void ForgetDevice(const RawAddress& mac_address); 103 104 /** 105 * Check if an id is valid. 106 * The id should be less than or equal to kMaxId and bigger than or equal to 107 * kMinId 108 * 109 * @param mac_address mac address of Bluetooth device 110 * @return true if delete successfully 111 */ 112 static bool IsValidId(const int id); 113 114 protected: 115 // Singleton 116 MetricIdAllocator(); 117 118 private: 119 static const std::string LOGGING_TAG; 120 mutable std::mutex id_allocator_mutex_; 121 122 LruCache<RawAddress, int> paired_device_cache_; 123 LruCache<RawAddress, 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 RawAddress& mac_address, const int id); 132 133 // delete copy constructor for singleton 134 MetricIdAllocator(MetricIdAllocator const&) = delete; 135 MetricIdAllocator& operator=(MetricIdAllocator const&) = delete; 136 }; 137 138 } // namespace common 139 } // namespace bluetooth 140