Loading system/btif/src/btif_config.cc +68 −0 Original line number Diff line number Diff line Loading @@ -29,9 +29,11 @@ #include <string.h> #include <time.h> #include <unistd.h> #include <functional> #include <mutex> #include <sstream> #include <string> #include <unordered_map> #include "bt_types.h" #include "btcore/include/module.h" Loading @@ -41,6 +43,7 @@ //#include "btif_keystore.h" #include "btif_util.h" #include "common/address_obfuscator.h" #include "common/metric_id_allocator.h" #include "main/shim/config.h" #include "main/shim/shim.h" #include "osi/include/alarm.h" Loading @@ -50,6 +53,7 @@ #include "osi/include/log.h" #include "osi/include/osi.h" #include "osi/include/properties.h" #include "raw_address.h" #define BT_CONFIG_SOURCE_TAG_NUM 1010001 Loading @@ -68,8 +72,11 @@ static const char* TIME_STRING_FORMAT = "%Y-%m-%d %H:%M:%S"; #define BT_CONFIG_METRICS_SECTION "Metrics" #define BT_CONFIG_METRICS_SALT_256BIT "Salt256Bit" #define BT_CONFIG_METRICS_ID_KEY "MetricsId" // using bluetooth::BtifKeystore; using bluetooth::common::AddressObfuscator; using bluetooth::common::MetricIdAllocator; // TODO(armansito): Find a better way than searching by a hardcoded path. #if defined(OS_GENERIC) Loading Loading @@ -191,6 +198,63 @@ static void read_or_set_metrics_salt() { AddressObfuscator::GetInstance()->Initialize(metrics_salt); } /** * Initialize metric id allocator by reading metric_id from config by mac * address. If there is no metric id for a mac address, then allocate it a new * metric id. */ static void init_metric_id_allocator() { std::unordered_map<RawAddress, int> paired_device_map; // When user update the system, there will be devices paired with older // version of android without a metric id. std::vector<RawAddress> addresses_without_id; for (auto& section : btif_config_sections()) { auto& section_name = section.name; RawAddress mac_address; if (!RawAddress::FromString(section_name, mac_address)) { continue; } // if the section name is a mac address bool is_valid_id_found = false; if (btif_config_exist(section_name, BT_CONFIG_METRICS_ID_KEY)) { // there is one metric id under this mac_address int id = 0; btif_config_get_int(section_name, BT_CONFIG_METRICS_ID_KEY, &id); if (MetricIdAllocator::IsValidId(id)) { paired_device_map[mac_address] = id; is_valid_id_found = true; } } if (!is_valid_id_found) { addresses_without_id.push_back(mac_address); } } // Initialize MetricIdAllocator MetricIdAllocator::Callback save_device_callback = [](const RawAddress& address, const int id) { return btif_config_set_int(address.ToString(), BT_CONFIG_METRICS_ID_KEY, id); }; MetricIdAllocator::Callback forget_device_callback = [](const RawAddress& address, const int id) { return btif_config_remove(address.ToString(), BT_CONFIG_METRICS_ID_KEY); }; if (!MetricIdAllocator::GetInstance().Init( paired_device_map, std::move(save_device_callback), std::move(forget_device_callback))) { LOG(FATAL) << __func__ << "Failed to initialize MetricIdAllocator"; } // Add device_without_id for (auto& address : addresses_without_id) { MetricIdAllocator::GetInstance().AllocateId(address); MetricIdAllocator::GetInstance().SaveDevice(address); } } static std::recursive_mutex config_lock; // protects operations on |config|. static std::unique_ptr<config_t> config; static alarm_t* config_timer; Loading Loading @@ -262,6 +326,9 @@ static future_t* init(void) { // Read or set metrics 256 bit hashing salt read_or_set_metrics_salt(); // Initialize MetricIdAllocator init_metric_id_allocator(); // TODO(sharvil): use a non-wake alarm for this once we have // API support for it. There's no need to wake the system to // write back to disk. Loading Loading @@ -326,6 +393,7 @@ static future_t* clean_up(void) { config_timer = NULL; std::unique_lock<std::recursive_mutex> lock(config_lock); MetricIdAllocator::GetInstance().Close(); config.reset(); return future_new_immediate(FUTURE_SUCCESS); } Loading system/btif/src/btif_dm.cc +20 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ #include "btif_storage.h" #include "btif_util.h" #include "btu.h" #include "common/metric_id_allocator.h" #include "common/metrics.h" #include "device/include/controller.h" #include "device/include/interop.h" Loading @@ -74,6 +75,7 @@ #include "stack_config.h" using bluetooth::Uuid; using bluetooth::common::MetricIdAllocator; /****************************************************************************** * Constants & Macros *****************************************************************************/ Loading Loading @@ -293,6 +295,15 @@ static void btif_dm_data_free(uint16_t event, tBTA_DM_SEC* dm_sec) { static void btif_dm_send_bond_state_changed(RawAddress address, bt_bond_state_t bond_state) { do_in_jni_thread(FROM_HERE, base::BindOnce([](RawAddress address, bt_bond_state_t bond_state) { btif_stats_add_bond_event(address, BTIF_DM_FUNC_BOND_STATE_CHANGED, bond_state); if (bond_state == BT_BOND_STATE_NONE) { MetricIdAllocator::GetInstance().ForgetDevice(address); } else if (bond_state == BT_BOND_STATE_BONDED) { MetricIdAllocator::GetInstance().AllocateId(address); if (!MetricIdAllocator::GetInstance().SaveDevice(address)) { LOG(FATAL) << __func__ << ": Fail to save metric id for device " << address; } } HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, BT_STATUS_SUCCESS, &address, bond_state); }, address, bond_state)); } Loading Loading @@ -545,6 +556,15 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr, BTIF_TRACE_DEBUG("%s: state=%d, prev_state=%d, sdp_attempts = %d", __func__, state, pairing_cb.state, pairing_cb.sdp_attempts); if (state == BT_BOND_STATE_NONE) { MetricIdAllocator::GetInstance().ForgetDevice(bd_addr); } else if (state == BT_BOND_STATE_BONDED) { MetricIdAllocator::GetInstance().AllocateId(bd_addr); if (!MetricIdAllocator::GetInstance().SaveDevice(bd_addr)) { LOG(FATAL) << __func__ << ": Fail to save metric id for device " << bd_addr; } } auto tmp = bd_addr; HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, &tmp, state); Loading system/common/metric_id_allocator.cc +18 −11 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ namespace common { const std::string MetricIdAllocator::LOGGING_TAG = "BluetoothMetricIdAllocator"; const size_t MetricIdAllocator::kMaxNumUnpairedDevicesInMemory = 200; const size_t MetricIdAllocator::kMaxNumPairedDevicesInMemory = 400; const size_t MetricIdAllocator::kMaxNumPairedDevicesInMemory = 65000; const int MetricIdAllocator::kMinId = 1; const int MetricIdAllocator::kMaxId = 65534; // 2^16 - 2 Loading @@ -43,13 +43,12 @@ static_assert((MetricIdAllocator::kMaxNumUnpairedDevicesInMemory + MetricIdAllocator::MetricIdAllocator() : paired_device_cache_(kMaxNumPairedDevicesInMemory, LOGGING_TAG, [this](RawAddress dummy, int to_remove) { this->id_set_.erase(to_remove); [this](RawAddress mac_address, int id) { ForgetDevicePostprocess(mac_address, id); }), temporary_device_cache_(kMaxNumUnpairedDevicesInMemory, LOGGING_TAG, [this](RawAddress dummy, int to_remove) { this->id_set_.erase(to_remove); }) {} temporary_device_cache_( kMaxNumUnpairedDevicesInMemory, LOGGING_TAG, [this](RawAddress dummy, int id) { this->id_set_.erase(id); }) {} bool MetricIdAllocator::Init( const std::unordered_map<RawAddress, int>& paired_device_map, Loading Loading @@ -157,16 +156,24 @@ bool MetricIdAllocator::SaveDevice(const RawAddress& mac_address) { } // call this function when a device is forgotten bool MetricIdAllocator::ForgetDevice(const RawAddress& mac_address) { void MetricIdAllocator::ForgetDevice(const RawAddress& mac_address) { std::lock_guard<std::mutex> lock(id_allocator_mutex_); int id = 0; bool success = paired_device_cache_.Get(mac_address, &id); success &= paired_device_cache_.Remove(mac_address); if (success) { id_set_.erase(id); success = forget_device_callback_(mac_address, id); ForgetDevicePostprocess(mac_address, id); } return success; } bool MetricIdAllocator::IsValidId(const int id) { return id >= kMinId && id <= kMaxId; } void MetricIdAllocator::ForgetDevicePostprocess(const RawAddress& mac_address, const int id) { id_set_.erase(id); forget_device_callback_(mac_address, id); } } // namespace common Loading system/common/metric_id_allocator.h +12 −1 Original line number Diff line number Diff line Loading @@ -98,9 +98,18 @@ class MetricIdAllocator { * Delete the id for a device to be forgotten * * @param mac_address mac address of Bluetooth device */ void ForgetDevice(const RawAddress& 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 */ bool ForgetDevice(const RawAddress& mac_address); static bool IsValidId(const int id); protected: // Singleton Loading @@ -119,6 +128,8 @@ class MetricIdAllocator { Callback save_id_callback_; Callback forget_device_callback_; void ForgetDevicePostprocess(const RawAddress& mac_address, const int id); // delete copy constructor for singleton MetricIdAllocator(MetricIdAllocator const&) = delete; MetricIdAllocator& operator=(MetricIdAllocator const&) = delete; Loading system/common/metric_id_allocator_unittest.cc +31 −28 Original line number Diff line number Diff line Loading @@ -170,9 +170,9 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorMainTest1) { EXPECT_EQ(dummy, 176); // forget EXPECT_FALSE(allocator.ForgetDevice(RawAddress({0, 0, 0, 0, 0, 1}))); allocator.ForgetDevice(RawAddress({0, 0, 0, 0, 0, 1})); EXPECT_EQ(dummy, 176); EXPECT_TRUE(allocator.ForgetDevice(RawAddress({0, 0, 0, 0, 0, 2}))); allocator.ForgetDevice(RawAddress({0, 0, 0, 0, 0, 2})); EXPECT_EQ(dummy, 88); EXPECT_TRUE(allocator.Close()); Loading @@ -183,7 +183,7 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { // preset a full map std::unordered_map<RawAddress, int> paired_device_map = generateAddresses(MetricIdAllocator::kMaxNumPairedDevicesInMemory); int dummy = 22; int dummy = 243; int* pointer = &dummy; MetricIdAllocator::Callback save_callback = [pointer](const RawAddress&, const int) { Loading @@ -192,7 +192,7 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { }; MetricIdAllocator::Callback forget_callback = [pointer](const RawAddress&, const int) { *pointer = *pointer / 2; *pointer = *pointer / 3; return true; }; Loading Loading @@ -222,7 +222,8 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { // save it and make sure the callback is called EXPECT_TRUE(allocator.SaveDevice(kthAddress(key))); EXPECT_EQ(dummy, 44); EXPECT_EQ(dummy, 162); // one key is evicted, another key is saved so *2/3 // paired: 1, 2 ... 199, 200, // scanned: Loading @@ -233,13 +234,13 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { // key == 200 // should fail, since id of device is not allocated EXPECT_FALSE(allocator.SaveDevice(kthAddress(key + 1))); EXPECT_EQ(dummy, 44); EXPECT_EQ(dummy, 162); // paired: 1, 2 ... 199, 200, // scanned: 0 EXPECT_EQ(allocator.AllocateId(kthAddress(key + 1)), id++); EXPECT_TRUE(allocator.SaveDevice(kthAddress(key + 1))); EXPECT_EQ(dummy, 88); EXPECT_EQ(dummy, 108); // one key is evicted, another key is saved so *2/3, // paired: 2 ... 199, 200, 201 // scanned: 0 Loading @@ -253,23 +254,24 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { // paired: 2 ... 199, 200, 201, // scanned: 0, 1, 202, 203 dummy = 44; dummy = 9; EXPECT_TRUE(allocator.SaveDevice(kthAddress(key + 2))); EXPECT_EQ(dummy, 88); EXPECT_EQ(dummy, 6); // one key is evicted, another key is saved so *2/3, EXPECT_TRUE(allocator.SaveDevice(kthAddress(key + 3))); EXPECT_EQ(dummy, 176); EXPECT_EQ(dummy, 4); // one key is evicted, another key is saved so *2/3, // paired: 4 ... 199, 200, 201, 202, 203 // scanned: 0, 1 // should fail, since id had been saved EXPECT_FALSE(allocator.SaveDevice(kthAddress(key + 2))); EXPECT_EQ(dummy, 176); EXPECT_EQ(dummy, 4); dummy = 27; // forget EXPECT_FALSE(allocator.ForgetDevice(kthAddress(key + 200))); EXPECT_EQ(dummy, 176); EXPECT_TRUE(allocator.ForgetDevice(kthAddress(key + 2))); EXPECT_EQ(dummy, 88); allocator.ForgetDevice(kthAddress(key + 200)); EXPECT_EQ(dummy, 27); // should fail, no such a key allocator.ForgetDevice(kthAddress(key + 2)); EXPECT_EQ(dummy, 9); // paired: 4 ... 199, 200, 201, 203 // scanned: 0, 1 Loading @@ -281,25 +283,25 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { // scanned: 0, 1, 202, 204, 205 EXPECT_TRUE(allocator.SaveDevice(kthAddress(key + 2))); EXPECT_EQ(dummy, 176); EXPECT_EQ(dummy, 18); // no key is evicted, a key is saved so *2, EXPECT_FALSE(allocator.SaveDevice(kthAddress(key + 3))); EXPECT_EQ(dummy, 176); EXPECT_EQ(dummy, 18); // no such a key in scanned EXPECT_TRUE(allocator.SaveDevice(kthAddress(key + 4))); EXPECT_EQ(dummy, 352); // paired: 6 ... 199, 200, 201, 203, 202, 204 EXPECT_EQ(dummy, 12); // one key is evicted, another key is saved so *2/3, // paired: 5 6 ... 199, 200, 201, 203, 202, 204 // scanned: 0, 1, 205 // verify paired: for (key = 6; key <= 199; key++) { dummy = 10; EXPECT_TRUE(allocator.ForgetDevice(kthAddress(key))); EXPECT_EQ(dummy, 5); for (key = 5; key <= 199; key++) { dummy = 3; allocator.ForgetDevice(kthAddress(key)); EXPECT_EQ(dummy, 1); } for (size_t k = MetricIdAllocator::kMaxNumPairedDevicesInMemory; k <= MetricIdAllocator::kMaxNumPairedDevicesInMemory + 4; k++) { dummy = 10; EXPECT_TRUE(allocator.ForgetDevice(kthAddress(k))); EXPECT_EQ(dummy, 5); dummy = 3; allocator.ForgetDevice(kthAddress(k)); EXPECT_EQ(dummy, 1); } // verify scanned Loading Loading @@ -397,14 +399,15 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorMultiThreadPressureTest) { // make sure no deadlock std::vector<std::thread> workers; for (int key = 0; key < static_cast<int>(MetricIdAllocator::kMaxNumPairedDevicesInMemory); key < static_cast<int>(MetricIdAllocator::kMaxNumUnpairedDevicesInMemory); key++) { workers.push_back(std::thread([key]() { auto& allocator = MetricIdAllocator::GetInstance(); RawAddress fake_mac_address = kthAddress(key); allocator.AllocateId(fake_mac_address); EXPECT_TRUE(allocator.SaveDevice(fake_mac_address)); EXPECT_TRUE(allocator.ForgetDevice(fake_mac_address)); allocator.ForgetDevice(fake_mac_address); })); } for (auto& worker : workers) { Loading Loading
system/btif/src/btif_config.cc +68 −0 Original line number Diff line number Diff line Loading @@ -29,9 +29,11 @@ #include <string.h> #include <time.h> #include <unistd.h> #include <functional> #include <mutex> #include <sstream> #include <string> #include <unordered_map> #include "bt_types.h" #include "btcore/include/module.h" Loading @@ -41,6 +43,7 @@ //#include "btif_keystore.h" #include "btif_util.h" #include "common/address_obfuscator.h" #include "common/metric_id_allocator.h" #include "main/shim/config.h" #include "main/shim/shim.h" #include "osi/include/alarm.h" Loading @@ -50,6 +53,7 @@ #include "osi/include/log.h" #include "osi/include/osi.h" #include "osi/include/properties.h" #include "raw_address.h" #define BT_CONFIG_SOURCE_TAG_NUM 1010001 Loading @@ -68,8 +72,11 @@ static const char* TIME_STRING_FORMAT = "%Y-%m-%d %H:%M:%S"; #define BT_CONFIG_METRICS_SECTION "Metrics" #define BT_CONFIG_METRICS_SALT_256BIT "Salt256Bit" #define BT_CONFIG_METRICS_ID_KEY "MetricsId" // using bluetooth::BtifKeystore; using bluetooth::common::AddressObfuscator; using bluetooth::common::MetricIdAllocator; // TODO(armansito): Find a better way than searching by a hardcoded path. #if defined(OS_GENERIC) Loading Loading @@ -191,6 +198,63 @@ static void read_or_set_metrics_salt() { AddressObfuscator::GetInstance()->Initialize(metrics_salt); } /** * Initialize metric id allocator by reading metric_id from config by mac * address. If there is no metric id for a mac address, then allocate it a new * metric id. */ static void init_metric_id_allocator() { std::unordered_map<RawAddress, int> paired_device_map; // When user update the system, there will be devices paired with older // version of android without a metric id. std::vector<RawAddress> addresses_without_id; for (auto& section : btif_config_sections()) { auto& section_name = section.name; RawAddress mac_address; if (!RawAddress::FromString(section_name, mac_address)) { continue; } // if the section name is a mac address bool is_valid_id_found = false; if (btif_config_exist(section_name, BT_CONFIG_METRICS_ID_KEY)) { // there is one metric id under this mac_address int id = 0; btif_config_get_int(section_name, BT_CONFIG_METRICS_ID_KEY, &id); if (MetricIdAllocator::IsValidId(id)) { paired_device_map[mac_address] = id; is_valid_id_found = true; } } if (!is_valid_id_found) { addresses_without_id.push_back(mac_address); } } // Initialize MetricIdAllocator MetricIdAllocator::Callback save_device_callback = [](const RawAddress& address, const int id) { return btif_config_set_int(address.ToString(), BT_CONFIG_METRICS_ID_KEY, id); }; MetricIdAllocator::Callback forget_device_callback = [](const RawAddress& address, const int id) { return btif_config_remove(address.ToString(), BT_CONFIG_METRICS_ID_KEY); }; if (!MetricIdAllocator::GetInstance().Init( paired_device_map, std::move(save_device_callback), std::move(forget_device_callback))) { LOG(FATAL) << __func__ << "Failed to initialize MetricIdAllocator"; } // Add device_without_id for (auto& address : addresses_without_id) { MetricIdAllocator::GetInstance().AllocateId(address); MetricIdAllocator::GetInstance().SaveDevice(address); } } static std::recursive_mutex config_lock; // protects operations on |config|. static std::unique_ptr<config_t> config; static alarm_t* config_timer; Loading Loading @@ -262,6 +326,9 @@ static future_t* init(void) { // Read or set metrics 256 bit hashing salt read_or_set_metrics_salt(); // Initialize MetricIdAllocator init_metric_id_allocator(); // TODO(sharvil): use a non-wake alarm for this once we have // API support for it. There's no need to wake the system to // write back to disk. Loading Loading @@ -326,6 +393,7 @@ static future_t* clean_up(void) { config_timer = NULL; std::unique_lock<std::recursive_mutex> lock(config_lock); MetricIdAllocator::GetInstance().Close(); config.reset(); return future_new_immediate(FUTURE_SUCCESS); } Loading
system/btif/src/btif_dm.cc +20 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ #include "btif_storage.h" #include "btif_util.h" #include "btu.h" #include "common/metric_id_allocator.h" #include "common/metrics.h" #include "device/include/controller.h" #include "device/include/interop.h" Loading @@ -74,6 +75,7 @@ #include "stack_config.h" using bluetooth::Uuid; using bluetooth::common::MetricIdAllocator; /****************************************************************************** * Constants & Macros *****************************************************************************/ Loading Loading @@ -293,6 +295,15 @@ static void btif_dm_data_free(uint16_t event, tBTA_DM_SEC* dm_sec) { static void btif_dm_send_bond_state_changed(RawAddress address, bt_bond_state_t bond_state) { do_in_jni_thread(FROM_HERE, base::BindOnce([](RawAddress address, bt_bond_state_t bond_state) { btif_stats_add_bond_event(address, BTIF_DM_FUNC_BOND_STATE_CHANGED, bond_state); if (bond_state == BT_BOND_STATE_NONE) { MetricIdAllocator::GetInstance().ForgetDevice(address); } else if (bond_state == BT_BOND_STATE_BONDED) { MetricIdAllocator::GetInstance().AllocateId(address); if (!MetricIdAllocator::GetInstance().SaveDevice(address)) { LOG(FATAL) << __func__ << ": Fail to save metric id for device " << address; } } HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, BT_STATUS_SUCCESS, &address, bond_state); }, address, bond_state)); } Loading Loading @@ -545,6 +556,15 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr, BTIF_TRACE_DEBUG("%s: state=%d, prev_state=%d, sdp_attempts = %d", __func__, state, pairing_cb.state, pairing_cb.sdp_attempts); if (state == BT_BOND_STATE_NONE) { MetricIdAllocator::GetInstance().ForgetDevice(bd_addr); } else if (state == BT_BOND_STATE_BONDED) { MetricIdAllocator::GetInstance().AllocateId(bd_addr); if (!MetricIdAllocator::GetInstance().SaveDevice(bd_addr)) { LOG(FATAL) << __func__ << ": Fail to save metric id for device " << bd_addr; } } auto tmp = bd_addr; HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, &tmp, state); Loading
system/common/metric_id_allocator.cc +18 −11 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ namespace common { const std::string MetricIdAllocator::LOGGING_TAG = "BluetoothMetricIdAllocator"; const size_t MetricIdAllocator::kMaxNumUnpairedDevicesInMemory = 200; const size_t MetricIdAllocator::kMaxNumPairedDevicesInMemory = 400; const size_t MetricIdAllocator::kMaxNumPairedDevicesInMemory = 65000; const int MetricIdAllocator::kMinId = 1; const int MetricIdAllocator::kMaxId = 65534; // 2^16 - 2 Loading @@ -43,13 +43,12 @@ static_assert((MetricIdAllocator::kMaxNumUnpairedDevicesInMemory + MetricIdAllocator::MetricIdAllocator() : paired_device_cache_(kMaxNumPairedDevicesInMemory, LOGGING_TAG, [this](RawAddress dummy, int to_remove) { this->id_set_.erase(to_remove); [this](RawAddress mac_address, int id) { ForgetDevicePostprocess(mac_address, id); }), temporary_device_cache_(kMaxNumUnpairedDevicesInMemory, LOGGING_TAG, [this](RawAddress dummy, int to_remove) { this->id_set_.erase(to_remove); }) {} temporary_device_cache_( kMaxNumUnpairedDevicesInMemory, LOGGING_TAG, [this](RawAddress dummy, int id) { this->id_set_.erase(id); }) {} bool MetricIdAllocator::Init( const std::unordered_map<RawAddress, int>& paired_device_map, Loading Loading @@ -157,16 +156,24 @@ bool MetricIdAllocator::SaveDevice(const RawAddress& mac_address) { } // call this function when a device is forgotten bool MetricIdAllocator::ForgetDevice(const RawAddress& mac_address) { void MetricIdAllocator::ForgetDevice(const RawAddress& mac_address) { std::lock_guard<std::mutex> lock(id_allocator_mutex_); int id = 0; bool success = paired_device_cache_.Get(mac_address, &id); success &= paired_device_cache_.Remove(mac_address); if (success) { id_set_.erase(id); success = forget_device_callback_(mac_address, id); ForgetDevicePostprocess(mac_address, id); } return success; } bool MetricIdAllocator::IsValidId(const int id) { return id >= kMinId && id <= kMaxId; } void MetricIdAllocator::ForgetDevicePostprocess(const RawAddress& mac_address, const int id) { id_set_.erase(id); forget_device_callback_(mac_address, id); } } // namespace common Loading
system/common/metric_id_allocator.h +12 −1 Original line number Diff line number Diff line Loading @@ -98,9 +98,18 @@ class MetricIdAllocator { * Delete the id for a device to be forgotten * * @param mac_address mac address of Bluetooth device */ void ForgetDevice(const RawAddress& 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 */ bool ForgetDevice(const RawAddress& mac_address); static bool IsValidId(const int id); protected: // Singleton Loading @@ -119,6 +128,8 @@ class MetricIdAllocator { Callback save_id_callback_; Callback forget_device_callback_; void ForgetDevicePostprocess(const RawAddress& mac_address, const int id); // delete copy constructor for singleton MetricIdAllocator(MetricIdAllocator const&) = delete; MetricIdAllocator& operator=(MetricIdAllocator const&) = delete; Loading
system/common/metric_id_allocator_unittest.cc +31 −28 Original line number Diff line number Diff line Loading @@ -170,9 +170,9 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorMainTest1) { EXPECT_EQ(dummy, 176); // forget EXPECT_FALSE(allocator.ForgetDevice(RawAddress({0, 0, 0, 0, 0, 1}))); allocator.ForgetDevice(RawAddress({0, 0, 0, 0, 0, 1})); EXPECT_EQ(dummy, 176); EXPECT_TRUE(allocator.ForgetDevice(RawAddress({0, 0, 0, 0, 0, 2}))); allocator.ForgetDevice(RawAddress({0, 0, 0, 0, 0, 2})); EXPECT_EQ(dummy, 88); EXPECT_TRUE(allocator.Close()); Loading @@ -183,7 +183,7 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { // preset a full map std::unordered_map<RawAddress, int> paired_device_map = generateAddresses(MetricIdAllocator::kMaxNumPairedDevicesInMemory); int dummy = 22; int dummy = 243; int* pointer = &dummy; MetricIdAllocator::Callback save_callback = [pointer](const RawAddress&, const int) { Loading @@ -192,7 +192,7 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { }; MetricIdAllocator::Callback forget_callback = [pointer](const RawAddress&, const int) { *pointer = *pointer / 2; *pointer = *pointer / 3; return true; }; Loading Loading @@ -222,7 +222,8 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { // save it and make sure the callback is called EXPECT_TRUE(allocator.SaveDevice(kthAddress(key))); EXPECT_EQ(dummy, 44); EXPECT_EQ(dummy, 162); // one key is evicted, another key is saved so *2/3 // paired: 1, 2 ... 199, 200, // scanned: Loading @@ -233,13 +234,13 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { // key == 200 // should fail, since id of device is not allocated EXPECT_FALSE(allocator.SaveDevice(kthAddress(key + 1))); EXPECT_EQ(dummy, 44); EXPECT_EQ(dummy, 162); // paired: 1, 2 ... 199, 200, // scanned: 0 EXPECT_EQ(allocator.AllocateId(kthAddress(key + 1)), id++); EXPECT_TRUE(allocator.SaveDevice(kthAddress(key + 1))); EXPECT_EQ(dummy, 88); EXPECT_EQ(dummy, 108); // one key is evicted, another key is saved so *2/3, // paired: 2 ... 199, 200, 201 // scanned: 0 Loading @@ -253,23 +254,24 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { // paired: 2 ... 199, 200, 201, // scanned: 0, 1, 202, 203 dummy = 44; dummy = 9; EXPECT_TRUE(allocator.SaveDevice(kthAddress(key + 2))); EXPECT_EQ(dummy, 88); EXPECT_EQ(dummy, 6); // one key is evicted, another key is saved so *2/3, EXPECT_TRUE(allocator.SaveDevice(kthAddress(key + 3))); EXPECT_EQ(dummy, 176); EXPECT_EQ(dummy, 4); // one key is evicted, another key is saved so *2/3, // paired: 4 ... 199, 200, 201, 202, 203 // scanned: 0, 1 // should fail, since id had been saved EXPECT_FALSE(allocator.SaveDevice(kthAddress(key + 2))); EXPECT_EQ(dummy, 176); EXPECT_EQ(dummy, 4); dummy = 27; // forget EXPECT_FALSE(allocator.ForgetDevice(kthAddress(key + 200))); EXPECT_EQ(dummy, 176); EXPECT_TRUE(allocator.ForgetDevice(kthAddress(key + 2))); EXPECT_EQ(dummy, 88); allocator.ForgetDevice(kthAddress(key + 200)); EXPECT_EQ(dummy, 27); // should fail, no such a key allocator.ForgetDevice(kthAddress(key + 2)); EXPECT_EQ(dummy, 9); // paired: 4 ... 199, 200, 201, 203 // scanned: 0, 1 Loading @@ -281,25 +283,25 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { // scanned: 0, 1, 202, 204, 205 EXPECT_TRUE(allocator.SaveDevice(kthAddress(key + 2))); EXPECT_EQ(dummy, 176); EXPECT_EQ(dummy, 18); // no key is evicted, a key is saved so *2, EXPECT_FALSE(allocator.SaveDevice(kthAddress(key + 3))); EXPECT_EQ(dummy, 176); EXPECT_EQ(dummy, 18); // no such a key in scanned EXPECT_TRUE(allocator.SaveDevice(kthAddress(key + 4))); EXPECT_EQ(dummy, 352); // paired: 6 ... 199, 200, 201, 203, 202, 204 EXPECT_EQ(dummy, 12); // one key is evicted, another key is saved so *2/3, // paired: 5 6 ... 199, 200, 201, 203, 202, 204 // scanned: 0, 1, 205 // verify paired: for (key = 6; key <= 199; key++) { dummy = 10; EXPECT_TRUE(allocator.ForgetDevice(kthAddress(key))); EXPECT_EQ(dummy, 5); for (key = 5; key <= 199; key++) { dummy = 3; allocator.ForgetDevice(kthAddress(key)); EXPECT_EQ(dummy, 1); } for (size_t k = MetricIdAllocator::kMaxNumPairedDevicesInMemory; k <= MetricIdAllocator::kMaxNumPairedDevicesInMemory + 4; k++) { dummy = 10; EXPECT_TRUE(allocator.ForgetDevice(kthAddress(k))); EXPECT_EQ(dummy, 5); dummy = 3; allocator.ForgetDevice(kthAddress(k)); EXPECT_EQ(dummy, 1); } // verify scanned Loading Loading @@ -397,14 +399,15 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorMultiThreadPressureTest) { // make sure no deadlock std::vector<std::thread> workers; for (int key = 0; key < static_cast<int>(MetricIdAllocator::kMaxNumPairedDevicesInMemory); key < static_cast<int>(MetricIdAllocator::kMaxNumUnpairedDevicesInMemory); key++) { workers.push_back(std::thread([key]() { auto& allocator = MetricIdAllocator::GetInstance(); RawAddress fake_mac_address = kthAddress(key); allocator.AllocateId(fake_mac_address); EXPECT_TRUE(allocator.SaveDevice(fake_mac_address)); EXPECT_TRUE(allocator.ForgetDevice(fake_mac_address)); allocator.ForgetDevice(fake_mac_address); })); } for (auto& worker : workers) { Loading