Loading tools/aconfig/aconfig/Android.bp +5 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,10 @@ rust_defaults { cfgs: select(release_flag("RELEASE_ACONFIG_FINGERPRINT_RUST"), { true: ["enable_fingerprint_rust"], default: [], }) + select(release_flag("RELEASE_ACONFIG_FINGERPRINT_CPP"), { true: ["enable_fingerprint_cpp"], default: [], }), } Loading tools/aconfig/aconfig/Cargo.toml +1 −1 Original line number Diff line number Diff line Loading @@ -28,4 +28,4 @@ serde_json = "1.0.93" convert_finalized_flags = { path = "../convert_finalized_flags" } [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(enable_fingerprint_rust)'] } unexpected_cfgs = { level = "warn", check-cfg = ['cfg(enable_fingerprint_rust)', 'cfg(enable_fingerprint_cpp)'] } tools/aconfig/aconfig/src/codegen/cpp.rs +294 −6 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ pub fn generate_cpp_code<I>( parsed_flags_iter: I, codegen_mode: CodegenMode, flag_ids: HashMap<String, u16>, package_fingerprint: Option<u64>, ) -> Result<Vec<OutputFile>> where I: Iterator<Item = ProtoParsedFlag>, Loading @@ -48,6 +49,7 @@ where ensure!(class_elements.len() > 0); let container = class_elements[0].container.clone(); ensure!(codegen::is_valid_name_ident(&header)); let use_package_fingerprint = package_fingerprint.is_some(); let context = Context { header: &header, package_macro: &package_macro, Loading @@ -59,6 +61,8 @@ where is_test_mode: codegen_mode == CodegenMode::Test, class_elements, container, use_package_fingerprint, package_fingerprint: package_fingerprint.unwrap_or_default(), }; let files = [ Loading Loading @@ -103,6 +107,8 @@ pub struct Context<'a> { pub is_test_mode: bool, pub class_elements: Vec<ClassElement>, pub container: String, pub use_package_fingerprint: bool, pub package_fingerprint: u64, } #[derive(Serialize)] Loading Loading @@ -608,6 +614,7 @@ namespace com::android::aconfig::test { virtual bool disabled_rw() override { if (cache_[0].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } Loading @@ -628,6 +635,7 @@ namespace com::android::aconfig::test { virtual bool disabled_rw_exported() override { if (cache_[1].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } Loading @@ -648,6 +656,7 @@ namespace com::android::aconfig::test { virtual bool disabled_rw_in_other_namespace() override { if (cache_[2].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } Loading Loading @@ -684,6 +693,7 @@ namespace com::android::aconfig::test { virtual bool enabled_rw() override { if (cache_[3].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return true; } Loading @@ -709,6 +719,264 @@ namespace com::android::aconfig::test { std::unique_ptr<aconfig_storage::MappedStorageFile> flag_value_file_; bool package_exists_in_storage_; }; std::unique_ptr<flag_provider_interface> provider_ = std::make_unique<flag_provider>(); } bool com_android_aconfig_test_disabled_ro() { return false; } bool com_android_aconfig_test_disabled_rw() { return com::android::aconfig::test::disabled_rw(); } bool com_android_aconfig_test_disabled_rw_exported() { return com::android::aconfig::test::disabled_rw_exported(); } bool com_android_aconfig_test_disabled_rw_in_other_namespace() { return com::android::aconfig::test::disabled_rw_in_other_namespace(); } bool com_android_aconfig_test_enabled_fixed_ro() { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO; } bool com_android_aconfig_test_enabled_fixed_ro_exported() { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO_EXPORTED; } bool com_android_aconfig_test_enabled_ro() { return true; } bool com_android_aconfig_test_enabled_ro_exported() { return true; } bool com_android_aconfig_test_enabled_rw() { return com::android::aconfig::test::enabled_rw(); } "#; const PROD_SOURCE_FILE_EXPECTED_WITH_FINGERPRINT: &str = r#" #include "com_android_aconfig_test.h" #include <unistd.h> #include "aconfig_storage/aconfig_storage_read_api.hpp" #include <android/log.h> #define LOG_TAG "aconfig_cpp_codegen" #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) #include <atomic> #include <vector> namespace com::android::aconfig::test { class flag_provider : public flag_provider_interface { public: flag_provider() : cache_(4) , boolean_start_index_() , flag_value_file_(nullptr) , package_exists_in_storage_(true) , fingerprint_matches_(true) { for (size_t i = 0 ; i < 4; i++) { cache_[i] = -1; } auto package_map_file = aconfig_storage::get_mapped_file( "system", aconfig_storage::StorageFileType::package_map); if (!package_map_file.ok()) { ALOGE("error: failed to get package map file: %s", package_map_file.error().c_str()); package_exists_in_storage_ = false; return; } auto context = aconfig_storage::get_package_read_context( **package_map_file, "com.android.aconfig.test"); if (!context.ok()) { ALOGE("error: failed to get package read context: %s", context.error().c_str()); package_exists_in_storage_ = false; return; } if (!(context->package_exists)) { package_exists_in_storage_ = false; return; } if (context->fingerprint != 5801144784618221668ULL) { ALOGE("Fingerprint mismatch for package com.android.aconfig.test."); fingerprint_matches_ = false; return; } // cache package boolean flag start index boolean_start_index_ = context->boolean_start_index; // unmap package map file and free memory delete *package_map_file; auto flag_value_file = aconfig_storage::get_mapped_file( "system", aconfig_storage::StorageFileType::flag_val); if (!flag_value_file.ok()) { ALOGE("error: failed to get flag value file: %s", flag_value_file.error().c_str()); package_exists_in_storage_ = false; return; } // cache flag value file flag_value_file_ = std::unique_ptr<aconfig_storage::MappedStorageFile>( *flag_value_file); } virtual bool disabled_ro() override { return false; } virtual bool disabled_rw() override { if (cache_[0].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } if (!fingerprint_matches_) { ALOGE("error: package fingerprint mismtach, returning flag default value."); return false; } auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, boolean_start_index_ + 0); if (!value.ok()) { ALOGE("error: failed to read flag value: %s", value.error().c_str()); return false; } cache_[0].store(*value, std::memory_order_relaxed); } return cache_[0].load(std::memory_order_relaxed); } virtual bool disabled_rw_exported() override { if (cache_[1].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } if (!fingerprint_matches_) { ALOGE("error: package fingerprint mismtach, returning flag default value."); return false; } auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, boolean_start_index_ + 1); if (!value.ok()) { ALOGE("error: failed to read flag value: %s", value.error().c_str()); return false; } cache_[1].store(*value, std::memory_order_relaxed); } return cache_[1].load(std::memory_order_relaxed); } virtual bool disabled_rw_in_other_namespace() override { if (cache_[2].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } if (!fingerprint_matches_) { ALOGE("error: package fingerprint mismtach, returning flag default value."); return false; } auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, boolean_start_index_ + 2); if (!value.ok()) { ALOGE("error: failed to read flag value: %s", value.error().c_str()); return false; } cache_[2].store(*value, std::memory_order_relaxed); } return cache_[2].load(std::memory_order_relaxed); } virtual bool enabled_fixed_ro() override { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO; } virtual bool enabled_fixed_ro_exported() override { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO_EXPORTED; } virtual bool enabled_ro() override { return true; } virtual bool enabled_ro_exported() override { return true; } virtual bool enabled_rw() override { if (cache_[3].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return true; } if (!fingerprint_matches_) { ALOGE("error: package fingerprint mismtach, returning flag default value."); return true; } auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, boolean_start_index_ + 7); if (!value.ok()) { ALOGE("error: failed to read flag value: %s", value.error().c_str()); return true; } cache_[3].store(*value, std::memory_order_relaxed); } return cache_[3].load(std::memory_order_relaxed); } private: std::vector<std::atomic_int8_t> cache_; uint32_t boolean_start_index_; std::unique_ptr<aconfig_storage::MappedStorageFile> flag_value_file_; bool package_exists_in_storage_; bool fingerprint_matches_; }; std::unique_ptr<flag_provider_interface> provider_ = Loading Loading @@ -848,6 +1116,7 @@ namespace com::android::aconfig::test { return it->second; } else { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } Loading @@ -874,6 +1143,7 @@ namespace com::android::aconfig::test { return it->second; } else { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } Loading @@ -900,6 +1170,7 @@ namespace com::android::aconfig::test { return it->second; } else { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } Loading Loading @@ -978,6 +1249,7 @@ namespace com::android::aconfig::test { return it->second; } else { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return true; } Loading Loading @@ -1279,16 +1551,19 @@ bool com_android_aconfig_test_enabled_ro() { mode: CodegenMode, expected_header: &str, expected_src: &str, with_fingerprint: bool, ) { let modified_parsed_flags = crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode).unwrap(); let flag_ids = assign_flag_ids(crate::test::TEST_PACKAGE, modified_parsed_flags.iter()).unwrap(); let package_fingerprint = if with_fingerprint { Some(5801144784618221668) } else { None }; let generated = generate_cpp_code( crate::test::TEST_PACKAGE, modified_parsed_flags.into_iter(), mode, flag_ids, package_fingerprint, ) .unwrap(); let mut generated_files_map = HashMap::new(); Loading @@ -1311,12 +1586,9 @@ bool com_android_aconfig_test_enabled_ro() { target_file_path = String::from("com_android_aconfig_test.cc"); assert!(generated_files_map.contains_key(&target_file_path)); assert_eq!( None, crate::test::first_significant_code_diff( crate::test::assert_no_significant_code_diff( expected_src, generated_files_map.get(&target_file_path).unwrap() ) generated_files_map.get(&target_file_path).unwrap(), ); } Loading @@ -1328,6 +1600,19 @@ bool com_android_aconfig_test_enabled_ro() { CodegenMode::Production, EXPORTED_PROD_HEADER_EXPECTED, PROD_SOURCE_FILE_EXPECTED, false, ); } #[test] fn test_generate_cpp_code_for_prod_with_fingerprint() { let parsed_flags = crate::test::parse_test_flags(); test_generate_cpp_code( parsed_flags, CodegenMode::Production, EXPORTED_PROD_HEADER_EXPECTED, PROD_SOURCE_FILE_EXPECTED_WITH_FINGERPRINT, true, ); } Loading @@ -1339,6 +1624,7 @@ bool com_android_aconfig_test_enabled_ro() { CodegenMode::Test, EXPORTED_TEST_HEADER_EXPECTED, TEST_SOURCE_FILE_EXPECTED, false, ); } Loading @@ -1350,6 +1636,7 @@ bool com_android_aconfig_test_enabled_ro() { CodegenMode::ForceReadOnly, EXPORTED_FORCE_READ_ONLY_HEADER_EXPECTED, FORCE_READ_ONLY_SOURCE_FILE_EXPECTED, false, ); } Loading @@ -1361,6 +1648,7 @@ bool com_android_aconfig_test_enabled_ro() { CodegenMode::Production, READ_ONLY_EXPORTED_PROD_HEADER_EXPECTED, READ_ONLY_PROD_SOURCE_FILE_EXPECTED, false, ); } } tools/aconfig/aconfig/src/commands.rs +15 −2 Original line number Diff line number Diff line Loading @@ -315,13 +315,26 @@ pub fn create_cpp_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<Vec "Exported mode for generated c/c++ flag library is disabled" ); let parsed_flags = input.try_parse_flags()?; let modified_parsed_flags = modify_parsed_flags_based_on_mode(parsed_flags, codegen_mode)?; let modified_parsed_flags = modify_parsed_flags_based_on_mode(parsed_flags.clone(), codegen_mode)?; let Some(package) = find_unique_package(&modified_parsed_flags) else { bail!("no parsed flags, or the parsed flags use different packages"); }; let package = package.to_string(); let flag_ids = assign_flag_ids(&package, modified_parsed_flags.iter())?; generate_cpp_code(&package, modified_parsed_flags.into_iter(), codegen_mode, flag_ids) let package_fingerprint: Option<u64> = if cfg!(enable_fingerprint_cpp) { let mut flag_names = extract_flag_names(parsed_flags)?; Some(compute_flags_fingerprint(&mut flag_names)) } else { None }; generate_cpp_code( &package, modified_parsed_flags.into_iter(), codegen_mode, flag_ids, package_fingerprint, ) } pub fn create_rust_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<OutputFile> { Loading tools/aconfig/aconfig/templates/cpp_source_file.template +50 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,10 @@ namespace {cpp_namespace} \{ std::unique_ptr<aconfig_storage::MappedStorageFile> flag_value_file_; bool package_exists_in_storage_; {{ if use_package_fingerprint- }} bool fingerprint_matches_; {{ -endif }}{#- end of use_package_fingerprint #} {{ -endif }} public: Loading @@ -39,7 +43,12 @@ namespace {cpp_namespace} \{ : overrides_() , boolean_start_index_() , flag_value_file_(nullptr) {{ if use_package_fingerprint- }} , package_exists_in_storage_(true) , fingerprint_matches_(true) \{ {{ -else }} , package_exists_in_storage_(true) \{ {{ -endif }}{#- end of use_package_fingerprint #} auto package_map_file = aconfig_storage::get_mapped_file( "{container}", Loading @@ -64,6 +73,14 @@ namespace {cpp_namespace} \{ package_exists_in_storage_ = false; return; } {{ if use_package_fingerprint- }} if (context->fingerprint != { package_fingerprint }ULL) \{ ALOGE("Fingerprint mismatch for package {package}."); fingerprint_matches_ = false; return; } {{ -endif }}{#- end of use_package_fingerprint #} // cache package boolean flag start index boolean_start_index_ = context->boolean_start_index; Loading Loading @@ -99,8 +116,16 @@ namespace {cpp_namespace} \{ } else \{ {{ if item.readwrite- }} if (!package_exists_in_storage_) \{ ALOGE("error: package does not exist, returning flag default value."); return {item.default_value}; } {{ if use_package_fingerprint- }} if (!fingerprint_matches_) \{ ALOGE("error: package fingerprint mismtach, returning flag default value."); return {item.default_value}; } {{ -endif }}{#- end of use_package_fingerprint #} auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, Loading Loading @@ -138,7 +163,12 @@ namespace {cpp_namespace} \{ : cache_({readwrite_count}) , boolean_start_index_() , flag_value_file_(nullptr) {{ if use_package_fingerprint- }} , package_exists_in_storage_(true) , fingerprint_matches_(true) \{ {{ -else }} , package_exists_in_storage_(true) \{ {{ -endif }}{#- end of use_package_fingerprint #} for (size_t i = 0 ; i < {readwrite_count}; i++) \{ cache_[i] = -1; } Loading @@ -164,6 +194,14 @@ namespace {cpp_namespace} \{ package_exists_in_storage_ = false; return; } {{ if use_package_fingerprint- }} if (context->fingerprint != { package_fingerprint }ULL) \{ ALOGE("Fingerprint mismatch for package {package}."); fingerprint_matches_ = false; return; } {{ -endif }}{#- end of use_package_fingerprint #} // cache package boolean flag start index boolean_start_index_ = context->boolean_start_index; Loading Loading @@ -192,8 +230,16 @@ namespace {cpp_namespace} \{ {{ -if item.readwrite }} if (cache_[{item.readwrite_idx}].load(std::memory_order_relaxed) == -1) \{ if (!package_exists_in_storage_) \{ ALOGE("error: package does not exist, returning flag default value."); return {item.default_value}; } {{ if use_package_fingerprint- }} if (!fingerprint_matches_) \{ ALOGE("error: package fingerprint mismtach, returning flag default value."); return {item.default_value}; } {{ -endif }}{#- end of use_package_fingerprint #} auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, Loading Loading @@ -226,6 +272,10 @@ namespace {cpp_namespace} \{ std::unique_ptr<aconfig_storage::MappedStorageFile> flag_value_file_; bool package_exists_in_storage_; {{ if use_package_fingerprint- }} bool fingerprint_matches_; {{ -endif }}{#- end of use_package_fingerprint #} {{ -endif }} }; Loading Loading
tools/aconfig/aconfig/Android.bp +5 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,10 @@ rust_defaults { cfgs: select(release_flag("RELEASE_ACONFIG_FINGERPRINT_RUST"), { true: ["enable_fingerprint_rust"], default: [], }) + select(release_flag("RELEASE_ACONFIG_FINGERPRINT_CPP"), { true: ["enable_fingerprint_cpp"], default: [], }), } Loading
tools/aconfig/aconfig/Cargo.toml +1 −1 Original line number Diff line number Diff line Loading @@ -28,4 +28,4 @@ serde_json = "1.0.93" convert_finalized_flags = { path = "../convert_finalized_flags" } [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(enable_fingerprint_rust)'] } unexpected_cfgs = { level = "warn", check-cfg = ['cfg(enable_fingerprint_rust)', 'cfg(enable_fingerprint_cpp)'] }
tools/aconfig/aconfig/src/codegen/cpp.rs +294 −6 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ pub fn generate_cpp_code<I>( parsed_flags_iter: I, codegen_mode: CodegenMode, flag_ids: HashMap<String, u16>, package_fingerprint: Option<u64>, ) -> Result<Vec<OutputFile>> where I: Iterator<Item = ProtoParsedFlag>, Loading @@ -48,6 +49,7 @@ where ensure!(class_elements.len() > 0); let container = class_elements[0].container.clone(); ensure!(codegen::is_valid_name_ident(&header)); let use_package_fingerprint = package_fingerprint.is_some(); let context = Context { header: &header, package_macro: &package_macro, Loading @@ -59,6 +61,8 @@ where is_test_mode: codegen_mode == CodegenMode::Test, class_elements, container, use_package_fingerprint, package_fingerprint: package_fingerprint.unwrap_or_default(), }; let files = [ Loading Loading @@ -103,6 +107,8 @@ pub struct Context<'a> { pub is_test_mode: bool, pub class_elements: Vec<ClassElement>, pub container: String, pub use_package_fingerprint: bool, pub package_fingerprint: u64, } #[derive(Serialize)] Loading Loading @@ -608,6 +614,7 @@ namespace com::android::aconfig::test { virtual bool disabled_rw() override { if (cache_[0].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } Loading @@ -628,6 +635,7 @@ namespace com::android::aconfig::test { virtual bool disabled_rw_exported() override { if (cache_[1].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } Loading @@ -648,6 +656,7 @@ namespace com::android::aconfig::test { virtual bool disabled_rw_in_other_namespace() override { if (cache_[2].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } Loading Loading @@ -684,6 +693,7 @@ namespace com::android::aconfig::test { virtual bool enabled_rw() override { if (cache_[3].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return true; } Loading @@ -709,6 +719,264 @@ namespace com::android::aconfig::test { std::unique_ptr<aconfig_storage::MappedStorageFile> flag_value_file_; bool package_exists_in_storage_; }; std::unique_ptr<flag_provider_interface> provider_ = std::make_unique<flag_provider>(); } bool com_android_aconfig_test_disabled_ro() { return false; } bool com_android_aconfig_test_disabled_rw() { return com::android::aconfig::test::disabled_rw(); } bool com_android_aconfig_test_disabled_rw_exported() { return com::android::aconfig::test::disabled_rw_exported(); } bool com_android_aconfig_test_disabled_rw_in_other_namespace() { return com::android::aconfig::test::disabled_rw_in_other_namespace(); } bool com_android_aconfig_test_enabled_fixed_ro() { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO; } bool com_android_aconfig_test_enabled_fixed_ro_exported() { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO_EXPORTED; } bool com_android_aconfig_test_enabled_ro() { return true; } bool com_android_aconfig_test_enabled_ro_exported() { return true; } bool com_android_aconfig_test_enabled_rw() { return com::android::aconfig::test::enabled_rw(); } "#; const PROD_SOURCE_FILE_EXPECTED_WITH_FINGERPRINT: &str = r#" #include "com_android_aconfig_test.h" #include <unistd.h> #include "aconfig_storage/aconfig_storage_read_api.hpp" #include <android/log.h> #define LOG_TAG "aconfig_cpp_codegen" #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) #include <atomic> #include <vector> namespace com::android::aconfig::test { class flag_provider : public flag_provider_interface { public: flag_provider() : cache_(4) , boolean_start_index_() , flag_value_file_(nullptr) , package_exists_in_storage_(true) , fingerprint_matches_(true) { for (size_t i = 0 ; i < 4; i++) { cache_[i] = -1; } auto package_map_file = aconfig_storage::get_mapped_file( "system", aconfig_storage::StorageFileType::package_map); if (!package_map_file.ok()) { ALOGE("error: failed to get package map file: %s", package_map_file.error().c_str()); package_exists_in_storage_ = false; return; } auto context = aconfig_storage::get_package_read_context( **package_map_file, "com.android.aconfig.test"); if (!context.ok()) { ALOGE("error: failed to get package read context: %s", context.error().c_str()); package_exists_in_storage_ = false; return; } if (!(context->package_exists)) { package_exists_in_storage_ = false; return; } if (context->fingerprint != 5801144784618221668ULL) { ALOGE("Fingerprint mismatch for package com.android.aconfig.test."); fingerprint_matches_ = false; return; } // cache package boolean flag start index boolean_start_index_ = context->boolean_start_index; // unmap package map file and free memory delete *package_map_file; auto flag_value_file = aconfig_storage::get_mapped_file( "system", aconfig_storage::StorageFileType::flag_val); if (!flag_value_file.ok()) { ALOGE("error: failed to get flag value file: %s", flag_value_file.error().c_str()); package_exists_in_storage_ = false; return; } // cache flag value file flag_value_file_ = std::unique_ptr<aconfig_storage::MappedStorageFile>( *flag_value_file); } virtual bool disabled_ro() override { return false; } virtual bool disabled_rw() override { if (cache_[0].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } if (!fingerprint_matches_) { ALOGE("error: package fingerprint mismtach, returning flag default value."); return false; } auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, boolean_start_index_ + 0); if (!value.ok()) { ALOGE("error: failed to read flag value: %s", value.error().c_str()); return false; } cache_[0].store(*value, std::memory_order_relaxed); } return cache_[0].load(std::memory_order_relaxed); } virtual bool disabled_rw_exported() override { if (cache_[1].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } if (!fingerprint_matches_) { ALOGE("error: package fingerprint mismtach, returning flag default value."); return false; } auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, boolean_start_index_ + 1); if (!value.ok()) { ALOGE("error: failed to read flag value: %s", value.error().c_str()); return false; } cache_[1].store(*value, std::memory_order_relaxed); } return cache_[1].load(std::memory_order_relaxed); } virtual bool disabled_rw_in_other_namespace() override { if (cache_[2].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } if (!fingerprint_matches_) { ALOGE("error: package fingerprint mismtach, returning flag default value."); return false; } auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, boolean_start_index_ + 2); if (!value.ok()) { ALOGE("error: failed to read flag value: %s", value.error().c_str()); return false; } cache_[2].store(*value, std::memory_order_relaxed); } return cache_[2].load(std::memory_order_relaxed); } virtual bool enabled_fixed_ro() override { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO; } virtual bool enabled_fixed_ro_exported() override { return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO_EXPORTED; } virtual bool enabled_ro() override { return true; } virtual bool enabled_ro_exported() override { return true; } virtual bool enabled_rw() override { if (cache_[3].load(std::memory_order_relaxed) == -1) { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return true; } if (!fingerprint_matches_) { ALOGE("error: package fingerprint mismtach, returning flag default value."); return true; } auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, boolean_start_index_ + 7); if (!value.ok()) { ALOGE("error: failed to read flag value: %s", value.error().c_str()); return true; } cache_[3].store(*value, std::memory_order_relaxed); } return cache_[3].load(std::memory_order_relaxed); } private: std::vector<std::atomic_int8_t> cache_; uint32_t boolean_start_index_; std::unique_ptr<aconfig_storage::MappedStorageFile> flag_value_file_; bool package_exists_in_storage_; bool fingerprint_matches_; }; std::unique_ptr<flag_provider_interface> provider_ = Loading Loading @@ -848,6 +1116,7 @@ namespace com::android::aconfig::test { return it->second; } else { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } Loading @@ -874,6 +1143,7 @@ namespace com::android::aconfig::test { return it->second; } else { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } Loading @@ -900,6 +1170,7 @@ namespace com::android::aconfig::test { return it->second; } else { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return false; } Loading Loading @@ -978,6 +1249,7 @@ namespace com::android::aconfig::test { return it->second; } else { if (!package_exists_in_storage_) { ALOGE("error: package does not exist, returning flag default value."); return true; } Loading Loading @@ -1279,16 +1551,19 @@ bool com_android_aconfig_test_enabled_ro() { mode: CodegenMode, expected_header: &str, expected_src: &str, with_fingerprint: bool, ) { let modified_parsed_flags = crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode).unwrap(); let flag_ids = assign_flag_ids(crate::test::TEST_PACKAGE, modified_parsed_flags.iter()).unwrap(); let package_fingerprint = if with_fingerprint { Some(5801144784618221668) } else { None }; let generated = generate_cpp_code( crate::test::TEST_PACKAGE, modified_parsed_flags.into_iter(), mode, flag_ids, package_fingerprint, ) .unwrap(); let mut generated_files_map = HashMap::new(); Loading @@ -1311,12 +1586,9 @@ bool com_android_aconfig_test_enabled_ro() { target_file_path = String::from("com_android_aconfig_test.cc"); assert!(generated_files_map.contains_key(&target_file_path)); assert_eq!( None, crate::test::first_significant_code_diff( crate::test::assert_no_significant_code_diff( expected_src, generated_files_map.get(&target_file_path).unwrap() ) generated_files_map.get(&target_file_path).unwrap(), ); } Loading @@ -1328,6 +1600,19 @@ bool com_android_aconfig_test_enabled_ro() { CodegenMode::Production, EXPORTED_PROD_HEADER_EXPECTED, PROD_SOURCE_FILE_EXPECTED, false, ); } #[test] fn test_generate_cpp_code_for_prod_with_fingerprint() { let parsed_flags = crate::test::parse_test_flags(); test_generate_cpp_code( parsed_flags, CodegenMode::Production, EXPORTED_PROD_HEADER_EXPECTED, PROD_SOURCE_FILE_EXPECTED_WITH_FINGERPRINT, true, ); } Loading @@ -1339,6 +1624,7 @@ bool com_android_aconfig_test_enabled_ro() { CodegenMode::Test, EXPORTED_TEST_HEADER_EXPECTED, TEST_SOURCE_FILE_EXPECTED, false, ); } Loading @@ -1350,6 +1636,7 @@ bool com_android_aconfig_test_enabled_ro() { CodegenMode::ForceReadOnly, EXPORTED_FORCE_READ_ONLY_HEADER_EXPECTED, FORCE_READ_ONLY_SOURCE_FILE_EXPECTED, false, ); } Loading @@ -1361,6 +1648,7 @@ bool com_android_aconfig_test_enabled_ro() { CodegenMode::Production, READ_ONLY_EXPORTED_PROD_HEADER_EXPECTED, READ_ONLY_PROD_SOURCE_FILE_EXPECTED, false, ); } }
tools/aconfig/aconfig/src/commands.rs +15 −2 Original line number Diff line number Diff line Loading @@ -315,13 +315,26 @@ pub fn create_cpp_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<Vec "Exported mode for generated c/c++ flag library is disabled" ); let parsed_flags = input.try_parse_flags()?; let modified_parsed_flags = modify_parsed_flags_based_on_mode(parsed_flags, codegen_mode)?; let modified_parsed_flags = modify_parsed_flags_based_on_mode(parsed_flags.clone(), codegen_mode)?; let Some(package) = find_unique_package(&modified_parsed_flags) else { bail!("no parsed flags, or the parsed flags use different packages"); }; let package = package.to_string(); let flag_ids = assign_flag_ids(&package, modified_parsed_flags.iter())?; generate_cpp_code(&package, modified_parsed_flags.into_iter(), codegen_mode, flag_ids) let package_fingerprint: Option<u64> = if cfg!(enable_fingerprint_cpp) { let mut flag_names = extract_flag_names(parsed_flags)?; Some(compute_flags_fingerprint(&mut flag_names)) } else { None }; generate_cpp_code( &package, modified_parsed_flags.into_iter(), codegen_mode, flag_ids, package_fingerprint, ) } pub fn create_rust_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<OutputFile> { Loading
tools/aconfig/aconfig/templates/cpp_source_file.template +50 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,10 @@ namespace {cpp_namespace} \{ std::unique_ptr<aconfig_storage::MappedStorageFile> flag_value_file_; bool package_exists_in_storage_; {{ if use_package_fingerprint- }} bool fingerprint_matches_; {{ -endif }}{#- end of use_package_fingerprint #} {{ -endif }} public: Loading @@ -39,7 +43,12 @@ namespace {cpp_namespace} \{ : overrides_() , boolean_start_index_() , flag_value_file_(nullptr) {{ if use_package_fingerprint- }} , package_exists_in_storage_(true) , fingerprint_matches_(true) \{ {{ -else }} , package_exists_in_storage_(true) \{ {{ -endif }}{#- end of use_package_fingerprint #} auto package_map_file = aconfig_storage::get_mapped_file( "{container}", Loading @@ -64,6 +73,14 @@ namespace {cpp_namespace} \{ package_exists_in_storage_ = false; return; } {{ if use_package_fingerprint- }} if (context->fingerprint != { package_fingerprint }ULL) \{ ALOGE("Fingerprint mismatch for package {package}."); fingerprint_matches_ = false; return; } {{ -endif }}{#- end of use_package_fingerprint #} // cache package boolean flag start index boolean_start_index_ = context->boolean_start_index; Loading Loading @@ -99,8 +116,16 @@ namespace {cpp_namespace} \{ } else \{ {{ if item.readwrite- }} if (!package_exists_in_storage_) \{ ALOGE("error: package does not exist, returning flag default value."); return {item.default_value}; } {{ if use_package_fingerprint- }} if (!fingerprint_matches_) \{ ALOGE("error: package fingerprint mismtach, returning flag default value."); return {item.default_value}; } {{ -endif }}{#- end of use_package_fingerprint #} auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, Loading Loading @@ -138,7 +163,12 @@ namespace {cpp_namespace} \{ : cache_({readwrite_count}) , boolean_start_index_() , flag_value_file_(nullptr) {{ if use_package_fingerprint- }} , package_exists_in_storage_(true) , fingerprint_matches_(true) \{ {{ -else }} , package_exists_in_storage_(true) \{ {{ -endif }}{#- end of use_package_fingerprint #} for (size_t i = 0 ; i < {readwrite_count}; i++) \{ cache_[i] = -1; } Loading @@ -164,6 +194,14 @@ namespace {cpp_namespace} \{ package_exists_in_storage_ = false; return; } {{ if use_package_fingerprint- }} if (context->fingerprint != { package_fingerprint }ULL) \{ ALOGE("Fingerprint mismatch for package {package}."); fingerprint_matches_ = false; return; } {{ -endif }}{#- end of use_package_fingerprint #} // cache package boolean flag start index boolean_start_index_ = context->boolean_start_index; Loading Loading @@ -192,8 +230,16 @@ namespace {cpp_namespace} \{ {{ -if item.readwrite }} if (cache_[{item.readwrite_idx}].load(std::memory_order_relaxed) == -1) \{ if (!package_exists_in_storage_) \{ ALOGE("error: package does not exist, returning flag default value."); return {item.default_value}; } {{ if use_package_fingerprint- }} if (!fingerprint_matches_) \{ ALOGE("error: package fingerprint mismtach, returning flag default value."); return {item.default_value}; } {{ -endif }}{#- end of use_package_fingerprint #} auto value = aconfig_storage::get_boolean_flag_value( *flag_value_file_, Loading Loading @@ -226,6 +272,10 @@ namespace {cpp_namespace} \{ std::unique_ptr<aconfig_storage::MappedStorageFile> flag_value_file_; bool package_exists_in_storage_; {{ if use_package_fingerprint- }} bool fingerprint_matches_; {{ -endif }}{#- end of use_package_fingerprint #} {{ -endif }} }; Loading