Merge "Pass LOCAL_MIN_SDK_VERSION to clang triple" into main
diff --git a/core/base_rules.mk b/core/base_rules.mk
index f533358..a446483 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -541,13 +541,14 @@
# Only set up copy rules once, even if another arch variant shares it
my_vintf_new_pairs := $(filter-out $(ALL_VINTF_MANIFEST_FRAGMENTS_LIST),$(my_vintf_pairs))
- my_vintf_new_installed := $(call copy-many-vintf-manifest-files-checked,$(my_vintf_new_pairs))
-
ALL_VINTF_MANIFEST_FRAGMENTS_LIST += $(my_vintf_new_pairs)
- $(my_all_targets) : $(my_vintf_installed)
- # Install fragments together with the target
- $(LOCAL_INSTALLED_MODULE) : | $(my_vintf_installed)
+ ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+ $(call copy-many-vintf-manifest-files-checked,$(my_vintf_new_pairs))
+ $(my_all_targets) : $(my_vintf_installed)
+ # Install fragments together with the target
+ $(LOCAL_INSTALLED_MODULE) : | $(my_vintf_installed)
+ endif
endif # my_vintf_fragments
# Rule to install the module's companion init.rc.
@@ -579,13 +580,14 @@
# Make sure we only set up the copy rules once, even if another arch variant
# shares a common LOCAL_INIT_RC.
my_init_rc_new_pairs := $(filter-out $(ALL_INIT_RC_INSTALLED_PAIRS),$(my_init_rc_pairs))
- my_init_rc_new_installed := $(call copy-many-init-script-files-checked,$(my_init_rc_new_pairs))
-
ALL_INIT_RC_INSTALLED_PAIRS += $(my_init_rc_new_pairs)
- $(my_all_targets) : $(my_init_rc_installed)
- # Install init_rc together with the target
- $(LOCAL_INSTALLED_MODULE) : | $(my_init_rc_installed)
+ ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+ $(call copy-many-init-script-files-checked,$(my_init_rc_new_pairs))
+ $(my_all_targets) : $(my_init_rc_installed)
+ # Install init_rc together with the target
+ $(LOCAL_INSTALLED_MODULE) : | $(my_init_rc_installed)
+ endif
endif # my_init_rc
endif # !LOCAL_IS_HOST_MODULE
@@ -1007,46 +1009,78 @@
my_required_modules += $(LOCAL_REQUIRED_MODULES_$($(my_prefix)OS))
endif
-ALL_MODULES.$(my_register_name).SHARED_LIBS := \
- $(ALL_MODULES.$(my_register_name).SHARED_LIBS) $(LOCAL_SHARED_LIBRARIES)
+ifndef LOCAL_SOONG_MODULE_INFO_JSON
+ ALL_MAKE_MODULE_INFO_JSON_MODULES += $(my_register_name)
+ ALL_MODULES.$(my_register_name).SHARED_LIBS := \
+ $(ALL_MODULES.$(my_register_name).SHARED_LIBS) $(LOCAL_SHARED_LIBRARIES)
-ALL_MODULES.$(my_register_name).STATIC_LIBS := \
- $(ALL_MODULES.$(my_register_name).STATIC_LIBS) $(LOCAL_STATIC_LIBRARIES)
+ ALL_MODULES.$(my_register_name).STATIC_LIBS := \
+ $(ALL_MODULES.$(my_register_name).STATIC_LIBS) $(LOCAL_STATIC_LIBRARIES)
-ALL_MODULES.$(my_register_name).SYSTEM_SHARED_LIBS := \
- $(ALL_MODULES.$(my_register_name).SYSTEM_SHARED_LIBS) $(LOCAL_SYSTEM_SHARED_LIBRARIES)
+ ALL_MODULES.$(my_register_name).SYSTEM_SHARED_LIBS := \
+ $(ALL_MODULES.$(my_register_name).SYSTEM_SHARED_LIBS) $(LOCAL_SYSTEM_SHARED_LIBRARIES)
-ALL_MODULES.$(my_register_name).LOCAL_RUNTIME_LIBRARIES := \
- $(ALL_MODULES.$(my_register_name).LOCAL_RUNTIME_LIBRARIES) $(LOCAL_RUNTIME_LIBRARIES) \
- $(LOCAL_JAVA_LIBRARIES)
+ ALL_MODULES.$(my_register_name).LOCAL_RUNTIME_LIBRARIES := \
+ $(ALL_MODULES.$(my_register_name).LOCAL_RUNTIME_LIBRARIES) $(LOCAL_RUNTIME_LIBRARIES) \
+ $(LOCAL_JAVA_LIBRARIES)
-ALL_MODULES.$(my_register_name).LOCAL_STATIC_LIBRARIES := \
- $(ALL_MODULES.$(my_register_name).LOCAL_STATIC_LIBRARIES) $(LOCAL_STATIC_JAVA_LIBRARIES)
+ ALL_MODULES.$(my_register_name).LOCAL_STATIC_LIBRARIES := \
+ $(ALL_MODULES.$(my_register_name).LOCAL_STATIC_LIBRARIES) $(LOCAL_STATIC_JAVA_LIBRARIES)
-ifneq ($(my_test_data_file_pairs),)
- # Export the list of targets that are handled as data inputs and required
- # by tests at runtime. The format of my_test_data_file_pairs is
- # is $(path):$(relative_file) but for module-info, only the string after
- # ":" is needed.
- ALL_MODULES.$(my_register_name).TEST_DATA := \
- $(strip $(ALL_MODULES.$(my_register_name).TEST_DATA) \
- $(foreach f, $(my_test_data_file_pairs),\
- $(call word-colon,2,$(f))))
+ ifneq ($(my_test_data_file_pairs),)
+ # Export the list of targets that are handled as data inputs and required
+ # by tests at runtime. The format of my_test_data_file_pairs is
+ # is $(path):$(relative_file) but for module-info, only the string after
+ # ":" is needed.
+ ALL_MODULES.$(my_register_name).TEST_DATA := \
+ $(strip $(ALL_MODULES.$(my_register_name).TEST_DATA) \
+ $(foreach f, $(my_test_data_file_pairs),\
+ $(call word-colon,2,$(f))))
+ endif
+
+ ifdef LOCAL_TEST_DATA_BINS
+ ALL_MODULES.$(my_register_name).TEST_DATA_BINS := \
+ $(ALL_MODULES.$(my_register_name).TEST_DATA_BINS) $(LOCAL_TEST_DATA_BINS)
+ endif
+
+ ALL_MODULES.$(my_register_name).SUPPORTED_VARIANTS := \
+ $(ALL_MODULES.$(my_register_name).SUPPORTED_VARIANTS) \
+ $(filter-out $(ALL_MODULES.$(my_register_name).SUPPORTED_VARIANTS),$(my_supported_variant))
+
+ ALL_MODULES.$(my_register_name).ACONFIG_FILES := \
+ $(ALL_MODULES.$(my_register_name).ACONFIG_FILES) $(LOCAL_ACONFIG_FILES)
+
+ ALL_MODULES.$(my_register_name).COMPATIBILITY_SUITES := \
+ $(ALL_MODULES.$(my_register_name).COMPATIBILITY_SUITES) $(LOCAL_COMPATIBILITY_SUITE)
+ ALL_MODULES.$(my_register_name).MODULE_NAME := $(LOCAL_MODULE)
+ ALL_MODULES.$(my_register_name).TEST_CONFIG := $(test_config)
+ ALL_MODULES.$(my_register_name).EXTRA_TEST_CONFIGS := $(LOCAL_EXTRA_FULL_TEST_CONFIGS)
+ ALL_MODULES.$(my_register_name).TEST_MAINLINE_MODULES := $(LOCAL_TEST_MAINLINE_MODULES)
+ ifdef LOCAL_IS_UNIT_TEST
+ ALL_MODULES.$(my_register_name).IS_UNIT_TEST := $(LOCAL_IS_UNIT_TEST)
+ endif
+ ifdef LOCAL_TEST_OPTIONS_TAGS
+ ALL_MODULES.$(my_register_name).TEST_OPTIONS_TAGS := $(LOCAL_TEST_OPTIONS_TAGS)
+ endif
+
+ ##########################################################
+ # Track module-level dependencies.
+ # (b/204397180) Unlock RECORD_ALL_DEPS was acknowledged reasonable for better Atest performance.
+ ALL_MODULES.$(my_register_name).ALL_DEPS := \
+ $(ALL_MODULES.$(my_register_name).ALL_DEPS) \
+ $(LOCAL_STATIC_LIBRARIES) \
+ $(LOCAL_WHOLE_STATIC_LIBRARIES) \
+ $(LOCAL_SHARED_LIBRARIES) \
+ $(LOCAL_DYLIB_LIBRARIES) \
+ $(LOCAL_RLIB_LIBRARIES) \
+ $(LOCAL_PROC_MACRO_LIBRARIES) \
+ $(LOCAL_HEADER_LIBRARIES) \
+ $(LOCAL_STATIC_JAVA_LIBRARIES) \
+ $(LOCAL_JAVA_LIBRARIES) \
+ $(LOCAL_JNI_SHARED_LIBRARIES)
+
endif
-ifdef LOCAL_TEST_DATA_BINS
- ALL_MODULES.$(my_register_name).TEST_DATA_BINS := \
- $(ALL_MODULES.$(my_register_name).TEST_DATA_BINS) $(LOCAL_TEST_DATA_BINS)
-endif
-
-ALL_MODULES.$(my_register_name).SUPPORTED_VARIANTS := \
- $(ALL_MODULES.$(my_register_name).SUPPORTED_VARIANTS) \
- $(filter-out $(ALL_MODULES.$(my_register_name).SUPPORTED_VARIANTS),$(my_supported_variant))
-
-ALL_MODULES.$(my_register_name).ACONFIG_FILES := \
- $(ALL_MODULES.$(my_register_name).ACONFIG_FILES) $(LOCAL_ACONFIG_FILES)
-
-
##########################################################################
## When compiling against API imported module, use API import stub
## libraries.
@@ -1126,55 +1160,32 @@
$(call pretty-error,LOCAL_TARGET_REQUIRED_MODULES may not be used from target modules. Use LOCAL_REQUIRED_MODULES instead)
endif
endif
-ALL_MODULES.$(my_register_name).EVENT_LOG_TAGS := \
- $(ALL_MODULES.$(my_register_name).EVENT_LOG_TAGS) $(event_log_tags)
+
+ifdef event_log_tags
+ ALL_MODULES.$(my_register_name).EVENT_LOG_TAGS := \
+ $(ALL_MODULES.$(my_register_name).EVENT_LOG_TAGS) $(event_log_tags)
+endif
+
ALL_MODULES.$(my_register_name).MAKEFILE := \
$(ALL_MODULES.$(my_register_name).MAKEFILE) $(LOCAL_MODULE_MAKEFILE)
+
ifdef LOCAL_MODULE_OWNER
-ALL_MODULES.$(my_register_name).OWNER := \
- $(sort $(ALL_MODULES.$(my_register_name).OWNER) $(LOCAL_MODULE_OWNER))
+ ALL_MODULES.$(my_register_name).OWNER := \
+ $(sort $(ALL_MODULES.$(my_register_name).OWNER) $(LOCAL_MODULE_OWNER))
endif
+
ifdef LOCAL_2ND_ARCH_VAR_PREFIX
ALL_MODULES.$(my_register_name).FOR_2ND_ARCH := true
endif
ALL_MODULES.$(my_register_name).FOR_HOST_CROSS := $(my_host_cross)
-ALL_MODULES.$(my_register_name).MODULE_NAME := $(LOCAL_MODULE)
-ALL_MODULES.$(my_register_name).COMPATIBILITY_SUITES := \
- $(ALL_MODULES.$(my_register_name).COMPATIBILITY_SUITES) \
- $(filter-out $(ALL_MODULES.$(my_register_name).COMPATIBILITY_SUITES),$(LOCAL_COMPATIBILITY_SUITE))
-ALL_MODULES.$(my_register_name).TEST_CONFIG := $(test_config)
-ALL_MODULES.$(my_register_name).EXTRA_TEST_CONFIGS := $(LOCAL_EXTRA_FULL_TEST_CONFIGS)
-ALL_MODULES.$(my_register_name).TEST_MAINLINE_MODULES := $(LOCAL_TEST_MAINLINE_MODULES)
ifndef LOCAL_IS_HOST_MODULE
ALL_MODULES.$(my_register_name).FILE_CONTEXTS := $(LOCAL_FILE_CONTEXTS)
ALL_MODULES.$(my_register_name).APEX_KEYS_FILE := $(LOCAL_APEX_KEY_PATH)
endif
-ifdef LOCAL_IS_UNIT_TEST
-ALL_MODULES.$(my_register_name).IS_UNIT_TEST := $(LOCAL_IS_UNIT_TEST)
-endif
-ifdef LOCAL_TEST_OPTIONS_TAGS
-ALL_MODULES.$(my_register_name).TEST_OPTIONS_TAGS := $(LOCAL_TEST_OPTIONS_TAGS)
-endif
test_config :=
INSTALLABLE_FILES.$(LOCAL_INSTALLED_MODULE).MODULE := $(my_register_name)
-##########################################################
-# Track module-level dependencies.
-# (b/204397180) Unlock RECORD_ALL_DEPS was acknowledged reasonable for better Atest performance.
-ALL_MODULES.$(my_register_name).ALL_DEPS := \
- $(ALL_MODULES.$(my_register_name).ALL_DEPS) \
- $(LOCAL_STATIC_LIBRARIES) \
- $(LOCAL_WHOLE_STATIC_LIBRARIES) \
- $(LOCAL_SHARED_LIBRARIES) \
- $(LOCAL_DYLIB_LIBRARIES) \
- $(LOCAL_RLIB_LIBRARIES) \
- $(LOCAL_PROC_MACRO_LIBRARIES) \
- $(LOCAL_HEADER_LIBRARIES) \
- $(LOCAL_STATIC_JAVA_LIBRARIES) \
- $(LOCAL_JAVA_LIBRARIES) \
- $(LOCAL_JNI_SHARED_LIBRARIES)
-
###########################################################
## umbrella targets used to verify builds
###########################################################
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index b73e9b4..2b84fcd 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -265,6 +265,7 @@
LOCAL_SOONG_LICENSE_METADATA :=
LOCAL_SOONG_LINK_TYPE :=
LOCAL_SOONG_LINT_REPORTS :=
+LOCAL_SOONG_MODULE_INFO_JSON :=
LOCAL_SOONG_MODULE_TYPE :=
LOCAL_SOONG_PROGUARD_DICT :=
LOCAL_SOONG_PROGUARD_USAGE_ZIP :=
diff --git a/core/definitions.mk b/core/definitions.mk
index 7a6c064..1f2d011 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -37,6 +37,8 @@
# sub-variables.
ALL_MODULES:=
+ALL_MAKE_MODULE_INFO_JSON_MODULES:=
+
# The relative paths of the non-module targets in the system.
ALL_NON_MODULES:=
NON_MODULES_WITHOUT_LICENSE_METADATA:=
@@ -3120,14 +3122,12 @@
# Copies many init script files and check they are well-formed.
# $(1): The init script files to copy. Each entry is a ':' separated src:dst pair.
-# Evaluates to the list of the dst files. (ie suitable for a dependency list.)
define copy-many-init-script-files-checked
$(foreach f, $(1), $(strip \
$(eval _cmf_tuple := $(subst :, ,$(f))) \
$(eval _cmf_src := $(word 1,$(_cmf_tuple))) \
$(eval _cmf_dest := $(word 2,$(_cmf_tuple))) \
- $(eval $(call copy-init-script-file-checked,$(_cmf_src),$(_cmf_dest))) \
- $(_cmf_dest)))
+ $(eval $(call copy-init-script-file-checked,$(_cmf_src),$(_cmf_dest)))))
endef
# Copy the file only if it's a well-formed xml file. For use via $(eval).
@@ -3165,14 +3165,12 @@
# Copies many vintf manifest files checked.
# $(1): The files to copy. Each entry is a ':' separated src:dst pair
-# Evaluates to the list of the dst files (ie suitable for a dependency list)
define copy-many-vintf-manifest-files-checked
$(foreach f, $(1), $(strip \
$(eval _cmf_tuple := $(subst :, ,$(f))) \
$(eval _cmf_src := $(word 1,$(_cmf_tuple))) \
$(eval _cmf_dest := $(word 2,$(_cmf_tuple))) \
- $(eval $(call copy-vintf-manifest-checked,$(_cmf_src),$(_cmf_dest))) \
- $(_cmf_dest)))
+ $(eval $(call copy-vintf-manifest-checked,$(_cmf_src),$(_cmf_dest)))))
endef
# Copy the file only if it's not an ELF file. For use via $(eval).
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index eb5c63c..8546828 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -13,10 +13,15 @@
$(if $(strip $(2)),'$(COMMA)$(strip $(1)): "$(strip $(2))"')
endef
-$(MODULE_INFO_JSON):
+SOONG_MODULE_INFO := $(SOONG_OUT_DIR)/module-info-$(TARGET_PRODUCT).json
+
+$(MODULE_INFO_JSON): PRIVATE_SOONG_MODULE_INFO := $(SOONG_MODULE_INFO)
+$(MODULE_INFO_JSON): PRIVATE_MERGE_JSON_OBJECTS := $(HOST_OUT_EXECUTABLES)/merge_module_info_json
+$(MODULE_INFO_JSON): $(HOST_OUT_EXECUTABLES)/merge_module_info_json
+$(MODULE_INFO_JSON): $(SOONG_MODULE_INFO)
@echo Generating $@
- $(hide) echo -ne '{\n ' > $@
- $(hide) echo -ne $(KATI_foreach_sep m,$(COMMA)$(_NEWLINE), $(sort $(ALL_MODULES)),\
+ $(hide) echo -ne '{\n ' > $@.tmp
+ $(hide) echo -ne $(KATI_foreach_sep m,$(COMMA)$(_NEWLINE), $(sort $(ALL_MAKE_MODULE_INFO_JSON_MODULES)),\
'"$(m)": {' \
'"module_name": "$(ALL_MODULES.$(m).MODULE_NAME)"' \
$(call write-optional-json-list, "class", $(sort $(ALL_MODULES.$(m).CLASS))) \
@@ -43,7 +48,9 @@
$(call write-optional-json-list, "supported_variants", $(sort $(ALL_MODULES.$(m).SUPPORTED_VARIANTS))) \
$(call write-optional-json-list, "host_dependencies", $(sort $(ALL_MODULES.$(m).HOST_REQUIRED_FROM_TARGET))) \
$(call write-optional-json-list, "target_dependencies", $(sort $(ALL_MODULES.$(m).TARGET_REQUIRED_FROM_HOST))) \
- '}')'\n}\n' >> $@
+ '}')'\n}\n' >> $@.tmp
+ $(PRIVATE_MERGE_JSON_OBJECTS) -o $@ $(PRIVATE_SOONG_MODULE_INFO) $@.tmp
+ rm $@.tmp
droidcore-unbundled: $(MODULE_INFO_JSON)
diff --git a/target/product/OWNERS b/target/product/OWNERS
index 008e4a2..48d3f2a 100644
--- a/target/product/OWNERS
+++ b/target/product/OWNERS
@@ -1,4 +1,4 @@
-per-file runtime_libart.mk = calin@google.com, mast@google.com, ngeoffray@google.com, oth@google.com, rpl@google.com, vmarko@google.com
+per-file runtime_libart.mk = mast@google.com, ngeoffray@google.com, rpl@google.com, vmarko@google.com
# GSI
per-file gsi_release.mk = file:/target/product/gsi/OWNERS
@@ -7,4 +7,4 @@
# Android Go
per-file go_defaults.mk = gkaiser@google.com, kushg@google.com, rajekumar@google.com
per-file go_defaults_512.mk = gkaiser@google.com, kushg@google.com, rajekumar@google.com
-per-file go_defaults_common.mk = gkaiser@google.com, kushg@google.com, rajekumar@google.com
\ No newline at end of file
+per-file go_defaults_common.mk = gkaiser@google.com, kushg@google.com, rajekumar@google.com
diff --git a/tools/aconfig/Android.bp b/tools/aconfig/Android.bp
index 37be2dd..d5b5b8f 100644
--- a/tools/aconfig/Android.bp
+++ b/tools/aconfig/Android.bp
@@ -96,6 +96,12 @@
srcs: ["tests/test_exported.aconfig"],
}
+aconfig_declarations {
+ name: "aconfig.test.forcereadonly.flags",
+ package: "com.android.aconfig.test.forcereadonly",
+ srcs: ["tests/test_force_read_only.aconfig"],
+}
+
aconfig_values {
name: "aconfig.test.flag.values",
package: "com.android.aconfig.test",
@@ -125,6 +131,12 @@
mode: "exported",
}
+java_aconfig_library {
+ name: "aconfig_test_java_library_forcereadonly",
+ aconfig_declarations: "aconfig.test.forcereadonly.flags",
+ mode: "force-read-only",
+}
+
android_test {
name: "aconfig.test.java",
srcs: [
@@ -135,6 +147,7 @@
static_libs: [
"aconfig_test_java_library",
"aconfig_test_java_library_exported",
+ "aconfig_test_java_library_forcereadonly",
"androidx.test.rules",
"testng",
],
@@ -179,6 +192,12 @@
mode: "exported",
}
+cc_aconfig_library {
+ name: "aconfig_test_cpp_library_force_read_only_variant",
+ aconfig_declarations: "aconfig.test.flags",
+ mode: "force-read-only",
+}
+
cc_test {
name: "aconfig.test.cpp",
srcs: [
@@ -224,6 +243,21 @@
test_suites: ["general-tests"],
}
+cc_test {
+ name: "aconfig.test.cpp.force_read_only_mode",
+ srcs: [
+ "tests/aconfig_force_read_only_mode_test.cpp",
+ ],
+ static_libs: [
+ "aconfig_test_cpp_library_force_read_only_variant",
+ "libgmock",
+ ],
+ shared_libs: [
+ "server_configurable_flags",
+ ],
+ test_suites: ["general-tests"],
+}
+
rust_aconfig_library {
name: "libaconfig_test_rust_library",
crate_name: "aconfig_test_rust_library",
@@ -276,3 +310,21 @@
],
test_suites: ["general-tests"],
}
+
+rust_aconfig_library {
+ name: "libaconfig_test_rust_library_with_force_read_only_mode",
+ crate_name: "aconfig_test_rust_library",
+ aconfig_declarations: "aconfig.test.flags",
+ mode: "force-read-only",
+}
+
+rust_test {
+ name: "aconfig.force_read_only_mode.test.rust",
+ srcs: [
+ "tests/aconfig_force_read_only_mode_test.rs"
+ ],
+ rustlibs: [
+ "libaconfig_test_rust_library_with_force_read_only_mode",
+ ],
+ test_suites: ["general-tests"],
+}
diff --git a/tools/aconfig/src/codegen/cpp.rs b/tools/aconfig/src/codegen/cpp.rs
index d6bebba..1279d8e 100644
--- a/tools/aconfig/src/codegen/cpp.rs
+++ b/tools/aconfig/src/codegen/cpp.rs
@@ -51,8 +51,6 @@
readwrite,
readwrite_count,
is_test_mode: codegen_mode == CodegenMode::Test,
- is_prod_mode: codegen_mode == CodegenMode::Production,
- is_exported_mode: codegen_mode == CodegenMode::Exported,
class_elements,
};
@@ -96,8 +94,6 @@
pub readwrite: bool,
pub readwrite_count: i32,
pub is_test_mode: bool,
- pub is_prod_mode: bool,
- pub is_exported_mode: bool,
pub class_elements: Vec<ClassElement>,
}
@@ -485,6 +481,88 @@
#endif
"#;
+ const EXPORTED_FORCE_READ_ONLY_HEADER_EXPECTED: &str = r#"
+#pragma once
+
+#ifndef COM_ANDROID_ACONFIG_TEST
+#define COM_ANDROID_ACONFIG_TEST(FLAG) COM_ANDROID_ACONFIG_TEST_##FLAG
+#endif
+
+#ifndef COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO
+#define COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO true
+#endif
+
+#ifdef __cplusplus
+
+#include <memory>
+
+namespace com::android::aconfig::test {
+
+class flag_provider_interface {
+public:
+ virtual ~flag_provider_interface() = default;
+
+ virtual bool disabled_ro() = 0;
+
+ virtual bool disabled_rw() = 0;
+
+ virtual bool disabled_rw_in_other_namespace() = 0;
+
+ virtual bool enabled_fixed_ro() = 0;
+
+ virtual bool enabled_ro() = 0;
+
+ virtual bool enabled_rw() = 0;
+};
+
+extern std::unique_ptr<flag_provider_interface> provider_;
+
+inline bool disabled_ro() {
+ return false;
+}
+
+inline bool disabled_rw() {
+ return false;
+}
+
+inline bool disabled_rw_in_other_namespace() {
+ return false;
+}
+
+inline bool enabled_fixed_ro() {
+ return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
+}
+
+inline bool enabled_ro() {
+ return true;
+}
+
+inline bool enabled_rw() {
+ return true;
+}
+
+}
+
+extern "C" {
+#endif // __cplusplus
+
+bool com_android_aconfig_test_disabled_ro();
+
+bool com_android_aconfig_test_disabled_rw();
+
+bool com_android_aconfig_test_disabled_rw_in_other_namespace();
+
+bool com_android_aconfig_test_enabled_fixed_ro();
+
+bool com_android_aconfig_test_enabled_ro();
+
+bool com_android_aconfig_test_enabled_rw();
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+"#;
+
const PROD_SOURCE_FILE_EXPECTED: &str = r#"
#include "com_android_aconfig_test.h"
#include <server_configurable_flags/get_flags.h>
@@ -906,6 +984,69 @@
"#;
+ const FORCE_READ_ONLY_SOURCE_FILE_EXPECTED: &str = r#"
+#include "com_android_aconfig_test.h"
+
+namespace com::android::aconfig::test {
+
+ class flag_provider : public flag_provider_interface {
+ public:
+
+ virtual bool disabled_ro() override {
+ return false;
+ }
+
+ virtual bool disabled_rw() override {
+ return false;
+ }
+
+ virtual bool disabled_rw_in_other_namespace() override {
+ return false;
+ }
+
+ virtual bool enabled_fixed_ro() override {
+ return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
+ }
+
+ virtual bool enabled_ro() override {
+ return true;
+ }
+
+ virtual bool enabled_rw() override {
+ return true;
+ }
+ };
+
+ 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 false;
+}
+
+bool com_android_aconfig_test_disabled_rw_in_other_namespace() {
+ return false;
+}
+
+bool com_android_aconfig_test_enabled_fixed_ro() {
+ return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
+}
+
+bool com_android_aconfig_test_enabled_ro() {
+ return true;
+}
+
+bool com_android_aconfig_test_enabled_rw() {
+ return true;
+}
+
+"#;
+
const READ_ONLY_EXPORTED_PROD_HEADER_EXPECTED: &str = r#"
#pragma once
@@ -1095,6 +1236,17 @@
}
#[test]
+ fn test_generate_cpp_code_for_force_read_only() {
+ let parsed_flags = crate::test::parse_test_flags();
+ test_generate_cpp_code(
+ parsed_flags,
+ CodegenMode::ForceReadOnly,
+ EXPORTED_FORCE_READ_ONLY_HEADER_EXPECTED,
+ FORCE_READ_ONLY_SOURCE_FILE_EXPECTED,
+ );
+ }
+
+ #[test]
fn test_generate_cpp_code_for_read_only_prod() {
let parsed_flags = crate::test::parse_read_only_test_flags();
test_generate_cpp_code(
diff --git a/tools/aconfig/src/codegen/java.rs b/tools/aconfig/src/codegen/java.rs
index a02a7e2..f214fa5 100644
--- a/tools/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/src/codegen/java.rs
@@ -834,6 +834,228 @@
}
#[test]
+ fn test_generate_java_code_force_read_only() {
+ let parsed_flags = crate::test::parse_test_flags();
+ let mode = CodegenMode::ForceReadOnly;
+ let modified_parsed_flags =
+ crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode).unwrap();
+ let generated_files =
+ generate_java_code(crate::test::TEST_PACKAGE, modified_parsed_flags.into_iter(), mode)
+ .unwrap();
+ let expect_featureflags_content = r#"
+ package com.android.aconfig.test;
+ // TODO(b/303773055): Remove the annotation after access issue is resolved.
+ import android.compat.annotation.UnsupportedAppUsage;
+ /** @hide */
+ public interface FeatureFlags {
+ @com.android.aconfig.annotations.AssumeFalseForR8
+ @UnsupportedAppUsage
+ boolean disabledRo();
+ @com.android.aconfig.annotations.AssumeFalseForR8
+ @UnsupportedAppUsage
+ boolean disabledRw();
+ @com.android.aconfig.annotations.AssumeFalseForR8
+ @UnsupportedAppUsage
+ boolean disabledRwInOtherNamespace();
+ @com.android.aconfig.annotations.AssumeTrueForR8
+ @UnsupportedAppUsage
+ boolean enabledFixedRo();
+ @com.android.aconfig.annotations.AssumeTrueForR8
+ @UnsupportedAppUsage
+ boolean enabledRo();
+ @com.android.aconfig.annotations.AssumeTrueForR8
+ @UnsupportedAppUsage
+ boolean enabledRw();
+ }"#;
+
+ let expect_featureflagsimpl_content = r#"
+ package com.android.aconfig.test;
+ // TODO(b/303773055): Remove the annotation after access issue is resolved.
+ import android.compat.annotation.UnsupportedAppUsage;
+ /** @hide */
+ public final class FeatureFlagsImpl implements FeatureFlags {
+ @Override
+ @UnsupportedAppUsage
+ public boolean disabledRo() {
+ return false;
+ }
+ @Override
+ @UnsupportedAppUsage
+ public boolean disabledRw() {
+ return false;
+ }
+ @Override
+ @UnsupportedAppUsage
+ public boolean disabledRwInOtherNamespace() {
+ return false;
+ }
+ @Override
+ @UnsupportedAppUsage
+ public boolean enabledFixedRo() {
+ return true;
+ }
+ @Override
+ @UnsupportedAppUsage
+ public boolean enabledRo() {
+ return true;
+ }
+ @Override
+ @UnsupportedAppUsage
+ public boolean enabledRw() {
+ return true;
+ }
+ }
+ "#;
+
+ let expect_flags_content = r#"
+ package com.android.aconfig.test;
+ // TODO(b/303773055): Remove the annotation after access issue is resolved.
+ import android.compat.annotation.UnsupportedAppUsage;
+ /** @hide */
+ public final class Flags {
+ /** @hide */
+ public static final String FLAG_DISABLED_RO = "com.android.aconfig.test.disabled_ro";
+ /** @hide */
+ public static final String FLAG_DISABLED_RW = "com.android.aconfig.test.disabled_rw";
+ /** @hide */
+ public static final String FLAG_DISABLED_RW_IN_OTHER_NAMESPACE = "com.android.aconfig.test.disabled_rw_in_other_namespace";
+ /** @hide */
+ public static final String FLAG_ENABLED_FIXED_RO = "com.android.aconfig.test.enabled_fixed_ro";
+ /** @hide */
+ public static final String FLAG_ENABLED_RO = "com.android.aconfig.test.enabled_ro";
+ /** @hide */
+ public static final String FLAG_ENABLED_RW = "com.android.aconfig.test.enabled_rw";
+
+ @com.android.aconfig.annotations.AssumeFalseForR8
+ @UnsupportedAppUsage
+ public static boolean disabledRo() {
+ return FEATURE_FLAGS.disabledRo();
+ }
+ @com.android.aconfig.annotations.AssumeFalseForR8
+ @UnsupportedAppUsage
+ public static boolean disabledRw() {
+ return FEATURE_FLAGS.disabledRw();
+ }
+ @com.android.aconfig.annotations.AssumeFalseForR8
+ @UnsupportedAppUsage
+ public static boolean disabledRwInOtherNamespace() {
+ return FEATURE_FLAGS.disabledRwInOtherNamespace();
+ }
+ @com.android.aconfig.annotations.AssumeTrueForR8
+ @UnsupportedAppUsage
+ public static boolean enabledFixedRo() {
+ return FEATURE_FLAGS.enabledFixedRo();
+ }
+ @com.android.aconfig.annotations.AssumeTrueForR8
+ @UnsupportedAppUsage
+ public static boolean enabledRo() {
+ return FEATURE_FLAGS.enabledRo();
+ }
+ @com.android.aconfig.annotations.AssumeTrueForR8
+ @UnsupportedAppUsage
+ public static boolean enabledRw() {
+ return FEATURE_FLAGS.enabledRw();
+ }
+ private static FeatureFlags FEATURE_FLAGS = new FeatureFlagsImpl();
+ }"#;
+
+ let expect_fakefeatureflags_content = r#"
+ package com.android.aconfig.test;
+ // TODO(b/303773055): Remove the annotation after access issue is resolved.
+ import android.compat.annotation.UnsupportedAppUsage;
+ import java.util.HashMap;
+ import java.util.Map;
+ /** @hide */
+ public class FakeFeatureFlagsImpl implements FeatureFlags {
+ public FakeFeatureFlagsImpl() {
+ resetAll();
+ }
+ @Override
+ @UnsupportedAppUsage
+ public boolean disabledRo() {
+ return getValue(Flags.FLAG_DISABLED_RO);
+ }
+ @Override
+ @UnsupportedAppUsage
+ public boolean disabledRw() {
+ return getValue(Flags.FLAG_DISABLED_RW);
+ }
+ @Override
+ @UnsupportedAppUsage
+ public boolean disabledRwInOtherNamespace() {
+ return getValue(Flags.FLAG_DISABLED_RW_IN_OTHER_NAMESPACE);
+ }
+ @Override
+ @UnsupportedAppUsage
+ public boolean enabledFixedRo() {
+ return getValue(Flags.FLAG_ENABLED_FIXED_RO);
+ }
+ @Override
+ @UnsupportedAppUsage
+ public boolean enabledRo() {
+ return getValue(Flags.FLAG_ENABLED_RO);
+ }
+ @Override
+ @UnsupportedAppUsage
+ public boolean enabledRw() {
+ return getValue(Flags.FLAG_ENABLED_RW);
+ }
+ public void setFlag(String flagName, boolean value) {
+ if (!this.mFlagMap.containsKey(flagName)) {
+ throw new IllegalArgumentException("no such flag " + flagName);
+ }
+ this.mFlagMap.put(flagName, value);
+ }
+ public void resetAll() {
+ for (Map.Entry entry : mFlagMap.entrySet()) {
+ entry.setValue(null);
+ }
+ }
+ private boolean getValue(String flagName) {
+ Boolean value = this.mFlagMap.get(flagName);
+ if (value == null) {
+ throw new IllegalArgumentException(flagName + " is not set");
+ }
+ return value;
+ }
+ private Map<String, Boolean> mFlagMap = new HashMap<>(
+ Map.ofEntries(
+ Map.entry(Flags.FLAG_DISABLED_RO, false),
+ Map.entry(Flags.FLAG_DISABLED_RW, false),
+ Map.entry(Flags.FLAG_DISABLED_RW_IN_OTHER_NAMESPACE, false),
+ Map.entry(Flags.FLAG_ENABLED_FIXED_RO, false),
+ Map.entry(Flags.FLAG_ENABLED_RO, false),
+ Map.entry(Flags.FLAG_ENABLED_RW, false)
+ )
+ );
+ }
+ "#;
+ let mut file_set = HashMap::from([
+ ("com/android/aconfig/test/Flags.java", expect_flags_content),
+ ("com/android/aconfig/test/FeatureFlagsImpl.java", expect_featureflagsimpl_content),
+ ("com/android/aconfig/test/FeatureFlags.java", expect_featureflags_content),
+ ("com/android/aconfig/test/FakeFeatureFlagsImpl.java", expect_fakefeatureflags_content),
+ ]);
+
+ for file in generated_files {
+ let file_path = file.path.to_str().unwrap();
+ assert!(file_set.contains_key(file_path), "Cannot find {}", file_path);
+ assert_eq!(
+ None,
+ crate::test::first_significant_code_diff(
+ file_set.get(file_path).unwrap(),
+ &String::from_utf8(file.contents).unwrap()
+ ),
+ "File {} content is not correct",
+ file_path
+ );
+ file_set.remove(file_path);
+ }
+
+ assert!(file_set.is_empty());
+ }
+
+ #[test]
fn test_format_java_method_name() {
let expected = "someSnakeName";
let input = "____some_snake___name____";
diff --git a/tools/aconfig/src/codegen/mod.rs b/tools/aconfig/src/codegen/mod.rs
index 476d2b3..4af1327 100644
--- a/tools/aconfig/src/codegen/mod.rs
+++ b/tools/aconfig/src/codegen/mod.rs
@@ -56,6 +56,7 @@
#[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum)]
pub enum CodegenMode {
Exported,
+ ForceReadOnly,
Production,
Test,
}
@@ -64,6 +65,7 @@
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
CodegenMode::Exported => write!(f, "exported"),
+ CodegenMode::ForceReadOnly => write!(f, "force-read-only"),
CodegenMode::Production => write!(f, "production"),
CodegenMode::Test => write!(f, "test"),
}
diff --git a/tools/aconfig/src/codegen/rust.rs b/tools/aconfig/src/codegen/rust.rs
index 56cb311..8a88ffe 100644
--- a/tools/aconfig/src/codegen/rust.rs
+++ b/tools/aconfig/src/codegen/rust.rs
@@ -44,9 +44,10 @@
template.add_template(
"rust_code_gen",
match codegen_mode {
- CodegenMode::Production => include_str!("../../templates/rust_prod.template"),
CodegenMode::Test => include_str!("../../templates/rust_test.template"),
- CodegenMode::Exported => include_str!("../../templates/rust_exported.template"),
+ CodegenMode::Exported | CodegenMode::ForceReadOnly | CodegenMode::Production => {
+ include_str!("../../templates/rust.template")
+ }
},
)?;
let contents = template.render("rust_code_gen", &context)?;
@@ -554,6 +555,84 @@
}
"#;
+ const FORCE_READ_ONLY_EXPECTED: &str = r#"
+//! codegenerated rust flag lib
+
+/// flag provider
+pub struct FlagProvider;
+
+impl FlagProvider {
+ /// query flag disabled_ro
+ pub fn disabled_ro(&self) -> bool {
+ false
+ }
+
+ /// query flag disabled_rw
+ pub fn disabled_rw(&self) -> bool {
+ false
+ }
+
+ /// query flag disabled_rw_in_other_namespace
+ pub fn disabled_rw_in_other_namespace(&self) -> bool {
+ false
+ }
+
+ /// query flag enabled_fixed_ro
+ pub fn enabled_fixed_ro(&self) -> bool {
+ true
+ }
+
+ /// query flag enabled_ro
+ pub fn enabled_ro(&self) -> bool {
+ true
+ }
+
+ /// query flag enabled_rw
+ pub fn enabled_rw(&self) -> bool {
+ true
+ }
+}
+
+/// flag provider
+pub static PROVIDER: FlagProvider = FlagProvider;
+
+/// query flag disabled_ro
+#[inline(always)]
+pub fn disabled_ro() -> bool {
+ false
+}
+
+/// query flag disabled_rw
+#[inline(always)]
+pub fn disabled_rw() -> bool {
+ false
+}
+
+/// query flag disabled_rw_in_other_namespace
+#[inline(always)]
+pub fn disabled_rw_in_other_namespace() -> bool {
+ false
+}
+
+/// query flag enabled_fixed_ro
+#[inline(always)]
+pub fn enabled_fixed_ro() -> bool {
+ true
+}
+
+/// query flag enabled_ro
+#[inline(always)]
+pub fn enabled_ro() -> bool {
+ true
+}
+
+/// query flag enabled_rw
+#[inline(always)]
+pub fn enabled_rw() -> bool {
+ true
+}
+"#;
+
fn test_generate_rust_code(mode: CodegenMode) {
let parsed_flags = crate::test::parse_test_flags();
let modified_parsed_flags =
@@ -569,6 +648,7 @@
CodegenMode::Production => PROD_EXPECTED,
CodegenMode::Test => TEST_EXPECTED,
CodegenMode::Exported => EXPORTED_EXPECTED,
+ CodegenMode::ForceReadOnly => FORCE_READ_ONLY_EXPECTED,
},
&String::from_utf8(generated.contents).unwrap()
)
@@ -589,4 +669,9 @@
fn test_generate_rust_code_for_exported() {
test_generate_rust_code(CodegenMode::Exported);
}
+
+ #[test]
+ fn test_generate_rust_code_for_force_read_only() {
+ test_generate_rust_code(CodegenMode::ForceReadOnly);
+ }
}
diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index a121b5e..ffd89a3 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -332,6 +332,11 @@
parsed_flag
}
+ fn force_read_only_mode_flag_modifier(mut parsed_flag: ProtoParsedFlag) -> ProtoParsedFlag {
+ parsed_flag.set_permission(ProtoFlagPermission::READ_ONLY);
+ parsed_flag
+ }
+
let modified_parsed_flags: Vec<_> = match codegen_mode {
CodegenMode::Exported => parsed_flags
.parsed_flag
@@ -339,6 +344,12 @@
.filter(|pf| pf.is_exported())
.map(exported_mode_flag_modifier)
.collect(),
+ CodegenMode::ForceReadOnly => parsed_flags
+ .parsed_flag
+ .into_iter()
+ .filter(|pf| !pf.is_exported())
+ .map(force_read_only_mode_flag_modifier)
+ .collect(),
CodegenMode::Production | CodegenMode::Test => {
parsed_flags.parsed_flag.into_iter().collect()
}
@@ -694,4 +705,25 @@
]);
assert_eq!(flag_ids, expected_flag_ids);
}
+
+ #[test]
+ fn test_modify_parsed_flags_based_on_mode_force_read_only() {
+ let parsed_flags = crate::test::parse_test_flags();
+ let p_parsed_flags =
+ modify_parsed_flags_based_on_mode(parsed_flags.clone(), CodegenMode::ForceReadOnly)
+ .unwrap();
+ assert_eq!(6, p_parsed_flags.len());
+ for pf in p_parsed_flags {
+ assert_eq!(ProtoFlagPermission::READ_ONLY, pf.permission());
+ }
+
+ let mut parsed_flags = crate::test::parse_test_flags();
+ parsed_flags.parsed_flag.retain_mut(|pf| pf.is_exported());
+ let error = modify_parsed_flags_based_on_mode(parsed_flags, CodegenMode::ForceReadOnly)
+ .unwrap_err();
+ assert_eq!(
+ "force-read-only library contains no force-read-only flags",
+ format!("{:?}", error)
+ );
+ }
}
diff --git a/tools/aconfig/templates/cpp_exported_header.template b/tools/aconfig/templates/cpp_exported_header.template
index 6b6daa7..0f7853e 100644
--- a/tools/aconfig/templates/cpp_exported_header.template
+++ b/tools/aconfig/templates/cpp_exported_header.template
@@ -44,7 +44,6 @@
{{ -if is_test_mode }}
return provider_->{item.flag_name}();
{{ -else }}
- {{ -if is_prod_mode }}
{{ -if item.readwrite }}
return provider_->{item.flag_name}();
{{ -else }}
@@ -54,11 +53,6 @@
return {item.default_value};
{{ -endif }}
{{ -endif }}
- {{ -else }}
- {{ -if is_exported_mode }}
- return provider_->{item.flag_name}();
- {{ -endif }}
- {{ -endif }}
{{ -endif }}
}
diff --git a/tools/aconfig/templates/cpp_source_file.template b/tools/aconfig/templates/cpp_source_file.template
index 4aec540..4bcd1b7 100644
--- a/tools/aconfig/templates/cpp_source_file.template
+++ b/tools/aconfig/templates/cpp_source_file.template
@@ -59,7 +59,6 @@
{{ -for item in class_elements }}
virtual bool {item.flag_name}() override \{
- {{ -if is_prod_mode }}
{{ -if item.readwrite }}
if (cache_[{item.readwrite_idx}] == -1) \{
cache_[{item.readwrite_idx}] = server_configurable_flags::GetServerConfigurableFlag(
@@ -75,17 +74,6 @@
return {item.default_value};
{{ -endif }}
{{ -endif }}
- {{ -else- }}
- {{ -if is_exported_mode }}
- if (cache_[{item.readwrite_idx}] == -1) \{
- cache_[{item.readwrite_idx}] = server_configurable_flags::GetServerConfigurableFlag(
- "aconfig_flags.{item.device_config_namespace}",
- "{item.device_config_flag}",
- "false") == "true";
- }
- return cache_[{item.readwrite_idx}];
- {{ -endif }}
- {{ -endif }}
}
{{ -endfor }}
{{ if readwrite- }}
@@ -106,7 +94,6 @@
{{ -if is_test_mode }}
return {cpp_namespace}::{item.flag_name}();
{{ -else }}
- {{ -if is_prod_mode }}
{{ -if item.readwrite }}
return {cpp_namespace}::{item.flag_name}();
{{ -else }}
@@ -116,11 +103,6 @@
return {item.default_value};
{{ -endif }}
{{ -endif }}
- {{ -else }}
- {{ -if is_exported_mode }}
- return {cpp_namespace}::{item.flag_name}();
- {{ -endif }}
- {{ -endif }}
{{ -endif }}
}
diff --git a/tools/aconfig/templates/rust_prod.template b/tools/aconfig/templates/rust.template
similarity index 100%
rename from tools/aconfig/templates/rust_prod.template
rename to tools/aconfig/templates/rust.template
diff --git a/tools/aconfig/templates/rust_exported.template b/tools/aconfig/templates/rust_exported.template
deleted file mode 100644
index 110f2d4..0000000
--- a/tools/aconfig/templates/rust_exported.template
+++ /dev/null
@@ -1,35 +0,0 @@
-//! codegenerated rust flag lib
-
-/// flag provider
-pub struct FlagProvider;
-
-lazy_static::lazy_static! \{
-{{ for flag in template_flags }}
- /// flag value cache for {flag.name}
- static ref CACHED_{flag.name}: bool = flags_rust::GetServerConfigurableFlag(
- "aconfig_flags.{flag.device_config_namespace}",
- "{flag.device_config_flag}",
- "false") == "true";
-{{ endfor }}
-}
-
-impl FlagProvider \{
-{{ for flag in template_flags }}
- /// query flag {flag.name}
- pub fn {flag.name}(&self) -> bool \{
- *CACHED_{flag.name}
- }
-{{ endfor }}
-
-}
-
-/// flag provider
-pub static PROVIDER: FlagProvider = FlagProvider;
-
-{{ for flag in template_flags }}
-/// query flag {flag.name}
-#[inline(always)]
-pub fn {flag.name}() -> bool \{
- PROVIDER.{flag.name}()
-}
-{{ endfor }}
diff --git a/tools/aconfig/tests/AconfigTest.java b/tools/aconfig/tests/AconfigTest.java
index b2deca0..7e76efb 100644
--- a/tools/aconfig/tests/AconfigTest.java
+++ b/tools/aconfig/tests/AconfigTest.java
@@ -10,6 +10,7 @@
import static com.android.aconfig.test.Flags.enabledRw;
import static com.android.aconfig.test.exported.Flags.exportedFlag;
import static com.android.aconfig.test.exported.Flags.FLAG_EXPORTED_FLAG;
+import static com.android.aconfig.test.forcereadonly.Flags.froRw;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
@@ -66,4 +67,9 @@
assertEquals("com.android.aconfig.test.exported.exported_flag", FLAG_EXPORTED_FLAG);
assertFalse(exportedFlag());
}
+
+ @Test
+ public void testForceReadOnly() {
+ assertFalse(froRw());
+ }
}
diff --git a/tools/aconfig/tests/aconfig_force_read_only_mode_test.cpp b/tools/aconfig/tests/aconfig_force_read_only_mode_test.cpp
new file mode 100644
index 0000000..0dec481
--- /dev/null
+++ b/tools/aconfig/tests/aconfig_force_read_only_mode_test.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 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 "com_android_aconfig_test.h"
+#include "gtest/gtest.h"
+
+using namespace com::android::aconfig::test;
+
+TEST(AconfigTest, TestDisabledReadOnlyFlag) {
+ ASSERT_FALSE(com_android_aconfig_test_disabled_ro());
+ ASSERT_FALSE(provider_->disabled_ro());
+ ASSERT_FALSE(disabled_ro());
+}
+
+TEST(AconfigTest, TestEnabledReadOnlyFlag) {
+ ASSERT_TRUE(com_android_aconfig_test_enabled_ro());
+ ASSERT_TRUE(provider_->enabled_ro());
+ ASSERT_TRUE(enabled_ro());
+}
+
+TEST(AconfigTest, TestDisabledReadWriteFlag) {
+ ASSERT_FALSE(com_android_aconfig_test_disabled_rw());
+ ASSERT_FALSE(provider_->disabled_rw());
+ ASSERT_FALSE(disabled_rw());
+}
+
+TEST(AconfigTest, TestEnabledReadWriteFlag) {
+ ASSERT_TRUE(com_android_aconfig_test_enabled_rw());
+ ASSERT_TRUE(provider_->enabled_rw());
+ ASSERT_TRUE(enabled_rw());
+}
+
+TEST(AconfigTest, TestEnabledFixedReadOnlyFlag) {
+ ASSERT_TRUE(com_android_aconfig_test_enabled_fixed_ro());
+ ASSERT_TRUE(provider_->enabled_fixed_ro());
+ ASSERT_TRUE(enabled_fixed_ro());
+}
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/tools/aconfig/tests/aconfig_force_read_only_mode_test.rs b/tools/aconfig/tests/aconfig_force_read_only_mode_test.rs
new file mode 100644
index 0000000..4f05e26
--- /dev/null
+++ b/tools/aconfig/tests/aconfig_force_read_only_mode_test.rs
@@ -0,0 +1,10 @@
+#[cfg(not(feature = "cargo"))]
+#[test]
+fn test_flags() {
+ assert!(!aconfig_test_rust_library::disabled_ro());
+ assert!(!aconfig_test_rust_library::disabled_rw());
+ assert!(!aconfig_test_rust_library::disabled_rw_in_other_namespace());
+ assert!(aconfig_test_rust_library::enabled_fixed_ro());
+ assert!(aconfig_test_rust_library::enabled_ro());
+ assert!(aconfig_test_rust_library::enabled_rw());
+}
diff --git a/tools/aconfig/tests/test_force_read_only.aconfig b/tools/aconfig/tests/test_force_read_only.aconfig
new file mode 100644
index 0000000..05ab0e2
--- /dev/null
+++ b/tools/aconfig/tests/test_force_read_only.aconfig
@@ -0,0 +1,17 @@
+package: "com.android.aconfig.test.forcereadonly"
+container: "system"
+
+flag {
+ name: "fro_exported"
+ namespace: "aconfig_test"
+ description: "This is an exported flag"
+ is_exported: true
+ bug: "888"
+}
+
+flag {
+ name: "fro_rw"
+ namespace: "aconfig_test"
+ description: "This flag is not exported"
+ bug: "777"
+}
diff --git a/tools/perf/benchmarks b/tools/perf/benchmarks
index df4c87b..e188858 100755
--- a/tools/perf/benchmarks
+++ b/tools/perf/benchmarks
@@ -335,6 +335,7 @@
"--build-mode",
"--all-modules",
f"--dir={self._options.root}",
+ "--skip-metrics-upload",
] + modules
env = dict(os.environ)
env["TARGET_PRODUCT"] = lunch.target_product
diff --git a/tools/perf/format_benchmarks b/tools/perf/format_benchmarks
index c01aa76..845d73f 100755
--- a/tools/perf/format_benchmarks
+++ b/tools/perf/format_benchmarks
@@ -73,14 +73,6 @@
# Rows:
# Benchmark
-@dataclasses.dataclass(frozen=True)
-class Key():
- pass
-
-class Column():
- def __init__(self):
- pass
-
def lunch_str(d):
"Convert a lunch dict to a string"
return f"{d['TARGET_PRODUCT']}-{d['TARGET_RELEASE']}-{d['TARGET_BUILD_VARIANT']}"
@@ -186,7 +178,7 @@
for key, column in summary["columns"]:
for id, cell in column:
duration_ns = statistics.median([b["duration_ns"] for b in cell])
- table.Set(tuple([summary["date"].strftime("YYYY-MM-DD"),
+ table.Set(tuple([summary["date"].strftime("%Y-%m-%d"),
summary["branch"],
summary["tag"]]
+ list(key)),