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