diff options
author | 2024-05-02 17:50:37 +0800 | |
---|---|---|
committer | 2024-05-09 08:55:40 +0800 | |
commit | 99ec7396f4d3cc06faa46fde825cb33c20b5840d (patch) | |
tree | c306f09bf9fb1d666ef249584f72882a38068837 | |
parent | ba2e67285bf8d6e30fc779ae82f4bca606241ca8 (diff) |
floss: Complete libflags shim
On Floss we store the aflags config inside sysprops module.
Bug: 307006275
Tag: #floss
Test: mmm packages/modules/Bluetooth
Test: atest --host bluetooth_test_gd_unit:ConfigCacheTest#test_get_section_property_names
Test: atest --host bluetooth_test_gd_unit:SyspropsModuleTest
Test: manual set/reset/remove persist.device_config.aconfig_flags.bluetooth.com.android.bluetooth.flags.msft_addr_tracking_quirk,
verified behavior changed
Flag: EXEMPT, Floss-only changes
Change-Id: I1d72b7e970d354a6b8c22e6e015d859bd1b48da7
-rw-r--r-- | floss/libflags/get_flags.cc | 6 | ||||
-rw-r--r-- | system/gd/Android.bp | 1 | ||||
-rw-r--r-- | system/gd/os/host/parameter_provider.cc | 9 | ||||
-rw-r--r-- | system/gd/storage/config_cache.cc | 26 | ||||
-rw-r--r-- | system/gd/storage/config_cache.h | 2 | ||||
-rw-r--r-- | system/gd/storage/config_cache_test.cc | 14 | ||||
-rw-r--r-- | system/gd/sysprops/Android.bp | 7 | ||||
-rw-r--r-- | system/gd/sysprops/sysprops_module.cc | 16 | ||||
-rw-r--r-- | system/gd/sysprops/sysprops_module.h | 4 | ||||
-rw-r--r-- | system/gd/sysprops/sysprops_module_test.cc | 114 |
10 files changed, 194 insertions, 5 deletions
diff --git a/floss/libflags/get_flags.cc b/floss/libflags/get_flags.cc index d7152e2edb..233662ac6d 100644 --- a/floss/libflags/get_flags.cc +++ b/floss/libflags/get_flags.cc @@ -16,11 +16,15 @@ #include "server_configurable_flags/get_flags.h" +#include "gd/os/system_properties.h" + namespace server_configurable_flags { std::string GetServerConfigurableFlag( const std::string& experiment_category_name, const std::string& experiment_flag_name, const std::string& default_value) { - return default_value; + std::string prop_name = "persist.device_config." + experiment_category_name + + "." + experiment_flag_name; + return bluetooth::os::GetSystemProperty(prop_name).value_or(default_value); } } // namespace server_configurable_flags diff --git a/system/gd/Android.bp b/system/gd/Android.bp index 7fa3a5c1fe..e902ee633b 100644 --- a/system/gd/Android.bp +++ b/system/gd/Android.bp @@ -429,6 +429,7 @@ cc_test { srcs: [ ":BluetoothHalTestSources_hci_host", ":BluetoothOsTestSources_host", + ":BluetoothSyspropsUnitTestSources", ], }, android: { diff --git a/system/gd/os/host/parameter_provider.cc b/system/gd/os/host/parameter_provider.cc index bd790f2e7b..61776c7d86 100644 --- a/system/gd/os/host/parameter_provider.cc +++ b/system/gd/os/host/parameter_provider.cc @@ -33,6 +33,7 @@ std::mutex parameter_mutex; std::string config_file_path; std::string snoop_log_file_path; std::string snooz_log_file_path; +std::string sysprops_file_path; } // namespace // Write to $PWD/bt_stack.conf if $PWD can be found, otherwise, write to $HOME/bt_stack.conf @@ -104,7 +105,13 @@ void ParameterProvider::OverrideSnoozLogFilePath(const std::string& path) { } std::string ParameterProvider::SyspropsFilePath() { - return ""; + std::lock_guard<std::mutex> lock(parameter_mutex); + return sysprops_file_path; +} + +void ParameterProvider::OverrideSyspropsFilePath(const std::string& path) { + std::lock_guard<std::mutex> lock(parameter_mutex); + sysprops_file_path = path; } bluetooth_keystore::BluetoothKeystoreInterface* ParameterProvider::GetBtKeystoreInterface() { diff --git a/system/gd/storage/config_cache.cc b/system/gd/storage/config_cache.cc index 359cebd6ac..df101720b2 100644 --- a/system/gd/storage/config_cache.cc +++ b/system/gd/storage/config_cache.cc @@ -418,6 +418,32 @@ std::vector<ConfigCache::SectionAndPropertyValue> ConfigCache::GetSectionNamesWi return result; } +std::vector<std::string> ConfigCache::GetPropertyNames(const std::string& section) const { + std::lock_guard<std::recursive_mutex> lock(mutex_); + + std::vector<std::string> property_names; + auto ProcessSections = [&](const auto& sections) { + auto section_iter = sections.find(section); + if (section_iter != sections.end()) { + for (const auto& [property_name, value] : section_iter->second) { + property_names.emplace_back(property_name); + } + return true; + } + return false; + }; + + // A section must exist in at most one map. + if (ProcessSections(information_sections_)) { + return property_names; + } + if (ProcessSections(persistent_devices_)) { + return property_names; + } + ProcessSections(temporary_devices_); + return property_names; +} + namespace { bool FixDeviceTypeInconsistencyInSection( diff --git a/system/gd/storage/config_cache.h b/system/gd/storage/config_cache.h index 44229e473d..9c9c5b1e6e 100644 --- a/system/gd/storage/config_cache.h +++ b/system/gd/storage/config_cache.h @@ -96,6 +96,8 @@ class ConfigCache { } }; virtual std::vector<SectionAndPropertyValue> GetSectionNamesWithProperty(const std::string& property) const; + // Returns all property names in the specific section. + virtual std::vector<std::string> GetPropertyNames(const std::string& section) const; // modifiers // Commit all mutation entries in sequence while holding the config mutex diff --git a/system/gd/storage/config_cache_test.cc b/system/gd/storage/config_cache_test.cc index d4fde9144a..13d0a90c74 100644 --- a/system/gd/storage/config_cache_test.cc +++ b/system/gd/storage/config_cache_test.cc @@ -442,4 +442,16 @@ TEST(ConfigCacheTest, test_empty_persistent_properties) { ASSERT_THAT(config.GetPersistentSections(), ElementsAre()); } -} // namespace testing
\ No newline at end of file +TEST(ConfigCacheTest, test_get_section_property_names) { + ConfigCache config(100, Device::kLinkKeyProperties); + config.SetProperty("A", "A", "A"); + config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "B"); + config.SetProperty("AA:BB:CC:DD:EE:EF", BTIF_STORAGE_KEY_LINK_KEY, "C"); + + ASSERT_THAT(config.GetPropertyNames("A"), ElementsAre("A")); + ASSERT_THAT(config.GetPropertyNames("AA:BB:CC:DD:EE:FF"), ElementsAre("B")); + ASSERT_THAT(config.GetPropertyNames("AA:BB:CC:DD:EE:EF"), ElementsAre(BTIF_STORAGE_KEY_LINK_KEY)); + ASSERT_THAT(config.GetPropertyNames("D"), ElementsAre()); +} + +} // namespace testing diff --git a/system/gd/sysprops/Android.bp b/system/gd/sysprops/Android.bp index bddede7f6e..98b9254bc4 100644 --- a/system/gd/sysprops/Android.bp +++ b/system/gd/sysprops/Android.bp @@ -13,3 +13,10 @@ filegroup { "sysprops_module.cc", ], } + +filegroup { + name: "BluetoothSyspropsUnitTestSources", + srcs: [ + "sysprops_module_test.cc", + ], +} diff --git a/system/gd/sysprops/sysprops_module.cc b/system/gd/sysprops/sysprops_module.cc index 4a822ba94f..3e52fdbd3d 100644 --- a/system/gd/sysprops/sysprops_module.cc +++ b/system/gd/sysprops/sysprops_module.cc @@ -28,6 +28,13 @@ namespace bluetooth { namespace sysprops { static const size_t kDefaultCapacity = 10000; +static const char* kAflagSection = "Aflags"; +static const char* kAflagPrefix = "persist.device_config.aconfig_flags.bluetooth."; + +SyspropsModule::SyspropsModule() {} +SyspropsModule::~SyspropsModule() { + pimpl_.reset(); +} const ModuleFactory SyspropsModule::Factory = ModuleFactory([]() { return new SyspropsModule(); }); @@ -127,6 +134,15 @@ void SyspropsModule::parse_config(std::string file_path) { bluetooth::os::SetSystemProperty(*s, *str); } } + + for (const auto& name : config->GetPropertyNames(kAflagSection)) { + if (name.find(kAflagPrefix) == 0) { + auto val = config->GetProperty(kAflagSection, name); + if (val) { + bluetooth::os::SetSystemProperty(name, *val); + } + } + } } } // namespace sysprops diff --git a/system/gd/sysprops/sysprops_module.h b/system/gd/sysprops/sysprops_module.h index c7a72191cd..3cdb0bbcd4 100644 --- a/system/gd/sysprops/sysprops_module.h +++ b/system/gd/sysprops/sysprops_module.h @@ -22,11 +22,11 @@ namespace sysprops { class SyspropsModule : public bluetooth::Module { public: - SyspropsModule() = default; + SyspropsModule(); SyspropsModule(const SyspropsModule&) = delete; SyspropsModule& operator=(const SyspropsModule&) = delete; - ~SyspropsModule() = default; + ~SyspropsModule(); static const ModuleFactory Factory; diff --git a/system/gd/sysprops/sysprops_module_test.cc b/system/gd/sysprops/sysprops_module_test.cc new file mode 100644 index 0000000000..545780dcfe --- /dev/null +++ b/system/gd/sysprops/sysprops_module_test.cc @@ -0,0 +1,114 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * 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. + */ + +#include "sysprops/sysprops_module.h" + +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +#include <filesystem> + +#include "os/files.h" +#include "os/parameter_provider.h" +#include "os/system_properties.h" + +namespace testing { + +class SyspropsModuleTest : public Test { + protected: + void SetUp() override { + EXPECT_TRUE(bluetooth::os::ClearSystemPropertiesForHost()); + temp_config_ = std::filesystem::temp_directory_path() / "temp_sysprops.conf"; + temp_override_dir_ = temp_config_ / ".d"; + DeleteConfigFiles(); + bluetooth::os::ParameterProvider::OverrideSyspropsFilePath(temp_config_); + } + + void TearDown() override { + EXPECT_TRUE(bluetooth::os::ClearSystemPropertiesForHost()); + test_registry_.StopAll(); + DeleteConfigFiles(); + } + + void DeleteConfigFiles() { + if (std::filesystem::exists(temp_config_)) { + EXPECT_TRUE(std::filesystem::remove(temp_config_)); + } + if (std::filesystem::exists(temp_override_dir_)) { + EXPECT_GT(std::filesystem::remove_all(temp_override_dir_), 0u); + EXPECT_FALSE(std::filesystem::exists(temp_override_dir_)); + } + } + + bluetooth::TestModuleRegistry test_registry_; + std::filesystem::path temp_config_; + std::filesystem::path temp_override_dir_; +}; + +static const std::string kSupportedSyspropName = "bluetooth.device.class_of_device"; +static const std::string kSupportedSyspropValue = "0,1,4"; +static const std::string kUnsupportedSyspropName = "i.am.an.unsupported.sysprop"; +static const std::string kCorrectPrefixAflagName = + "persist.device_config.aconfig_flags.bluetooth.com.android.bluetooth.flags.msft_addr_tracking_" + "quirk"; +static const std::string kCorrectPrefixAflagValue = "true"; +static const std::string kIncorrectPrefixAflagName = + "persist.device_config.aconfig_flags.not_bluetooth.testing_flag"; + +static const std::string kParseConfigTestConfig = + "[Sysprops]\n" + kSupportedSyspropName + "=" + kSupportedSyspropValue + "\n" + + kUnsupportedSyspropName + "=true\n" + "\n" + "[Aflags]\n" + kCorrectPrefixAflagName + "=" + + kCorrectPrefixAflagValue + "\n" + kIncorrectPrefixAflagName + "=true\n"; + +TEST_F(SyspropsModuleTest, parse_config_test) { + // Verify the state before test + EXPECT_THAT(bluetooth::os::GetSystemProperty(kSupportedSyspropName), std::nullopt); + EXPECT_THAT(bluetooth::os::GetSystemProperty(kUnsupportedSyspropName), std::nullopt); + EXPECT_THAT(bluetooth::os::GetSystemProperty(kCorrectPrefixAflagName), std::nullopt); + EXPECT_THAT(bluetooth::os::GetSystemProperty(kIncorrectPrefixAflagName), std::nullopt); + + EXPECT_TRUE(bluetooth::os::WriteToFile(temp_config_.string(), kParseConfigTestConfig)); + auto* sysprops_module = new bluetooth::sysprops::SyspropsModule(); + test_registry_.InjectTestModule(&bluetooth::sysprops::SyspropsModule::Factory, sysprops_module); + + EXPECT_THAT( + bluetooth::os::GetSystemProperty(kSupportedSyspropName), + Optional(StrEq(kSupportedSyspropValue))); + EXPECT_THAT(bluetooth::os::GetSystemProperty(kUnsupportedSyspropName), std::nullopt); + EXPECT_THAT( + bluetooth::os::GetSystemProperty(kCorrectPrefixAflagName), + Optional(StrEq(kCorrectPrefixAflagValue))); + EXPECT_THAT(bluetooth::os::GetSystemProperty(kIncorrectPrefixAflagName), std::nullopt); +} + +TEST_F(SyspropsModuleTest, empty_sysprops_file_path_test) { + // Verify the state before test + EXPECT_THAT(bluetooth::os::GetSystemProperty(kSupportedSyspropName), std::nullopt); + EXPECT_THAT(bluetooth::os::GetSystemProperty(kUnsupportedSyspropName), std::nullopt); + EXPECT_THAT(bluetooth::os::GetSystemProperty(kCorrectPrefixAflagName), std::nullopt); + EXPECT_THAT(bluetooth::os::GetSystemProperty(kIncorrectPrefixAflagName), std::nullopt); + + bluetooth::os::ParameterProvider::OverrideSyspropsFilePath(""); + auto* sysprops_module = new bluetooth::sysprops::SyspropsModule(); + test_registry_.InjectTestModule(&bluetooth::sysprops::SyspropsModule::Factory, sysprops_module); + + EXPECT_THAT(bluetooth::os::GetSystemProperty(kSupportedSyspropName), std::nullopt); + EXPECT_THAT(bluetooth::os::GetSystemProperty(kUnsupportedSyspropName), std::nullopt); + EXPECT_THAT(bluetooth::os::GetSystemProperty(kCorrectPrefixAflagName), std::nullopt); + EXPECT_THAT(bluetooth::os::GetSystemProperty(kIncorrectPrefixAflagName), std::nullopt); +} + +} // namespace testing |