From: Chen Chen Date: Sat, 14 Mar 2020 00:00:24 +0000 (-0700) Subject: Bluetooth Metrics: Init and Close MetricIdAllocator and use its APIs X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=4c23956486;p=android-x86%2Fsystem-bt.git Bluetooth Metrics: Init and Close MetricIdAllocator and use its APIs Test: Manually pair device and cat config file Bug: 142563377 Change-Id: I4492dc9b4c9d810e7919e97ef36ea151b76b2dbc Merged-In: I4492dc9b4c9d810e7919e97ef36ea151b76b2dbc (cherry picked from commit f6a356ead8e711e3b94e0e915a5b94cfac978ffa) --- diff --git a/btif/src/btif_config.cc b/btif/src/btif_config.cc index 80127451e..d0f36cc27 100644 --- a/btif/src/btif_config.cc +++ b/btif/src/btif_config.cc @@ -29,9 +29,11 @@ #include #include #include +#include #include #include #include +#include #include "bt_types.h" #include "btcore/include/module.h" @@ -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" @@ -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 @@ -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) @@ -192,6 +199,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 paired_device_map; + + // When user update the system, there will be devices paired with older + // version of android without a metric id. + std::vector 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; static alarm_t* config_timer; @@ -265,6 +329,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. @@ -329,6 +396,7 @@ static future_t* clean_up(void) { config_timer = NULL; std::unique_lock lock(config_lock); + MetricIdAllocator::GetInstance().Close(); config.reset(); return future_new_immediate(FUTURE_SUCCESS); } diff --git a/btif/src/btif_dm.cc b/btif/src/btif_dm.cc index 59954ada8..f2fcee86b 100644 --- a/btif/src/btif_dm.cc +++ b/btif/src/btif_dm.cc @@ -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" @@ -72,6 +73,7 @@ #include "stack_config.h" using bluetooth::Uuid; +using bluetooth::common::MetricIdAllocator; /****************************************************************************** * Constants & Macros *****************************************************************************/ @@ -505,6 +507,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); diff --git a/common/metric_id_allocator.cc b/common/metric_id_allocator.cc index 92a582250..652803b28 100644 --- a/common/metric_id_allocator.cc +++ b/common/metric_id_allocator.cc @@ -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 @@ -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& paired_device_map, @@ -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 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 diff --git a/common/metric_id_allocator.h b/common/metric_id_allocator.h index bbef02e67..63236e49b 100644 --- a/common/metric_id_allocator.h +++ b/common/metric_id_allocator.h @@ -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 @@ -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; diff --git a/common/metric_id_allocator_unittest.cc b/common/metric_id_allocator_unittest.cc index 416b671ef..eae2ffee8 100644 --- a/common/metric_id_allocator_unittest.cc +++ b/common/metric_id_allocator_unittest.cc @@ -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()); @@ -183,7 +183,7 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { // preset a full map std::unordered_map paired_device_map = generateAddresses(MetricIdAllocator::kMaxNumPairedDevicesInMemory); - int dummy = 22; + int dummy = 243; int* pointer = &dummy; MetricIdAllocator::Callback save_callback = [pointer](const RawAddress&, const int) { @@ -192,7 +192,7 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorFullPairedMap) { }; MetricIdAllocator::Callback forget_callback = [pointer](const RawAddress&, const int) { - *pointer = *pointer / 2; + *pointer = *pointer / 3; return true; }; @@ -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: @@ -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 @@ -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 @@ -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 @@ -397,14 +399,15 @@ TEST(BluetoothMetricIdAllocatorTest, MetricIdAllocatorMultiThreadPressureTest) { // make sure no deadlock std::vector workers; for (int key = 0; - key < static_cast(MetricIdAllocator::kMaxNumPairedDevicesInMemory); + key < + static_cast(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) {