summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--floss/libflags/get_flags.cc6
-rw-r--r--system/gd/Android.bp1
-rw-r--r--system/gd/os/host/parameter_provider.cc9
-rw-r--r--system/gd/storage/config_cache.cc26
-rw-r--r--system/gd/storage/config_cache.h2
-rw-r--r--system/gd/storage/config_cache_test.cc14
-rw-r--r--system/gd/sysprops/Android.bp7
-rw-r--r--system/gd/sysprops/sysprops_module.cc16
-rw-r--r--system/gd/sysprops/sysprops_module.h4
-rw-r--r--system/gd/sysprops/sysprops_module_test.cc114
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