diff options
80 files changed, 2323 insertions, 2163 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk index dfc0cd0fff..f8c96ffffe 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -779,6 +779,14 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/bazel/output/execroot/__main__/bazel-ou # Clear out rustc compiler intermediates after reverting rust compiler/linker split. $(call add-clean-step, find $(OUT_DIR) -name "*.rsp.whole.a" -print0 | xargs -0 /bin/bash -c 'rm -f $$$${@}; rm -f $$$${@/.rsp.whole.a/.rsp.a}; rm -f $$$${@/.rsp.whole.a/.rsp}') +# Remove obsolete java compilation artifacts +$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/) +$(call add-clean-step, find $(OUT_DIR) -type f -name "*.jar" -print0 | xargs -0 rm -f) + +# Remove obsolete java compilation artifacts +$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/) +$(call add-clean-step, find $(OUT_DIR) -type f -name "*.jar" -print0 | xargs -0 rm -f) + # ************************************************ # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST # ************************************************ diff --git a/METADATA b/METADATA deleted file mode 100644 index 44781a7088..0000000000 --- a/METADATA +++ /dev/null @@ -1,8 +0,0 @@ -third_party { - license_note: "would be NOTICE save for GPL in:\n" - " core/LINUX_KERNEL_COPYING\n" - " tools/droiddoc/templates-pdk/assets/jquery-1.6.2.min.js\n" - " tools/droiddoc/templates-pdk/assets/jquery-history.js\n" - " tools/droiddoc/templates-pdk/assets/jquery-resizable.min.js" - license_type: RESTRICTED -} diff --git a/core/Makefile b/core/Makefile index 00577edfa5..02deaddd82 100644 --- a/core/Makefile +++ b/core/Makefile @@ -3406,12 +3406,29 @@ endif FULL_SYSTEMIMAGE_DEPS += $(INTERNAL_ROOT_FILES) $(INSTALLED_FILES_FILE_ROOT) -define write-file-lines -$(1): +# Returns a list of EXTRA_INSTALL_ZIPS trios whose primary file is contained within $(1) +# The trios will contain the primary installed file : the directory to unzip the zip to : the zip +define relevant-extra-install-zips +$(strip $(foreach p,$(EXTRA_INSTALL_ZIPS), \ + $(if $(filter $(call word-colon,1,$(p)),$(1)), \ + $(p)))) +endef + +# Writes a text file that contains all of the files that will be inside a partition. +# All the file paths will be relative to the partition's staging directory. +# It will also take into account files inside zips listed in EXTRA_INSTALL_ZIPS. +# +# Arguments: +# $(1): Output file +# $(2): The partition's staging directory +# $(3): Files to include in the partition +define write-partition-file-list +$(1): $$(HOST_OUT_EXECUTABLES)/extra_install_zips_file_list $(foreach p,$(call relevant-extra-install-zips,$(filter $(2)/%,$(3))),$(call word-colon,3,$(p))) @echo Writing $$@ rm -f $$@ echo -n > $$@ - $$(foreach f,$(2),echo "$$(f)" >> $$@$$(newline)) + $$(foreach f,$(subst $(2)/,,$(filter $(2)/%,$(3))),echo "$$(f)" >> $$@$$(newline)) + $$(HOST_OUT_EXECUTABLES)/extra_install_zips_file_list $(2) $(call relevant-extra-install-zips,$(filter $(2)/%,$(3))) >> $$@ endef # ----------------------------------------------------------------- @@ -3477,7 +3494,7 @@ define build-systemimage-target exit 1 ) endef -$(eval $(call write-file-lines,$(systemimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT)/,,$(filter $(TARGET_OUT)/%,$(FULL_SYSTEMIMAGE_DEPS))))) +$(eval $(call write-partition-file-list,$(systemimage_intermediates)/file_list.txt,$(TARGET_OUT),$(FULL_SYSTEMIMAGE_DEPS))) # Used by soong sandwich to request the staging dir be built $(systemimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT)/%,$(FULL_SYSTEMIMAGE_DEPS)) touch $@ @@ -3594,7 +3611,7 @@ INSTALLED_USERDATAIMAGE_TARGET_DEPS := \ $(INTERNAL_USERIMAGES_DEPS) \ $(INTERNAL_USERDATAIMAGE_FILES) -$(eval $(call write-file-lines,$(userdataimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_DATA)/,,$(filter $(TARGET_OUT_DATA)/%,$(INSTALLED_USERDATAIMAGE_TARGET_DEPS))))) +$(eval $(call write-partition-file-list,$(userdataimage_intermediates)/file_list.txt,$(TARGET_OUT_DATA),$(INSTALLED_USERDATAIMAGE_TARGET_DEPS))) # Used by soong sandwich to request the staging dir be built $(userdataimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_DATA)/%,$(INSTALLED_USERDATAIMAGE_TARGET_DEPS)) touch $@ @@ -3650,7 +3667,7 @@ define build-cacheimage-target $(call assert-max-image-size,$(INSTALLED_CACHEIMAGE_TARGET),$(BOARD_CACHEIMAGE_PARTITION_SIZE)) endef -$(eval $(call write-file-lines,$(cacheimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_CACHE)/,,$(filter $(TARGET_OUT_CACHE)/%,$(INTERNAL_CACHEIMAGE_FILES))))) +$(eval $(call write-partition-file-list,$(cacheimage_intermediates)/file_list.txt,$(TARGET_OUT_CACHE),$(INTERNAL_CACHEIMAGE_FILES))) # Used by soong sandwich to request the staging dir be built $(cacheimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_CACHE)/%,$(INTERNAL_CACHEIMAGE_FILES)) touch $@ @@ -3737,7 +3754,7 @@ define build-systemotherimage-target $(call assert-max-image-size,$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)) endef -$(eval $(call write-file-lines,$(systemotherimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_SYSTEM_OTHER)/,,$(filter $(TARGET_OUT_SYSTEM_OTHER)/%,$(INTERNAL_SYSTEMOTHERIMAGE_FILES))))) +$(eval $(call write-partition-file-list,$(systemotherimage_intermediates)/file_list.txt,$(TARGET_OUT_SYSTEM_OTHER),$(INTERNAL_SYSTEMOTHERIMAGE_FILES))) # Used by soong sandwich to request the staging dir be built $(systemotherimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_SYSTEM_OTHER)/%,$(INTERNAL_SYSTEMOTHERIMAGE_FILES)) touch $@ @@ -3843,7 +3860,7 @@ define build-vendorimage-target $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET) $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_VENDORIMAGE_PARTITION_SIZE)) endef -$(eval $(call write-file-lines,$(vendorimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_VENDOR)/,,$(filter $(TARGET_OUT_VENDOR)/%,$(INTERNAL_VENDORIMAGE_FILES))))) +$(eval $(call write-partition-file-list,$(vendorimage_intermediates)/file_list.txt,$(TARGET_OUT_VENDOR),$(INTERNAL_VENDORIMAGE_FILES))) # Used by soong sandwich to request the staging dir be built $(vendorimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_VENDOR)/%,$(INTERNAL_VENDORIMAGE_FILES)) touch $@ @@ -3916,7 +3933,7 @@ define build-productimage-target $(call assert-max-image-size,$(INSTALLED_PRODUCTIMAGE_TARGET),$(BOARD_PRODUCTIMAGE_PARTITION_SIZE)) endef -$(eval $(call write-file-lines,$(productimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_PRODUCT)/,,$(filter $(TARGET_OUT_PRODUCT)/%,$(INTERNAL_PRODUCTIMAGE_FILES))))) +$(eval $(call write-partition-file-list,$(productimage_intermediates)/file_list.txt,$(TARGET_OUT_PRODUCT),$(INTERNAL_PRODUCTIMAGE_FILES))) # Used by soong sandwich to request the staging dir be built $(productimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_PRODUCT)/%,$(INTERNAL_PRODUCTIMAGE_FILES)) touch $@ @@ -3986,7 +4003,7 @@ define build-system_extimage-target $(call assert-max-image-size,$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET),$(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE)) endef -$(eval $(call write-file-lines,$(system_extimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_SYSTEM_EXT)/,,$(filter $(TARGET_OUT_SYSTEM_EXT)/%,$(INTERNAL_SYSTEM_EXTIMAGE_FILES))))) +$(eval $(call write-partition-file-list,$(system_extimage_intermediates)/file_list.txt,$(TARGET_OUT_SYSTEM_EXT),$(INTERNAL_SYSTEM_EXTIMAGE_FILES))) # Used by soong sandwich to request the staging dir be built $(system_extimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_SYSTEM_EXT)/%,$(INTERNAL_SYSTEM_EXTIMAGE_FILES)) touch $@ @@ -4075,7 +4092,7 @@ define build-odmimage-target $(call assert-max-image-size,$(INSTALLED_ODMIMAGE_TARGET),$(BOARD_ODMIMAGE_PARTITION_SIZE)) endef -$(eval $(call write-file-lines,$(odmimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_ODM)/,,$(filter $(TARGET_OUT_ODM)/%,$(INTERNAL_ODMIMAGE_FILES))))) +$(eval $(call write-partition-file-list,$(odmimage_intermediates)/file_list.txt,$(TARGET_OUT_ODM),$(INTERNAL_ODMIMAGE_FILES))) # Used by soong sandwich to request the staging dir be built $(odmimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_ODM)/%,$(INTERNAL_ODMIMAGE_FILES)) touch $@ @@ -4144,7 +4161,7 @@ define build-vendor_dlkmimage-target $(call assert-max-image-size,$(INSTALLED_VENDOR_DLKMIMAGE_TARGET),$(BOARD_VENDOR_DLKMIMAGE_PARTITION_SIZE)) endef -$(eval $(call write-file-lines,$(vendor_dlkmimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_VENDOR_DLKM)/,,$(filter $(TARGET_OUT_VENDOR_DLKM)/%,$(INTERNAL_VENDOR_DLKMIMAGE_FILES))))) +$(eval $(call write-partition-file-list,$(vendor_dlkmimage_intermediates)/file_list.txt,$(TARGET_OUT_VENDOR_DLKM),$(INTERNAL_VENDOR_DLKMIMAGE_FILES))) # Used by soong sandwich to request the staging dir be built $(vendor_dlkmimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_VENDOR_DLKM)/%,$(INTERNAL_VENDOR_DLKMIMAGE_FILES)) touch $@ @@ -4213,7 +4230,7 @@ define build-odm_dlkmimage-target $(call assert-max-image-size,$(INSTALLED_ODM_DLKMIMAGE_TARGET),$(BOARD_ODM_DLKMIMAGE_PARTITION_SIZE)) endef -$(eval $(call write-file-lines,$(odm_dlkmimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_ODM_DLKM)/,,$(filter $(TARGET_OUT_ODM_DLKM)/%,$(INTERNAL_ODM_DLKMIMAGE_FILES))))) +$(eval $(call write-partition-file-list,$(odm_dlkmimage_intermediates)/file_list.txt,$(TARGET_OUT_ODM_DLKM),$(INTERNAL_ODM_DLKMIMAGE_FILES))) # Used by soong sandwich to request the staging dir be built $(odm_dlkmimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_ODM_DLKM)/%,$(INTERNAL_ODM_DLKMIMAGE_FILES)) touch $@ @@ -4284,7 +4301,7 @@ define build-system_dlkmimage-target $(call assert-max-image-size,$(INSTALLED_SYSTEM_DLKMIMAGE_TARGET),$(BOARD_SYSTEM_DLKMIMAGE_PARTITION_SIZE)) endef -$(eval $(call write-file-lines,$(system_dlkmimage_intermediates)/file_list.txt,$(subst $(TARGET_OUT_SYSTEM_DLKM)/,,$(filter $(TARGET_OUT_SYSTEM_DLKM)/%,$(INTERNAL_SYSTEM_DLKMIMAGE_FILES))))) +$(eval $(call write-partition-file-list,$(system_dlkmimage_intermediates)/file_list.txt,$(TARGET_OUT_SYSTEM_DLKM),$(INTERNAL_SYSTEM_DLKMIMAGE_FILES))) # Used by soong sandwich to request the staging dir be built $(system_dlkmimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_SYSTEM_DLKM)/%,$(INTERNAL_SYSTEM_DLKMIMAGE_FILES)) touch $@ diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk index 56da5741e7..c43081e4a9 100644 --- a/core/android_soong_config_vars.mk +++ b/core/android_soong_config_vars.mk @@ -38,38 +38,6 @@ $(call add_soong_config_var,ANDROID,TARGET_DYNAMIC_64_32_MEDIASERVER) # PRODUCT_PRECOMPILED_SEPOLICY defaults to true. Explicitly check if it's "false" or not. $(call add_soong_config_var_value,ANDROID,PRODUCT_PRECOMPILED_SEPOLICY,$(if $(filter false,$(PRODUCT_PRECOMPILED_SEPOLICY)),false,true)) -# Default behavior for the tree wrt building modules or using prebuilts. This -# can always be overridden by setting the environment variable -# MODULE_BUILD_FROM_SOURCE. -BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := $(RELEASE_DEFAULT_MODULE_BUILD_FROM_SOURCE) -# TODO(b/301454934): The value from build flag is set to empty when use `False` -# The condition below can be removed after the issue get sorted. -ifeq (,$(BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE)) - BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := false -endif - -ifneq (,$(MODULE_BUILD_FROM_SOURCE)) - # Keep an explicit setting. -else ifeq (,$(filter docs sdk win_sdk sdk_addon,$(MAKECMDGOALS))) - MODULE_BUILD_FROM_SOURCE := true -else ifneq (,$(PRODUCT_MODULE_BUILD_FROM_SOURCE)) - # Let products override the branch default. - MODULE_BUILD_FROM_SOURCE := $(PRODUCT_MODULE_BUILD_FROM_SOURCE) -else - MODULE_BUILD_FROM_SOURCE := $(BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE) -endif - -ifneq (,$(ART_MODULE_BUILD_FROM_SOURCE)) - # Keep an explicit setting. -else ifneq (,$(findstring .android.art,$(TARGET_BUILD_APPS))) - # Build ART modules from source if they are listed in TARGET_BUILD_APPS. - ART_MODULE_BUILD_FROM_SOURCE := true -else - # Do the same as other modules by default. - ART_MODULE_BUILD_FROM_SOURCE := $(MODULE_BUILD_FROM_SOURCE) -endif - -$(call soong_config_set,art_module,source_build,$(ART_MODULE_BUILD_FROM_SOURCE)) ifdef ART_DEBUG_OPT_FLAG $(call soong_config_set,art_module,art_debug_opt_flag,$(ART_DEBUG_OPT_FLAG)) endif @@ -87,9 +55,10 @@ $(call add_soong_config_var_value,ANDROID,library_linking_strategy,prefer_static endif endif -ifeq (true,$(MODULE_BUILD_FROM_SOURCE)) +# TODO(b/308187800): some internal modules set `prefer` to true on the prebuilt apex module, +# and set that to false when `ANDROID.module_build_from_source` is true. +# Set this soong config variable to true for now, and cleanup `prefer` as part of b/308187800 $(call add_soong_config_var_value,ANDROID,module_build_from_source,true) -endif # Messaging app vars ifeq (eng,$(TARGET_BUILD_VARIANT)) @@ -125,6 +94,7 @@ $(call add_soong_config_var_value,ANDROID,release_avf_enable_device_assignment,$ $(call add_soong_config_var_value,ANDROID,release_avf_enable_dice_changes,$(RELEASE_AVF_ENABLE_DICE_CHANGES)) $(call add_soong_config_var_value,ANDROID,release_avf_enable_llpvm_changes,$(RELEASE_AVF_ENABLE_LLPVM_CHANGES)) $(call add_soong_config_var_value,ANDROID,release_avf_enable_multi_tenant_microdroid_vm,$(RELEASE_AVF_ENABLE_MULTI_TENANT_MICRODROID_VM)) +$(call add_soong_config_var_value,ANDROID,release_avf_enable_network,$(RELEASE_AVF_ENABLE_NETWORK)) $(call add_soong_config_var_value,ANDROID,release_avf_enable_remote_attestation,$(RELEASE_AVF_ENABLE_REMOTE_ATTESTATION)) $(call add_soong_config_var_value,ANDROID,release_avf_enable_vendor_modules,$(RELEASE_AVF_ENABLE_VENDOR_MODULES)) $(call add_soong_config_var_value,ANDROID,release_avf_enable_virt_cpufreq,$(RELEASE_AVF_ENABLE_VIRT_CPUFREQ)) diff --git a/core/art_config.mk b/core/art_config.mk index 47b4bcfce6..9e87a7bbe9 100644 --- a/core/art_config.mk +++ b/core/art_config.mk @@ -19,22 +19,19 @@ ifeq (,$(filter default true false,$(config_enable_uffd_gc))) endif ENABLE_UFFD_GC := $(config_enable_uffd_gc) -# If the value is "default", it will be mangled by post_process_props.py. -ADDITIONAL_PRODUCT_PROPERTIES += ro.dalvik.vm.enable_uffd_gc=$(config_enable_uffd_gc) # Create APEX_BOOT_JARS_EXCLUDED which is a list of jars to be removed from # ApexBoorJars when built from mainline prebuilts. -# soong variables indicate whether the prebuilt is enabled: -# - $(m)_module/source_build for art and TOGGLEABLE_PREBUILT_MODULES -# - ANDROID/module_build_from_source for other mainline modules # Note that RELEASE_APEX_BOOT_JARS_PREBUILT_EXCLUDED_LIST is the list of module names # and library names of jars that need to be removed. We have to keep separated list per # release config due to possibility of different prebuilt content. -APEX_BOOT_JARS_EXCLUDED := -$(foreach pair, $(RELEASE_APEX_BOOT_JARS_PREBUILT_EXCLUDED_LIST),\ - $(eval m := $(subst com.android.,,$(call word-colon,1,$(pair)))) \ - $(if $(call soong_config_get,$(m)_module,source_build), \ - $(if $(filter true,$(call soong_config_get,$(m)_module,source_build)),, \ - $(eval APEX_BOOT_JARS_EXCLUDED += $(pair))), \ - $(if $(filter true,$(call soong_config_get,ANDROID,module_build_from_source)),, \ - $(eval APEX_BOOT_JARS_EXCLUDED += $(pair))))) +# +# If a device has opted to not use google prebuilts (determined using +# PRODUCT_BUILD_IGNORE_APEX_CONTRIBUTION_CONTENTS), then no jars need to be removed. +# Example of products where PRODUCT_BUILD_IGNORE_APEX_CONTRIBUTION_CONTENTS is true are +# 1. aosp devices (they do not use google apexes) +# 2. hwasan devices (apex prebuilts are not compatible with these devices) +# 3. coverage builds +ifneq (true, $(PRODUCT_BUILD_IGNORE_APEX_CONTRIBUTION_CONTENTS)) + APEX_BOOT_JARS_EXCLUDED += $(RELEASE_APEX_BOOT_JARS_PREBUILT_EXCLUDED_LIST) +endif diff --git a/core/base_rules.mk b/core/base_rules.mk index 4c9281492a..9c7e906671 100644 --- a/core/base_rules.mk +++ b/core/base_rules.mk @@ -393,8 +393,8 @@ endif logtags_sources := $(filter %.logtags,$(LOCAL_SRC_FILES)) $(LOCAL_LOGTAGS_FILES) -ifneq ($(strip $(logtags_sources)),) -event_log_tags := $(foreach f,$(addprefix $(LOCAL_PATH)/,$(logtags_sources)),$(call clean-path,$(f))) +ifneq ($(strip $(logtags_sources) $(LOCAL_SOONG_LOGTAGS_FILES)),) +event_log_tags := $(foreach f,$(LOCAL_SOONG_LOGTAGS_FILES) $(addprefix $(LOCAL_PATH)/,$(logtags_sources)),$(call clean-path,$(f))) else event_log_tags := endif @@ -716,6 +716,14 @@ else test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml) endif +ifeq ($(EXCLUDE_MCTS),true) + ifneq (,$(test_config)) + ifneq (,$(filter mcts-%,$(LOCAL_COMPATIBILITY_SUITE))) + LOCAL_COMPATIBILITY_SUITE := $(filter-out cts,$(LOCAL_COMPATIBILITY_SUITE)) + endif + endif +endif + ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE)) # If we are building a native test or benchmark and its stem variants are not defined, diff --git a/core/binary.mk b/core/binary.mk index b17ab00aad..f86b5a464e 100644 --- a/core/binary.mk +++ b/core/binary.mk @@ -1196,6 +1196,17 @@ ifneq ($(filter hwaddress,$(my_sanitize)),) endif ################################################################### +## When compiling a memtag_stack enabled target, use the .memtag_stack variant +## of any static dependencies (where they exist). +################################################################## +ifneq ($(filter memtag_stack,$(my_sanitize)),) + my_whole_static_libraries := $(call use_soong_sanitized_static_libraries,\ + $(my_whole_static_libraries),memtag_stack) + my_static_libraries := $(call use_soong_sanitized_static_libraries,\ + $(my_static_libraries),memtag_stack) +endif + +################################################################### ## When compiling against API imported module, use API import stub ## libraries. ################################################################## diff --git a/core/board_config.mk b/core/board_config.mk index 633303f01a..e184601008 100644 --- a/core/board_config.mk +++ b/core/board_config.mk @@ -274,7 +274,7 @@ endif ifneq ($(MALLOC_IMPL),) $(warning *** Unsupported option MALLOC_IMPL defined by board config: $(board_config_mk).) - $(error Use `MALLOC_SVELTE := true` to configure jemalloc for low-memory) + $(error Use `MALLOC_LOW_MEMORY := true` to use low-memory allocator config) endif board_config_mk := diff --git a/core/build_id.mk b/core/build_id.mk index ce1b6fa724..dfba7c05f8 100644 --- a/core/build_id.mk +++ b/core/build_id.mk @@ -18,4 +18,4 @@ # (like "CRB01"). It must be a single word, and is # capitalized by convention. -BUILD_ID=RBT1.240501.002 +BUILD_ID=RBT1.240523.001 diff --git a/core/clear_vars.mk b/core/clear_vars.mk index 5481d50713..fb42878584 100644 --- a/core/clear_vars.mk +++ b/core/clear_vars.mk @@ -264,6 +264,7 @@ LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR := LOCAL_SOONG_LICENSE_METADATA := LOCAL_SOONG_LINK_TYPE := LOCAL_SOONG_LINT_REPORTS := +LOCAL_SOONG_LOGTAGS_FILES := LOCAL_SOONG_MODULE_INFO_JSON := LOCAL_SOONG_MODULE_TYPE := LOCAL_SOONG_PROGUARD_DICT := diff --git a/core/config.mk b/core/config.mk index aaf81177dd..ce11b1d558 100644 --- a/core/config.mk +++ b/core/config.mk @@ -1231,6 +1231,8 @@ BUILD_WARNING_BAD_OPTIONAL_USES_LIBS_ALLOWLIST := LegacyCamera Gallery2 # in the source tree. dont_bother_goals := out product-graph +include $(BUILD_SYSTEM)/sysprop_config.mk + # Make ANDROID Soong config variables visible to Android.mk files, for # consistency with those defined in BoardConfig.mk files. include $(BUILD_SYSTEM)/android_soong_config_vars.mk diff --git a/core/envsetup.mk b/core/envsetup.mk index 1c3a1b3b6b..3271079abc 100644 --- a/core/envsetup.mk +++ b/core/envsetup.mk @@ -255,6 +255,7 @@ endif HOST_PREBUILT_ARCH := x86 # This is the standard way to name a directory containing prebuilt host # objects. E.g., prebuilt/$(HOST_PREBUILT_TAG)/cc +# This must match the logic in get_host_prebuilt_prefix in envsetup.sh HOST_PREBUILT_TAG := $(BUILD_OS)-$(HOST_PREBUILT_ARCH) # TARGET_COPY_OUT_* are all relative to the staging directory, ie PRODUCT_OUT. diff --git a/core/main.mk b/core/main.mk index 8182740321..62fa53d08e 100644 --- a/core/main.mk +++ b/core/main.mk @@ -113,37 +113,8 @@ ifdef TARGET_ARCH_SUITE # $(error TARGET_ARCH_SUITE is not supported in kati/make builds) endif -# ADDITIONAL_<partition>_PROPERTIES are properties that are determined by the -# build system itself. Don't let it be defined from outside of the core build -# system like Android.mk or <product>.mk files. -_additional_prop_var_names := \ - ADDITIONAL_SYSTEM_PROPERTIES \ - ADDITIONAL_VENDOR_PROPERTIES \ - ADDITIONAL_ODM_PROPERTIES \ - ADDITIONAL_PRODUCT_PROPERTIES - -$(foreach name, $(_additional_prop_var_names),\ - $(if $($(name)),\ - $(error $(name) must not set before here. $($(name)))\ - ,)\ - $(eval $(name) :=)\ -) -_additional_prop_var_names := - $(KATI_obsolete_var ADDITIONAL_BUILD_PROPERTIES, Please use ADDITIONAL_SYSTEM_PROPERTIES) -# -# ----------------------------------------------------------------- -# Add the product-defined properties to the build properties. -ifneq ($(BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED), true) - ADDITIONAL_SYSTEM_PROPERTIES += $(PRODUCT_PROPERTY_OVERRIDES) -else - ifndef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE - ADDITIONAL_SYSTEM_PROPERTIES += $(PRODUCT_PROPERTY_OVERRIDES) - endif -endif - - # Bring in standard build system definitions. include $(BUILD_SYSTEM)/definitions.mk @@ -175,178 +146,8 @@ endif # PDK builds are no longer supported, this is always platform TARGET_BUILD_JAVA_SUPPORT_LEVEL :=$= platform -# ----------------------------------------------------------------- - -ADDITIONAL_SYSTEM_PROPERTIES += ro.treble.enabled=${PRODUCT_FULL_TREBLE} - $(KATI_obsolete_var PRODUCT_FULL_TREBLE,\ Code should be written to work regardless of a device being Treble) - -# Set ro.llndk.api_level to show the maximum vendor API level that the LLNDK in -# the system partition supports. -ifdef RELEASE_BOARD_API_LEVEL -ADDITIONAL_SYSTEM_PROPERTIES += ro.llndk.api_level=$(RELEASE_BOARD_API_LEVEL) -endif - -# Sets ro.actionable_compatible_property.enabled to know on runtime whether the -# allowed list of actionable compatible properties is enabled or not. -ADDITIONAL_SYSTEM_PROPERTIES += ro.actionable_compatible_property.enabled=true - -# Add the system server compiler filter if they are specified for the product. -ifneq (,$(PRODUCT_SYSTEM_SERVER_COMPILER_FILTER)) -ADDITIONAL_PRODUCT_PROPERTIES += dalvik.vm.systemservercompilerfilter=$(PRODUCT_SYSTEM_SERVER_COMPILER_FILTER) -endif - -# Add the 16K developer option if it is defined for the product. -ifeq ($(PRODUCT_16K_DEVELOPER_OPTION),true) -ADDITIONAL_PRODUCT_PROPERTIES += ro.product.build.16k_page.enabled=true -else -ADDITIONAL_PRODUCT_PROPERTIES += ro.product.build.16k_page.enabled=false -endif - -# Enable core platform API violation warnings on userdebug and eng builds. -ifneq ($(TARGET_BUILD_VARIANT),user) -ADDITIONAL_SYSTEM_PROPERTIES += persist.debug.dalvik.vm.core_platform_api_policy=just-warn -endif - -# Define ro.sanitize.<name> properties for all global sanitizers. -ADDITIONAL_SYSTEM_PROPERTIES += $(foreach s,$(SANITIZE_TARGET),ro.sanitize.$(s)=true) - -# Sets the default value of ro.postinstall.fstab.prefix to /system. -# Device board config should override the value to /product when needed by: -# -# PRODUCT_PRODUCT_PROPERTIES += ro.postinstall.fstab.prefix=/product -# -# It then uses ${ro.postinstall.fstab.prefix}/etc/fstab.postinstall to -# mount system_other partition. -ADDITIONAL_SYSTEM_PROPERTIES += ro.postinstall.fstab.prefix=/system - -# Add cpu properties for bionic and ART. -ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.arch=$(TARGET_ARCH) -ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.cpu_variant=$(TARGET_CPU_VARIANT_RUNTIME) -ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.2nd_arch=$(TARGET_2ND_ARCH) -ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.2nd_cpu_variant=$(TARGET_2ND_CPU_VARIANT_RUNTIME) - -ADDITIONAL_VENDOR_PROPERTIES += persist.sys.dalvik.vm.lib.2=libart.so -ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_ARCH).variant=$(DEX2OAT_TARGET_CPU_VARIANT_RUNTIME) -ifneq ($(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES),) - ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_ARCH).features=$(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) -endif - -ifdef TARGET_2ND_ARCH - ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_2ND_ARCH).variant=$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT_RUNTIME) - ifneq ($($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES),) - ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_2ND_ARCH).features=$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) - endif -endif - -# Although these variables are prefixed with TARGET_RECOVERY_, they are also needed under charger -# mode (via libminui). -ifdef TARGET_RECOVERY_DEFAULT_ROTATION -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.minui.default_rotation=$(TARGET_RECOVERY_DEFAULT_ROTATION) -endif -ifdef TARGET_RECOVERY_OVERSCAN_PERCENT -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.minui.overscan_percent=$(TARGET_RECOVERY_OVERSCAN_PERCENT) -endif -ifdef TARGET_RECOVERY_PIXEL_FORMAT -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.minui.pixel_format=$(TARGET_RECOVERY_PIXEL_FORMAT) -endif - -ifdef PRODUCT_USE_DYNAMIC_PARTITIONS -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.boot.dynamic_partitions=$(PRODUCT_USE_DYNAMIC_PARTITIONS) -endif - -ifdef PRODUCT_RETROFIT_DYNAMIC_PARTITIONS -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.boot.dynamic_partitions_retrofit=$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS) -endif - -ifdef PRODUCT_SHIPPING_API_LEVEL -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.product.first_api_level=$(PRODUCT_SHIPPING_API_LEVEL) -endif - -ifdef PRODUCT_SHIPPING_VENDOR_API_LEVEL -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.vendor.api_level=$(PRODUCT_SHIPPING_VENDOR_API_LEVEL) -endif - -ifneq ($(TARGET_BUILD_VARIANT),user) - ifdef PRODUCT_SET_DEBUGFS_RESTRICTIONS - ADDITIONAL_VENDOR_PROPERTIES += \ - ro.product.debugfs_restrictions.enabled=$(PRODUCT_SET_DEBUGFS_RESTRICTIONS) - endif -endif - -# Vendors with GRF must define BOARD_SHIPPING_API_LEVEL for the vendor API level. -# This must not be defined for the non-GRF devices. -# The values of the GRF properties will be verified by post_process_props.py -ifdef BOARD_SHIPPING_API_LEVEL -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.board.first_api_level=$(BOARD_SHIPPING_API_LEVEL) -endif - -# Build system set BOARD_API_LEVEL to show the api level of the vendor API surface. -# This must not be altered outside of build system. -ifdef BOARD_API_LEVEL -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.board.api_level=$(BOARD_API_LEVEL) -endif -# RELEASE_BOARD_API_LEVEL_FROZEN is true when the vendor API surface is frozen. -ifdef RELEASE_BOARD_API_LEVEL_FROZEN -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.board.api_frozen=$(RELEASE_BOARD_API_LEVEL_FROZEN) -endif - -# Set build prop. This prop is read by ota_from_target_files when generating OTA, -# to decide if VABC should be disabled. -ifeq ($(BOARD_DONT_USE_VABC_OTA),true) -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.vendor.build.dont_use_vabc=true -endif - -# Set the flag in vendor. So VTS would know if the new fingerprint format is in use when -# the system images are replaced by GSI. -ifeq ($(BOARD_USE_VBMETA_DIGTEST_IN_FINGERPRINT),true) -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.vendor.build.fingerprint_has_digest=1 -endif - -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.vendor.build.security_patch=$(VENDOR_SECURITY_PATCH) \ - ro.product.board=$(TARGET_BOOTLOADER_BOARD_NAME) \ - ro.board.platform=$(TARGET_BOARD_PLATFORM) \ - ro.hwui.use_vulkan=$(TARGET_USES_VULKAN) - -ifdef TARGET_SCREEN_DENSITY -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.sf.lcd_density=$(TARGET_SCREEN_DENSITY) -endif - -ifdef AB_OTA_UPDATER -ADDITIONAL_VENDOR_PROPERTIES += \ - ro.build.ab_update=$(AB_OTA_UPDATER) -endif - -ADDITIONAL_PRODUCT_PROPERTIES += ro.build.characteristics=$(TARGET_AAPT_CHARACTERISTICS) - -ifeq ($(AB_OTA_UPDATER),true) -ADDITIONAL_PRODUCT_PROPERTIES += ro.product.ab_ota_partitions=$(subst $(space),$(comma),$(sort $(AB_OTA_PARTITIONS))) -ADDITIONAL_VENDOR_PROPERTIES += ro.vendor.build.ab_ota_partitions=$(subst $(space),$(comma),$(sort $(AB_OTA_PARTITIONS))) -endif - -# Set this property for VTS to skip large page size tests on unsupported devices. -ADDITIONAL_PRODUCT_PROPERTIES += \ - ro.product.cpu.pagesize.max=$(TARGET_MAX_PAGE_SIZE_SUPPORTED) - -ifeq ($(PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO),true) -ADDITIONAL_PRODUCT_PROPERTIES += ro.product.build.no_bionic_page_size_macro=true -endif - # ----------------------------------------------------------------- ### ### In this section we set up the things that are different @@ -359,66 +160,15 @@ ifneq ($(filter sdk sdk_addon,$(MAKECMDGOALS)),) is_sdk_build := true endif -## user/userdebug ## - -user_variant := $(filter user userdebug,$(TARGET_BUILD_VARIANT)) -enable_target_debugging := true tags_to_install := -ifneq (,$(user_variant)) - # Target is secure in user builds. - ADDITIONAL_SYSTEM_PROPERTIES += ro.secure=1 - ADDITIONAL_SYSTEM_PROPERTIES += security.perf_harden=1 - ifeq ($(user_variant),user) - ADDITIONAL_SYSTEM_PROPERTIES += ro.adb.secure=1 - endif - - ifeq ($(user_variant),userdebug) - # Pick up some extra useful tools - tags_to_install += debug - else - # Disable debugging in plain user builds. - enable_target_debugging := - endif - - # Disallow mock locations by default for user builds - ADDITIONAL_SYSTEM_PROPERTIES += ro.allow.mock.location=0 - -else # !user_variant - # Turn on checkjni for non-user builds. - ADDITIONAL_SYSTEM_PROPERTIES += ro.kernel.android.checkjni=1 - # Set device insecure for non-user builds. - ADDITIONAL_SYSTEM_PROPERTIES += ro.secure=0 - # Allow mock locations by default for non user builds - ADDITIONAL_SYSTEM_PROPERTIES += ro.allow.mock.location=1 -endif # !user_variant - -ifeq (true,$(strip $(enable_target_debugging))) - # Target is more debuggable and adbd is on by default - ADDITIONAL_SYSTEM_PROPERTIES += ro.debuggable=1 - # Enable Dalvik lock contention logging. - ADDITIONAL_SYSTEM_PROPERTIES += dalvik.vm.lockprof.threshold=500 -else # !enable_target_debugging - # Target is less debuggable and adbd is off by default - ADDITIONAL_SYSTEM_PROPERTIES += ro.debuggable=0 -endif # !enable_target_debugging - -## eng ## +ifeq ($(TARGET_BUILD_VARIANT),userdebug) +# Pick up some extra useful tools +tags_to_install := debug +endif ifeq ($(TARGET_BUILD_VARIANT),eng) tags_to_install := debug eng -ifneq ($(filter ro.setupwizard.mode=ENABLED, $(call collapse-pairs, $(ADDITIONAL_SYSTEM_PROPERTIES))),) - # Don't require the setup wizard on eng builds - ADDITIONAL_SYSTEM_PROPERTIES := $(filter-out ro.setupwizard.mode=%,\ - $(call collapse-pairs, $(ADDITIONAL_SYSTEM_PROPERTIES))) \ - ro.setupwizard.mode=OPTIONAL -endif -ifndef is_sdk_build - # To speedup startup of non-preopted builds, don't verify or compile the boot image. - ADDITIONAL_SYSTEM_PROPERTIES += dalvik.vm.image-dex2oat-filter=extract -endif -# b/323566535 -ADDITIONAL_SYSTEM_PROPERTIES += init.svc_debug.no_fatal.zygote=true endif ## asan ## @@ -454,18 +204,11 @@ endif # TODO: this should be eng I think. Since the sdk is built from the eng # variant. tags_to_install := debug eng -ADDITIONAL_SYSTEM_PROPERTIES += xmpp.auto-presence=true -ADDITIONAL_SYSTEM_PROPERTIES += ro.config.nocheckin=yes else # !sdk endif BUILD_WITHOUT_PV := true -ADDITIONAL_SYSTEM_PROPERTIES += net.bt.name=Android - -# This property is set by flashing debug boot image, so default to false. -ADDITIONAL_SYSTEM_PROPERTIES += ro.force.debuggable=0 - # ------------------------------------------------------------ # Define a function that, given a list of module tags, returns # non-empty if that module should be installed in /system. @@ -506,10 +249,6 @@ include $(BUILD_SYSTEM)/dex_preopt.mk # Strip and readonly a few more variables so they won't be modified. $(readonly-final-product-vars) -ADDITIONAL_SYSTEM_PROPERTIES := $(strip $(ADDITIONAL_SYSTEM_PROPERTIES)) -.KATI_READONLY := ADDITIONAL_SYSTEM_PROPERTIES -ADDITIONAL_PRODUCT_PROPERTIES := $(strip $(ADDITIONAL_PRODUCT_PROPERTIES)) -.KATI_READONLY := ADDITIONAL_PRODUCT_PROPERTIES ifneq ($(PRODUCT_ENFORCE_RRO_TARGETS),) ENFORCE_RRO_SOURCES := diff --git a/core/product.mk b/core/product.mk index f8634efd25..15faf7d88f 100644 --- a/core/product.mk +++ b/core/product.mk @@ -418,8 +418,9 @@ _product_single_value_vars += PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT # /system/etc/security/fsverity/BuildManifest.apk _product_single_value_vars += PRODUCT_FSVERITY_GENERATE_METADATA -# If true, sets the default for MODULE_BUILD_FROM_SOURCE. This overrides -# BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE but not an explicitly set value. +# If true, this builds the mainline modules from source. This overrides any +# prebuilts selected via RELEASE_APEX_CONTRIBUTIONS_* build flags for the +# current release config. _product_single_value_vars += PRODUCT_MODULE_BUILD_FROM_SOURCE # If true, installs a full version of com.android.virt APEX. @@ -446,7 +447,8 @@ _product_list_vars += PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS # device may have to re-compile everything on the first boot if the kernel doesn't support # userfaultfd # - "false": disallows the build system and the runtime to use userfaultfd GC even if the device -# supports it +# supports it. This option is temporary - the plan is to remove it by Aug 2025, at which time +# Mainline updates of the ART module will ignore it as well. _product_single_value_vars += PRODUCT_ENABLE_UFFD_GC # Specifies COW version to be used by update_engine and libsnapshot. If this value is not @@ -482,6 +484,9 @@ _product_single_value_vars += PRODUCT_EXPORT_RUNTIME_APIS # TODO(b/325991735): link to documentation once it is done. _product_single_value_vars += PRODUCT_AVF_MICRODROID_GUEST_GKI_VERSION +# Enables 16KB developer option for device if set. +_product_single_value_vars += PRODUCT_16K_DEVELOPER_OPTION + .KATI_READONLY := _product_single_value_vars _product_list_vars _product_var_list :=$= $(_product_single_value_vars) $(_product_list_vars) diff --git a/core/proguard/kotlin.flags b/core/proguard/kotlin.flags index 70dbaa7e81..ef6bf0e9e3 100644 --- a/core/proguard/kotlin.flags +++ b/core/proguard/kotlin.flags @@ -10,7 +10,9 @@ # Kotlin DebugMetadata has no value in release builds, these two rules, will # allow AppReduce to strip out DebutMetadata. --checkdiscard interface kotlin.coroutines.jvm.internal.DebugMetadata +# TODO(b/302383328): Restore the below checkdiscard after resolving transitive +# inclusion of kotlin-stdlib from androidx.annotation library deps. +# -checkdiscard interface kotlin.coroutines.jvm.internal.DebugMetadata -assumenosideeffects class kotlin.coroutines.jvm.internal.DebugMetadataKt { *** getDebugMetadataAnnotation(...); } diff --git a/core/release_config.mk b/core/release_config.mk index 3e51af5a44..e3ec3a06d3 100644 --- a/core/release_config.mk +++ b/core/release_config.mk @@ -14,6 +14,16 @@ # ----------------------------------------------------------------- +# Determine which pass this is. +# ----------------------------------------------------------------- +# On the first pass, we are asked for only PRODUCT_RELEASE_CONFIG_MAPS, +# on the second pass, we are asked for whatever else is wanted. +_final_product_config_pass:= +ifneq (PRODUCT_RELEASE_CONFIG_MAPS,$(DUMP_MANY_VARS)) + _final_product_config_pass:=true +endif + +# ----------------------------------------------------------------- # Choose the flag files # ----------------------------------------------------------------- # Release configs are defined in reflease_config_map files, which map @@ -41,6 +51,7 @@ # which has OWNERS control. If it isn't let others define their own. # TODO: Remove wildcard for build/release one when all branch manifests # have updated. +_must_protobuf := config_map_files := $(wildcard build/release/release_config_map.mk) \ $(wildcard vendor/google_shared/build/release/release_config_map.mk) \ $(if $(wildcard vendor/google/release/release_config_map.mk), \ @@ -53,13 +64,96 @@ config_map_files := $(wildcard build/release/release_config_map.mk) \ ) \ ) +protobuf_map_files := $(wildcard build/release/release_config_map.textproto) \ + $(wildcard vendor/google_shared/build/release/release_config_map.textproto) \ + $(if $(wildcard vendor/google/release/release_config_map.textproto), \ + vendor/google/release/release_config_map.textproto, \ + $(sort \ + $(wildcard device/*/release/release_config_map.textproto) \ + $(wildcard device/*/*/release/release_config_map.textproto) \ + $(wildcard vendor/*/release/release_config_map.textproto) \ + $(wildcard vendor/*/*/release/release_config_map.textproto) \ + ) \ + ) + # PRODUCT_RELEASE_CONFIG_MAPS is set by Soong using an initial run of product # config to capture only the list of config maps needed by the build. # Keep them in the order provided, but remove duplicates. +# Treat .mk and .textproto as equal for duplicate elimination, but force +# protobuf if any PRODUCT_RELEASE_CONFIG_MAPS specify .textproto. $(foreach map,$(PRODUCT_RELEASE_CONFIG_MAPS), \ - $(if $(filter $(map),$(config_map_files)),,$(eval config_map_files += $(map))) \ + $(if $(filter $(basename $(map)),$(basename $(config_map_files))),, \ + $(eval config_map_files += $(map))) \ + $(if $(filter $(basename $(map)).textproto,$(map)),$(eval _must_protobuf := true)) \ ) + +# If we are missing the textproto version of any of $(config_map_files), we cannot use protobuf. +_can_protobuf := true +$(foreach map,$(config_map_files), \ + $(if $(wildcard $(basename $(map)).textproto),,$(eval _can_protobuf :=)) \ +) +# If we are missing the mk version of any of $(protobuf_map_files), we must use protobuf. +$(foreach map,$(protobuf_map_files), \ + $(if $(wildcard $(basename $(map)).mk),,$(eval _must_protobuf := true)) \ +) + +ifneq (,$(_must_protobuf)) + ifeq (,$(_can_protobuf)) + # We must use protobuf, but we cannot use protobuf. + $(error release config is a mixture of .scl and .textproto) + endif +endif + +_use_protobuf := +ifneq (,$(_must_protobuf)) + _use_protobuf := true +else + ifneq ($(_can_protobuf),) + # Determine the default + $(foreach map,$(config_map_files), \ + $(if $(wildcard $(dir $(map))/build_config/DEFAULT=proto),$(eval _use_protobuf := true)) \ + $(if $(wildcard $(dir $(map))/build_config/DEFAULT=make),$(eval _use_protobuf := )) \ + ) + # Update for this specific release config only (no inheritance). + $(foreach map,$(config_map_files), \ + $(if $(wildcard $(dir $(map))/build_config/$(TARGET_RELEASE)=proto),$(eval _use_protobuf := true)) \ + $(if $(wildcard $(dir $(map))/build_config/$(TARGET_RELEASE)=make),$(eval _use_protobuf := )) \ + ) + endif +endif + +ifneq (,$(_use_protobuf)) + # The .textproto files are the canonical source of truth. + _args := $(foreach map,$(config_map_files), --map $(map) ) + ifneq (,$(_must_protobuf)) + # Disable the build flag in release-config. + _args += --guard=false + endif + _flags_file:=$(OUT_DIR)/soong/release-config/release_config-$(TARGET_PRODUCT)-$(TARGET_RELEASE).vars + # release-config generates $(_flags_varmk) + _flags_varmk:=$(_flags_file:.vars=.varmk) + $(shell $(OUT_DIR)/release-config $(_args) >$(OUT_DIR)/release-config.out && touch -t 200001010000 $(_flags_varmk)) + $(if $(filter-out 0,$(.SHELLSTATUS)),$(error release-config failed to run)) + ifneq (,$(_final_product_config_pass)) + # Save the final version of the config. + $(shell if ! cmp --quiet $(_flags_varmk) $(_flags_file); then cp $(_flags_varmk) $(_flags_file); fi) + # This will also set _all_release_configs and _used_files for us. + $(eval include $(_flags_file)) + $(KATI_extra_file_deps $(OUT_DIR)/release-config $(protobuf_map_files) $(_flags_file)) + else + # This is the first pass of product config. + $(eval include $(_flags_varmk)) + endif + _used_files := + ifeq (,$(_must_protobuf)$(RELEASE_BUILD_FLAGS_IN_PROTOBUF)) + _use_protobuf := + endif +endif +ifeq (,$(_use_protobuf)) + # The .mk files are the canonical source of truth. + + # Declare an alias release-config # # This should be used to declare a release as an alias of another, meaning no @@ -144,6 +238,9 @@ $(foreach r,$(_all_release_configs),\ $(error Alias release config "$(r)" may not specify release config files $(_all_release_configs.$(r).FILES))\ ))) +# Use makefiles +endif + ifeq ($(TARGET_RELEASE),) # We allow some internal paths to explicitly set TARGET_RELEASE to the # empty string. For the most part, 'make' treats unset and empty string as @@ -161,12 +258,13 @@ endif # During pass 1 of product config, using a non-existent release config is not an error. # We can safely assume that we are doing pass 1 if DUMP_MANY_VARS=="PRODUCT_RELEASE_CONFIG_MAPS". -ifneq (PRODUCT_RELEASE_CONFIG_MAPS,$(DUMP_MANY_VARS)) +ifneq (,$(_final_product_config_pass)) ifeq ($(filter $(_all_release_configs), $(TARGET_RELEASE)),) $(error No release config found for TARGET_RELEASE: $(TARGET_RELEASE). Available releases are: $(_all_release_configs)) endif endif +ifeq (,$(_use_protobuf)) # Choose flag files # Don't sort this, use it in the order they gave us. # Do allow duplicate entries, retaining only the first usage. @@ -196,6 +294,9 @@ define _apply-release-config-overrides $(error invalid use of apply-release-config-overrides) endef +# use makefiles +endif + # TODO: Remove this check after enough people have sourced lunch that we don't # need to worry about it trying to do get_build_vars TARGET_RELEASE. Maybe after ~9/2023 ifneq ($(CALLED_FROM_SETUP),true) @@ -207,15 +308,20 @@ TARGET_RELEASE:= endif .KATI_READONLY := TARGET_RELEASE +ifeq (,$(_use_protobuf)) $(foreach config, $(_all_release_configs), \ $(eval _all_release_configs.$(config).DECLARED_IN:= ) \ $(eval _all_release_configs.$(config).FILES:= ) \ ) +applied_releases:= +# use makefiles +endif _all_release_configs:= config_map_files:= -applied_releases:= +protobuf_map_files:= +ifeq (,$(_use_protobuf)) # ----------------------------------------------------------------- # Flag declarations and values # ----------------------------------------------------------------- @@ -252,3 +358,8 @@ filename_to_starlark:= # outside of the source tree. $(call run-starlark,$(OUT_DIR)/release_config_entrypoint.scl,$(OUT_DIR)/release_config_entrypoint.scl,--allow_external_entrypoint) +# use makefiles +endif +_can_protobuf := +_must_protobuf := +_use_protobuf := diff --git a/core/soong_config.mk b/core/soong_config.mk index 534270e308..7300e8cf9a 100644 --- a/core/soong_config.mk +++ b/core/soong_config.mk @@ -154,7 +154,7 @@ $(call add_json_list, ExtraVndkVersions, $(PRODUCT_EXTRA_VNDK_VE $(call add_json_list, DeviceSystemSdkVersions, $(BOARD_SYSTEMSDK_VERSIONS)) $(call add_json_str, RecoverySnapshotVersion, $(RECOVERY_SNAPSHOT_VERSION)) $(call add_json_list, Platform_systemsdk_versions, $(PLATFORM_SYSTEMSDK_VERSIONS)) -$(call add_json_bool, Malloc_not_svelte, $(call invert_bool,$(filter true,$(MALLOC_SVELTE)))) +$(call add_json_bool, Malloc_low_memory, $(findstring true,$(MALLOC_SVELTE) $(MALLOC_LOW_MEMORY))) $(call add_json_bool, Malloc_zero_contents, $(call invert_bool,$(filter false,$(MALLOC_ZERO_CONTENTS)))) $(call add_json_bool, Malloc_pattern_fill_contents, $(MALLOC_PATTERN_FILL_CONTENTS)) $(call add_json_str, Override_rs_driver, $(OVERRIDE_RS_DRIVER)) @@ -174,6 +174,10 @@ $(call add_json_map, BuildFlags) $(foreach flag,$(_ALL_RELEASE_FLAGS),\ $(call add_json_str,$(flag),$(_ALL_RELEASE_FLAGS.$(flag).VALUE))) $(call end_json_map) +$(call add_json_map, BuildFlagTypes) +$(foreach flag,$(_ALL_RELEASE_FLAGS),\ + $(call add_json_str,$(flag),$(_ALL_RELEASE_FLAGS.$(flag).TYPE))) +$(call end_json_map) $(call add_json_bool, DirectedVendorSnapshot, $(DIRECTED_VENDOR_SNAPSHOT)) $(call add_json_map, VendorSnapshotModules) diff --git a/core/sysprop_config.mk b/core/sysprop_config.mk new file mode 100644 index 0000000000..e8428c8eaf --- /dev/null +++ b/core/sysprop_config.mk @@ -0,0 +1,281 @@ +# ADDITIONAL_<partition>_PROPERTIES are properties that are determined by the +# build system itself. Don't let it be defined from outside of the core build +# system like Android.mk or <product>.mk files. +_additional_prop_var_names := \ + ADDITIONAL_SYSTEM_PROPERTIES \ + ADDITIONAL_VENDOR_PROPERTIES \ + ADDITIONAL_ODM_PROPERTIES \ + ADDITIONAL_PRODUCT_PROPERTIES + +$(foreach name, $(_additional_prop_var_names),\ + $(if $($(name)),\ + $(error $(name) must not set before here. $($(name)))\ + ,)\ + $(eval $(name) :=)\ +) +_additional_prop_var_names := + +# +# ----------------------------------------------------------------- +# Add the product-defined properties to the build properties. +ifneq ($(BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED), true) + ADDITIONAL_SYSTEM_PROPERTIES += $(PRODUCT_PROPERTY_OVERRIDES) +else + ifndef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE + ADDITIONAL_SYSTEM_PROPERTIES += $(PRODUCT_PROPERTY_OVERRIDES) + endif +endif + +ADDITIONAL_SYSTEM_PROPERTIES += ro.treble.enabled=${PRODUCT_FULL_TREBLE} + +# Set ro.llndk.api_level to show the maximum vendor API level that the LLNDK in +# the system partition supports. +ifdef RELEASE_BOARD_API_LEVEL +ADDITIONAL_SYSTEM_PROPERTIES += ro.llndk.api_level=$(RELEASE_BOARD_API_LEVEL) +endif + +# Sets ro.actionable_compatible_property.enabled to know on runtime whether the +# allowed list of actionable compatible properties is enabled or not. +ADDITIONAL_SYSTEM_PROPERTIES += ro.actionable_compatible_property.enabled=true + +# Add the system server compiler filter if they are specified for the product. +ifneq (,$(PRODUCT_SYSTEM_SERVER_COMPILER_FILTER)) +ADDITIONAL_PRODUCT_PROPERTIES += dalvik.vm.systemservercompilerfilter=$(PRODUCT_SYSTEM_SERVER_COMPILER_FILTER) +endif + +# Add the 16K developer option if it is defined for the product. +ifeq ($(PRODUCT_16K_DEVELOPER_OPTION),true) +ADDITIONAL_PRODUCT_PROPERTIES += ro.product.build.16k_page.enabled=true +else +ADDITIONAL_PRODUCT_PROPERTIES += ro.product.build.16k_page.enabled=false +endif + +# Enable core platform API violation warnings on userdebug and eng builds. +ifneq ($(TARGET_BUILD_VARIANT),user) +ADDITIONAL_SYSTEM_PROPERTIES += persist.debug.dalvik.vm.core_platform_api_policy=just-warn +endif + +# Define ro.sanitize.<name> properties for all global sanitizers. +ADDITIONAL_SYSTEM_PROPERTIES += $(foreach s,$(SANITIZE_TARGET),ro.sanitize.$(s)=true) + +# Sets the default value of ro.postinstall.fstab.prefix to /system. +# Device board config should override the value to /product when needed by: +# +# PRODUCT_PRODUCT_PROPERTIES += ro.postinstall.fstab.prefix=/product +# +# It then uses ${ro.postinstall.fstab.prefix}/etc/fstab.postinstall to +# mount system_other partition. +ADDITIONAL_SYSTEM_PROPERTIES += ro.postinstall.fstab.prefix=/system + +# Add cpu properties for bionic and ART. +ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.arch=$(TARGET_ARCH) +ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.cpu_variant=$(TARGET_CPU_VARIANT_RUNTIME) +ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.2nd_arch=$(TARGET_2ND_ARCH) +ADDITIONAL_VENDOR_PROPERTIES += ro.bionic.2nd_cpu_variant=$(TARGET_2ND_CPU_VARIANT_RUNTIME) + +ADDITIONAL_VENDOR_PROPERTIES += persist.sys.dalvik.vm.lib.2=libart.so +ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_ARCH).variant=$(DEX2OAT_TARGET_CPU_VARIANT_RUNTIME) +ifneq ($(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES),) + ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_ARCH).features=$(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) +endif + +ifdef TARGET_2ND_ARCH + ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_2ND_ARCH).variant=$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT_RUNTIME) + ifneq ($($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES),) + ADDITIONAL_VENDOR_PROPERTIES += dalvik.vm.isa.$(TARGET_2ND_ARCH).features=$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) + endif +endif + +# Although these variables are prefixed with TARGET_RECOVERY_, they are also needed under charger +# mode (via libminui). +ifdef TARGET_RECOVERY_DEFAULT_ROTATION +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.minui.default_rotation=$(TARGET_RECOVERY_DEFAULT_ROTATION) +endif +ifdef TARGET_RECOVERY_OVERSCAN_PERCENT +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.minui.overscan_percent=$(TARGET_RECOVERY_OVERSCAN_PERCENT) +endif +ifdef TARGET_RECOVERY_PIXEL_FORMAT +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.minui.pixel_format=$(TARGET_RECOVERY_PIXEL_FORMAT) +endif + +ifdef PRODUCT_USE_DYNAMIC_PARTITIONS +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.boot.dynamic_partitions=$(PRODUCT_USE_DYNAMIC_PARTITIONS) +endif + +ifdef PRODUCT_RETROFIT_DYNAMIC_PARTITIONS +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.boot.dynamic_partitions_retrofit=$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS) +endif + +ifdef PRODUCT_SHIPPING_API_LEVEL +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.product.first_api_level=$(PRODUCT_SHIPPING_API_LEVEL) +endif + +ifdef PRODUCT_SHIPPING_VENDOR_API_LEVEL +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.vendor.api_level=$(PRODUCT_SHIPPING_VENDOR_API_LEVEL) +endif + +ifneq ($(TARGET_BUILD_VARIANT),user) + ifdef PRODUCT_SET_DEBUGFS_RESTRICTIONS + ADDITIONAL_VENDOR_PROPERTIES += \ + ro.product.debugfs_restrictions.enabled=$(PRODUCT_SET_DEBUGFS_RESTRICTIONS) + endif +endif + +# Vendors with GRF must define BOARD_SHIPPING_API_LEVEL for the vendor API level. +# This must not be defined for the non-GRF devices. +# The values of the GRF properties will be verified by post_process_props.py +ifdef BOARD_SHIPPING_API_LEVEL +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.board.first_api_level=$(BOARD_SHIPPING_API_LEVEL) +endif + +# Build system set BOARD_API_LEVEL to show the api level of the vendor API surface. +# This must not be altered outside of build system. +ifdef BOARD_API_LEVEL +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.board.api_level=$(BOARD_API_LEVEL) +endif +# RELEASE_BOARD_API_LEVEL_FROZEN is true when the vendor API surface is frozen. +ifdef RELEASE_BOARD_API_LEVEL_FROZEN +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.board.api_frozen=$(RELEASE_BOARD_API_LEVEL_FROZEN) +endif + +# Set build prop. This prop is read by ota_from_target_files when generating OTA, +# to decide if VABC should be disabled. +ifeq ($(BOARD_DONT_USE_VABC_OTA),true) +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.vendor.build.dont_use_vabc=true +endif + +# Set the flag in vendor. So VTS would know if the new fingerprint format is in use when +# the system images are replaced by GSI. +ifeq ($(BOARD_USE_VBMETA_DIGTEST_IN_FINGERPRINT),true) +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.vendor.build.fingerprint_has_digest=1 +endif + +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.vendor.build.security_patch=$(VENDOR_SECURITY_PATCH) \ + ro.product.board=$(TARGET_BOOTLOADER_BOARD_NAME) \ + ro.board.platform=$(TARGET_BOARD_PLATFORM) \ + ro.hwui.use_vulkan=$(TARGET_USES_VULKAN) + +ifdef TARGET_SCREEN_DENSITY +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.sf.lcd_density=$(TARGET_SCREEN_DENSITY) +endif + +ifdef AB_OTA_UPDATER +ADDITIONAL_VENDOR_PROPERTIES += \ + ro.build.ab_update=$(AB_OTA_UPDATER) +endif + +ADDITIONAL_PRODUCT_PROPERTIES += ro.build.characteristics=$(TARGET_AAPT_CHARACTERISTICS) + +ifeq ($(AB_OTA_UPDATER),true) +ADDITIONAL_PRODUCT_PROPERTIES += ro.product.ab_ota_partitions=$(subst $(space),$(comma),$(sort $(AB_OTA_PARTITIONS))) +ADDITIONAL_VENDOR_PROPERTIES += ro.vendor.build.ab_ota_partitions=$(subst $(space),$(comma),$(sort $(AB_OTA_PARTITIONS))) +endif + +# Set this property for VTS to skip large page size tests on unsupported devices. +ADDITIONAL_PRODUCT_PROPERTIES += \ + ro.product.cpu.pagesize.max=$(TARGET_MAX_PAGE_SIZE_SUPPORTED) + +ifeq ($(PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO),true) +ADDITIONAL_PRODUCT_PROPERTIES += ro.product.build.no_bionic_page_size_macro=true +endif + +user_variant := $(filter user userdebug,$(TARGET_BUILD_VARIANT)) +enable_target_debugging := true +ifneq (,$(user_variant)) + # Target is secure in user builds. + ADDITIONAL_SYSTEM_PROPERTIES += ro.secure=1 + ADDITIONAL_SYSTEM_PROPERTIES += security.perf_harden=1 + + ifeq ($(user_variant),user) + ADDITIONAL_SYSTEM_PROPERTIES += ro.adb.secure=1 + endif + + ifneq ($(user_variant),userdebug) + # Disable debugging in plain user builds. + enable_target_debugging := + endif + + # Disallow mock locations by default for user builds + ADDITIONAL_SYSTEM_PROPERTIES += ro.allow.mock.location=0 + +else # !user_variant + # Turn on checkjni for non-user builds. + ADDITIONAL_SYSTEM_PROPERTIES += ro.kernel.android.checkjni=1 + # Set device insecure for non-user builds. + ADDITIONAL_SYSTEM_PROPERTIES += ro.secure=0 + # Allow mock locations by default for non user builds + ADDITIONAL_SYSTEM_PROPERTIES += ro.allow.mock.location=1 +endif # !user_variant + +ifeq (true,$(strip $(enable_target_debugging))) + # Target is more debuggable and adbd is on by default + ADDITIONAL_SYSTEM_PROPERTIES += ro.debuggable=1 + # Enable Dalvik lock contention logging. + ADDITIONAL_SYSTEM_PROPERTIES += dalvik.vm.lockprof.threshold=500 +else # !enable_target_debugging + # Target is less debuggable and adbd is off by default + ADDITIONAL_SYSTEM_PROPERTIES += ro.debuggable=0 +endif # !enable_target_debugging + +ifneq ($(filter sdk sdk_addon,$(MAKECMDGOALS)),) +_is_sdk_build := true +endif + +ifeq ($(TARGET_BUILD_VARIANT),eng) +ifneq ($(filter ro.setupwizard.mode=ENABLED, $(call collapse-pairs, $(ADDITIONAL_SYSTEM_PROPERTIES))),) + # Don't require the setup wizard on eng builds + ADDITIONAL_SYSTEM_PROPERTIES := $(filter-out ro.setupwizard.mode=%,\ + $(call collapse-pairs, $(ADDITIONAL_SYSTEM_PROPERTIES))) \ + ro.setupwizard.mode=OPTIONAL +endif +ifndef _is_sdk_build + # To speedup startup of non-preopted builds, don't verify or compile the boot image. + ADDITIONAL_SYSTEM_PROPERTIES += dalvik.vm.image-dex2oat-filter=extract +endif +# b/323566535 +ADDITIONAL_SYSTEM_PROPERTIES += init.svc_debug.no_fatal.zygote=true +endif + +ifdef _is_sdk_build +ADDITIONAL_SYSTEM_PROPERTIES += xmpp.auto-presence=true +ADDITIONAL_SYSTEM_PROPERTIES += ro.config.nocheckin=yes +endif + +_is_sdk_build := + +ADDITIONAL_SYSTEM_PROPERTIES += net.bt.name=Android + +# This property is set by flashing debug boot image, so default to false. +ADDITIONAL_SYSTEM_PROPERTIES += ro.force.debuggable=0 + +config_enable_uffd_gc := \ + $(firstword $(OVERRIDE_ENABLE_UFFD_GC) $(PRODUCT_ENABLE_UFFD_GC) default) + +# This is a temporary system property that controls the ART module. The plan is +# to remove it by Aug 2025, at which time Mainline updates of the ART module +# will ignore it as well. +# If the value is "default", it will be mangled by post_process_props.py. +ADDITIONAL_PRODUCT_PROPERTIES += ro.dalvik.vm.enable_uffd_gc=$(config_enable_uffd_gc) + +ADDITIONAL_SYSTEM_PROPERTIES := $(strip $(ADDITIONAL_SYSTEM_PROPERTIES)) +ADDITIONAL_PRODUCT_PROPERTIES := $(strip $(ADDITIONAL_PRODUCT_PROPERTIES)) +ADDITIONAL_VENDOR_PROPERTIES := $(strip $(ADDITIONAL_VENDOR_PROPERTIES)) + +.KATI_READONLY += \ + ADDITIONAL_SYSTEM_PROPERTIES \ + ADDITIONAL_PRODUCT_PROPERTIES \ + ADDITIONAL_VENDOR_PROPERTIES diff --git a/core/tasks/device-platinum-tests.mk b/core/tasks/device-platinum-tests.mk new file mode 100644 index 0000000000..270248c4b1 --- /dev/null +++ b/core/tasks/device-platinum-tests.mk @@ -0,0 +1,68 @@ +# Copyright (C) 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. + + +.PHONY: device-platinum-tests + +device-platinum-tests-zip := $(PRODUCT_OUT)/device-platinum-tests.zip +# Create an artifact to include a list of test config files in device-platinum-tests. +device-platinum-tests-list-zip := $(PRODUCT_OUT)/device-platinum-tests_list.zip +# Create an artifact to include all test config files in device-platinum-tests. +device-platinum-tests-configs-zip := $(PRODUCT_OUT)/device-platinum-tests_configs.zip +my_host_shared_lib_for_device_platinum_tests := $(call copy-many-files,$(COMPATIBILITY.device-platinum-tests.HOST_SHARED_LIBRARY.FILES)) +device_platinum_tests_host_shared_libs_zip := $(PRODUCT_OUT)/device-platinum-tests_host-shared-libs.zip + +$(device-platinum-tests-zip) : .KATI_IMPLICIT_OUTPUTS := $(device-platinum-tests-list-zip) $(device-platinum-tests-configs-zip) $(device_platinum_tests_host_shared_libs_zip) +$(device-platinum-tests-zip) : PRIVATE_device_platinum_tests_list := $(PRODUCT_OUT)/device-platinum-tests_list +$(device-platinum-tests-zip) : PRIVATE_HOST_SHARED_LIBS := $(my_host_shared_lib_for_device_platinum_tests) +$(device-platinum-tests-zip) : PRIVATE_device_host_shared_libs_zip := $(device_platinum_tests_host_shared_libs_zip) +$(device-platinum-tests-zip) : $(COMPATIBILITY.device-platinum-tests.FILES) $(my_host_shared_lib_for_device_platinum_tests) $(SOONG_ZIP) + rm -f $@-shared-libs.list + echo $(sort $(COMPATIBILITY.device-platinum-tests.FILES)) | tr " " "\n" > $@.list + grep $(HOST_OUT_TESTCASES) $@.list > $@-host.list || true + grep -e .*\\.config$$ $@-host.list > $@-host-test-configs.list || true + $(hide) for shared_lib in $(PRIVATE_HOST_SHARED_LIBS); do \ + echo $$shared_lib >> $@-host.list; \ + echo $$shared_lib >> $@-shared-libs.list; \ + done + grep $(HOST_OUT_TESTCASES) $@-shared-libs.list > $@-host-shared-libs.list || true + grep $(TARGET_OUT_TESTCASES) $@.list > $@-target.list || true + grep -e .*\\.config$$ $@-target.list > $@-target-test-configs.list || true + $(hide) $(SOONG_ZIP) -d -o $@ -P host -C $(HOST_OUT) -l $@-host.list -P target -C $(PRODUCT_OUT) -l $@-target.list -sha256 + $(hide) $(SOONG_ZIP) -d -o $(device-platinum-tests-configs-zip) \ + -P host -C $(HOST_OUT) -l $@-host-test-configs.list \ + -P target -C $(PRODUCT_OUT) -l $@-target-test-configs.list + $(SOONG_ZIP) -d -o $(PRIVATE_device_host_shared_libs_zip) \ + -P host -C $(HOST_OUT) -l $@-host-shared-libs.list + rm -f $(PRIVATE_device_platinum_tests_list) + $(hide) grep -e .*\\.config$$ $@-host.list | sed s%$(HOST_OUT)%host%g > $(PRIVATE_device_platinum_tests_list) + $(hide) grep -e .*\\.config$$ $@-target.list | sed s%$(PRODUCT_OUT)%target%g >> $(PRIVATE_device_platinum_tests_list) + $(hide) $(SOONG_ZIP) -d -o $(device-platinum-tests-list-zip) -C $(dir $@) -f $(PRIVATE_device_platinum_tests_list) + rm -f $@.list $@-host.list $@-target.list $@-host-test-configs.list $@-target-test-configs.list \ + $@-shared-libs.list $@-host-shared-libs.list $(PRIVATE_device_platinum_tests_list) + +device-platinum-tests: $(device-platinum-tests-zip) +$(call dist-for-goals, device-platinum-tests, $(device-platinum-tests-zip) $(device-platinum-tests-list-zip) $(device-platinum-tests-configs-zip) $(device_platinum_tests_host_shared_libs_zip)) + +$(call declare-1p-container,$(device-platinum-tests-zip),) +$(call declare-container-license-deps,$(device-platinum-tests-zip),$(COMPATIBILITY.device-platinum-tests.FILES) $(my_host_shared_lib_for_device_platinum_tests),$(PRODUCT_OUT)/:/) + +tests: device-platinum-tests + +# Reset temp vars +device-platinum-tests-zip := +device-platinum-tests-list-zip := +device-platinum-tests-configs-zip := +my_host_shared_lib_for_device_platinum_tests := +device_platinum_tests_host_shared_libs_zip :=
\ No newline at end of file diff --git a/core/tasks/meta-lic.mk b/core/tasks/meta-lic.mk index c630bcc59c..c41de63b0a 100644 --- a/core/tasks/meta-lic.mk +++ b/core/tasks/meta-lic.mk @@ -30,6 +30,23 @@ $(eval $(call declare-1p-copy-files,device/google_car/common,)) $(eval $(call declare-1p-copy-files,device/google/atv,atv-component-overrides.xml)) $(eval $(call declare-1p-copy-files,device/google/atv,tv_core_hardware.xml)) +# Moved here from device/google/barbet/Android.mk +$(eval $(call declare-copy-files-license-metadata,device/google/barbet,default-permissions.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/barbet,libnfc-nci.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/barbet,fstab.postinstall,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/barbet,ueventd.rc,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/barbet,wpa_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/barbet,hals.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/barbet,media_profiles_V1_0.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/barbet,media_codecs_performance.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/barbet,device_state_configuration.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/barbet,task_profiles.json,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/barbet,p2p_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/barbet,wpa_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/barbet,wpa_supplicant_overlay.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) + +$(eval $(call declare-1p-copy-files,device/google/barbet,audio_policy_configuration.xml)) + # Moved here from device/google/coral/Android.mk $(eval $(call declare-copy-files-license-metadata,device/google/coral,default-permissions.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) $(eval $(call declare-copy-files-license-metadata,device/google/coral,libnfc-nci.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) @@ -84,9 +101,29 @@ $(eval $(call declare-copy-files-license-metadata,device/google/raviole,wpa_supp $(eval $(call declare-1p-copy-files,device/google/raviole,audio_policy_configuration.xml)) +# Moved here from device/google/redfin/Android.mk +$(eval $(call declare-copy-files-license-metadata,device/google/redfin,default-permissions.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/redfin,libnfc-nci.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/redfin,fstab.postinstall,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/redfin,ueventd.rc,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/redfin,wpa_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/redfin,hals.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/redfin,media_profiles_V1_0.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/redfin,media_codecs_performance.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/redfin,device_state_configuration.xml,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/redfin,task_profiles.json,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/redfin,p2p_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/redfin,wpa_supplicant.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) +$(eval $(call declare-copy-files-license-metadata,device/google/redfin,wpa_supplicant_overlay.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,)) + +$(eval $(call declare-1p-copy-files,device/google/redfin,audio_policy_configuration.xml)) + # Moved here from device/sample/Android.mk $(eval $(call declare-1p-copy-files,device/sample,)) +# Moved here from device/google/trout/Android.mk +$(eval $(call declare-1p-copy-files,device/google/trout,)) + # Moved here from frameworks/av/media/Android.mk $(eval $(call declare-1p-copy-files,frameworks/av/media/libeffects,audio_effects.conf)) $(eval $(call declare-1p-copy-files,frameworks/av/media/libeffects,audio_effects.xml)) @@ -103,3 +140,10 @@ $(eval $(call declare-1p-copy-files,frameworks/base,.idc)) $(eval $(call declare-1p-copy-files,frameworks/base,dirty-image-objects)) $(eval $(call declare-1p-copy-files,frameworks/base/config,)) $(eval $(call declare-1p-copy-files,frameworks/native/data,)) + +# Moved here from hardware/google/camera/Android.mk +$(eval $(call declare-1p-copy-files,hardware/google/camera,)) + +# Moved here from hardware/interfaces/tv/Android.mk +$(eval $(call declare-1p-copy-files,hardware/interfaces/tv,tuner_vts_config_1_0.xml)) +$(eval $(call declare-1p-copy-files,hardware/interfaces/tv,tuner_vts_config_1_1.xml)) diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk index aa695eb31c..daa708938f 100644 --- a/core/tasks/module-info.mk +++ b/core/tasks/module-info.mk @@ -32,6 +32,7 @@ $(MODULE_INFO_JSON): $(SOONG_MODULE_INFO) $(call write-optional-json-list, "auto_test_config", $(sort $(ALL_MODULES.$(m).auto_test_config))) \ $(call write-optional-json-list, "test_config", $(strip $(ALL_MODULES.$(m).TEST_CONFIG) $(ALL_MODULES.$(m).EXTRA_TEST_CONFIGS))) \ $(call write-optional-json-list, "dependencies", $(sort $(ALL_MODULES.$(m).ALL_DEPS))) \ + $(call write-optional-json-list, "required", $(sort $(ALL_MODULES.$(m).REQUIRED_FROM_TARGET))) \ $(call write-optional-json-list, "shared_libs", $(sort $(ALL_MODULES.$(m).SHARED_LIBS))) \ $(call write-optional-json-list, "static_libs", $(sort $(ALL_MODULES.$(m).STATIC_LIBS))) \ $(call write-optional-json-list, "system_shared_libs", $(sort $(ALL_MODULES.$(m).SYSTEM_SHARED_LIBS))) \ @@ -52,6 +53,8 @@ $(MODULE_INFO_JSON): $(SOONG_MODULE_INFO) $(PRIVATE_MERGE_JSON_OBJECTS) -o $@ $(PRIVATE_SOONG_MODULE_INFO) $@.tmp rm $@.tmp +.PHONY: module-info +module-info: $(MODULE_INFO_JSON) droidcore-unbundled: $(MODULE_INFO_JSON) diff --git a/core/tasks/performance-tests.mk b/core/tasks/performance-tests.mk new file mode 100644 index 0000000000..32c156d3c7 --- /dev/null +++ b/core/tasks/performance-tests.mk @@ -0,0 +1,54 @@ +# Copyright (C) 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. + + +.PHONY: performance-tests + +performance-tests-zip := $(PRODUCT_OUT)/performance-tests.zip +# Create an artifact to include a list of test config files in performance-tests. +performance-tests-list-zip := $(PRODUCT_OUT)/performance-tests_list.zip +# Create an artifact to include all test config files in performance-tests. +performance-tests-configs-zip := $(PRODUCT_OUT)/performance-tests_configs.zip + +$(performance-tests-zip) : .KATI_IMPLICIT_OUTPUTS := $(performance-tests-list-zip) $(performance-tests-configs-zip) +$(performance-tests-zip) : PRIVATE_performance_tests_list := $(PRODUCT_OUT)/performance-tests_list +$(performance-tests-zip) : $(COMPATIBILITY.performance-tests.FILES) $(SOONG_ZIP) + echo $(sort $(COMPATIBILITY.performance-tests.FILES)) | tr " " "\n" > $@.list + grep $(HOST_OUT_TESTCASES) $@.list > $@-host.list || true + grep -e .*\\.config$$ $@-host.list > $@-host-test-configs.list || true + grep $(TARGET_OUT_TESTCASES) $@.list > $@-target.list || true + grep -e .*\\.config$$ $@-target.list > $@-target-test-configs.list || true + $(hide) $(SOONG_ZIP) -d -o $@ -P host -C $(HOST_OUT) -l $@-host.list -P target -C $(PRODUCT_OUT) -l $@-target.list -sha256 + $(hide) $(SOONG_ZIP) -d -o $(performance-tests-configs-zip) \ + -P host -C $(HOST_OUT) -l $@-host-test-configs.list \ + -P target -C $(PRODUCT_OUT) -l $@-target-test-configs.list + rm -f $(PRIVATE_performance_tests_list) + $(hide) grep -e .*\\.config$$ $@-host.list | sed s%$(HOST_OUT)%host%g > $(PRIVATE_performance_tests_list) + $(hide) grep -e .*\\.config$$ $@-target.list | sed s%$(PRODUCT_OUT)%target%g >> $(PRIVATE_performance_tests_list) + $(hide) $(SOONG_ZIP) -d -o $(performance-tests-list-zip) -C $(dir $@) -f $(PRIVATE_performance_tests_list) + rm -f $@.list $@-host.list $@-target.list $@-host-test-configs.list $@-target-test-configs.list \ + $(PRIVATE_performance_tests_list) + +performance-tests: $(performance-tests-zip) +$(call dist-for-goals, performance-tests, $(performance-tests-zip) $(performance-tests-list-zip) $(performance-tests-configs-zip)) + +$(call declare-1p-container,$(performance-tests-zip),) +$(call declare-container-license-deps,$(performance-tests-zip),$(COMPATIBILITY.performance-tests.FILES),$(PRODUCT_OUT)/:/) + +tests: performance-tests + +# Reset temp vars +performance-tests-zip := +performance-tests-list-zip := +performance-tests-configs-zip := diff --git a/envsetup.sh b/envsetup.sh index ab43ada1f6..640ed149e6 100644 --- a/envsetup.sh +++ b/envsetup.sh @@ -93,7 +93,6 @@ Invoke ". build/envsetup.sh" from your shell to add the following functions to y - godir: Go to the directory containing a file. - allmod: List all modules. - gomod: Go to the directory containing a module. -- bmod: Get the Bazel label of a Soong module if it is converted with bp2build. - pathmod: Get the directory containing a module. - outmod: Gets the location of a module's installed outputs with a certain extension. - dirmods: Gets the modules defined in a given directory. @@ -196,40 +195,19 @@ function get_build_var() (\cd $T; build/soong/soong_ui.bash --dumpvar-mode $1) } -# check to see if the supplied product is one we can build -function check_product() +# This logic matches envsetup.mk +function get_host_prebuilt_prefix { - local T=$(gettop) - if [ ! "$T" ]; then - echo "Couldn't locate the top of the tree. Try setting TOP." >&2 - return - fi - TARGET_PRODUCT=$1 \ - TARGET_RELEASE= \ - TARGET_BUILD_VARIANT= \ - TARGET_BUILD_TYPE= \ - TARGET_BUILD_APPS= \ - get_build_var TARGET_DEVICE > /dev/null - # hide successful answers, but allow the errors to show -} - -VARIANT_CHOICES=(user userdebug eng) - -# check to see if the supplied variant is valid -function check_variant() -{ - local v - for v in ${VARIANT_CHOICES[@]} - do - if [ "$v" = "$1" ] - then - return 0 - fi - done - return 1 + local un=$(uname) + if [[ $un == "Linux" ]] ; then + echo linux-x86 + elif [[ $un == "Darwin" ]] ; then + echo darwin-x86 + else + echo "Error: Invalid host operating system: $un" 1>&2 + fi } - # Add directories to PATH that are dependent on the lunch target. # For directories that are not lunch-specific, add them in set_global_paths function set_lunch_paths() @@ -467,9 +445,6 @@ function addcompletions() fi done - if should_add_completion bit ; then - complete -C "bit --tab" bit - fi if [ -z "$ZSH_VERSION" ]; then # Doesn't work in zsh. complete -o nospace -F _croot croot @@ -482,240 +457,9 @@ function addcompletions() complete -F _complete_android_module_names gomod complete -F _complete_android_module_names outmod complete -F _complete_android_module_names installmod - complete -F _complete_android_module_names bmod complete -F _complete_android_module_names m } -function multitree_lunch_help() -{ - echo "usage: lunch PRODUCT-RELEASE-VARIANT" 1>&2 - echo " Set up android build environment based on a product short name and variant" 1>&2 - echo 1>&2 - echo "lunch COMBO_FILE VARIANT" 1>&2 - echo " Set up android build environment based on a specific lunch combo file" 1>&2 - echo " and variant." 1>&2 - echo 1>&2 - echo "lunch --print [CONFIG]" 1>&2 - echo " Print the contents of a configuration. If CONFIG is supplied, that config" 1>&2 - echo " will be flattened and printed. If CONFIG is not supplied, the currently" 1>&2 - echo " selected config will be printed. Returns 0 on success or nonzero on error." 1>&2 - echo 1>&2 - echo "lunch --list" 1>&2 - echo " List all possible combo files available in the current tree" 1>&2 - echo 1>&2 - echo "lunch --help" 1>&2 - echo "lunch -h" 1>&2 - echo " Prints this message." 1>&2 -} - -function multitree_lunch() -{ - local code - local results - # Lunch must be run in the topdir, but this way we get a clear error - # message, instead of FileNotFound. - local T=$(multitree_gettop) - if [ -z "$T" ]; then - _multitree_lunch_error - return 1 - fi - if $(echo "$1" | grep -q '^-') ; then - # Calls starting with a -- argument are passed directly and the function - # returns with the lunch.py exit code. - "${T}/orchestrator/build/orchestrator/core/lunch.py" "$@" - code=$? - if [[ $code -eq 2 ]] ; then - echo 1>&2 - multitree_lunch_help - return $code - elif [[ $code -ne 0 ]] ; then - return $code - fi - else - # All other calls go through the --lunch variant of lunch.py - results=($(${T}/orchestrator/build/orchestrator/core/lunch.py --lunch "$@")) - code=$? - if [[ $code -eq 2 ]] ; then - echo 1>&2 - multitree_lunch_help - return $code - elif [[ $code -ne 0 ]] ; then - return $code - fi - - export TARGET_BUILD_COMBO=${results[0]} - export TARGET_BUILD_VARIANT=${results[1]} - fi -} - -function choosetype() -{ - echo "Build type choices are:" - echo " 1. release" - echo " 2. debug" - echo - - local DEFAULT_NUM DEFAULT_VALUE - DEFAULT_NUM=1 - DEFAULT_VALUE=release - - export TARGET_BUILD_TYPE= - local ANSWER - while [ -z $TARGET_BUILD_TYPE ] - do - echo -n "Which would you like? ["$DEFAULT_NUM"] " - if [ -z "$1" ] ; then - read ANSWER - else - echo $1 - ANSWER=$1 - fi - case $ANSWER in - "") - export TARGET_BUILD_TYPE=$DEFAULT_VALUE - ;; - 1) - export TARGET_BUILD_TYPE=release - ;; - release) - export TARGET_BUILD_TYPE=release - ;; - 2) - export TARGET_BUILD_TYPE=debug - ;; - debug) - export TARGET_BUILD_TYPE=debug - ;; - *) - echo - echo "I didn't understand your response. Please try again." - echo - ;; - esac - if [ -n "$1" ] ; then - break - fi - done - - build_build_var_cache - set_stuff_for_environment - destroy_build_var_cache -} - -# -# This function isn't really right: It chooses a TARGET_PRODUCT -# based on the list of boards. Usually, that gets you something -# that kinda works with a generic product, but really, you should -# pick a product by name. -# -function chooseproduct() -{ - local default_value - if [ "x$TARGET_PRODUCT" != x ] ; then - default_value=$TARGET_PRODUCT - else - default_value=aosp_arm - fi - - export TARGET_BUILD_APPS= - export TARGET_PRODUCT= - local ANSWER - while [ -z "$TARGET_PRODUCT" ] - do - echo -n "Which product would you like? [$default_value] " - if [ -z "$1" ] ; then - read ANSWER - else - echo $1 - ANSWER=$1 - fi - - if [ -z "$ANSWER" ] ; then - export TARGET_PRODUCT=$default_value - else - if check_product $ANSWER - then - export TARGET_PRODUCT=$ANSWER - else - echo "** Not a valid product: $ANSWER" - fi - fi - if [ -n "$1" ] ; then - break - fi - done - - build_build_var_cache - set_stuff_for_environment - destroy_build_var_cache -} - -function choosevariant() -{ - echo "Variant choices are:" - local index=1 - local v - for v in ${VARIANT_CHOICES[@]} - do - # The product name is the name of the directory containing - # the makefile we found, above. - echo " $index. $v" - index=$(($index+1)) - done - - local default_value=eng - local ANSWER - - export TARGET_BUILD_VARIANT= - while [ -z "$TARGET_BUILD_VARIANT" ] - do - echo -n "Which would you like? [$default_value] " - if [ -z "$1" ] ; then - read ANSWER - else - echo $1 - ANSWER=$1 - fi - - if [ -z "$ANSWER" ] ; then - export TARGET_BUILD_VARIANT=$default_value - elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then - if [ "$ANSWER" -le "${#VARIANT_CHOICES[@]}" ] ; then - export TARGET_BUILD_VARIANT=${VARIANT_CHOICES[@]:$(($ANSWER-1)):1} - fi - else - if check_variant $ANSWER - then - export TARGET_BUILD_VARIANT=$ANSWER - else - echo "** Not a valid variant: $ANSWER" - fi - fi - if [ -n "$1" ] ; then - break - fi - done -} - -function choosecombo() -{ - choosetype $1 - - echo - echo - chooseproduct $2 - - echo - echo - choosevariant $3 - - echo - build_build_var_cache - set_stuff_for_environment - printconfig - destroy_build_var_cache -} - function add_lunch_combo() { if [ -n "$ZSH_VERSION" ]; then @@ -1013,34 +757,6 @@ function banchan() destroy_build_var_cache } -# TODO: Merge into gettop as part of launching multitree -function multitree_gettop -{ - local TOPFILE=orchestrator/build/make/core/envsetup.mk - if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then - # The following circumlocution ensures we remove symlinks from TOP. - (cd "$TOP"; PWD= /bin/pwd) - else - if [ -f $TOPFILE ] ; then - # The following circumlocution (repeated below as well) ensures - # that we record the true directory name and not one that is - # faked up with symlink names. - PWD= /bin/pwd - else - local HERE=$PWD - local T= - while [ \( ! \( -f $TOPFILE \) \) -a \( "$PWD" != "/" \) ]; do - \cd .. - T=`PWD= /bin/pwd -P` - done - \cd "$HERE" - if [ -f "$T/$TOPFILE" ]; then - echo "$T" - fi - fi - fi -} - function croot() { local T=$(gettop) @@ -1112,8 +828,8 @@ function run_tool_with_logging() { local tool_binary="$1" shift - # If logging is not enabled or the logger is not configured, run the original command and return. - if [[ "${ANDROID_ENABLE_TOOL_LOGGING}" != "true" ]] || [[ -z "${ANDROID_TOOL_LOGGER}" ]]; then + # If the logger is not configured, run the original command and return. + if [[ -z "${ANDROID_TOOL_LOGGER}" ]]; then "${tool_binary}" "${@}" return $? fi @@ -1131,11 +847,12 @@ function run_tool_with_logging() { # Remove the trap to prevent duplicate log. trap - EXIT; "${logger}" \ - --tool_tag "${tool_tag}" \ - --start_timestamp "${start_time}" \ - --end_timestamp "$(date +%s.%N)" \ - --tool_args \""${@}"\" \ - --exit_code "${exit_code}" \ + --tool_tag="${tool_tag}" \ + --start_timestamp="${start_time}" \ + --end_timestamp="$(date +%s.%N)" \ + --tool_args="$*" \ + --exit_code="${exit_code}" \ + ${ANDROID_TOOL_LOGGER_EXTRA_ARGS} \ > /dev/null 2>&1 & exit ${exit_code} ' SIGINT SIGTERM SIGQUIT EXIT @@ -1169,18 +886,6 @@ function qpid() { fi } -# syswrite - disable verity, reboot if needed, and remount image -# -# Easy way to make system.img/etc writable -function syswrite() { - adb wait-for-device && adb root && adb wait-for-device || return 1 - if [[ $(adb disable-verity | grep -i "reboot") ]]; then - echo "rebooting" - adb reboot && adb wait-for-device && adb root && adb wait-for-device || return 1 - fi - adb remount || return 1 -} - # coredump_setup - enable core dumps globally for any process # that has the core-file-size limit set correctly # @@ -1283,146 +988,11 @@ function is64bit() fi } -case `uname -s` in - Darwin) - function sgrep() - { - find -E . -name .repo -prune -o -name .git -prune -o -type f -iregex '.*\.(c|h|cc|cpp|hpp|S|java|kt|xml|sh|mk|aidl|vts|proto|rs|go)' \ - -exec grep --color -n "$@" {} + - } - - ;; - *) - function sgrep() - { - find . -name .repo -prune -o -name .git -prune -o -type f -iregex '.*\.\(c\|h\|cc\|cpp\|hpp\|S\|java\|kt\|xml\|sh\|mk\|aidl\|vts\|proto\|rs\|go\)' \ - -exec grep --color -n "$@" {} + - } - ;; -esac - function gettargetarch { get_build_var TARGET_ARCH } -function ggrep() -{ - find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.gradle" \ - -exec grep --color -n "$@" {} + -} - -function gogrep() -{ - find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.go" \ - -exec grep --color -n "$@" {} + -} - -function jgrep() -{ - find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.java" \ - -exec grep --color -n "$@" {} + -} - -function rsgrep() -{ - find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.rs" \ - -exec grep --color -n "$@" {} + -} - -function jsongrep() -{ - find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.json" \ - -exec grep --color -n "$@" {} + -} - -function tomlgrep() -{ - find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.toml" \ - -exec grep --color -n "$@" {} + -} - -function ktgrep() -{ - find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.kt" \ - -exec grep --color -n "$@" {} + -} - -function cgrep() -{ - find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) \ - -exec grep --color -n "$@" {} + -} - -function resgrep() -{ - local dir - for dir in `find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -name res -type d`; do - find $dir -type f -name '*\.xml' -exec grep --color -n "$@" {} + - done -} - -function mangrep() -{ - find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -name 'AndroidManifest.xml' \ - -exec grep --color -n "$@" {} + -} - -function owngrep() -{ - find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -name 'OWNERS' \ - -exec grep --color -n "$@" {} + -} - -function sepgrep() -{ - find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -name sepolicy -type d \ - -exec grep --color -n -r --exclude-dir=\.git "$@" {} + -} - -function rcgrep() -{ - find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.rc*" \ - -exec grep --color -n "$@" {} + -} - -function pygrep() -{ - find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.py" \ - -exec grep --color -n "$@" {} + -} - -case `uname -s` in - Darwin) - function mgrep() - { - find -E . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o \( -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk|.*\.bp)' -o -regex '(.*/)?(build|soong)/.*[^/]*\.go' \) -type f \ - -exec grep --color -n "$@" {} + - } - - function treegrep() - { - find -E . -name .repo -prune -o -name .git -prune -o -type f -iregex '.*\.(c|h|cpp|hpp|S|java|kt|xml)' \ - -exec grep --color -n -i "$@" {} + - } - - ;; - *) - function mgrep() - { - find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o \( -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk|.*\.bp)' -o -regextype posix-extended -regex '(.*/)?(build|soong)/.*[^/]*\.go' \) -type f \ - -exec grep --color -n "$@" {} + - } - - function treegrep() - { - find . -name .repo -prune -o -name .git -prune -o -regextype posix-egrep -iregex '.*\.(c|h|cpp|hpp|S|java|kt|xml)' -type f \ - -exec grep --color -n -i "$@" {} + - } - - ;; -esac - function getprebuilt { get_abs_build_var ANDROID_PREBUILTS @@ -1574,17 +1144,6 @@ function smoketest() adb shell am instrument -w com.android.smoketest.tests/android.test.InstrumentationTestRunner } -# simple shortcut to the runtest command -function runtest() -{ - local T=$(gettop) - if [ ! "$T" ]; then - echo "Couldn't locate the top of the tree. Try setting TOP." >&2 - return - fi - ("$T"/development/testrunner/runtest.py $@) -} - function godir () { if [[ -z "$1" ]]; then echo "Usage: godir <regex>" @@ -1636,23 +1195,6 @@ function godir () { \cd $T/$pathname } -# Update module-info.json in out. -function refreshmod() { - if [ ! "$ANDROID_PRODUCT_OUT" ]; then - echo "No ANDROID_PRODUCT_OUT. Try running 'lunch' first." >&2 - return 1 - fi - - echo "Refreshing modules (building module-info.json). Log at $ANDROID_PRODUCT_OUT/module-info.json.build.log." >&2 - - # for the output of the next command - mkdir -p $ANDROID_PRODUCT_OUT || return 1 - - # Note, can't use absolute path because of the way make works. - m $(get_build_var PRODUCT_OUT)/module-info.json \ - > $ANDROID_PRODUCT_OUT/module-info.json.build.log 2>&1 -} - # Verifies that module-info.txt exists, returning nonzero if it doesn't. function verifymodinfo() { if [ ! "$ANDROID_PRODUCT_OUT" ]; then @@ -1676,48 +1218,6 @@ function allmod() { cat $ANDROID_PRODUCT_OUT/all_modules.txt 2>/dev/null } -# Return the Bazel label of a Soong module if it is converted with bp2build. -function bmod() -( - if [ $# -eq 0 ]; then - echo "usage: bmod <module 1> <module 2> ... <module n>" >&2 - return 1 - fi - - # We could run bp2build here, but it might trigger bp2build invalidation - # when used with `b` (e.g. --run_soong_tests) and/or add unnecessary waiting - # time overhead. - # - # For a snappy result, use the latest generated version in soong_injection, - # and ask users to run m bp2build if it doesn't exist. - converted_json="$(get_abs_build_var OUT_DIR)/soong/soong_injection/metrics/converted_modules_path_map.json" - - if [ ! -f ${converted_json} ]; then - echo "bp2build files not found. Have you ran 'm bp2build'?" >&2 - return 1 - fi - - modules=() - for m in "$@"; do - modules+=("\"$m\",") - done - local res=$(python3 -c "import json -modules = [${modules[*]}] -converted_json='$converted_json' -bp2build_converted_map = json.load(open(converted_json)) -for module in modules: - if module not in bp2build_converted_map: - print(module + ' is not converted to Bazel.') - else: - print(bp2build_converted_map[module] + ':' + module)") - - echo "${res}" - unconverted_count=$(echo "${res}" | grep -c "not converted to Bazel") - if [[ ${unconverted_count} -ne 0 ]]; then - return 1 - fi -) - # Get the path of a specific module in the android tree, as cached in module-info.json. # If any build change is made, and it should be reflected in the output, you should run # 'refreshmod' first. Note: This is the inverse of dirmods. @@ -1890,50 +1390,6 @@ function get_make_command() fi } -function _wrap_build() -{ - if [[ "${ANDROID_QUIET_BUILD:-}" == true ]]; then - "$@" - return $? - fi - local start_time=$(date +"%s") - "$@" - local ret=$? - local end_time=$(date +"%s") - local tdiff=$(($end_time-$start_time)) - local hours=$(($tdiff / 3600 )) - local mins=$((($tdiff % 3600) / 60)) - local secs=$(($tdiff % 60)) - local ncolors=$(tput colors 2>/dev/null) - if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then - color_failed=$'\E'"[0;31m" - color_success=$'\E'"[0;32m" - color_warning=$'\E'"[0;33m" - color_reset=$'\E'"[00m" - else - color_failed="" - color_success="" - color_reset="" - fi - - echo - if [ $ret -eq 0 ] ; then - echo -n "${color_success}#### build completed successfully " - else - echo -n "${color_failed}#### failed to build some targets " - fi - if [ $hours -gt 0 ] ; then - printf "(%02g:%02g:%02g (hh:mm:ss))" $hours $mins $secs - elif [ $mins -gt 0 ] ; then - printf "(%02g:%02g (mm:ss))" $mins $secs - elif [ $secs -gt 0 ] ; then - printf "(%s seconds)" $secs - fi - echo " ####${color_reset}" - echo - return $ret -} - function _trigger_build() ( local -r bc="$1"; shift @@ -1951,52 +1407,11 @@ function _trigger_build() return $ret ) -function m() -( - _trigger_build "all-modules" "$@" -) - -function mm() -( - _trigger_build "modules-in-a-dir-no-deps" "$@" -) - -function mmm() -( - _trigger_build "modules-in-dirs-no-deps" "$@" -) - -function mma() -( - _trigger_build "modules-in-a-dir" "$@" -) - -function mmma() -( - _trigger_build "modules-in-dirs" "$@" -) - function make() { _wrap_build $(get_make_command "$@") "$@" } -function _multitree_lunch_error() -{ - >&2 echo "Couldn't locate the top of the tree. Please run \'source build/envsetup.sh\' and multitree_lunch from the root of your workspace." -} - -function multitree_build() -{ - local T=$(multitree_gettop) - if [ -n "$T" ]; then - "$T/orchestrator/build/orchestrator/core/orchestrator.py" "$@" - else - _multitree_lunch_error - return 1 - fi -} - function provision() { if [ ! "$ANDROID_PRODUCT_OUT" ]; then @@ -2118,25 +1533,42 @@ function showcommands() { fi } -function avbtool() { - if [[ ! -f "$ANDROID_SOONG_HOST_OUT"/bin/avbtool ]]; then - m avbtool - fi - "$ANDROID_SOONG_HOST_OUT"/bin/avbtool $@ -} - -function overrideflags() { - local T="$(gettop)" - (\cd "${T}" && build/make/tools/overrideflags.sh "$@") -} +# These functions used to be here but are now standalone scripts +# in build/soong/bin. Unset these for the time being so the real +# script is picked up. +# TODO: Remove this some time after a suitable delay (maybe 2025?) +unset aninja +unset overrideflags +unset m +unset mm +unset mmm +unset mma +unset mmma +unset cgrep +unset ggrep +unset gogrep +unset jgrep +unset jsongrep +unset ktgrep +unset mangrep +unset mgrep +unset owngrep +unset pygrep +unset rcgrep +unset resgrep +unset rsgrep +unset sepgrep +unset sgrep +unset tomlgrep +unset treegrep +unset syswrite +unset refreshmod -function aninja() { - local T="$(gettop)" - (\cd "${T}" && prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-${TARGET_PRODUCT}.ninja "$@") -} validate_current_shell set_global_paths source_vendorsetup addcompletions + + diff --git a/shell_utils.sh b/shell_utils.sh index 9de5a504e5..450bb836a6 100644 --- a/shell_utils.sh +++ b/shell_utils.sh @@ -40,15 +40,24 @@ function gettop fi } -# Sets TOP, or if the root of the tree can't be found, prints a message and -# exits. Since this function exits, it should not be called from functions -# defined in envsetup.sh. +# Asserts that the root of the tree can be found. if [ -z "${IMPORTING_ENVSETUP:-}" ] ; then function require_top { TOP=$(gettop) if [[ ! $TOP ]] ; then - echo "Can not locate root of source tree. $(basename $0) must be run from within the Android source tree." >&2 + echo "Can not locate root of source tree. $(basename $0) must be run from within the Android source tree or TOP must be set." >&2 + exit 1 + fi +} +fi + +# Asserts that the lunch variables have been set +if [ -z "${IMPORTING_ENVSETUP:-}" ] ; then +function require_lunch +{ + if [[ ! $TARGET_PRODUCT || ! $TARGET_RELEASE || ! $TARGET_BUILD_VARIANT ]] ; then + echo "Please run lunch and try again." >&2 exit 1 fi } @@ -71,4 +80,50 @@ function getoutdir echo "${out_dir}" } +# Pretty print the build status and duration +function _wrap_build() +{ + if [[ "${ANDROID_QUIET_BUILD:-}" == true ]]; then + "$@" + return $? + fi + local start_time=$(date +"%s") + "$@" + local ret=$? + local end_time=$(date +"%s") + local tdiff=$(($end_time-$start_time)) + local hours=$(($tdiff / 3600 )) + local mins=$((($tdiff % 3600) / 60)) + local secs=$(($tdiff % 60)) + local ncolors=$(tput colors 2>/dev/null) + if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then + color_failed=$'\E'"[0;31m" + color_success=$'\E'"[0;32m" + color_warning=$'\E'"[0;33m" + color_reset=$'\E'"[00m" + else + color_failed="" + color_success="" + color_reset="" + fi + + echo + if [ $ret -eq 0 ] ; then + echo -n "${color_success}#### build completed successfully " + else + echo -n "${color_failed}#### failed to build some targets " + fi + if [ $hours -gt 0 ] ; then + printf "(%02g:%02g:%02g (hh:mm:ss))" $hours $mins $secs + elif [ $mins -gt 0 ] ; then + printf "(%02g:%02g (mm:ss))" $mins $secs + elif [ $secs -gt 0 ] ; then + printf "(%s seconds)" $secs + fi + echo " ####${color_reset}" + echo + return $ret +} + + diff --git a/target/board/ndk/BoardConfig.mk b/target/board/ndk/BoardConfig.mk index b485f8b79e..c7d9d4c908 100644 --- a/target/board/ndk/BoardConfig.mk +++ b/target/board/ndk/BoardConfig.mk @@ -15,6 +15,4 @@ TARGET_ARCH_SUITE := ndk -MALLOC_SVELTE := true - -USE_SAFESTACK := false +MALLOC_LOW_MEMORY := true diff --git a/target/product/base_system.mk b/target/product/base_system.mk index 57e8275270..634bf668ce 100644 --- a/target/product/base_system.mk +++ b/target/product/base_system.mk @@ -172,7 +172,6 @@ PRODUCT_PACKAGES += \ libjpeg \ liblog \ libm.bootstrap \ - libmdnssd \ libmedia \ libmedia_jni \ libmediandk \ @@ -289,6 +288,7 @@ PRODUCT_PACKAGES += \ uncrypt \ usbd \ vdc \ + vintf \ voip-common \ vold \ watchdogd \ @@ -486,6 +486,11 @@ PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\ # Enable dirty image object binning to reduce dirty pages in the image. PRODUCT_PACKAGES += dirty-image-objects +# Enable go/perfetto-persistent-tracing for eng builds +ifneq (,$(filter eng, $(TARGET_BUILD_VARIANT))) + PRODUCT_PRODUCT_PROPERTIES += persist.debug.perfetto.persistent_sysui_tracing_for_bugreport=1 +endif + $(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk) # Ensure all trunk-stable flags are available. diff --git a/target/product/go_defaults.mk b/target/product/go_defaults.mk index b7174868ee..a10cfa858f 100644 --- a/target/product/go_defaults.mk +++ b/target/product/go_defaults.mk @@ -17,6 +17,8 @@ # Inherit common Android Go defaults. $(call inherit-product, build/make/target/product/go_defaults_common.mk) +PRODUCT_RELEASE_CONFIG_MAPS += $(wildcard vendor/google/release/go_devices/release_config_map.mk) + # Add the system properties. TARGET_SYSTEM_PROP += \ build/make/target/board/go_defaults.prop diff --git a/target/product/module_arm64.mk b/target/product/module_arm64.mk index 634a03dca1..d6487ca56b 100644 --- a/target/product/module_arm64.mk +++ b/target/product/module_arm64.mk @@ -21,3 +21,4 @@ PRODUCT_NAME := module_arm64 PRODUCT_DEVICE := module_arm64 PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true +PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 diff --git a/target/product/module_arm64only.mk b/target/product/module_arm64only.mk index 822ac247c0..137701a441 100644 --- a/target/product/module_arm64only.mk +++ b/target/product/module_arm64only.mk @@ -21,3 +21,4 @@ PRODUCT_NAME := module_arm64only PRODUCT_DEVICE := module_arm64only PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true +PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 diff --git a/target/product/module_common.mk b/target/product/module_common.mk index bf146a0d2f..da4ea23ad9 100644 --- a/target/product/module_common.mk +++ b/target/product/module_common.mk @@ -24,8 +24,9 @@ $(call inherit-product, $(SRC_TARGET_DIR)/product/memtag-common.mk) # uses -DENFORCE_VINTF_MANIFEST. See b/185759877 PRODUCT_SHIPPING_API_LEVEL := 29 -# Builds using a module product should build modules from source, even if -# BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE says otherwise. +# If true, this builds the mainline modules from source. This overrides any +# prebuilts selected via RELEASE_APEX_CONTRIBUTIONS_* build flags for the +# current release config. PRODUCT_MODULE_BUILD_FROM_SOURCE := true # Build sdk from source if the branch is not using slim manifests. diff --git a/target/product/module_x86_64.mk b/target/product/module_x86_64.mk index 9bd0264f36..e182bf6578 100644 --- a/target/product/module_x86_64.mk +++ b/target/product/module_x86_64.mk @@ -21,3 +21,4 @@ PRODUCT_NAME := module_x86_64 PRODUCT_DEVICE := module_x86_64 PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true +PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 diff --git a/target/product/module_x86_64only.mk b/target/product/module_x86_64only.mk index 056fb9097c..fa4a04d7e8 100644 --- a/target/product/module_x86_64only.mk +++ b/target/product/module_x86_64only.mk @@ -21,3 +21,4 @@ PRODUCT_NAME := module_x86_64only PRODUCT_DEVICE := module_x86_64only PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true +PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 diff --git a/target/product/ndk.mk b/target/product/ndk.mk index 1dfd0db328..e4f77f74c4 100644 --- a/target/product/ndk.mk +++ b/target/product/ndk.mk @@ -19,3 +19,5 @@ PRODUCT_NAME := ndk PRODUCT_BRAND := Android PRODUCT_DEVICE := ndk + +PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true diff --git a/target/product/virtual_ab_ota/vabc_features.mk b/target/product/virtual_ab_ota/vabc_features.mk index 3f484e4f3e..1219763b0d 100644 --- a/target/product/virtual_ab_ota/vabc_features.mk +++ b/target/product/virtual_ab_ota/vabc_features.mk @@ -34,6 +34,21 @@ PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.io_uring.enabled=true PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.batch_writes=true +# Low memory device configurations. If memory usage and cpu utilization is +# a bottleneck during OTA, the below configurations can be added to a +# device's .mk file improve performance for low mem devices. Disabling +# ro.virtual_ab.compression.xor.enabled and ro.virtual_ab.io_uring.enabled +# is also recommended +# +# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.o_direct.enabled=true +# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.merge_thread_priority=19 +# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.worker_thread_priority=0 +# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.num_worker_threads=3 +# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.num_merge_threads=1 +# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.num_verify_threads=1 +# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.cow_op_merge_size=16 +# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.verify_threshold_size=1073741824 +# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.verify_block_size=1048576 # Enabling this property, will improve OTA install time # but will use an additional CPU core diff --git a/teams/Android.bp b/teams/Android.bp index 78efa61f03..b3a5752749 100644 --- a/teams/Android.bp +++ b/teams/Android.bp @@ -4337,39 +4337,45 @@ team { } team { - name: "trendy_team_media_framework_drm", + name: "trendy_team_media_framework_drm", - // go/trendy/manage/engineers/5311752690335744 - trendy_team_id: "5311752690335744", + // go/trendy/manage/engineers/5311752690335744 + trendy_team_id: "5311752690335744", } team { - name: "trendy_team_media_framework_audio", + name: "trendy_team_media_framework_audio", - // go/trendy/manage/engineers/5823575353065472 - trendy_team_id: "5823575353065472", + // go/trendy/manage/engineers/5823575353065472 + trendy_team_id: "5823575353065472", } team { - name: "trendy_team_ar_sensors_context_hub", + name: "trendy_team_pixel_pearl", - // go/trendy/manage/engineers/4776371090259968 - trendy_team_id: "4776371090259968", + // go/trendy/manage/engineers/6326219602231296 + trendy_team_id: "6326219602231296", } +team { + name: "trendy_team_ar_sensors_context_hub", + + // go/trendy/manage/engineers/4776371090259968 + trendy_team_id: "4776371090259968", +} team { - name: "trendy_team_media_codec_framework", + name: "trendy_team_media_codec_framework", - // go/trendy/manage/engineers/4943966050844672 - trendy_team_id: "4943966050844672", + // go/trendy/manage/engineers/4943966050844672 + trendy_team_id: "4943966050844672", } team { - name: "trendy_team_android_platform_performance_testing", + name: "trendy_team_android_platform_performance_testing", - // go/trendy/manage/engineers/5810097836621824 - trendy_team_id: "5810097836621824", + // go/trendy/manage/engineers/5810097836621824 + trendy_team_id: "5810097836621824", } team { @@ -4378,3 +4384,10 @@ team { // go/trendy/manage/engineers/5551098528825344 trendy_team_id: "5551098528825344", } + +team { + name: "trendy_team_incremental", + + // go/trendy/manage/engineers/5955405559201792 + trendy_team_id: "5955405559201792", +} diff --git a/tests/Android.bp b/tests/Android.bp index d3964e5aee..39debf5c6d 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -29,6 +29,7 @@ python_test_host { }, data: [ ":envsetup_minimum.zip", + ":tool_event_logger", ], test_suites: [ "general-tests", diff --git a/tests/run_tool_with_logging_test.py b/tests/run_tool_with_logging_test.py index 1eb78f14ba..6f9b59c5c8 100644 --- a/tests/run_tool_with_logging_test.py +++ b/tests/run_tool_with_logging_test.py @@ -13,20 +13,22 @@ # limitations under the License. import dataclasses +import glob from importlib import resources import logging import os from pathlib import Path import re +import shutil import signal import stat import subprocess +import sys import tempfile import textwrap import time import unittest import zipfile -import sys EXII_RETURN_CODE = 0 INTERRUPTED_RETURN_CODE = 130 @@ -40,7 +42,7 @@ class RunToolWithLoggingTest(unittest.TestCase): # Configure to print logging to stdout. logging.basicConfig(filename=None, level=logging.DEBUG) console = logging.StreamHandler(sys.stdout) - logging.getLogger('').addHandler(console) + logging.getLogger("").addHandler(console) def setUp(self): super().setUp() @@ -49,7 +51,7 @@ class RunToolWithLoggingTest(unittest.TestCase): os.chdir(self.working_dir.name) # Extract envsetup.zip which contains the envsetup.sh and other dependent # scripts required to set up the build environments. - with resources.files("testdata").joinpath("envsetup.zip").open('rb') as p: + with resources.files("testdata").joinpath("envsetup.zip").open("rb") as p: with zipfile.ZipFile(p, "r") as zip_f: zip_f.extractall() @@ -57,37 +59,10 @@ class RunToolWithLoggingTest(unittest.TestCase): self.working_dir.cleanup() super().tearDown() - def test_does_not_log_when_logging_disabled(self): - test_tool = TestScript.create(self.working_dir) - test_logger = TestScript.create(self.working_dir) - - self._run_script_and_wait(f""" - ANDROID_ENABLE_TOOL_LOGGING=false - ANDROID_TOOL_LOGGER="{test_logger.executable}" - run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2 - """) - - test_tool.assert_called_once_with_args("arg1 arg2") - test_logger.assert_not_called() - - def test_does_not_log_when_logger_var_unset(self): - test_tool = TestScript.create(self.working_dir) - test_logger = TestScript.create(self.working_dir) - - self._run_script_and_wait(f""" - unset ANDROID_ENABLE_TOOL_LOGGING - ANDROID_TOOL_LOGGER="{test_logger.executable}" - run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2 - """) - - test_tool.assert_called_once_with_args("arg1 arg2") - test_logger.assert_not_called() - def test_does_not_log_when_logger_var_empty(self): test_tool = TestScript.create(self.working_dir) self._run_script_and_wait(f""" - ANDROID_ENABLE_TOOL_LOGGING=true ANDROID_TOOL_LOGGER="" run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2 """) @@ -98,7 +73,6 @@ class RunToolWithLoggingTest(unittest.TestCase): test_tool = TestScript.create(self.working_dir) self._run_script_and_wait(f""" - ANDROID_ENABLE_TOOL_LOGGING=true unset ANDROID_TOOL_LOGGER run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2 """) @@ -110,15 +84,14 @@ class RunToolWithLoggingTest(unittest.TestCase): test_logger = TestScript.create(self.working_dir) self._run_script_and_wait(f""" - ANDROID_ENABLE_TOOL_LOGGING=true ANDROID_TOOL_LOGGER="{test_logger.executable}" run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2 """) test_tool.assert_called_once_with_args("arg1 arg2") expected_logger_args = ( - "--tool_tag FAKE_TOOL --start_timestamp \d+\.\d+ --end_timestamp" - ' \d+\.\d+ --tool_args "arg1 arg2" --exit_code 0' + "--tool_tag=FAKE_TOOL --start_timestamp=\d+\.\d+ --end_timestamp=" + "\d+\.\d+ --tool_args=arg1 arg2 --exit_code=0" ) test_logger.assert_called_once_with_args(expected_logger_args) @@ -128,7 +101,6 @@ class RunToolWithLoggingTest(unittest.TestCase): run_tool_with_logging_stdout, run_tool_with_logging_stderr = ( self._run_script_and_wait(f""" - ANDROID_ENABLE_TOOL_LOGGING=true ANDROID_TOOL_LOGGER="{test_logger.executable}" run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2 """) @@ -136,7 +108,6 @@ class RunToolWithLoggingTest(unittest.TestCase): run_tool_without_logging_stdout, run_tool_without_logging_stderr = ( self._run_script_and_wait(f""" - ANDROID_ENABLE_TOOL_LOGGING=true ANDROID_TOOL_LOGGER="{test_logger.executable}" {test_tool.executable} arg1 arg2 """) @@ -154,7 +125,6 @@ class RunToolWithLoggingTest(unittest.TestCase): test_logger = TestScript.create(self.working_dir, "echo 'logger called'") run_tool_with_logging_output, _ = self._run_script_and_wait(f""" - ANDROID_ENABLE_TOOL_LOGGING=true ANDROID_TOOL_LOGGER="{test_logger.executable}" run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2 """) @@ -168,7 +138,6 @@ class RunToolWithLoggingTest(unittest.TestCase): ) _, err = self._run_script_and_wait(f""" - ANDROID_ENABLE_TOOL_LOGGING=true ANDROID_TOOL_LOGGER="{test_logger.executable}" run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2 """) @@ -180,7 +149,6 @@ class RunToolWithLoggingTest(unittest.TestCase): test_logger = TestScript.create(self.working_dir) process = self._run_script_in_build_env(f""" - ANDROID_ENABLE_TOOL_LOGGING=true ANDROID_TOOL_LOGGER="{test_logger.executable}" run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2 """) @@ -195,8 +163,8 @@ class RunToolWithLoggingTest(unittest.TestCase): self.assertEqual(returncode, INTERRUPTED_RETURN_CODE) expected_logger_args = ( - "--tool_tag FAKE_TOOL --start_timestamp \d+\.\d+ --end_timestamp" - ' \d+\.\d+ --tool_args "arg1 arg2" --exit_code 130' + "--tool_tag=FAKE_TOOL --start_timestamp=\d+\.\d+ --end_timestamp=" + "\d+\.\d+ --tool_args=arg1 arg2 --exit_code=130" ) test_logger.assert_called_once_with_args(expected_logger_args) @@ -205,9 +173,8 @@ class RunToolWithLoggingTest(unittest.TestCase): test_logger = TestScript.create(self.working_dir) self._run_script_and_wait(f""" - ANDROID_ENABLE_TOOL_LOGGING=false + ANDROID_TOOL_LOGGER="" ANDROID_TOOL_LOGGER="{test_logger.executable}" - ANDROID_ENABLE_TOOL_LOGGING=true run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2 """) @@ -218,14 +185,56 @@ class RunToolWithLoggingTest(unittest.TestCase): test_logger = TestScript.create(self.working_dir) self._run_script_and_wait(f""" - ANDROID_ENABLE_TOOL_LOGGING=true ANDROID_TOOL_LOGGER="{test_logger.executable}" - ANDROID_ENABLE_TOOL_LOGGING=false + ANDROID_TOOL_LOGGER="" run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2 """) test_logger.assert_not_called() + def test_integration_tool_event_logger_dry_run(self): + test_tool = TestScript.create(self.working_dir) + logger_path = self._import_logger() + + self._run_script_and_wait(f""" + TMPDIR="{self.working_dir.name}" + ANDROID_TOOL_LOGGER="{logger_path}" + ANDROID_TOOL_LOGGER_EXTRA_ARGS="--dry_run" + run_tool_with_logging "FAKE_TOOL" {test_tool.executable} arg1 arg2 + """) + + self._assert_logger_dry_run() + + def test_tool_args_do_not_fail_logger(self): + test_tool = TestScript.create(self.working_dir) + logger_path = self._import_logger() + + self._run_script_and_wait(f""" + TMPDIR="{self.working_dir.name}" + ANDROID_TOOL_LOGGER="{logger_path}" + ANDROID_TOOL_LOGGER_EXTRA_ARGS="--dry_run" + run_tool_with_logging "FAKE_TOOL" {test_tool.executable} --tool-arg1 + """) + + self._assert_logger_dry_run() + + def _import_logger(self) -> Path: + logger = "tool_event_logger" + logger_path = Path(self.working_dir.name).joinpath(logger) + with resources.as_file(resources.files("testdata").joinpath(logger)) as p: + shutil.copy(p, logger_path) + Path.chmod(logger_path, 0o755) + return logger_path + + def _assert_logger_dry_run(self): + log_files = glob.glob(self.working_dir.name + "/tool_event_logger_*/*.log") + self.assertEqual(len(log_files), 1) + + with open(log_files[0], "r") as f: + lines = f.readlines() + self.assertEqual(len(lines), 1) + self.assertIn("dry run", lines[0]) + def _create_build_env_script(self) -> str: return f""" source {Path(self.working_dir.name).joinpath("build/make/envsetup.sh")} @@ -248,7 +257,7 @@ class RunToolWithLoggingTest(unittest.TestCase): stderr=subprocess.PIPE, text=True, start_new_session=True, - executable='/bin/bash' + executable="/bin/bash", ) def _wait_for_process( @@ -301,7 +310,7 @@ class TestScript: """) f.write(executable_contents.encode("utf-8")) - os.chmod(f.name, os.stat(f.name).st_mode | stat.S_IEXEC) + Path.chmod(f.name, os.stat(f.name).st_mode | stat.S_IEXEC) return TestScript(executable, output_file) diff --git a/tools/Android.bp b/tools/Android.bp index 0a55ed4b85..59831a61ec 100644 --- a/tools/Android.bp +++ b/tools/Android.bp @@ -115,3 +115,11 @@ python_binary_host { }, }, } + +python_binary_host { + name: "merge-event-log-tags", + srcs: [ + "event_log_tags.py", + "merge-event-log-tags.py", + ], +} diff --git a/tools/aconfig/aconfig/templates/cpp_source_file.template b/tools/aconfig/aconfig/templates/cpp_source_file.template index 62664bc566..4c098c5b41 100644 --- a/tools/aconfig/aconfig/templates/cpp_source_file.template +++ b/tools/aconfig/aconfig/templates/cpp_source_file.template @@ -129,12 +129,14 @@ bool {header}_{item.flag_name}() \{ } auto package_read_context = aconfig_storage::get_package_read_context( - *package_map_file, "{package}"); + **package_map_file, "{package}"); if (!package_read_context.ok()) \{ ALOGI("error: failed to get package read context: %s", package_map_file.error().message().c_str()); return result; } + delete *package_map_file; + auto flag_val_map = aconfig_storage::get_mapped_file( "{item.container}", aconfig_storage::StorageFileType::flag_val); @@ -144,13 +146,15 @@ bool {header}_{item.flag_name}() \{ } auto value = aconfig_storage::get_boolean_flag_value( - *flag_val_map, - package_read_context->package_id + {item.flag_offset}); + **flag_val_map, + package_read_context->boolean_start_index + {item.flag_offset}); if (!value.ok()) \{ ALOGI("error: failed to get flag val: %s", package_map_file.error().message().c_str()); return result; } + delete *flag_val_map; + if (*value != result) \{ ALOGI("error: new storage value '%d' does not match current value '%d'", *value, result); } else \{ diff --git a/tools/aconfig/aconfig_device_paths/Android.bp b/tools/aconfig/aconfig_device_paths/Android.bp index 21aa9a9e08..2c771e09f5 100644 --- a/tools/aconfig/aconfig_device_paths/Android.bp +++ b/tools/aconfig/aconfig_device_paths/Android.bp @@ -36,3 +36,16 @@ rust_library { host_supported: true, defaults: ["libaconfig_device_paths.defaults"], } + +genrule { + name: "libaconfig_java_device_paths_src", + srcs: ["src/DevicePathsTemplate.java"], + out: ["DevicePaths.java"], + tool_files: ["partition_aconfig_flags_paths.txt"], + cmd: "sed -e '/TEMPLATE/{r$(location partition_aconfig_flags_paths.txt)' -e 'd}' $(in) > $(out)" +} + +java_library { + name: "aconfig_device_paths_java", + srcs: [":libaconfig_java_device_paths_src"], +} diff --git a/tools/aconfig/aconfig_device_paths/partition_aconfig_flags_paths.txt b/tools/aconfig/aconfig_device_paths/partition_aconfig_flags_paths.txt index 3d2deb2375..140cd21ac8 100644 --- a/tools/aconfig/aconfig_device_paths/partition_aconfig_flags_paths.txt +++ b/tools/aconfig/aconfig_device_paths/partition_aconfig_flags_paths.txt @@ -1,6 +1,4 @@ -[ - "/system/etc/aconfig_flags.pb", - "/system_ext/etc/aconfig_flags.pb", - "/product/etc/aconfig_flags.pb", - "/vendor/etc/aconfig_flags.pb", -] +"/system/etc/aconfig_flags.pb", +"/system_ext/etc/aconfig_flags.pb", +"/product/etc/aconfig_flags.pb", +"/vendor/etc/aconfig_flags.pb", diff --git a/tools/aconfig/aconfig_device_paths/src/DevicePathsTemplate.java b/tools/aconfig/aconfig_device_paths/src/DevicePathsTemplate.java new file mode 100644 index 0000000000..f27b9bd360 --- /dev/null +++ b/tools/aconfig/aconfig_device_paths/src/DevicePathsTemplate.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 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. + */ +package android.aconfig; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @hide + */ +public class DevicePaths { + static final String[] PATHS = { + TEMPLATE + }; + + private static final String APEX_DIR = "/apex"; + private static final String APEX_ACONFIG_PATH_SUFFIX = "/etc/aconfig_flags.pb"; + + + /** + * Returns the list of all on-device aconfig protos paths. + * @hide + */ + public List<String> parsedFlagsProtoPaths() { + ArrayList<String> paths = new ArrayList(Arrays.asList(PATHS)); + + File apexDirectory = new File(APEX_DIR); + if (!apexDirectory.isDirectory()) { + return paths; + } + + File[] subdirs = apexDirectory.listFiles(); + if (subdirs == null) { + return paths; + } + + for (File prefix : subdirs) { + // For each mainline modules, there are two directories, one <modulepackage>/, + // and one <modulepackage>@<versioncode>/. Just read the former. + if (prefix.getAbsolutePath().contains("@")) { + continue; + } + + File protoPath = new File(prefix + APEX_ACONFIG_PATH_SUFFIX); + if (!protoPath.exists()) { + continue; + } + + paths.add(protoPath.getAbsolutePath()); + } + return paths; + } +} diff --git a/tools/aconfig/aconfig_device_paths/src/lib.rs b/tools/aconfig/aconfig_device_paths/src/lib.rs index 7bb62f4247..7480b3002c 100644 --- a/tools/aconfig/aconfig_device_paths/src/lib.rs +++ b/tools/aconfig/aconfig_device_paths/src/lib.rs @@ -21,11 +21,19 @@ use std::path::PathBuf; use std::fs; +fn read_partition_paths() -> Vec<PathBuf> { + include_str!("../partition_aconfig_flags_paths.txt") + .split(',') + .map(|s| s.trim().trim_matches('"')) + .filter(|s| !s.is_empty()) + .map(|s| PathBuf::from(s.to_string())) + .collect() +} + /// Determine all paths that contain an aconfig protobuf file. pub fn parsed_flags_proto_paths() -> Result<Vec<PathBuf>> { - let mut result: Vec<PathBuf> = include!("../partition_aconfig_flags_paths.txt") - .map(|s| PathBuf::from(s.to_string())) - .to_vec(); + let mut result: Vec<PathBuf> = read_partition_paths(); + for dir in fs::read_dir("/apex")? { let dir = dir?; @@ -45,3 +53,23 @@ pub fn parsed_flags_proto_paths() -> Result<Vec<PathBuf>> { Ok(result) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_read_partition_paths() { + assert_eq!(read_partition_paths().len(), 4); + + assert_eq!( + read_partition_paths(), + vec![ + PathBuf::from("/system/etc/aconfig_flags.pb"), + PathBuf::from("/system_ext/etc/aconfig_flags.pb"), + PathBuf::from("/product/etc/aconfig_flags.pb"), + PathBuf::from("/vendor/etc/aconfig_flags.pb") + ] + ); + } +} diff --git a/tools/aconfig/aconfig_protos/Android.bp b/tools/aconfig/aconfig_protos/Android.bp index 18c545ae96..d24199443c 100644 --- a/tools/aconfig/aconfig_protos/Android.bp +++ b/tools/aconfig/aconfig_protos/Android.bp @@ -17,7 +17,22 @@ java_library { apex_available: [ "com.android.configinfrastructure", "//apex_available:platform", - ] + ], +} + +java_library { + name: "libaconfig_java_proto_nano", + srcs: ["protos/aconfig.proto"], + static_libs: ["libprotobuf-java-nano"], + proto: { + type: "nano", + }, + sdk_version: "current", + min_sdk_version: "UpsideDownCake", + apex_available: [ + "//apex_available:platform", + ], + jarjar_rules: "jarjar-nano-rules.txt", } java_library_host { @@ -58,7 +73,7 @@ rust_defaults { ], proc_macros: [ "libpaste", - ] + ], } rust_library { diff --git a/tools/aconfig/aconfig_protos/jarjar-nano-rules.txt b/tools/aconfig/aconfig_protos/jarjar-nano-rules.txt new file mode 100644 index 0000000000..b58fa64838 --- /dev/null +++ b/tools/aconfig/aconfig_protos/jarjar-nano-rules.txt @@ -0,0 +1 @@ +rule com.google.protobuf.** android.internal.framework.protobuf.@1
\ No newline at end of file diff --git a/tools/aconfig/aconfig_storage_file/aconfig_storage_file.cpp b/tools/aconfig/aconfig_storage_file/aconfig_storage_file.cpp index 548078f48f..7af024b39d 100644 --- a/tools/aconfig/aconfig_storage_file/aconfig_storage_file.cpp +++ b/tools/aconfig/aconfig_storage_file/aconfig_storage_file.cpp @@ -7,6 +7,29 @@ using namespace android::base; namespace aconfig_storage { +Result<std::vector<FlagValueSummary>> list_flags( + const std::string& package_map, + const std::string& flag_map, + const std::string& flag_val) { + auto flag_list_cxx = list_flags_cxx(rust::Str(package_map.c_str()), + rust::Str(flag_map.c_str()), + rust::Str(flag_val.c_str())); + if (flag_list_cxx.query_success) { + auto flag_list = std::vector<FlagValueSummary>(); + for (const auto& flag_cxx : flag_list_cxx.flags) { + auto flag = FlagValueSummary(); + flag.package_name = std::string(flag_cxx.package_name); + flag.flag_name = std::string(flag_cxx.flag_name); + flag.flag_value = std::string(flag_cxx.flag_value); + flag.value_type = std::string(flag_cxx.value_type); + flag_list.push_back(flag); + } + return flag_list; + } else { + return Error() << flag_list_cxx.error_message; + } +} + Result<std::vector<FlagValueAndInfoSummary>> list_flags_with_info( const std::string& package_map, const std::string& flag_map, diff --git a/tools/aconfig/aconfig_storage_file/include/aconfig_storage/aconfig_storage_file.hpp b/tools/aconfig/aconfig_storage_file/include/aconfig_storage/aconfig_storage_file.hpp index 5044a4dbfc..9f3cdb046b 100644 --- a/tools/aconfig/aconfig_storage_file/include/aconfig_storage/aconfig_storage_file.hpp +++ b/tools/aconfig/aconfig_storage_file/include/aconfig_storage/aconfig_storage_file.hpp @@ -6,6 +6,23 @@ namespace aconfig_storage { +/// Flag value summary for a flag +struct FlagValueSummary { + std::string package_name; + std::string flag_name; + std::string flag_value; + std::string value_type; +}; + +/// List all flag values +/// \input package_map: package map file +/// \input flag_map: flag map file +/// \input flag_val: flag value file +android::base::Result<std::vector<FlagValueSummary>> list_flags( + const std::string& package_map, + const std::string& flag_map, + const std::string& flag_val); + /// Flag value and info summary for a flag struct FlagValueAndInfoSummary { std::string package_name; diff --git a/tools/aconfig/aconfig_storage_file/protos/aconfig_storage_metadata.proto b/tools/aconfig/aconfig_storage_file/protos/aconfig_storage_metadata.proto index 7de43ca918..e1c1c7ffca 100644 --- a/tools/aconfig/aconfig_storage_file/protos/aconfig_storage_metadata.proto +++ b/tools/aconfig/aconfig_storage_file/protos/aconfig_storage_metadata.proto @@ -27,8 +27,7 @@ message storage_file_info { optional string flag_map = 4; optional string flag_val = 5; optional string flag_info = 6; - optional string local_overrides = 7; - optional int64 timestamp = 8; + optional int64 timestamp = 7; } message storage_files { diff --git a/tools/aconfig/aconfig_storage_file/src/lib.rs b/tools/aconfig/aconfig_storage_file/src/lib.rs index 80602bbfb0..26e9c1a3be 100644 --- a/tools/aconfig/aconfig_storage_file/src/lib.rs +++ b/tools/aconfig/aconfig_storage_file/src/lib.rs @@ -382,6 +382,14 @@ pub fn list_flags_with_info( // Exported rust data structure and methods, c++ code will be generated #[cxx::bridge] mod ffi { + /// flag value summary cxx return + pub struct FlagValueSummaryCXX { + pub package_name: String, + pub flag_name: String, + pub flag_value: String, + pub value_type: String, + } + /// flag value and info summary cxx return pub struct FlagValueAndInfoSummaryCXX { pub package_name: String, @@ -394,6 +402,13 @@ mod ffi { } /// list flag result cxx return + pub struct ListFlagValueResultCXX { + pub query_success: bool, + pub error_message: String, + pub flags: Vec<FlagValueSummaryCXX>, + } + + /// list flag with info result cxx return pub struct ListFlagValueAndInfoResultCXX { pub query_success: bool, pub error_message: String, @@ -402,6 +417,12 @@ mod ffi { // Rust export to c++ extern "Rust" { + pub fn list_flags_cxx( + package_map: &str, + flag_map: &str, + flag_val: &str, + ) -> ListFlagValueResultCXX; + pub fn list_flags_with_info_cxx( package_map: &str, flag_map: &str, @@ -411,6 +432,18 @@ mod ffi { } } +/// implement flag value summary cxx return type +impl ffi::FlagValueSummaryCXX { + pub(crate) fn new(summary: FlagValueSummary) -> Self { + Self { + package_name: summary.package_name, + flag_name: summary.flag_name, + flag_value: summary.flag_value, + value_type: format!("{:?}", summary.value_type), + } + } +} + /// implement flag value and info summary cxx return type impl ffi::FlagValueAndInfoSummaryCXX { pub(crate) fn new(summary: FlagValueAndInfoSummary) -> Self { @@ -426,6 +459,26 @@ impl ffi::FlagValueAndInfoSummaryCXX { } } +/// implement list flag cxx interlop +pub fn list_flags_cxx( + package_map: &str, + flag_map: &str, + flag_val: &str, +) -> ffi::ListFlagValueResultCXX { + match list_flags(package_map, flag_map, flag_val) { + Ok(summary) => ffi::ListFlagValueResultCXX { + query_success: true, + error_message: String::new(), + flags: summary.into_iter().map(ffi::FlagValueSummaryCXX::new).collect(), + }, + Err(errmsg) => ffi::ListFlagValueResultCXX { + query_success: false, + error_message: format!("{:?}", errmsg), + flags: Vec::new(), + }, + } +} + /// implement list flag with info cxx interlop pub fn list_flags_with_info_cxx( package_map: &str, diff --git a/tools/aconfig/aconfig_storage_file/tests/storage_file_test.cpp b/tools/aconfig/aconfig_storage_file/tests/storage_file_test.cpp index eccbca53d5..ebd1dd89bd 100644 --- a/tools/aconfig/aconfig_storage_file/tests/storage_file_test.cpp +++ b/tools/aconfig/aconfig_storage_file/tests/storage_file_test.cpp @@ -24,15 +24,25 @@ using namespace android::base; using namespace aconfig_storage; +void verify_value(const FlagValueSummary& flag, + const std::string& package_name, + const std::string& flag_name, + const std::string& flag_val, + const std::string& value_type) { + ASSERT_EQ(flag.package_name, package_name); + ASSERT_EQ(flag.flag_name, flag_name); + ASSERT_EQ(flag.flag_value, flag_val); + ASSERT_EQ(flag.value_type, value_type); +} -void verify_flag(const FlagValueAndInfoSummary& flag, - const std::string& package_name, - const std::string& flag_name, - const std::string& flag_val, - const std::string& value_type, - bool is_readwrite, - bool has_server_override, - bool has_local_override) { +void verify_value_info(const FlagValueAndInfoSummary& flag, + const std::string& package_name, + const std::string& flag_name, + const std::string& flag_val, + const std::string& value_type, + bool is_readwrite, + bool has_server_override, + bool has_local_override) { ASSERT_EQ(flag.package_name, package_name); ASSERT_EQ(flag.flag_name, flag_name); ASSERT_EQ(flag.flag_value, flag_val); @@ -42,6 +52,35 @@ void verify_flag(const FlagValueAndInfoSummary& flag, ASSERT_EQ(flag.has_local_override, has_local_override); } +TEST(AconfigStorageFileTest, test_list_flag) { + auto const test_dir = GetExecutableDirectory(); + auto const package_map = test_dir + "/package.map"; + auto const flag_map = test_dir + "/flag.map"; + auto const flag_val = test_dir + "/flag.val"; + auto flag_list_result = aconfig_storage::list_flags( + package_map, flag_map, flag_val); + ASSERT_TRUE(flag_list_result.ok()); + + auto const& flag_list = *flag_list_result; + ASSERT_EQ(flag_list.size(), 8); + verify_value(flag_list[0], "com.android.aconfig.storage.test_1", "disabled_rw", + "false", "ReadWriteBoolean"); + verify_value(flag_list[1], "com.android.aconfig.storage.test_1", "enabled_ro", + "true", "ReadOnlyBoolean"); + verify_value(flag_list[2], "com.android.aconfig.storage.test_1", "enabled_rw", + "true", "ReadWriteBoolean"); + verify_value(flag_list[3], "com.android.aconfig.storage.test_2", "disabled_rw", + "false", "ReadWriteBoolean"); + verify_value(flag_list[4], "com.android.aconfig.storage.test_2", "enabled_fixed_ro", + "true", "FixedReadOnlyBoolean"); + verify_value(flag_list[5], "com.android.aconfig.storage.test_2", "enabled_ro", + "true", "ReadOnlyBoolean"); + verify_value(flag_list[6], "com.android.aconfig.storage.test_4", "enabled_fixed_ro", + "true", "FixedReadOnlyBoolean"); + verify_value(flag_list[7], "com.android.aconfig.storage.test_4", "enabled_rw", + "true", "ReadWriteBoolean"); +} + TEST(AconfigStorageFileTest, test_list_flag_with_info) { auto const test_dir = GetExecutableDirectory(); auto const package_map = test_dir + "/package.map"; @@ -54,20 +93,20 @@ TEST(AconfigStorageFileTest, test_list_flag_with_info) { auto const& flag_list = *flag_list_result; ASSERT_EQ(flag_list.size(), 8); - verify_flag(flag_list[0], "com.android.aconfig.storage.test_1", "disabled_rw", - "false", "ReadWriteBoolean", true, false, false); - verify_flag(flag_list[1], "com.android.aconfig.storage.test_1", "enabled_ro", - "true", "ReadOnlyBoolean", false, false, false); - verify_flag(flag_list[2], "com.android.aconfig.storage.test_1", "enabled_rw", - "true", "ReadWriteBoolean", true, false, false); - verify_flag(flag_list[3], "com.android.aconfig.storage.test_2", "disabled_rw", - "false", "ReadWriteBoolean", true, false, false); - verify_flag(flag_list[4], "com.android.aconfig.storage.test_2", "enabled_fixed_ro", - "true", "FixedReadOnlyBoolean", false, false, false); - verify_flag(flag_list[5], "com.android.aconfig.storage.test_2", "enabled_ro", - "true", "ReadOnlyBoolean", false, false, false); - verify_flag(flag_list[6], "com.android.aconfig.storage.test_4", "enabled_fixed_ro", - "true", "FixedReadOnlyBoolean", false, false, false); - verify_flag(flag_list[7], "com.android.aconfig.storage.test_4", "enabled_rw", - "true", "ReadWriteBoolean", true, false, false); + verify_value_info(flag_list[0], "com.android.aconfig.storage.test_1", "disabled_rw", + "false", "ReadWriteBoolean", true, false, false); + verify_value_info(flag_list[1], "com.android.aconfig.storage.test_1", "enabled_ro", + "true", "ReadOnlyBoolean", false, false, false); + verify_value_info(flag_list[2], "com.android.aconfig.storage.test_1", "enabled_rw", + "true", "ReadWriteBoolean", true, false, false); + verify_value_info(flag_list[3], "com.android.aconfig.storage.test_2", "disabled_rw", + "false", "ReadWriteBoolean", true, false, false); + verify_value_info(flag_list[4], "com.android.aconfig.storage.test_2", "enabled_fixed_ro", + "true", "FixedReadOnlyBoolean", false, false, false); + verify_value_info(flag_list[5], "com.android.aconfig.storage.test_2", "enabled_ro", + "true", "ReadOnlyBoolean", false, false, false); + verify_value_info(flag_list[6], "com.android.aconfig.storage.test_4", "enabled_fixed_ro", + "true", "FixedReadOnlyBoolean", false, false, false); + verify_value_info(flag_list[7], "com.android.aconfig.storage.test_4", "enabled_rw", + "true", "ReadWriteBoolean", true, false, false); } diff --git a/tools/aconfig/aconfig_storage_read_api/Android.bp b/tools/aconfig/aconfig_storage_read_api/Android.bp index 217104b6b2..d1c282d982 100644 --- a/tools/aconfig/aconfig_storage_read_api/Android.bp +++ b/tools/aconfig/aconfig_storage_read_api/Android.bp @@ -9,8 +9,6 @@ rust_defaults { srcs: ["src/lib.rs"], rustlibs: [ "libanyhow", - "libonce_cell", - "libtempfile", "libmemmap2", "libcxx", "libthiserror", @@ -34,6 +32,9 @@ rust_test_host { name: "aconfig_storage_read_api.test", test_suites: ["general-tests"], defaults: ["aconfig_storage_read_api.defaults"], + rustlibs: [ + "librand", + ], data: [ "tests/package.map", "tests/flag.map", @@ -89,13 +90,9 @@ cc_library { host_supported: true, vendor_available: true, product_available: true, - static_libs: [ - "libaconfig_storage_protos_cc", - "libprotobuf-cpp-lite", - "libbase", - ], shared_libs: [ "liblog", + "libbase", ], apex_available: [ "//apex_available:platform", diff --git a/tools/aconfig/aconfig_storage_read_api/Cargo.toml b/tools/aconfig/aconfig_storage_read_api/Cargo.toml index 30a4298826..2b27e4b491 100644 --- a/tools/aconfig/aconfig_storage_read_api/Cargo.toml +++ b/tools/aconfig/aconfig_storage_read_api/Cargo.toml @@ -8,10 +8,9 @@ default = ["cargo"] cargo = [] [dependencies] +rand = "0.8.5" anyhow = "1.0.69" memmap2 = "0.8.0" -once_cell = "1.19.0" -tempfile = "3.9.0" cxx = "1.0" thiserror = "1.0.56" aconfig_storage_file = { path = "../aconfig_storage_file" } diff --git a/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp b/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp index 8fe42ceddc..50076aab31 100644 --- a/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp +++ b/tools/aconfig/aconfig_storage_read_api/aconfig_storage_read_api.cpp @@ -1,6 +1,5 @@ #include <android-base/file.h> #include <android-base/logging.h> -#include <protos/aconfig_storage_metadata.pb.h> #include <sys/mman.h> #include <sys/stat.h> @@ -10,69 +9,45 @@ #include "aconfig_storage/lib.rs.h" #include "aconfig_storage/aconfig_storage_read_api.hpp" -using storage_records_pb = android::aconfig_storage_metadata::storage_files; -using storage_record_pb = android::aconfig_storage_metadata::storage_file_info; using namespace android::base; namespace aconfig_storage { /// Storage location pb file -static constexpr char kAvailableStorageRecordsPb[] = - "/metadata/aconfig/boot/available_storage_file_records.pb"; - -/// Read aconfig storage records pb file -static Result<storage_records_pb> read_storage_records_pb(std::string const& pb_file) { - auto records = storage_records_pb(); - auto content = std::string(); - if (!ReadFileToString(pb_file, &content)) { - return ErrnoError() << "ReadFileToString failed"; - } +static constexpr char kStorageDir[] = "/metadata/aconfig"; - if (!records.ParseFromString(content)) { - return ErrnoError() << "Unable to parse persistent storage records protobuf"; - } - return records; +/// destructor +MappedStorageFile::~MappedStorageFile() { + munmap(file_ptr, file_size); } /// Get storage file path static Result<std::string> find_storage_file( - std::string const& pb_file, + std::string const& storage_dir, std::string const& container, StorageFileType file_type) { - auto records_pb = read_storage_records_pb(pb_file); - if (!records_pb.ok()) { - return Error() << "Unable to read storage records from " << pb_file - << " : " << records_pb.error(); - } - - for (auto& entry : records_pb->files()) { - if (entry.container() == container) { - switch(file_type) { - case StorageFileType::package_map: - return entry.package_map(); - case StorageFileType::flag_map: - return entry.flag_map(); - case StorageFileType::flag_val: - return entry.flag_val(); - case StorageFileType::flag_info: - return entry.flag_info(); - default: - return Error() << "Invalid file type " << file_type; - } - } + switch(file_type) { + case StorageFileType::package_map: + return storage_dir + "/maps/" + container + ".package.map"; + case StorageFileType::flag_map: + return storage_dir + "/maps/" + container + ".flag.map"; + case StorageFileType::flag_val: + return storage_dir + "/boot/" + container + ".val"; + case StorageFileType::flag_info: + return storage_dir + "/boot/" + container + ".info"; + default: + return Error() << "Invalid file type " << file_type; } - - return Error() << "Unable to find storage files for container " << container;; } namespace private_internal_api { /// Get mapped file implementation. -Result<MappedStorageFile> get_mapped_file_impl( - std::string const& pb_file, +Result<MappedStorageFile*> get_mapped_file_impl( + std::string const& storage_dir, std::string const& container, StorageFileType file_type) { - auto file_result = find_storage_file(pb_file, container, file_type); + auto file_result = find_storage_file(storage_dir, container, file_type); if (!file_result.ok()) { return Error() << file_result.error(); } @@ -82,7 +57,7 @@ Result<MappedStorageFile> get_mapped_file_impl( } // namespace private internal api /// Map a storage file -Result<MappedStorageFile> map_storage_file(std::string const& file) { +Result<MappedStorageFile*> map_storage_file(std::string const& file) { int fd = open(file.c_str(), O_CLOEXEC | O_NOFOLLOW | O_RDONLY); if (fd == -1) { return ErrnoError() << "failed to open " << file; @@ -99,9 +74,9 @@ Result<MappedStorageFile> map_storage_file(std::string const& file) { return ErrnoError() << "mmap failed"; } - auto mapped_file = MappedStorageFile(); - mapped_file.file_ptr = map_result; - mapped_file.file_size = file_size; + auto mapped_file = new MappedStorageFile(); + mapped_file->file_ptr = map_result; + mapped_file->file_size = file_size; return mapped_file; } @@ -120,11 +95,11 @@ android::base::Result<FlagValueType> map_to_flag_value_type( } /// Get mapped storage file -Result<MappedStorageFile> get_mapped_file( +Result<MappedStorageFile*> get_mapped_file( std::string const& container, StorageFileType file_type) { return private_internal_api::get_mapped_file_impl( - kAvailableStorageRecordsPb, container, file_type); + kStorageDir, container, file_type); } /// Get storage file version number diff --git a/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp b/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp index 2bd84fcf20..e6d75373a9 100644 --- a/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp +++ b/tools/aconfig/aconfig_storage_read_api/include/aconfig_storage/aconfig_storage_read_api.hpp @@ -41,6 +41,7 @@ enum FlagInfoBit { struct MappedStorageFile { void* file_ptr; size_t file_size; + virtual ~MappedStorageFile(); }; /// Package read context query result @@ -60,7 +61,7 @@ struct FlagReadContext { /// DO NOT USE APIS IN THE FOLLOWING NAMESPACE DIRECTLY namespace private_internal_api { -android::base::Result<MappedStorageFile> get_mapped_file_impl( +android::base::Result<MappedStorageFile*> get_mapped_file_impl( std::string const& pb_file, std::string const& container, StorageFileType file_type); @@ -68,7 +69,7 @@ android::base::Result<MappedStorageFile> get_mapped_file_impl( } // namespace private_internal_api /// Map a storage file -android::base::Result<MappedStorageFile> map_storage_file( +android::base::Result<MappedStorageFile*> map_storage_file( std::string const& file); @@ -82,7 +83,7 @@ android::base::Result<FlagValueType> map_to_flag_value_type( /// \input container: stoarge container name /// \input file_type: storage file type enum /// \returns a MappedStorageFileQuery -android::base::Result<MappedStorageFile> get_mapped_file( +android::base::Result<MappedStorageFile*> get_mapped_file( std::string const& container, StorageFileType file_type); diff --git a/tools/aconfig/aconfig_storage_read_api/src/lib.rs b/tools/aconfig/aconfig_storage_read_api/src/lib.rs index e4192066d5..61f9e96f84 100644 --- a/tools/aconfig/aconfig_storage_read_api/src/lib.rs +++ b/tools/aconfig/aconfig_storage_read_api/src/lib.rs @@ -42,9 +42,6 @@ pub mod flag_value_query; pub mod mapped_file; pub mod package_table_query; -#[cfg(test)] -mod test_utils; - pub use aconfig_storage_file::{AconfigStorageError, FlagValueType, StorageFileType}; pub use flag_table_query::FlagReadContext; pub use package_table_query::PackageReadContext; @@ -60,8 +57,8 @@ use memmap2::Mmap; use std::fs::File; use std::io::Read; -/// Storage file location pb file -pub const STORAGE_LOCATION_FILE: &str = "/metadata/aconfig/boot/available_storage_file_records.pb"; +/// Storage file location +pub const STORAGE_LOCATION: &str = "/metadata/aconfig"; /// Get read only mapped storage files. /// @@ -78,7 +75,7 @@ pub unsafe fn get_mapped_storage_file( container: &str, file_type: StorageFileType, ) -> Result<Mmap, AconfigStorageError> { - unsafe { crate::mapped_file::get_mapped_file(STORAGE_LOCATION_FILE, container, file_type) } + unsafe { crate::mapped_file::get_mapped_file(STORAGE_LOCATION, container, file_type) } } /// Get package read context for a specific package. @@ -394,45 +391,41 @@ pub fn get_storage_file_version_cxx(file_path: &str) -> ffi::VersionNumberQueryC mod tests { use super::*; use crate::mapped_file::get_mapped_file; - use crate::test_utils::copy_to_temp_file; - use aconfig_storage_file::protos::storage_record_pb::write_proto_to_temp_file; use aconfig_storage_file::{FlagInfoBit, StoredFlagType}; - use tempfile::NamedTempFile; - - fn create_test_storage_files() -> [NamedTempFile; 5] { - let package_map = copy_to_temp_file("./tests/package.map").unwrap(); - let flag_map = copy_to_temp_file("./tests/flag.map").unwrap(); - let flag_val = copy_to_temp_file("./tests/flag.val").unwrap(); - let flag_info = copy_to_temp_file("./tests/flag.info").unwrap(); - - let text_proto = format!( - r#" -files {{ - version: 0 - container: "mockup" - package_map: "{}" - flag_map: "{}" - flag_val: "{}" - flag_info: "{}" - timestamp: 12345 -}} -"#, - package_map.path().display(), - flag_map.path().display(), - flag_val.path().display(), - flag_info.path().display() - ); - let pb_file = write_proto_to_temp_file(&text_proto).unwrap(); - [package_map, flag_map, flag_val, flag_info, pb_file] + use rand::Rng; + use std::fs; + + fn create_test_storage_files() -> String { + let mut rng = rand::thread_rng(); + let number: u32 = rng.gen(); + let storage_dir = String::from("/tmp/") + &number.to_string(); + if std::fs::metadata(&storage_dir).is_ok() { + fs::remove_dir_all(&storage_dir).unwrap(); + } + let maps_dir = storage_dir.clone() + "/maps"; + let boot_dir = storage_dir.clone() + "/boot"; + fs::create_dir(&storage_dir).unwrap(); + fs::create_dir(&maps_dir).unwrap(); + fs::create_dir(&boot_dir).unwrap(); + + let package_map = storage_dir.clone() + "/maps/mockup.package.map"; + let flag_map = storage_dir.clone() + "/maps/mockup.flag.map"; + let flag_val = storage_dir.clone() + "/boot/mockup.val"; + let flag_info = storage_dir.clone() + "/boot/mockup.info"; + fs::copy("./tests/package.map", &package_map).unwrap(); + fs::copy("./tests/flag.map", &flag_map).unwrap(); + fs::copy("./tests/flag.val", &flag_val).unwrap(); + fs::copy("./tests/flag.info", &flag_info).unwrap(); + + return storage_dir; } #[test] // this test point locks down flag package read context query fn test_package_context_query() { - let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); + let storage_dir = create_test_storage_files(); let package_mapped_file = unsafe { - get_mapped_file(&pb_file_path, "mockup", StorageFileType::PackageMap).unwrap() + get_mapped_file(&storage_dir, "mockup", StorageFileType::PackageMap).unwrap() }; let package_context = @@ -460,10 +453,9 @@ files {{ #[test] // this test point locks down flag read context query fn test_flag_context_query() { - let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); + let storage_dir = create_test_storage_files(); let flag_mapped_file = - unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagMap).unwrap() }; + unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagMap).unwrap() }; let baseline = vec![ (0, "enabled_ro", StoredFlagType::ReadOnlyBoolean, 1u16), @@ -486,10 +478,9 @@ files {{ #[test] // this test point locks down flag value query fn test_flag_value_query() { - let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); + let storage_dir = create_test_storage_files(); let flag_value_file = - unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagVal).unwrap() }; + unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagVal).unwrap() }; let baseline: Vec<bool> = vec![false, true, true, false, true, true, true, true]; for (offset, expected_value) in baseline.into_iter().enumerate() { let flag_value = get_boolean_flag_value(&flag_value_file, offset as u32).unwrap(); @@ -500,10 +491,9 @@ files {{ #[test] // this test point locks donw flag info query fn test_flag_info_query() { - let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); + let storage_dir = create_test_storage_files(); let flag_info_file = - unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagInfo).unwrap() }; + unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagInfo).unwrap() }; let is_rw: Vec<bool> = vec![true, false, true, true, false, false, false, true]; for (offset, expected_value) in is_rw.into_iter().enumerate() { let attribute = diff --git a/tools/aconfig/aconfig_storage_read_api/src/mapped_file.rs b/tools/aconfig/aconfig_storage_read_api/src/mapped_file.rs index 378644317c..5a1664535f 100644 --- a/tools/aconfig/aconfig_storage_read_api/src/mapped_file.rs +++ b/tools/aconfig/aconfig_storage_read_api/src/mapped_file.rs @@ -14,47 +14,12 @@ * limitations under the License. */ -use std::fs::File; -use std::io::{BufReader, Read}; - use anyhow::anyhow; use memmap2::Mmap; +use std::fs::File; -use crate::AconfigStorageError::{ - self, FileReadFail, MapFileFail, ProtobufParseFail, StorageFileNotFound, -}; +use crate::AconfigStorageError::{self, FileReadFail, MapFileFail, StorageFileNotFound}; use crate::StorageFileType; -use aconfig_storage_file::protos::{ - storage_record_pb::try_from_binary_proto, ProtoStorageFileInfo, ProtoStorageFiles, -}; - -/// Find where storage files are stored for a particular container -pub fn find_container_storage_location( - location_pb_file: &str, - container: &str, -) -> Result<ProtoStorageFileInfo, AconfigStorageError> { - let file = File::open(location_pb_file).map_err(|errmsg| { - FileReadFail(anyhow!("Failed to open file {}: {}", location_pb_file, errmsg)) - })?; - let mut reader = BufReader::new(file); - let mut bytes = Vec::new(); - reader.read_to_end(&mut bytes).map_err(|errmsg| { - FileReadFail(anyhow!("Failed to read file {}: {}", location_pb_file, errmsg)) - })?; - let storage_locations: ProtoStorageFiles = try_from_binary_proto(&bytes).map_err(|errmsg| { - ProtobufParseFail(anyhow!( - "Failed to parse storage location pb file {}: {}", - location_pb_file, - errmsg - )) - })?; - for location_info in storage_locations.files.iter() { - if location_info.container() == container { - return Ok(location_info.clone()); - } - } - Err(StorageFileNotFound(anyhow!("Storage file does not exist for {}", container))) -} /// Get the read only memory mapping of a storage file /// @@ -82,123 +47,70 @@ unsafe fn map_file(file_path: &str) -> Result<Mmap, AconfigStorageError> { /// file after being mapped. Ensure no writes can happen to this file while this /// mapping stays alive. pub unsafe fn get_mapped_file( - location_pb_file: &str, + storage_dir: &str, container: &str, file_type: StorageFileType, ) -> Result<Mmap, AconfigStorageError> { - let files_location = find_container_storage_location(location_pb_file, container)?; - match file_type { - StorageFileType::PackageMap => unsafe { map_file(files_location.package_map()) }, - StorageFileType::FlagMap => unsafe { map_file(files_location.flag_map()) }, - StorageFileType::FlagVal => unsafe { map_file(files_location.flag_val()) }, - StorageFileType::FlagInfo => unsafe { map_file(files_location.flag_info()) }, + let storage_file = match file_type { + StorageFileType::PackageMap => { + String::from(storage_dir) + "/maps/" + container + ".package.map" + } + StorageFileType::FlagMap => String::from(storage_dir) + "/maps/" + container + ".flag.map", + StorageFileType::FlagVal => String::from(storage_dir) + "/boot/" + container + ".val", + StorageFileType::FlagInfo => String::from(storage_dir) + "/boot/" + container + ".info", + }; + if std::fs::metadata(&storage_file).is_err() { + return Err(StorageFileNotFound(anyhow!("storage file {} does not exist", storage_file))); } + unsafe { map_file(&storage_file) } } #[cfg(test)] mod tests { use super::*; - use crate::test_utils::copy_to_temp_file; - use aconfig_storage_file::protos::storage_record_pb::write_proto_to_temp_file; - use tempfile::NamedTempFile; + use rand::Rng; + use std::fs; + use std::io::Read; - #[test] - fn test_find_storage_file_location() { - let text_proto = r#" -files { - version: 0 - container: "system" - package_map: "/system/etc/package.map" - flag_map: "/system/etc/flag.map" - flag_val: "/metadata/aconfig/system.val" - timestamp: 12345 -} -files { - version: 1 - container: "product" - package_map: "/product/etc/package.map" - flag_map: "/product/etc/flag.map" - flag_val: "/metadata/aconfig/product.val" - timestamp: 54321 -} -"#; - let file = write_proto_to_temp_file(&text_proto).unwrap(); - let file_full_path = file.path().display().to_string(); - let file_info = find_container_storage_location(&file_full_path, "system").unwrap(); - assert_eq!(file_info.version(), 0); - assert_eq!(file_info.container(), "system"); - assert_eq!(file_info.package_map(), "/system/etc/package.map"); - assert_eq!(file_info.flag_map(), "/system/etc/flag.map"); - assert_eq!(file_info.flag_val(), "/metadata/aconfig/system.val"); - assert_eq!(file_info.timestamp(), 12345); - - let file_info = find_container_storage_location(&file_full_path, "product").unwrap(); - assert_eq!(file_info.version(), 1); - assert_eq!(file_info.container(), "product"); - assert_eq!(file_info.package_map(), "/product/etc/package.map"); - assert_eq!(file_info.flag_map(), "/product/etc/flag.map"); - assert_eq!(file_info.flag_val(), "/metadata/aconfig/product.val"); - assert_eq!(file_info.timestamp(), 54321); - - let err = find_container_storage_location(&file_full_path, "vendor").unwrap_err(); - assert_eq!( - format!("{:?}", err), - "StorageFileNotFound(Storage file does not exist for vendor)" - ); - } - - fn map_and_verify(location_pb_file: &str, file_type: StorageFileType, actual_file: &str) { + fn map_and_verify(storage_dir: &str, file_type: StorageFileType, actual_file: &str) { let mut opened_file = File::open(actual_file).unwrap(); let mut content = Vec::new(); opened_file.read_to_end(&mut content).unwrap(); - - let mmaped_file = - unsafe { get_mapped_file(location_pb_file, "system", file_type).unwrap() }; + let mmaped_file = unsafe { get_mapped_file(storage_dir, "mockup", file_type).unwrap() }; assert_eq!(mmaped_file[..], content[..]); } - fn create_test_storage_files() -> [NamedTempFile; 4] { - let package_map = copy_to_temp_file("./tests/package.map").unwrap(); - let flag_map = copy_to_temp_file("./tests/flag.map").unwrap(); - let flag_val = copy_to_temp_file("./tests/package.map").unwrap(); + fn create_test_storage_files() -> String { + let mut rng = rand::thread_rng(); + let number: u32 = rng.gen(); + let storage_dir = String::from("/tmp/") + &number.to_string(); + if std::fs::metadata(&storage_dir).is_ok() { + fs::remove_dir_all(&storage_dir).unwrap(); + } + let maps_dir = storage_dir.clone() + "/maps"; + let boot_dir = storage_dir.clone() + "/boot"; + fs::create_dir(&storage_dir).unwrap(); + fs::create_dir(&maps_dir).unwrap(); + fs::create_dir(&boot_dir).unwrap(); + + let package_map = storage_dir.clone() + "/maps/mockup.package.map"; + let flag_map = storage_dir.clone() + "/maps/mockup.flag.map"; + let flag_val = storage_dir.clone() + "/boot/mockup.val"; + let flag_info = storage_dir.clone() + "/boot/mockup.info"; + fs::copy("./tests/package.map", &package_map).unwrap(); + fs::copy("./tests/flag.map", &flag_map).unwrap(); + fs::copy("./tests/flag.val", &flag_val).unwrap(); + fs::copy("./tests/flag.info", &flag_info).unwrap(); - let text_proto = format!( - r#" -files {{ - version: 0 - container: "system" - package_map: "{}" - flag_map: "{}" - flag_val: "{}" - timestamp: 12345 -}} -"#, - package_map.path().display(), - flag_map.path().display(), - flag_val.path().display() - ); - let pb_file = write_proto_to_temp_file(&text_proto).unwrap(); - [package_map, flag_map, flag_val, pb_file] + return storage_dir; } #[test] fn test_mapped_file_contents() { - let [package_map, flag_map, flag_val, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); - map_and_verify( - &pb_file_path, - StorageFileType::PackageMap, - &package_map.path().display().to_string(), - ); - map_and_verify( - &pb_file_path, - StorageFileType::FlagMap, - &flag_map.path().display().to_string(), - ); - map_and_verify( - &pb_file_path, - StorageFileType::FlagVal, - &flag_val.path().display().to_string(), - ); + let storage_dir = create_test_storage_files(); + map_and_verify(&storage_dir, StorageFileType::PackageMap, "./tests/package.map"); + map_and_verify(&storage_dir, StorageFileType::FlagMap, "./tests/flag.map"); + map_and_verify(&storage_dir, StorageFileType::FlagVal, "./tests/flag.val"); + map_and_verify(&storage_dir, StorageFileType::FlagInfo, "./tests/flag.info"); } } diff --git a/tools/aconfig/aconfig_storage_read_api/src/test_utils.rs b/tools/aconfig/aconfig_storage_read_api/src/test_utils.rs deleted file mode 100644 index 84f31aa710..0000000000 --- a/tools/aconfig/aconfig_storage_read_api/src/test_utils.rs +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -use anyhow::Result; -use std::fs; -use tempfile::NamedTempFile; - -/// Create temp file copy -pub(crate) fn copy_to_temp_file(source_file: &str) -> Result<NamedTempFile> { - let file = NamedTempFile::new()?; - fs::copy(source_file, file.path())?; - Ok(file) -} diff --git a/tools/aconfig/aconfig_storage_read_api/tests/Android.bp b/tools/aconfig/aconfig_storage_read_api/tests/Android.bp index 6b05ca6fb1..98944d60dc 100644 --- a/tools/aconfig/aconfig_storage_read_api/tests/Android.bp +++ b/tools/aconfig/aconfig_storage_read_api/tests/Android.bp @@ -7,8 +7,7 @@ rust_test { "libanyhow", "libaconfig_storage_file", "libaconfig_storage_read_api", - "libprotobuf", - "libtempfile", + "librand", ], data: [ "package.map", @@ -26,8 +25,6 @@ cc_test { ], static_libs: [ "libgmock", - "libaconfig_storage_protos_cc", - "libprotobuf-cpp-lite", "libaconfig_storage_read_api_cc", "libbase", "liblog", diff --git a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp index cfd128d123..86a0541c53 100644 --- a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp +++ b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.cpp @@ -16,16 +16,15 @@ #include <string> #include <vector> +#include <memory> #include <cstdio> #include <sys/stat.h> #include "aconfig_storage/aconfig_storage_read_api.hpp" #include <gtest/gtest.h> -#include <protos/aconfig_storage_metadata.pb.h> #include <android-base/file.h> #include <android-base/result.h> -using android::aconfig_storage_metadata::storage_files; using namespace android::base; namespace api = aconfig_storage; @@ -33,49 +32,33 @@ namespace private_api = aconfig_storage::private_internal_api; class AconfigStorageTest : public ::testing::Test { protected: - Result<std::string> copy_to_temp_file(std::string const& source_file) { - auto temp_file = std::string(std::tmpnam(nullptr)); + Result<void> copy_file(std::string const& src_file, + std::string const& dst_file) { auto content = std::string(); - if (!ReadFileToString(source_file, &content)) { - return Error() << "failed to read file: " << source_file; + if (!ReadFileToString(src_file, &content)) { + return Error() << "failed to read file: " << src_file; } - if (!WriteStringToFile(content, temp_file)) { - return Error() << "failed to copy file: " << source_file; + if (!WriteStringToFile(content, dst_file)) { + return Error() << "failed to copy file: " << dst_file; } - return temp_file; - } - - Result<std::string> write_storage_location_pb_file(std::string const& package_map, - std::string const& flag_map, - std::string const& flag_val, - std::string const& flag_info) { - auto temp_file = std::tmpnam(nullptr); - auto proto = storage_files(); - auto* info = proto.add_files(); - info->set_version(0); - info->set_container("mockup"); - info->set_package_map(package_map); - info->set_flag_map(flag_map); - info->set_flag_val(flag_val); - info->set_flag_info(flag_info); - info->set_timestamp(12345); - - auto content = std::string(); - proto.SerializeToString(&content); - if (!WriteStringToFile(content, temp_file)) { - return Error() << "failed to write storage records pb file"; - } - return temp_file; + return {}; } void SetUp() override { auto const test_dir = android::base::GetExecutableDirectory(); - package_map = *copy_to_temp_file(test_dir + "/package.map"); - flag_map = *copy_to_temp_file(test_dir + "/flag.map"); - flag_val = *copy_to_temp_file(test_dir + "/flag.val"); - flag_info = *copy_to_temp_file(test_dir + "/flag.info"); - storage_record_pb = *write_storage_location_pb_file( - package_map, flag_map, flag_val, flag_info); + storage_dir = std::string(root_dir.path); + auto maps_dir = storage_dir + "/maps"; + auto boot_dir = storage_dir + "/boot"; + mkdir(maps_dir.c_str(), 0775); + mkdir(boot_dir.c_str(), 0775); + package_map = std::string(maps_dir) + "/mockup.package.map"; + flag_map = std::string(maps_dir) + "/mockup.flag.map"; + flag_val = std::string(boot_dir) + "/mockup.val"; + flag_info = std::string(boot_dir) + "/mockup.info"; + copy_file(test_dir + "/package.map", package_map); + copy_file(test_dir + "/flag.map", flag_map); + copy_file(test_dir + "/flag.val", flag_val); + copy_file(test_dir + "/flag.info", flag_info); } void TearDown() override { @@ -83,14 +66,14 @@ class AconfigStorageTest : public ::testing::Test { std::remove(flag_map.c_str()); std::remove(flag_val.c_str()); std::remove(flag_info.c_str()); - std::remove(storage_record_pb.c_str()); } + TemporaryDir root_dir; + std::string storage_dir; std::string package_map; std::string flag_map; std::string flag_val; std::string flag_info; - std::string storage_record_pb; }; /// Test to lock down storage file version query api @@ -111,18 +94,20 @@ TEST_F(AconfigStorageTest, test_storage_version_query) { /// Negative test to lock down the error when mapping none exist storage files TEST_F(AconfigStorageTest, test_none_exist_storage_file_mapping) { - auto mapped_file = private_api::get_mapped_file_impl( - storage_record_pb, "vendor", api::StorageFileType::package_map); - ASSERT_FALSE(mapped_file.ok()); - ASSERT_EQ(mapped_file.error().message(), - "Unable to find storage files for container vendor"); + auto mapped_file_result = private_api::get_mapped_file_impl( + storage_dir, "vendor", api::StorageFileType::package_map); + ASSERT_FALSE(mapped_file_result.ok()); + ASSERT_EQ(mapped_file_result.error().message(), + std::string("failed to open ") + storage_dir + + "/maps/vendor.package.map: No such file or directory"); } /// Test to lock down storage package context query api TEST_F(AconfigStorageTest, test_package_context_query) { - auto mapped_file = private_api::get_mapped_file_impl( - storage_record_pb, "mockup", api::StorageFileType::package_map); - ASSERT_TRUE(mapped_file.ok()); + auto mapped_file_result = private_api::get_mapped_file_impl( + storage_dir, "mockup", api::StorageFileType::package_map); + ASSERT_TRUE(mapped_file_result.ok()); + auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result); auto context = api::get_package_read_context( *mapped_file, "com.android.aconfig.storage.test_1"); @@ -148,9 +133,10 @@ TEST_F(AconfigStorageTest, test_package_context_query) { /// Test to lock down when querying none exist package TEST_F(AconfigStorageTest, test_none_existent_package_context_query) { - auto mapped_file = private_api::get_mapped_file_impl( - storage_record_pb, "mockup", api::StorageFileType::package_map); - ASSERT_TRUE(mapped_file.ok()); + auto mapped_file_result = private_api::get_mapped_file_impl( + storage_dir, "mockup", api::StorageFileType::package_map); + ASSERT_TRUE(mapped_file_result.ok()); + auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result); auto context = api::get_package_read_context( *mapped_file, "com.android.aconfig.storage.test_3"); @@ -160,9 +146,10 @@ TEST_F(AconfigStorageTest, test_none_existent_package_context_query) { /// Test to lock down storage flag context query api TEST_F(AconfigStorageTest, test_flag_context_query) { - auto mapped_file = private_api::get_mapped_file_impl( - storage_record_pb, "mockup", api::StorageFileType::flag_map); - ASSERT_TRUE(mapped_file.ok()); + auto mapped_file_result = private_api::get_mapped_file_impl( + storage_dir, "mockup", api::StorageFileType::flag_map); + ASSERT_TRUE(mapped_file_result.ok()); + auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result); auto baseline = std::vector<std::tuple<int, std::string, api::StoredFlagType, int>>{ {0, "enabled_ro", api::StoredFlagType::ReadOnlyBoolean, 1}, @@ -185,9 +172,10 @@ TEST_F(AconfigStorageTest, test_flag_context_query) { /// Test to lock down when querying none exist flag TEST_F(AconfigStorageTest, test_none_existent_flag_context_query) { - auto mapped_file = private_api::get_mapped_file_impl( - storage_record_pb, "mockup", api::StorageFileType::flag_map); - ASSERT_TRUE(mapped_file.ok()); + auto mapped_file_result = private_api::get_mapped_file_impl( + storage_dir, "mockup", api::StorageFileType::flag_map); + ASSERT_TRUE(mapped_file_result.ok()); + auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result); auto context = api::get_flag_read_context(*mapped_file, 0, "none_exist"); ASSERT_TRUE(context.ok()); @@ -200,9 +188,10 @@ TEST_F(AconfigStorageTest, test_none_existent_flag_context_query) { /// Test to lock down storage flag value query api TEST_F(AconfigStorageTest, test_boolean_flag_value_query) { - auto mapped_file = private_api::get_mapped_file_impl( - storage_record_pb, "mockup", api::StorageFileType::flag_val); - ASSERT_TRUE(mapped_file.ok()); + auto mapped_file_result = private_api::get_mapped_file_impl( + storage_dir, "mockup", api::StorageFileType::flag_val); + ASSERT_TRUE(mapped_file_result.ok()); + auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result); auto expected_value = std::vector<bool>{ false, true, true, false, true, true, true, true}; @@ -215,9 +204,10 @@ TEST_F(AconfigStorageTest, test_boolean_flag_value_query) { /// Negative test to lock down the error when querying flag value out of range TEST_F(AconfigStorageTest, test_invalid_boolean_flag_value_query) { - auto mapped_file = private_api::get_mapped_file_impl( - storage_record_pb, "mockup", api::StorageFileType::flag_val); - ASSERT_TRUE(mapped_file.ok()); + auto mapped_file_result = private_api::get_mapped_file_impl( + storage_dir, "mockup", api::StorageFileType::flag_val); + ASSERT_TRUE(mapped_file_result.ok()); + auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result); auto value = api::get_boolean_flag_value(*mapped_file, 8); ASSERT_FALSE(value.ok()); @@ -227,9 +217,10 @@ TEST_F(AconfigStorageTest, test_invalid_boolean_flag_value_query) { /// Test to lock down storage flag info query api TEST_F(AconfigStorageTest, test_boolean_flag_info_query) { - auto mapped_file = private_api::get_mapped_file_impl( - storage_record_pb, "mockup", api::StorageFileType::flag_info); - ASSERT_TRUE(mapped_file.ok()); + auto mapped_file_result = private_api::get_mapped_file_impl( + storage_dir, "mockup", api::StorageFileType::flag_info); + ASSERT_TRUE(mapped_file_result.ok()); + auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result); auto expected_value = std::vector<bool>{ true, false, true, true, false, false, false, true}; @@ -245,9 +236,10 @@ TEST_F(AconfigStorageTest, test_boolean_flag_info_query) { /// Negative test to lock down the error when querying flag info out of range TEST_F(AconfigStorageTest, test_invalid_boolean_flag_info_query) { - auto mapped_file = private_api::get_mapped_file_impl( - storage_record_pb, "mockup", api::StorageFileType::flag_info); - ASSERT_TRUE(mapped_file.ok()); + auto mapped_file_result = private_api::get_mapped_file_impl( + storage_dir, "mockup", api::StorageFileType::flag_info); + ASSERT_TRUE(mapped_file_result.ok()); + auto mapped_file = std::unique_ptr<api::MappedStorageFile>(*mapped_file_result); auto attribute = api::get_flag_attribute(*mapped_file, api::FlagValueType::Boolean, 8); ASSERT_FALSE(attribute.ok()); diff --git a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.rs b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.rs index ecba573d82..afc44d4d70 100644 --- a/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.rs +++ b/tools/aconfig/aconfig_storage_read_api/tests/storage_read_api_test.rs @@ -1,71 +1,63 @@ #[cfg(not(feature = "cargo"))] mod aconfig_storage_rust_test { - use aconfig_storage_file::protos::storage_record_pb::write_proto_to_temp_file; use aconfig_storage_file::{FlagInfoBit, FlagValueType, StorageFileType, StoredFlagType}; use aconfig_storage_read_api::{ get_boolean_flag_value, get_flag_attribute, get_flag_read_context, get_package_read_context, get_storage_file_version, mapped_file::get_mapped_file, PackageReadContext, }; + use rand::Rng; use std::fs; - use tempfile::NamedTempFile; - pub fn copy_to_temp_file(source_file: &str) -> NamedTempFile { - let file = NamedTempFile::new().unwrap(); - fs::copy(source_file, file.path()).unwrap(); - file - } - - fn create_test_storage_files() -> [NamedTempFile; 5] { - let package_map = copy_to_temp_file("./package.map"); - let flag_map = copy_to_temp_file("./flag.map"); - let flag_val = copy_to_temp_file("./flag.val"); - let flag_info = copy_to_temp_file("./flag.info"); - - let text_proto = format!( - r#" -files {{ - version: 0 - container: "mockup" - package_map: "{}" - flag_map: "{}" - flag_val: "{}" - flag_info: "{}" - timestamp: 12345 -}} -"#, - package_map.path().display(), - flag_map.path().display(), - flag_val.path().display(), - flag_info.path().display() - ); - let pb_file = write_proto_to_temp_file(&text_proto).unwrap(); - [package_map, flag_map, flag_val, flag_info, pb_file] + fn create_test_storage_files() -> String { + let mut rng = rand::thread_rng(); + let number: u32 = rng.gen(); + let storage_dir = String::from("/tmp/") + &number.to_string(); + if std::fs::metadata(&storage_dir).is_ok() { + fs::remove_dir_all(&storage_dir).unwrap(); + } + let maps_dir = storage_dir.clone() + "/maps"; + let boot_dir = storage_dir.clone() + "/boot"; + fs::create_dir(&storage_dir).unwrap(); + fs::create_dir(maps_dir).unwrap(); + fs::create_dir(boot_dir).unwrap(); + + let package_map = storage_dir.clone() + "/maps/mockup.package.map"; + let flag_map = storage_dir.clone() + "/maps/mockup.flag.map"; + let flag_val = storage_dir.clone() + "/boot/mockup.val"; + let flag_info = storage_dir.clone() + "/boot/mockup.info"; + fs::copy("./package.map", package_map).unwrap(); + fs::copy("./flag.map", flag_map).unwrap(); + fs::copy("./flag.val", flag_val).unwrap(); + fs::copy("./flag.info", flag_info).unwrap(); + + storage_dir } #[test] fn test_unavailable_stoarge() { - let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); + let storage_dir = create_test_storage_files(); // SAFETY: // The safety here is ensured as the test process will not write to temp storage file let err = unsafe { - get_mapped_file(&pb_file_path, "vendor", StorageFileType::PackageMap).unwrap_err() + get_mapped_file(&storage_dir, "vendor", StorageFileType::PackageMap).unwrap_err() }; assert_eq!( format!("{:?}", err), - "StorageFileNotFound(Storage file does not exist for vendor)" + format!( + "StorageFileNotFound(storage file {}/maps/vendor.package.map does not exist)", + storage_dir + ) ); } #[test] fn test_package_context_query() { - let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); + let storage_dir = create_test_storage_files(); // SAFETY: // The safety here is ensured as the test process will not write to temp storage file let package_mapped_file = unsafe { - get_mapped_file(&pb_file_path, "mockup", StorageFileType::PackageMap).unwrap() + get_mapped_file(&storage_dir, "mockup", StorageFileType::PackageMap).unwrap() }; let package_context = @@ -92,12 +84,11 @@ files {{ #[test] fn test_none_exist_package_context_query() { - let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); + let storage_dir = create_test_storage_files(); // SAFETY: // The safety here is ensured as the test process will not write to temp storage file let package_mapped_file = unsafe { - get_mapped_file(&pb_file_path, "mockup", StorageFileType::PackageMap).unwrap() + get_mapped_file(&storage_dir, "mockup", StorageFileType::PackageMap).unwrap() }; let package_context_option = @@ -108,12 +99,11 @@ files {{ #[test] fn test_flag_context_query() { - let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); + let storage_dir = create_test_storage_files(); // SAFETY: // The safety here is ensured as the test process will not write to temp storage file let flag_mapped_file = - unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagMap).unwrap() }; + unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagMap).unwrap() }; let baseline = vec![ (0, "enabled_ro", StoredFlagType::ReadOnlyBoolean, 1u16), @@ -135,12 +125,11 @@ files {{ #[test] fn test_none_exist_flag_context_query() { - let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); + let storage_dir = create_test_storage_files(); // SAFETY: // The safety here is ensured as the test process will not write to temp storage file let flag_mapped_file = - unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagMap).unwrap() }; + unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagMap).unwrap() }; let flag_context_option = get_flag_read_context(&flag_mapped_file, 0, "none_exist").unwrap(); assert_eq!(flag_context_option, None); @@ -152,12 +141,11 @@ files {{ #[test] fn test_boolean_flag_value_query() { - let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); + let storage_dir = create_test_storage_files(); // SAFETY: // The safety here is ensured as the test process will not write to temp storage file let flag_value_file = - unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagVal).unwrap() }; + unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagVal).unwrap() }; let baseline: Vec<bool> = vec![false, true, true, false, true, true, true, true]; for (offset, expected_value) in baseline.into_iter().enumerate() { let flag_value = get_boolean_flag_value(&flag_value_file, offset as u32).unwrap(); @@ -167,12 +155,11 @@ files {{ #[test] fn test_invalid_boolean_flag_value_query() { - let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); + let storage_dir = create_test_storage_files(); // SAFETY: // The safety here is ensured as the test process will not write to temp storage file let flag_value_file = - unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagVal).unwrap() }; + unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagVal).unwrap() }; let err = get_boolean_flag_value(&flag_value_file, 8u32).unwrap_err(); assert_eq!( format!("{:?}", err), @@ -182,12 +169,11 @@ files {{ #[test] fn test_flag_info_query() { - let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); + let storage_dir = create_test_storage_files(); // SAFETY: // The safety here is ensured as the test process will not write to temp storage file let flag_info_file = - unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagInfo).unwrap() }; + unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagInfo).unwrap() }; let is_rw: Vec<bool> = vec![true, false, true, true, false, false, false, true]; for (offset, expected_value) in is_rw.into_iter().enumerate() { let attribute = @@ -200,12 +186,11 @@ files {{ #[test] fn test_invalid_boolean_flag_info_query() { - let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files(); - let pb_file_path = pb_file.path().display().to_string(); + let storage_dir = create_test_storage_files(); // SAFETY: // The safety here is ensured as the test process will not write to temp storage file let flag_info_file = - unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagInfo).unwrap() }; + unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagInfo).unwrap() }; let err = get_flag_attribute(&flag_info_file, FlagValueType::Boolean, 8u32).unwrap_err(); assert_eq!( format!("{:?}", err), diff --git a/tools/aconfig/aconfig_storage_write_api/Android.bp b/tools/aconfig/aconfig_storage_write_api/Android.bp index 4dbdbbfb2f..0f1962c3ac 100644 --- a/tools/aconfig/aconfig_storage_write_api/Android.bp +++ b/tools/aconfig/aconfig_storage_write_api/Android.bp @@ -77,7 +77,6 @@ cc_library_static { export_include_dirs: ["include"], static_libs: [ "libaconfig_storage_read_api_cc", - "libaconfig_storage_protos_cc", "libprotobuf-cpp-lite", "libbase", ], diff --git a/tools/aconfig/aconfig_storage_write_api/Cargo.toml b/tools/aconfig/aconfig_storage_write_api/Cargo.toml index eaa55f2531..2ce6edfe96 100644 --- a/tools/aconfig/aconfig_storage_write_api/Cargo.toml +++ b/tools/aconfig/aconfig_storage_write_api/Cargo.toml @@ -13,7 +13,6 @@ cxx = "1.0" memmap2 = "0.8.0" tempfile = "3.9.0" thiserror = "1.0.56" -protobuf = "3.2.0" aconfig_storage_file = { path = "../aconfig_storage_file" } aconfig_storage_read_api = { path = "../aconfig_storage_read_api" } diff --git a/tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp b/tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp index cd57f4fb29..b441e057ed 100644 --- a/tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp +++ b/tools/aconfig/aconfig_storage_write_api/aconfig_storage_write_api.cpp @@ -1,7 +1,6 @@ #include <android-base/file.h> #include <android-base/logging.h> -#include <protos/aconfig_storage_metadata.pb.h> #include <sys/mman.h> #include <sys/stat.h> @@ -11,14 +10,12 @@ #include "aconfig_storage/lib.rs.h" #include "aconfig_storage/aconfig_storage_write_api.hpp" -using storage_records_pb = android::aconfig_storage_metadata::storage_files; -using storage_record_pb = android::aconfig_storage_metadata::storage_file_info; using namespace android::base; namespace aconfig_storage { /// Map a storage file -Result<MutableMappedStorageFile> map_mutable_storage_file(std::string const& file) { +Result<MutableMappedStorageFile*> map_mutable_storage_file(std::string const& file) { struct stat file_stat; if (stat(file.c_str(), &file_stat) < 0) { return ErrnoError() << "stat failed"; @@ -41,9 +38,9 @@ Result<MutableMappedStorageFile> map_mutable_storage_file(std::string const& fil return ErrnoError() << "mmap failed"; } - auto mapped_file = MutableMappedStorageFile(); - mapped_file.file_ptr = map_result; - mapped_file.file_size = file_size; + auto mapped_file = new MutableMappedStorageFile(); + mapped_file->file_ptr = map_result; + mapped_file->file_size = file_size; return mapped_file; } diff --git a/tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp b/tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp index 7148396b82..ff06cbc6de 100644 --- a/tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp +++ b/tools/aconfig/aconfig_storage_write_api/include/aconfig_storage/aconfig_storage_write_api.hpp @@ -11,13 +11,10 @@ using namespace android::base; namespace aconfig_storage { /// Mapped flag value file -struct MutableMappedStorageFile{ - void* file_ptr; - size_t file_size; -}; +struct MutableMappedStorageFile : MappedStorageFile {}; /// Map a storage file -Result<MutableMappedStorageFile> map_mutable_storage_file( +Result<MutableMappedStorageFile*> map_mutable_storage_file( std::string const& file); /// Set boolean flag value diff --git a/tools/aconfig/aconfig_storage_write_api/tests/Android.bp b/tools/aconfig/aconfig_storage_write_api/tests/Android.bp index 85568e063b..f6409b7090 100644 --- a/tools/aconfig/aconfig_storage_write_api/tests/Android.bp +++ b/tools/aconfig/aconfig_storage_write_api/tests/Android.bp @@ -25,8 +25,6 @@ cc_test { ], static_libs: [ "libgmock", - "libaconfig_storage_protos_cc", - "libprotobuf-cpp-lite", "libaconfig_storage_read_api_cc", "libaconfig_storage_write_api_cc", "libbase", diff --git a/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.cpp b/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.cpp index bd39e9e1de..31183fa01b 100644 --- a/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.cpp +++ b/tools/aconfig/aconfig_storage_write_api/tests/storage_write_api_test.cpp @@ -22,11 +22,9 @@ #include "aconfig_storage/aconfig_storage_read_api.hpp" #include "aconfig_storage/aconfig_storage_write_api.hpp" #include <gtest/gtest.h> -#include <protos/aconfig_storage_metadata.pb.h> #include <android-base/file.h> #include <android-base/result.h> -using android::aconfig_storage_metadata::storage_files; using namespace android::base; namespace api = aconfig_storage; @@ -78,15 +76,12 @@ TEST_F(AconfigStorageTest, test_non_writable_storage_file_mapping) { TEST_F(AconfigStorageTest, test_boolean_flag_value_update) { auto mapped_file_result = api::map_mutable_storage_file(flag_val); ASSERT_TRUE(mapped_file_result.ok()); + auto mapped_file = std::unique_ptr<api::MutableMappedStorageFile>(*mapped_file_result); - auto mapped_file = *mapped_file_result; for (int offset = 0; offset < 8; ++offset) { - auto update_result = api::set_boolean_flag_value(mapped_file, offset, true); + auto update_result = api::set_boolean_flag_value(*mapped_file, offset, true); ASSERT_TRUE(update_result.ok()); - auto ro_mapped_file = api::MappedStorageFile(); - ro_mapped_file.file_ptr = mapped_file.file_ptr; - ro_mapped_file.file_size = mapped_file.file_size; - auto value = api::get_boolean_flag_value(ro_mapped_file, offset); + auto value = api::get_boolean_flag_value(*mapped_file, offset); ASSERT_TRUE(value.ok()); ASSERT_TRUE(*value); } @@ -96,9 +91,8 @@ TEST_F(AconfigStorageTest, test_boolean_flag_value_update) { TEST_F(AconfigStorageTest, test_invalid_boolean_flag_value_update) { auto mapped_file_result = api::map_mutable_storage_file(flag_val); ASSERT_TRUE(mapped_file_result.ok()); - auto mapped_file = *mapped_file_result; - - auto update_result = api::set_boolean_flag_value(mapped_file, 8, true); + auto mapped_file = std::unique_ptr<api::MutableMappedStorageFile>(*mapped_file_result); + auto update_result = api::set_boolean_flag_value(*mapped_file, 8, true); ASSERT_FALSE(update_result.ok()); ASSERT_EQ(update_result.error().message(), std::string("InvalidStorageFileOffset(Flag value offset goes beyond the end of the file.)")); @@ -108,27 +102,22 @@ TEST_F(AconfigStorageTest, test_invalid_boolean_flag_value_update) { TEST_F(AconfigStorageTest, test_flag_has_server_override_update) { auto mapped_file_result = api::map_mutable_storage_file(flag_info); ASSERT_TRUE(mapped_file_result.ok()); - auto mapped_file = *mapped_file_result; + auto mapped_file = std::unique_ptr<api::MutableMappedStorageFile>(*mapped_file_result); for (int offset = 0; offset < 8; ++offset) { auto update_result = api::set_flag_has_server_override( - mapped_file, api::FlagValueType::Boolean, offset, true); + *mapped_file, api::FlagValueType::Boolean, offset, true); ASSERT_TRUE(update_result.ok()) << update_result.error(); - auto ro_mapped_file = api::MappedStorageFile(); - ro_mapped_file.file_ptr = mapped_file.file_ptr; - ro_mapped_file.file_size = mapped_file.file_size; auto attribute = api::get_flag_attribute( - ro_mapped_file, api::FlagValueType::Boolean, offset); + *mapped_file, api::FlagValueType::Boolean, offset); ASSERT_TRUE(attribute.ok()); ASSERT_TRUE(*attribute & api::FlagInfoBit::HasServerOverride); update_result = api::set_flag_has_server_override( - mapped_file, api::FlagValueType::Boolean, offset, false); + *mapped_file, api::FlagValueType::Boolean, offset, false); ASSERT_TRUE(update_result.ok()); - ro_mapped_file.file_ptr = mapped_file.file_ptr; - ro_mapped_file.file_size = mapped_file.file_size; attribute = api::get_flag_attribute( - ro_mapped_file, api::FlagValueType::Boolean, offset); + *mapped_file, api::FlagValueType::Boolean, offset); ASSERT_TRUE(attribute.ok()); ASSERT_FALSE(*attribute & api::FlagInfoBit::HasServerOverride); } @@ -138,27 +127,22 @@ TEST_F(AconfigStorageTest, test_flag_has_server_override_update) { TEST_F(AconfigStorageTest, test_flag_has_local_override_update) { auto mapped_file_result = api::map_mutable_storage_file(flag_info); ASSERT_TRUE(mapped_file_result.ok()); - auto mapped_file = *mapped_file_result; + auto mapped_file = std::unique_ptr<api::MutableMappedStorageFile>(*mapped_file_result); for (int offset = 0; offset < 8; ++offset) { auto update_result = api::set_flag_has_local_override( - mapped_file, api::FlagValueType::Boolean, offset, true); + *mapped_file, api::FlagValueType::Boolean, offset, true); ASSERT_TRUE(update_result.ok()); - auto ro_mapped_file = api::MappedStorageFile(); - ro_mapped_file.file_ptr = mapped_file.file_ptr; - ro_mapped_file.file_size = mapped_file.file_size; auto attribute = api::get_flag_attribute( - ro_mapped_file, api::FlagValueType::Boolean, offset); + *mapped_file, api::FlagValueType::Boolean, offset); ASSERT_TRUE(attribute.ok()); ASSERT_TRUE(*attribute & api::FlagInfoBit::HasLocalOverride); update_result = api::set_flag_has_local_override( - mapped_file, api::FlagValueType::Boolean, offset, false); + *mapped_file, api::FlagValueType::Boolean, offset, false); ASSERT_TRUE(update_result.ok()); - ro_mapped_file.file_ptr = mapped_file.file_ptr; - ro_mapped_file.file_size = mapped_file.file_size; attribute = api::get_flag_attribute( - ro_mapped_file, api::FlagValueType::Boolean, offset); + *mapped_file, api::FlagValueType::Boolean, offset); ASSERT_TRUE(attribute.ok()); ASSERT_FALSE(*attribute & api::FlagInfoBit::HasLocalOverride); } diff --git a/tools/aconfig/aflags/src/aconfig_storage_source.rs b/tools/aconfig/aflags/src/aconfig_storage_source.rs index c21c5424bb..04140c7fa3 100644 --- a/tools/aconfig/aflags/src/aconfig_storage_source.rs +++ b/tools/aconfig/aflags/src/aconfig_storage_source.rs @@ -27,8 +27,7 @@ impl FlagSource for AconfigStorageSource { let container = file_info.container.ok_or(anyhow!("storage file is missing container"))?; - for listed_flag in - aconfig_storage_file::list_flags(&package_map, &flag_map, &flag_val)? + for listed_flag in aconfig_storage_file::list_flags(&package_map, &flag_map, &flag_val)? { result.push(Flag { name: listed_flag.flag_name, diff --git a/tools/aconfig/aflags/src/main.rs b/tools/aconfig/aflags/src/main.rs index 4ce0d35ba1..05c15bb304 100644 --- a/tools/aconfig/aflags/src/main.rs +++ b/tools/aconfig/aflags/src/main.rs @@ -33,12 +33,16 @@ enum FlagPermission { ReadWrite, } -impl ToString for FlagPermission { - fn to_string(&self) -> String { - match &self { - Self::ReadOnly => "read-only".into(), - Self::ReadWrite => "read-write".into(), - } +impl std::fmt::Display for FlagPermission { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match &self { + Self::ReadOnly => "read-only", + Self::ReadWrite => "read-write", + } + ) } } @@ -48,12 +52,16 @@ enum ValuePickedFrom { Server, } -impl ToString for ValuePickedFrom { - fn to_string(&self) -> String { - match &self { - Self::Default => "default".into(), - Self::Server => "server".into(), - } +impl std::fmt::Display for ValuePickedFrom { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match &self { + Self::Default => "default", + Self::Server => "server", + } + ) } } @@ -75,12 +83,16 @@ impl TryFrom<&str> for FlagValue { } } -impl ToString for FlagValue { - fn to_string(&self) -> String { - match &self { - Self::Enabled => "enabled".into(), - Self::Disabled => "disabled".into(), - } +impl std::fmt::Display for FlagValue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match &self { + Self::Enabled => "enabled", + Self::Disabled => "disabled", + } + ) } } @@ -103,7 +115,7 @@ impl Flag { fn display_staged_value(&self) -> String { match self.staged_value { - Some(v) => format!("(->{})", v.to_string()), + Some(v) => format!("(->{})", v), None => "-".to_string(), } } @@ -153,6 +165,10 @@ enum Command { /// Read from the new flag storage. #[clap(long)] use_new_storage: bool, + + /// Optionally filter by container name. + #[clap(short = 'c', long = "container")] + container: Option<String>, }, /// Enable an aconfig flag on this device, on the next boot. @@ -176,6 +192,23 @@ struct PaddingInfo { longest_permission_col: usize, } +struct Filter { + container: Option<String>, +} + +impl Filter { + fn apply(&self, flags: &[Flag]) -> Vec<Flag> { + flags + .iter() + .filter(|flag| match &self.container { + Some(c) => flag.container == *c, + None => true, + }) + .cloned() + .collect() + } +} + fn format_flag_row(flag: &Flag, info: &PaddingInfo) -> String { let full_name = flag.qualified_name(); let p0 = info.longest_flag_col + 1; @@ -215,11 +248,12 @@ fn set_flag(qualified_name: &str, value: &str) -> Result<()> { Ok(()) } -fn list(source_type: FlagSourceType) -> Result<String> { - let flags = match source_type { +fn list(source_type: FlagSourceType, container: Option<String>) -> Result<String> { + let flags_unfiltered = match source_type { FlagSourceType::DeviceConfig => DeviceConfigSource::list_flags()?, FlagSourceType::AconfigStorage => AconfigStorageSource::list_flags()?, }; + let flags = (Filter { container }).apply(&flags_unfiltered); let padding_info = PaddingInfo { longest_flag_col: flags.iter().map(|f| f.qualified_name().len()).max().unwrap_or(0), longest_val_col: flags.iter().map(|f| f.value.to_string().len()).max().unwrap_or(0), @@ -251,8 +285,12 @@ fn list(source_type: FlagSourceType) -> Result<String> { fn main() { let cli = Cli::parse(); let output = match cli.command { - Command::List { use_new_storage: true } => list(FlagSourceType::AconfigStorage).map(Some), - Command::List { use_new_storage: false } => list(FlagSourceType::DeviceConfig).map(Some), + Command::List { use_new_storage: true, container } => { + list(FlagSourceType::AconfigStorage, container).map(Some) + } + Command::List { use_new_storage: false, container } => { + list(FlagSourceType::DeviceConfig, container).map(Some) + } Command::Enable { qualified_name } => set_flag(&qualified_name, "true").map(|_| None), Command::Disable { qualified_name } => set_flag(&qualified_name, "false").map(|_| None), }; @@ -262,3 +300,84 @@ fn main() { Err(message) => println!("Error: {message}"), } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_filter_container() { + let flags = vec![ + Flag { + namespace: "namespace".to_string(), + name: "test1".to_string(), + package: "package".to_string(), + value: FlagValue::Disabled, + staged_value: None, + permission: FlagPermission::ReadWrite, + value_picked_from: ValuePickedFrom::Default, + container: "system".to_string(), + }, + Flag { + namespace: "namespace".to_string(), + name: "test2".to_string(), + package: "package".to_string(), + value: FlagValue::Disabled, + staged_value: None, + permission: FlagPermission::ReadWrite, + value_picked_from: ValuePickedFrom::Default, + container: "not_system".to_string(), + }, + Flag { + namespace: "namespace".to_string(), + name: "test3".to_string(), + package: "package".to_string(), + value: FlagValue::Disabled, + staged_value: None, + permission: FlagPermission::ReadWrite, + value_picked_from: ValuePickedFrom::Default, + container: "system".to_string(), + }, + ]; + + assert_eq!((Filter { container: Some("system".to_string()) }).apply(&flags).len(), 2); + } + + #[test] + fn test_filter_no_container() { + let flags = vec![ + Flag { + namespace: "namespace".to_string(), + name: "test1".to_string(), + package: "package".to_string(), + value: FlagValue::Disabled, + staged_value: None, + permission: FlagPermission::ReadWrite, + value_picked_from: ValuePickedFrom::Default, + container: "system".to_string(), + }, + Flag { + namespace: "namespace".to_string(), + name: "test2".to_string(), + package: "package".to_string(), + value: FlagValue::Disabled, + staged_value: None, + permission: FlagPermission::ReadWrite, + value_picked_from: ValuePickedFrom::Default, + container: "not_system".to_string(), + }, + Flag { + namespace: "namespace".to_string(), + name: "test3".to_string(), + package: "package".to_string(), + value: FlagValue::Disabled, + staged_value: None, + permission: FlagPermission::ReadWrite, + value_picked_from: ValuePickedFrom::Default, + container: "system".to_string(), + }, + ]; + + assert_eq!((Filter { container: None }).apply(&flags).len(), 3); + } +} diff --git a/tools/check-flagged-apis/check-flagged-apis.sh b/tools/check-flagged-apis/check-flagged-apis.sh index cd37a2d52e..d9934a11fe 100755 --- a/tools/check-flagged-apis/check-flagged-apis.sh +++ b/tools/check-flagged-apis/check-flagged-apis.sh @@ -20,18 +20,36 @@ source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../../shell_utils.sh require_top +PUBLIC_XML_VERSIONS=out/target/common/obj/PACKAGING/api_versions_public_generated-api-versions.xml +SYSTEM_XML_VERSIONS=out/target/common/obj/PACKAGING/api_versions_system_generated-api-versions.xml +SYSTEM_SERVER_XML_VERSONS=out/target/common/obj/PACKAGING/api_versions_system_server_complete_generated-api-versions.xml +MODULE_LIB_XML_VERSIONS=out/target/common/obj/PACKAGING/api_versions_module_lib_complete_generated-api-versions.xml + function m() { $(gettop)/build/soong/soong_ui.bash --build-mode --all-modules --dir="$(pwd)" "$@" } function build() { - m sdk dist && m \ + m \ check-flagged-apis \ all_aconfig_declarations \ frameworks-base-api-current.txt \ frameworks-base-api-system-current.txt \ frameworks-base-api-system-server-current.txt \ - frameworks-base-api-module-lib-current.txt + frameworks-base-api-module-lib-current.txt \ + $PUBLIC_XML_VERSIONS \ + $SYSTEM_XML_VERSIONS \ + $SYSTEM_SERVER_XML_VERSONS \ + $MODULE_LIB_XML_VERSIONS +} + +function aninja() { + local T="$(gettop)" + (\cd "${T}" && prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-${TARGET_PRODUCT}.ninja "$@") +} + +function path_to_api_signature_file { + aninja -t query device_"$1"_all_targets | grep -A1 -e input: | tail -n1 } function run() { @@ -39,33 +57,33 @@ function run() { echo "# current" check-flagged-apis \ - --api-signature $(gettop)/out/target/product/mainline_x86/obj/ETC/frameworks-base-api-current.txt_intermediates/frameworks-base-api-current.txt \ + --api-signature $(path_to_api_signature_file "frameworks-base-api-current.txt") \ --flag-values $(gettop)/out/soong/.intermediates/all_aconfig_declarations.pb \ - --api-versions $(gettop)/out/dist/data/api-versions.xml + --api-versions $PUBLIC_XML_VERSIONS (( errors += $? )) echo echo "# system-current" check-flagged-apis \ - --api-signature $(gettop)/out/target/product/mainline_x86/obj/ETC/frameworks-base-api-system-current.txt_intermediates/frameworks-base-api-system-current.txt \ + --api-signature $(path_to_api_signature_file "frameworks-base-api-system-current.txt") \ --flag-values $(gettop)/out/soong/.intermediates/all_aconfig_declarations.pb \ - --api-versions $(gettop)/out/dist/system-data/api-versions.xml + --api-versions $SYSTEM_XML_VERSIONS (( errors += $? )) echo echo "# system-server-current" check-flagged-apis \ - --api-signature $(gettop)/out/target/product/mainline_x86/obj/ETC/frameworks-base-api-system-server-current.txt_intermediates/frameworks-base-api-system-server-current.txt \ + --api-signature $(path_to_api_signature_file "frameworks-base-api-system-server-current.txt") \ --flag-values $(gettop)/out/soong/.intermediates/all_aconfig_declarations.pb \ - --api-versions $(gettop)/out/dist/system-server-data/api-versions.xml + --api-versions $SYSTEM_SERVER_XML_VERSONS (( errors += $? )) echo echo "# module-lib" check-flagged-apis \ - --api-signature $(gettop)/out/target/product/mainline_x86/obj/ETC/frameworks-base-api-module-lib-current.txt_intermediates/frameworks-base-api-module-lib-current.txt \ + --api-signature $(path_to_api_signature_file "frameworks-base-api-module-lib-current.txt") \ --flag-values $(gettop)/out/soong/.intermediates/all_aconfig_declarations.pb \ - --api-versions $(gettop)/out/dist/module-lib-data/api-versions.xml + --api-versions $MODULE_LIB_XML_VERSIONS (( errors += $? )) return $errors diff --git a/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt b/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt index 0569bfd71b..8e285f6216 100644 --- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt +++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt @@ -34,6 +34,9 @@ private val API_SIGNATURE = ctor @FlaggedApi("android.flag.foo") public Clazz(); field @FlaggedApi("android.flag.foo") public static final int FOO = 1; // 0x1 method @FlaggedApi("android.flag.foo") public int getErrorCode(); + method @FlaggedApi("android.flag.foo") public boolean setData(int, int[][], @NonNull android.util.Utility<T, U>); + method @FlaggedApi("android.flag.foo") public boolean setVariableData(int, android.util.Atom...); + method @FlaggedApi("android.flag.foo") public boolean innerClassArg(android.Clazz.Builder); } @FlaggedApi("android.flag.bar") public static class Clazz.Builder { } @@ -46,11 +49,16 @@ private val API_VERSIONS = <?xml version="1.0" encoding="utf-8"?> <api version="3"> <class name="android/Clazz" since="1"> + <extends name="java/lang/Object"/> <method name="<init>()V"/> <field name="FOO"/> <method name="getErrorCode()I"/> + <method name="setData(I[[ILandroid/util/Utility;)Z"/> + <method name="setVariableData(I[Landroid/util/Atom;)Z"/> + <method name="innerClassArg(Landroid/Clazz${"$"}Builder;)"/> </class> <class name="android/Clazz${"$"}Builder" since="2"> + <extends name="java/lang/Object"/> </class> </api> """ @@ -89,17 +97,50 @@ class CheckFlaggedApisTest { fun testParseApiSignature() { val expected = setOf( - Pair(Symbol("android.Clazz"), Flag("android.flag.foo")), - Pair(Symbol("android.Clazz.Clazz()"), Flag("android.flag.foo")), - Pair(Symbol("android.Clazz.FOO"), Flag("android.flag.foo")), - Pair(Symbol("android.Clazz.getErrorCode()"), Flag("android.flag.foo")), - Pair(Symbol("android.Clazz.Builder"), Flag("android.flag.bar")), + Pair( + Symbol.createClass("android/Clazz", "java/lang/Object", setOf()), + Flag("android.flag.foo")), + Pair(Symbol.createMethod("android/Clazz", "Clazz()"), Flag("android.flag.foo")), + Pair(Symbol.createField("android/Clazz", "FOO"), Flag("android.flag.foo")), + Pair(Symbol.createMethod("android/Clazz", "getErrorCode()"), Flag("android.flag.foo")), + Pair( + Symbol.createMethod("android/Clazz", "setData(I[[ILandroid/util/Utility;)"), + Flag("android.flag.foo")), + Pair( + Symbol.createMethod("android/Clazz", "setVariableData(I[Landroid/util/Atom;)"), + Flag("android.flag.foo")), + Pair( + Symbol.createMethod("android/Clazz", "innerClassArg(Landroid/Clazz/Builder;)"), + Flag("android.flag.foo")), + Pair( + Symbol.createClass("android/Clazz/Builder", "java/lang/Object", setOf()), + Flag("android.flag.bar")), ) val actual = parseApiSignature("in-memory", API_SIGNATURE.byteInputStream()) assertEquals(expected, actual) } @Test + fun testParseApiSignatureInterfacesInheritFromJavaLangObject() { + val apiSignature = + """ + // Signature format: 2.0 + package android { + @FlaggedApi("android.flag.foo") public interface Interface { + } + } + """ + .trim() + val expected = + setOf( + Pair( + Symbol.createClass("android/Interface", "java/lang/Object", setOf()), + Flag("android.flag.foo"))) + val actual = parseApiSignature("in-memory", apiSignature.byteInputStream()) + assertEquals(expected, actual) + } + + @Test fun testParseFlagValues() { val expected: Map<Flag, Boolean> = mapOf(Flag("android.flag.foo") to true, Flag("android.flag.bar") to true) @@ -111,17 +152,42 @@ class CheckFlaggedApisTest { fun testParseApiVersions() { val expected: Set<Symbol> = setOf( - Symbol("android.Clazz"), - Symbol("android.Clazz.Clazz()"), - Symbol("android.Clazz.FOO"), - Symbol("android.Clazz.getErrorCode()"), - Symbol("android.Clazz.Builder"), + Symbol.createClass("android/Clazz", "java/lang/Object", setOf()), + Symbol.createMethod("android/Clazz", "Clazz()"), + Symbol.createField("android/Clazz", "FOO"), + Symbol.createMethod("android/Clazz", "getErrorCode()"), + Symbol.createMethod("android/Clazz", "setData(I[[ILandroid/util/Utility;)"), + Symbol.createMethod("android/Clazz", "setVariableData(I[Landroid/util/Atom;)"), + Symbol.createMethod("android/Clazz", "innerClassArg(Landroid/Clazz/Builder;)"), + Symbol.createClass("android/Clazz/Builder", "java/lang/Object", setOf()), ) val actual = parseApiVersions(API_VERSIONS.byteInputStream()) assertEquals(expected, actual) } @Test + fun testParseApiVersionsNestedClasses() { + val apiVersions = + """ + <?xml version="1.0" encoding="utf-8"?> + <api version="3"> + <class name="android/Clazz${'$'}Foo${'$'}Bar" since="1"> + <extends name="java/lang/Object"/> + <method name="<init>()V"/> + </class> + </api> + """ + .trim() + val expected: Set<Symbol> = + setOf( + Symbol.createClass("android/Clazz/Foo/Bar", "java/lang/Object", setOf()), + Symbol.createMethod("android/Clazz/Foo/Bar", "Bar()"), + ) + val actual = parseApiVersions(apiVersions.byteInputStream()) + assertEquals(expected, actual) + } + + @Test fun testFindErrorsNoErrors() { val expected = setOf<ApiError>() val actual = @@ -133,17 +199,157 @@ class CheckFlaggedApisTest { } @Test + fun testFindErrorsVerifyImplements() { + val apiSignature = + """ + // Signature format: 2.0 + package android { + @FlaggedApi("android.flag.foo") public final class Clazz implements android.Interface { + method @FlaggedApi("android.flag.foo") public boolean foo(); + method @FlaggedApi("android.flag.foo") public boolean bar(); + } + public interface Interface { + method public boolean bar(); + } + } + """ + .trim() + + val apiVersions = + """ + <?xml version="1.0" encoding="utf-8"?> + <api version="3"> + <class name="android/Clazz" since="1"> + <extends name="java/lang/Object"/> + <implements name="android/Interface"/> + <method name="foo()Z"/> + </class> + <class name="android/Interface" since="1"> + <method name="bar()Z"/> + </class> + </api> + """ + .trim() + + val expected = setOf<ApiError>() + val actual = + findErrors( + parseApiSignature("in-memory", apiSignature.byteInputStream()), + parseFlagValues(generateFlagsProto(ENABLED, ENABLED)), + parseApiVersions(apiVersions.byteInputStream())) + assertEquals(expected, actual) + } + + @Test + fun testFindErrorsVerifySuperclass() { + val apiSignature = + """ + // Signature format: 2.0 + package android { + @FlaggedApi("android.flag.foo") public final class C extends android.B { + method @FlaggedApi("android.flag.foo") public boolean c(); + method @FlaggedApi("android.flag.foo") public boolean b(); + method @FlaggedApi("android.flag.foo") public boolean a(); + } + public final class B extends android.A { + method public boolean b(); + } + public final class A { + method public boolean a(); + } + } + """ + .trim() + + val apiVersions = + """ + <?xml version="1.0" encoding="utf-8"?> + <api version="3"> + <class name="android/C" since="1"> + <extends name="android/B"/> + <method name="c()Z"/> + </class> + <class name="android/B" since="1"> + <extends name="android/A"/> + <method name="b()Z"/> + </class> + <class name="android/A" since="1"> + <method name="a()Z"/> + </class> + </api> + """ + .trim() + + val expected = setOf<ApiError>() + val actual = + findErrors( + parseApiSignature("in-memory", apiSignature.byteInputStream()), + parseFlagValues(generateFlagsProto(ENABLED, ENABLED)), + parseApiVersions(apiVersions.byteInputStream())) + assertEquals(expected, actual) + } + + @Test + fun testNestedFlagsOuterFlagWins() { + val apiSignature = + """ + // Signature format: 2.0 + package android { + @FlaggedApi("android.flag.foo") public final class A { + method @FlaggedApi("android.flag.bar") public boolean method(); + } + @FlaggedApi("android.flag.bar") public final class B { + method @FlaggedApi("android.flag.foo") public boolean method(); + } + } + """ + .trim() + + val apiVersions = + """ + <?xml version="1.0" encoding="utf-8"?> + <api version="3"> + <class name="android/B" since="1"> + <extends name="java/lang/Object"/> + </class> + </api> + """ + .trim() + + val expected = setOf<ApiError>() + val actual = + findErrors( + parseApiSignature("in-memory", apiSignature.byteInputStream()), + parseFlagValues(generateFlagsProto(DISABLED, ENABLED)), + parseApiVersions(apiVersions.byteInputStream())) + assertEquals(expected, actual) + } + + @Test fun testFindErrorsDisabledFlaggedApiIsPresent() { val expected = setOf<ApiError>( - DisabledFlaggedApiIsPresentError(Symbol("android.Clazz"), Flag("android.flag.foo")), DisabledFlaggedApiIsPresentError( - Symbol("android.Clazz.Clazz()"), Flag("android.flag.foo")), - DisabledFlaggedApiIsPresentError(Symbol("android.Clazz.FOO"), Flag("android.flag.foo")), + Symbol.createClass("android/Clazz", "java/lang/Object", setOf()), + Flag("android.flag.foo")), + DisabledFlaggedApiIsPresentError( + Symbol.createMethod("android/Clazz", "Clazz()"), Flag("android.flag.foo")), + DisabledFlaggedApiIsPresentError( + Symbol.createField("android/Clazz", "FOO"), Flag("android.flag.foo")), + DisabledFlaggedApiIsPresentError( + Symbol.createMethod("android/Clazz", "getErrorCode()"), Flag("android.flag.foo")), + DisabledFlaggedApiIsPresentError( + Symbol.createMethod("android/Clazz", "setData(I[[ILandroid/util/Utility;)"), + Flag("android.flag.foo")), + DisabledFlaggedApiIsPresentError( + Symbol.createMethod("android/Clazz", "setVariableData(I[Landroid/util/Atom;)"), + Flag("android.flag.foo")), DisabledFlaggedApiIsPresentError( - Symbol("android.Clazz.getErrorCode()"), Flag("android.flag.foo")), + Symbol.createMethod("android/Clazz", "innerClassArg(Landroid/Clazz/Builder;)"), + Flag("android.flag.foo")), DisabledFlaggedApiIsPresentError( - Symbol("android.Clazz.Builder"), Flag("android.flag.bar")), + Symbol.createClass("android/Clazz/Builder", "java/lang/Object", setOf()), + Flag("android.flag.bar")), ) val actual = findErrors( diff --git a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt index 0c078a0b93..1d2440dee8 100644 --- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt +++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt @@ -41,34 +41,61 @@ import org.w3c.dom.Node * a Java symbol slightly differently. To keep things consistent, all parsed APIs are converted to * Symbols. * - * All parts of the fully qualified name of the Symbol are separated by a dot, e.g.: + * Symbols are encoded using the format similar to the one described in section 4.3.2 of the JVM + * spec [1], that is, "package.class.inner-class.method(int, int[], android.util.Clazz)" is + * represented as * <pre> - * package.class.inner-class.field - * </pre> + * package.class.inner-class.method(II[Landroid/util/Clazz;) + * <pre> + * + * Where possible, the format has been simplified (to make translation of the + * various input formats easier): for instance, only / is used as delimiter (# + * and $ are never used). + * + * 1. https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.2 */ -@JvmInline -internal value class Symbol(val name: String) { +internal sealed class Symbol { companion object { - private val FORBIDDEN_CHARS = listOf('#', '$') + private val FORBIDDEN_CHARS = listOf('#', '$', '.') + + fun createClass(clazz: String, superclass: String?, interfaces: Set<String>): Symbol { + return ClassSymbol( + toInternalFormat(clazz), + superclass?.let { toInternalFormat(it) }, + interfaces.map { toInternalFormat(it) }.toSet()) + } - /** Create a new Symbol from a String that may include delimiters other than dot. */ - fun create(name: String): Symbol { - var sanitizedName = name + fun createField(clazz: String, field: String): Symbol { + require(!field.contains("(") && !field.contains(")")) + return MemberSymbol(toInternalFormat(clazz), toInternalFormat(field)) + } + + fun createMethod(clazz: String, method: String): Symbol { + return MemberSymbol(toInternalFormat(clazz), toInternalFormat(method)) + } + + protected fun toInternalFormat(name: String): String { + var internalName = name for (ch in FORBIDDEN_CHARS) { - sanitizedName = sanitizedName.replace(ch, '.') + internalName = internalName.replace(ch, '/') } - return Symbol(sanitizedName) + return internalName } } - init { - require(!name.isEmpty()) { "empty string" } - for (ch in FORBIDDEN_CHARS) { - require(!name.contains(ch)) { "$name: contains $ch" } - } - } + abstract fun toPrettyString(): String +} - override fun toString(): String = name.toString() +internal data class ClassSymbol( + val clazz: String, + val superclass: String?, + val interfaces: Set<String> +) : Symbol() { + override fun toPrettyString(): String = "$clazz" +} + +internal data class MemberSymbol(val clazz: String, val member: String) : Symbol() { + override fun toPrettyString(): String = "$clazz/$member" } /** @@ -94,7 +121,7 @@ internal data class EnabledFlaggedApiNotPresentError( override val flag: Flag ) : ApiError() { override fun toString(): String { - return "error: enabled @FlaggedApi not present in built artifact: symbol=$symbol flag=$flag" + return "error: enabled @FlaggedApi not present in built artifact: symbol=${symbol.toPrettyString()} flag=$flag" } } @@ -103,14 +130,14 @@ internal data class DisabledFlaggedApiIsPresentError( override val flag: Flag ) : ApiError() { override fun toString(): String { - return "error: disabled @FlaggedApi is present in built artifact: symbol=$symbol flag=$flag" + return "error: disabled @FlaggedApi is present in built artifact: symbol=${symbol.toPrettyString()} flag=$flag" } } internal data class UnknownFlagError(override val symbol: Symbol, override val flag: Flag) : ApiError() { override fun toString(): String { - return "error: unknown flag: symbol=$symbol flag=$flag" + return "error: unknown flag: symbol=${symbol.toPrettyString()} flag=$flag" } } @@ -170,39 +197,44 @@ The tool will exit with a non-zero exit code if any flagged APIs are found to be } internal fun parseApiSignature(path: String, input: InputStream): Set<Pair<Symbol, Flag>> { - // TODO(334870672): add support for metods val output = mutableSetOf<Pair<Symbol, Flag>>() val visitor = object : BaseItemVisitor() { override fun visitClass(cls: ClassItem) { getFlagOrNull(cls)?.let { flag -> - val symbol = Symbol.create(cls.baselineElementId()) + val symbol = + Symbol.createClass( + cls.baselineElementId(), + if (cls.isInterface()) { + "java/lang/Object" + } else { + cls.superClass()?.baselineElementId() + }, + cls.allInterfaces() + .map { it.baselineElementId() } + .filter { it != cls.baselineElementId() } + .toSet()) output.add(Pair(symbol, flag)) } } override fun visitField(field: FieldItem) { getFlagOrNull(field)?.let { flag -> - val symbol = Symbol.create(field.baselineElementId()) + val symbol = + Symbol.createField(field.containingClass().baselineElementId(), field.name()) output.add(Pair(symbol, flag)) } } override fun visitMethod(method: MethodItem) { getFlagOrNull(method)?.let { flag -> - val name = buildString { - append(method.containingClass().qualifiedName()) - append(".") + val methodName = buildString { append(method.name()) append("(") - // TODO(334870672): replace this early return with proper parsing of the command line - // arguments, followed by translation to Lname/of/class; + III format - if (!method.parameters().isEmpty()) { - return - } + method.parameters().joinTo(this, separator = "") { it.type().internalName() } append(")") } - val symbol = Symbol.create(name) + val symbol = Symbol.createMethod(method.containingClass().qualifiedName(), methodName) output.add(Pair(symbol, flag)) } } @@ -243,7 +275,28 @@ internal fun parseApiVersions(input: InputStream): Set<Symbol> { requireNotNull(cls.getAttribute("name")) { "Bad XML: <class> element without name attribute" } - output.add(Symbol.create(className.replace("/", "."))) + var superclass: String? = null + val interfaces = mutableSetOf<String>() + val children = cls.getChildNodes() + for (j in 0.rangeUntil(children.getLength())) { + val child = children.item(j) + when (child.getNodeName()) { + "extends" -> { + superclass = + requireNotNull(child.getAttribute("name")) { + "Bad XML: <extends> element without name attribute" + } + } + "implements" -> { + val interfaceName = + requireNotNull(child.getAttribute("name")) { + "Bad XML: <implements> element without name attribute" + } + interfaces.add(interfaceName) + } + } + } + output.add(Symbol.createClass(className, superclass, interfaces)) } val fields = document.getElementsByTagName("field") @@ -255,8 +308,10 @@ internal fun parseApiVersions(input: InputStream): Set<Symbol> { "Bad XML: <field> element without name attribute" } val className = - requireNotNull(field.getParentNode()?.getAttribute("name")) { "Bad XML: top level <field> element" } - output.add(Symbol.create("${className.replace("/", ".")}.$fieldName")) + requireNotNull(field.getParentNode()?.getAttribute("name")) { + "Bad XML: top level <field> element" + } + output.add(Symbol.createField(className, fieldName)) } val methods = document.getElementsByTagName("method") @@ -271,15 +326,16 @@ internal fun parseApiVersions(input: InputStream): Set<Symbol> { if (methodSignatureParts.size != 3) { throw Exception("Bad XML: method signature '$methodSignature'") } - var (methodName, methodArgs, methodReturnValue) = methodSignatureParts + var (methodName, methodArgs, _) = methodSignatureParts val packageAndClassName = requireNotNull(method.getParentNode()?.getAttribute("name")) { - "Bad XML: top level <method> element, or <class> element missing name attribute" - } + "Bad XML: top level <method> element, or <class> element missing name attribute" + } + .replace("$", "/") if (methodName == "<init>") { methodName = packageAndClassName.split("/").last() } - output.add(Symbol.create("${packageAndClassName.replace("/", ".")}.$methodName($methodArgs)")) + output.add(Symbol.createMethod(packageAndClassName, "$methodName($methodArgs)")) } return output @@ -298,15 +354,88 @@ internal fun findErrors( flags: Map<Flag, Boolean>, symbolsInOutput: Set<Symbol> ): Set<ApiError> { + fun Set<Symbol>.containsSymbol(symbol: Symbol): Boolean { + // trivial case: the symbol is explicitly listed in api-versions.xml + if (contains(symbol)) { + return true + } + + // non-trivial case: the symbol could be part of the surrounding class' + // super class or interfaces + val (className, memberName) = + when (symbol) { + is ClassSymbol -> return false + is MemberSymbol -> { + Pair(symbol.clazz, symbol.member) + } + } + val clazz = find { it is ClassSymbol && it.clazz == className } as? ClassSymbol? + if (clazz == null) { + return false + } + + for (interfaceName in clazz.interfaces) { + // createMethod is the same as createField, except it allows parenthesis + val interfaceSymbol = Symbol.createMethod(interfaceName, memberName) + if (contains(interfaceSymbol)) { + return true + } + } + + if (clazz.superclass != null) { + val superclassSymbol = Symbol.createMethod(clazz.superclass, memberName) + return containsSymbol(superclassSymbol) + } + + return false + } + + /** + * Returns whether the given flag is enabled for the given symbol. + * + * A flagged member inside a flagged class is ignored (and the flag value considered disabled) if + * the class' flag is disabled. + * + * @param symbol the symbol to check + * @param flag the flag to check + * @return whether the flag is enabled for the given symbol + */ + fun isFlagEnabledForSymbol(symbol: Symbol, flag: Flag): Boolean { + when (symbol) { + is ClassSymbol -> return flags.getValue(flag) + is MemberSymbol -> { + val memberFlagValue = flags.getValue(flag) + if (!memberFlagValue) { + return false + } + // Special case: if the MemberSymbol's flag is enabled, but the outer + // ClassSymbol's flag (if the class is flagged) is disabled, consider + // the MemberSymbol's flag as disabled: + // + // @FlaggedApi(this-flag-is-disabled) Clazz { + // @FlaggedApi(this-flag-is-enabled) method(); // The Clazz' flag "wins" + // } + // + // Note: the current implementation does not handle nested classes. + val classFlagValue = + flaggedSymbolsInSource + .find { it.first.toPrettyString() == symbol.clazz } + ?.let { flags.getValue(it.second) } + ?: true + return classFlagValue + } + } + } + val errors = mutableSetOf<ApiError>() for ((symbol, flag) in flaggedSymbolsInSource) { try { - if (flags.getValue(flag)) { - if (!symbolsInOutput.contains(symbol)) { + if (isFlagEnabledForSymbol(symbol, flag)) { + if (!symbolsInOutput.containsSymbol(symbol)) { errors.add(EnabledFlaggedApiNotPresentError(symbol, flag)) } } else { - if (symbolsInOutput.contains(symbol)) { + if (symbolsInOutput.containsSymbol(symbol)) { errors.add(DisabledFlaggedApiIsPresentError(symbol, flag)) } } diff --git a/tools/fs_config/Android.bp b/tools/fs_config/Android.bp index bd9543a2e2..6aa528963d 100644 --- a/tools/fs_config/Android.bp +++ b/tools/fs_config/Android.bp @@ -258,3 +258,173 @@ prebuilt_etc { system_ext_specific: true, src: ":group_gen_system_ext", } + +fs_config_cmd = "$(location fs_config_generator) fsconfig " + + "--aid-header $(location :android_filesystem_config_header) " + + "--capability-header $(location :linux_capability_header) " + + "--out_file $(out) " +fs_config_cmd_dirs = fs_config_cmd + "--dirs " +fs_config_cmd_files = fs_config_cmd + "--files " + +genrule_defaults { + name: "fs_config_defaults", + tools: ["fs_config_generator"], + srcs: [ + ":android_filesystem_config_header", + ":linux_capability_header", + ":target_fs_config_gen", + ], + out: ["out"], +} + +genrule { + name: "fs_config_dirs_system_gen", + defaults: ["fs_config_defaults"], + cmd: fs_config_cmd_dirs + + "--partition system " + + "--all-partitions vendor,oem,odm,vendor_dlkm,odm_dlkm,system_dlkm " + + "$(locations :target_fs_config_gen)", +} + +prebuilt_etc { + name: "fs_config_dirs_system", + filename: "fs_config_dirs", + src: ":fs_config_dirs_system_gen", +} + +genrule { + name: "fs_config_files_system_gen", + defaults: ["fs_config_defaults"], + cmd: fs_config_cmd_files + + "--partition system " + + "--all-partitions vendor,oem,odm,vendor_dlkm,odm_dlkm,system_dlkm " + + "$(locations :target_fs_config_gen)", +} + +prebuilt_etc { + name: "fs_config_files_system", + filename: "fs_config_files", + src: ":fs_config_files_system_gen", +} + +genrule { + name: "fs_config_dirs_system_ext_gen", + defaults: ["fs_config_defaults"], + cmd: fs_config_cmd_dirs + + "--partition system_ext " + + "$(locations :target_fs_config_gen)", +} + +prebuilt_etc { + name: "fs_config_dirs_system_ext", + filename: "fs_config_dirs", + src: ":fs_config_dirs_system_ext_gen", + system_ext_specific: true, +} + +genrule { + name: "fs_config_files_system_ext_gen", + defaults: ["fs_config_defaults"], + cmd: fs_config_cmd_files + + "--partition system_ext " + + "$(locations :target_fs_config_gen)", +} + +prebuilt_etc { + name: "fs_config_files_system_ext", + filename: "fs_config_files", + src: ":fs_config_files_system_ext_gen", + system_ext_specific: true, +} + +genrule { + name: "fs_config_dirs_product_gen", + defaults: ["fs_config_defaults"], + cmd: fs_config_cmd_dirs + + "--partition product " + + "$(locations :target_fs_config_gen)", +} + +prebuilt_etc { + name: "fs_config_dirs_product", + filename: "fs_config_dirs", + src: ":fs_config_dirs_product_gen", + product_specific: true, +} + +genrule { + name: "fs_config_files_product_gen", + defaults: ["fs_config_defaults"], + cmd: fs_config_cmd_files + + "--partition product " + + "$(locations :target_fs_config_gen)", +} + +prebuilt_etc { + name: "fs_config_files_product", + filename: "fs_config_files", + src: ":fs_config_files_product_gen", + product_specific: true, +} + +genrule { + name: "fs_config_dirs_vendor_gen", + defaults: ["fs_config_defaults"], + cmd: fs_config_cmd_dirs + + "--partition vendor " + + "$(locations :target_fs_config_gen)", +} + +prebuilt_etc { + name: "fs_config_dirs_vendor", + filename: "fs_config_dirs", + src: ":fs_config_dirs_vendor_gen", + vendor: true, +} + +genrule { + name: "fs_config_files_vendor_gen", + defaults: ["fs_config_defaults"], + cmd: fs_config_cmd_files + + "--partition vendor " + + "$(locations :target_fs_config_gen)", +} + +prebuilt_etc { + name: "fs_config_files_vendor", + filename: "fs_config_files", + src: ":fs_config_files_vendor_gen", + vendor: true, +} + +genrule { + name: "fs_config_dirs_odm_gen", + defaults: ["fs_config_defaults"], + cmd: fs_config_cmd_dirs + + "--partition odm " + + "$(locations :target_fs_config_gen)", +} + +prebuilt_etc { + name: "fs_config_dirs_odm", + filename: "fs_config_dirs", + src: ":fs_config_dirs_odm_gen", + device_specific: true, +} + +genrule { + name: "fs_config_files_odm_gen", + defaults: ["fs_config_defaults"], + cmd: fs_config_cmd_files + + "--partition odm " + + "$(locations :target_fs_config_gen)", +} + +prebuilt_etc { + name: "fs_config_files_odm", + filename: "fs_config_files", + src: ":fs_config_files_odm_gen", + device_specific: true, +} + +// TODO(jiyong): add fs_config for oem, system_dlkm, vendor_dlkm, odm_dlkm partitions diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk index c36c3aa6a2..e4c362630f 100644 --- a/tools/fs_config/Android.mk +++ b/tools/fs_config/Android.mk @@ -24,23 +24,8 @@ ifneq ($(wildcard $(TARGET_DEVICE_DIR)/android_filesystem_config.h),) $(error Using $(TARGET_DEVICE_DIR)/android_filesystem_config.h is deprecated, please use TARGET_FS_CONFIG_GEN instead) endif -system_android_filesystem_config := system/core/libcutils/include/private/android_filesystem_config.h -system_capability_header := bionic/libc/kernel/uapi/linux/capability.h - -# Use snapshots if exist -vendor_android_filesystem_config := $(strip \ - $(if $(filter-out current,$(BOARD_VNDK_VERSION)), \ - $(SOONG_VENDOR_$(BOARD_VNDK_VERSION)_SNAPSHOT_DIR)/include/$(system_android_filesystem_config))) -ifeq (,$(wildcard $(vendor_android_filesystem_config))) -vendor_android_filesystem_config := $(system_android_filesystem_config) -endif - -vendor_capability_header := $(strip \ - $(if $(filter-out current,$(BOARD_VNDK_VERSION)), \ - $(SOONG_VENDOR_$(BOARD_VNDK_VERSION)_SNAPSHOT_DIR)/include/$(system_capability_header))) -ifeq (,$(wildcard $(vendor_capability_header))) -vendor_capability_header := $(system_capability_header) -endif +android_filesystem_config := system/core/libcutils/include/private/android_filesystem_config.h +capability_header := bionic/libc/kernel/uapi/linux/capability.h # List of supported vendor, oem, odm, vendor_dlkm, odm_dlkm, and system_dlkm Partitions fs_config_generate_extra_partition_list := $(strip \ @@ -85,58 +70,6 @@ LOCAL_REQUIRED_MODULES := \ include $(BUILD_PHONY_PACKAGE) ################################## -# Generate the system_ext/etc/fs_config_dirs binary file for the target if the -# system_ext partition is generated. Add fs_config_dirs or fs_config_dirs_system_ext -# to PRODUCT_PACKAGES in the device make file to enable. -include $(CLEAR_VARS) - -LOCAL_MODULE := fs_config_dirs_system_ext -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_SYSTEM_EXTIMAGE)$(BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE),_fs_config_dirs_system_ext) -include $(BUILD_PHONY_PACKAGE) - -################################## -# Generate the system_ext/etc/fs_config_files binary file for the target if the -# system_ext partition is generated. Add fs_config_files or fs_config_files_system_ext -# to PRODUCT_PACKAGES in the device make file to enable. -include $(CLEAR_VARS) - -LOCAL_MODULE := fs_config_files_system_ext -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_SYSTEM_EXTIMAGE)$(BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE),_fs_config_files_system_ext) -include $(BUILD_PHONY_PACKAGE) - -################################## -# Generate the product/etc/fs_config_dirs binary file for the target if the -# product partition is generated. Add fs_config_dirs or fs_config_dirs_product -# to PRODUCT_PACKAGES in the device make file to enable. -include $(CLEAR_VARS) - -LOCAL_MODULE := fs_config_dirs_product -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_PRODUCTIMAGE)$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),_fs_config_dirs_product) -include $(BUILD_PHONY_PACKAGE) - -################################## -# Generate the product/etc/fs_config_files binary file for the target if the -# product partition is generated. Add fs_config_files or fs_config_files_product -# to PRODUCT_PACKAGES in the device make file to enable. -include $(CLEAR_VARS) - -LOCAL_MODULE := fs_config_files_product -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_PRODUCTIMAGE)$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),_fs_config_files_product) -include $(BUILD_PHONY_PACKAGE) - -################################## # Generate the <p>/etc/fs_config_dirs binary files for all enabled partitions # excluding /system, /system_ext and /product. Add fs_config_dirs_nonsystem to # PRODUCT_PACKAGES in the device make file to enable. @@ -146,7 +79,7 @@ LOCAL_MODULE := fs_config_dirs_nonsystem LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 LOCAL_LICENSE_CONDITIONS := notice LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),_fs_config_dirs_$(t)) +LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),fs_config_dirs_$(t)) include $(BUILD_PHONY_PACKAGE) ################################## @@ -159,122 +92,9 @@ LOCAL_MODULE := fs_config_files_nonsystem LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 LOCAL_LICENSE_CONDITIONS := notice LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),_fs_config_files_$(t)) +LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),fs_config_files_$(t)) include $(BUILD_PHONY_PACKAGE) -################################## -# Generate the system/etc/fs_config_dirs binary file for the target -# Add fs_config_dirs or fs_config_dirs_system to PRODUCT_PACKAGES in -# the device make file to enable -include $(CLEAR_VARS) - -LOCAL_MODULE := fs_config_dirs_system -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_MODULE_CLASS := ETC -LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs -include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header) -$(LOCAL_BUILT_MODULE): PRIVATE_PARTITION_LIST := $(fs_config_generate_extra_partition_list) -$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header) - @mkdir -p $(dir $@) - $< fsconfig \ - --aid-header $(PRIVATE_ANDROID_FS_HDR) \ - --capability-header $(PRIVATE_ANDROID_CAP_HDR) \ - --partition system \ - --all-partitions "$(subst $(space),$(comma),$(PRIVATE_PARTITION_LIST))" \ - --dirs \ - --out_file $@ \ - $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) - -################################## -# Generate the system/etc/fs_config_files binary file for the target -# Add fs_config_files or fs_config_files_system to PRODUCT_PACKAGES in -# the device make file to enable -include $(CLEAR_VARS) - -LOCAL_MODULE := fs_config_files_system -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_MODULE_CLASS := ETC -LOCAL_INSTALLED_MODULE_STEM := fs_config_files -include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header) -$(LOCAL_BUILT_MODULE): PRIVATE_PARTITION_LIST := $(fs_config_generate_extra_partition_list) -$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header) - @mkdir -p $(dir $@) - $< fsconfig \ - --aid-header $(PRIVATE_ANDROID_FS_HDR) \ - --capability-header $(PRIVATE_ANDROID_CAP_HDR) \ - --partition system \ - --all-partitions "$(subst $(space),$(comma),$(PRIVATE_PARTITION_LIST))" \ - --files \ - --out_file $@ \ - $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) - -ifneq ($(filter vendor,$(fs_config_generate_extra_partition_list)),) -################################## -# Generate the vendor/etc/fs_config_dirs binary file for the target -# Add fs_config_dirs or fs_config_dirs_nonsystem to PRODUCT_PACKAGES -# in the device make file to enable -include $(CLEAR_VARS) - -LOCAL_MODULE := _fs_config_dirs_vendor -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_MODULE_CLASS := ETC -LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs -LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc -include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header) -$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header) - @mkdir -p $(dir $@) - $< fsconfig \ - --aid-header $(PRIVATE_ANDROID_FS_HDR) \ - --capability-header $(PRIVATE_ANDROID_CAP_HDR) \ - --partition vendor \ - --dirs \ - --out_file $@ \ - $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) - -################################## -# Generate the vendor/etc/fs_config_files binary file for the target -# Add fs_config_files or fs_config_files_nonsystem to PRODUCT_PACKAGES -# in the device make file to enable -include $(CLEAR_VARS) - -LOCAL_MODULE := _fs_config_files_vendor -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_MODULE_CLASS := ETC -LOCAL_INSTALLED_MODULE_STEM := fs_config_files -LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc -include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header) -$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header) - @mkdir -p $(dir $@) - $< fsconfig \ - --aid-header $(PRIVATE_ANDROID_FS_HDR) \ - --capability-header $(PRIVATE_ANDROID_CAP_HDR) \ - --partition vendor \ - --files \ - --out_file $@ \ - $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) - -endif - ifneq ($(filter oem,$(fs_config_generate_extra_partition_list)),) ################################## # Generate the oem/etc/fs_config_dirs binary file for the target @@ -282,7 +102,7 @@ ifneq ($(filter oem,$(fs_config_generate_extra_partition_list)),) # in the device make file to enable include $(CLEAR_VARS) -LOCAL_MODULE := _fs_config_dirs_oem +LOCAL_MODULE := fs_config_dirs_oem LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 LOCAL_LICENSE_CONDITIONS := notice LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE @@ -290,10 +110,10 @@ LOCAL_MODULE_CLASS := ETC LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs LOCAL_MODULE_PATH := $(TARGET_OUT_OEM)/etc include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header) $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header) +$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header) @mkdir -p $(dir $@) $< fsconfig \ --aid-header $(PRIVATE_ANDROID_FS_HDR) \ @@ -309,7 +129,7 @@ $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_G # in the device make file to enable include $(CLEAR_VARS) -LOCAL_MODULE := _fs_config_files_oem +LOCAL_MODULE := fs_config_files_oem LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 LOCAL_LICENSE_CONDITIONS := notice LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE @@ -317,10 +137,10 @@ LOCAL_MODULE_CLASS := ETC LOCAL_INSTALLED_MODULE_STEM := fs_config_files LOCAL_MODULE_PATH := $(TARGET_OUT_OEM)/etc include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header) $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header) +$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header) @mkdir -p $(dir $@) $< fsconfig \ --aid-header $(PRIVATE_ANDROID_FS_HDR) \ @@ -332,63 +152,6 @@ $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_G endif -ifneq ($(filter odm,$(fs_config_generate_extra_partition_list)),) -################################## -# Generate the odm/etc/fs_config_dirs binary file for the target -# Add fs_config_dirs or fs_config_dirs_nonsystem to PRODUCT_PACKAGES -# in the device make file to enable -include $(CLEAR_VARS) - -LOCAL_MODULE := _fs_config_dirs_odm -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_MODULE_CLASS := ETC -LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs -LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc -include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header) -$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header) - @mkdir -p $(dir $@) - $< fsconfig \ - --aid-header $(PRIVATE_ANDROID_FS_HDR) \ - --capability-header $(PRIVATE_ANDROID_CAP_HDR) \ - --partition odm \ - --dirs \ - --out_file $@ \ - $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) - -################################## -# Generate the odm/etc/fs_config_files binary file for the target -# Add fs_config_files or fs_config_files_nonsystem to PRODUCT_PACKAGES -# in the device make file to enable -include $(CLEAR_VARS) - -LOCAL_MODULE := _fs_config_files_odm -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_MODULE_CLASS := ETC -LOCAL_INSTALLED_MODULE_STEM := fs_config_files -LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc -include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header) -$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header) - @mkdir -p $(dir $@) - $< fsconfig \ - --aid-header $(PRIVATE_ANDROID_FS_HDR) \ - --capability-header $(PRIVATE_ANDROID_CAP_HDR) \ - --partition odm \ - --files \ - --out_file $@ \ - $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) - -endif - ifneq ($(filter vendor_dlkm,$(fs_config_generate_extra_partition_list)),) ################################## # Generate the vendor_dlkm/etc/fs_config_dirs binary file for the target @@ -396,7 +159,7 @@ ifneq ($(filter vendor_dlkm,$(fs_config_generate_extra_partition_list)),) # the device make file to enable include $(CLEAR_VARS) -LOCAL_MODULE := _fs_config_dirs_vendor_dlkm +LOCAL_MODULE := fs_config_dirs_vendor_dlkm LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 LOCAL_LICENSE_CONDITIONS := notice LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE @@ -404,10 +167,10 @@ LOCAL_MODULE_CLASS := ETC LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_DLKM)/etc include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header) $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header) +$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header) @mkdir -p $(dir $@) $< fsconfig \ --aid-header $(PRIVATE_ANDROID_FS_HDR) \ @@ -423,7 +186,7 @@ $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_G # the device make file to enable include $(CLEAR_VARS) -LOCAL_MODULE := _fs_config_files_vendor_dlkm +LOCAL_MODULE := fs_config_files_vendor_dlkm LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 LOCAL_LICENSE_CONDITIONS := notice LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE @@ -431,10 +194,10 @@ LOCAL_MODULE_CLASS := ETC LOCAL_INSTALLED_MODULE_STEM := fs_config_files LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_DLKM)/etc include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header) $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header) +$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header) @mkdir -p $(dir $@) $< fsconfig \ --aid-header $(PRIVATE_ANDROID_FS_HDR) \ @@ -453,7 +216,7 @@ ifneq ($(filter odm_dlkm,$(fs_config_generate_extra_partition_list)),) # in the device make file to enable include $(CLEAR_VARS) -LOCAL_MODULE := _fs_config_dirs_odm_dlkm +LOCAL_MODULE := fs_config_dirs_odm_dlkm LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 LOCAL_LICENSE_CONDITIONS := notice LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE @@ -461,10 +224,10 @@ LOCAL_MODULE_CLASS := ETC LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs LOCAL_MODULE_PATH := $(TARGET_OUT_ODM_DLKM)/etc include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header) $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header) +$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header) @mkdir -p $(dir $@) $< fsconfig \ --aid-header $(PRIVATE_ANDROID_FS_HDR) \ @@ -480,7 +243,7 @@ $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_G # in the device make file to enable include $(CLEAR_VARS) -LOCAL_MODULE := _fs_config_files_odm_dlkm +LOCAL_MODULE := fs_config_files_odm_dlkm LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 LOCAL_LICENSE_CONDITIONS := notice LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE @@ -488,10 +251,10 @@ LOCAL_MODULE_CLASS := ETC LOCAL_INSTALLED_MODULE_STEM := fs_config_files LOCAL_MODULE_PATH := $(TARGET_OUT_ODM_DLKM)/etc include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header) $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header) +$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header) @mkdir -p $(dir $@) $< fsconfig \ --aid-header $(PRIVATE_ANDROID_FS_HDR) \ @@ -510,7 +273,7 @@ ifneq ($(filter system_dlkm,$(fs_config_generate_extra_partition_list)),) # in the device make file to enable include $(CLEAR_VARS) -LOCAL_MODULE := _fs_config_dirs_system_dlkm +LOCAL_MODULE := fs_config_dirs_system_dlkm LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 LOCAL_LICENSE_CONDITIONS := notice LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE @@ -518,10 +281,10 @@ LOCAL_MODULE_CLASS := ETC LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_DLKM)/etc include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header) $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header) +$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header) @mkdir -p $(dir $@) $< fsconfig \ --aid-header $(PRIVATE_ANDROID_FS_HDR) \ @@ -537,7 +300,7 @@ $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_G # in the device make file to enable include $(CLEAR_VARS) -LOCAL_MODULE := _fs_config_files_system_dlkm +LOCAL_MODULE := fs_config_files_system_dlkm LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 LOCAL_LICENSE_CONDITIONS := notice LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE @@ -545,10 +308,10 @@ LOCAL_MODULE_CLASS := ETC LOCAL_INSTALLED_MODULE_STEM := fs_config_files LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_DLKM)/etc include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(vendor_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(vendor_capability_header) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(android_filesystem_config) +$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(capability_header) $(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(vendor_android_filesystem_config) $(vendor_capability_header) +$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(android_filesystem_config) $(capability_header) @mkdir -p $(dir $@) $< fsconfig \ --aid-header $(PRIVATE_ANDROID_FS_HDR) \ @@ -560,118 +323,6 @@ $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_G endif -ifneq ($(BOARD_USES_PRODUCTIMAGE)$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),) -################################## -# Generate the product/etc/fs_config_dirs binary file for the target -# Add fs_config_dirs or fs_config_dirs_product to PRODUCT_PACKAGES in -# the device make file to enable -include $(CLEAR_VARS) - -LOCAL_MODULE := _fs_config_dirs_product -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_MODULE_CLASS := ETC -LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs -LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/etc -include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header) -$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header) - @mkdir -p $(dir $@) - $< fsconfig \ - --aid-header $(PRIVATE_ANDROID_FS_HDR) \ - --capability-header $(PRIVATE_ANDROID_CAP_HDR) \ - --partition product \ - --dirs \ - --out_file $@ \ - $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) - -################################## -# Generate the product/etc/fs_config_files binary file for the target -# Add fs_config_files or fs_config_files_product to PRODUCT_PACKAGES in -# the device make file to enable -include $(CLEAR_VARS) - -LOCAL_MODULE := _fs_config_files_product -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_MODULE_CLASS := ETC -LOCAL_INSTALLED_MODULE_STEM := fs_config_files -LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/etc -include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header) -$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header) - @mkdir -p $(dir $@) - $< fsconfig \ - --aid-header $(PRIVATE_ANDROID_FS_HDR) \ - --capability-header $(PRIVATE_ANDROID_CAP_HDR) \ - --partition product \ - --files \ - --out_file $@ \ - $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) -endif - -ifneq ($(BOARD_USES_SYSTEM_EXTIMAGE)$(BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE),) -################################## -# Generate the system_ext/etc/fs_config_dirs binary file for the target -# Add fs_config_dirs or fs_config_dirs_system_ext to PRODUCT_PACKAGES in -# the device make file to enable -include $(CLEAR_VARS) - -LOCAL_MODULE := _fs_config_dirs_system_ext -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_MODULE_CLASS := ETC -LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs -LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_EXT)/etc -include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header) -$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header) - @mkdir -p $(dir $@) - $< fsconfig \ - --aid-header $(PRIVATE_ANDROID_FS_HDR) \ - --capability-header $(PRIVATE_ANDROID_CAP_HDR) \ - --partition system_ext \ - --dirs \ - --out_file $@ \ - $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) - -################################## -# Generate the system_ext/etc/fs_config_files binary file for the target -# Add fs_config_files or fs_config_files_system_ext to PRODUCT_PACKAGES in -# the device make file to enable -include $(CLEAR_VARS) - -LOCAL_MODULE := _fs_config_files_system_ext -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE -LOCAL_MODULE_CLASS := ETC -LOCAL_INSTALLED_MODULE_STEM := fs_config_files -LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_EXT)/etc -include $(BUILD_SYSTEM)/base_rules.mk -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config) -$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header) -$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header) - @mkdir -p $(dir $@) - $< fsconfig \ - --aid-header $(PRIVATE_ANDROID_FS_HDR) \ - --capability-header $(PRIVATE_ANDROID_CAP_HDR) \ - --partition system_ext \ - --files \ - --out_file $@ \ - $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) -endif - -system_android_filesystem_config := -system_capability_header := +android_filesystem_config := +capability_header := fs_config_generate_extra_partition_list := diff --git a/tools/overrideflags.sh b/tools/overrideflags.sh deleted file mode 100755 index b8605dc034..0000000000 --- a/tools/overrideflags.sh +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/bash -e -# 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. - - -source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../shell_utils.sh -require_top - -function print_help() { - echo -e "overrideflags is used to set default value for local build." - echo -e "\nOptions:" - echo -e "\t--release-config \tPath to release configuration directory. Required" - echo -e "\t--no-edit \tIf present, skip editing flag value file." - echo -e "\t-h/--help \tShow this help." -} - -function main() { - while (($# > 0)); do - case $1 in - --release-config) - if [[ $# -le 1 ]]; then - echo "--release-config requires a path" - return 1 - fi - local release_config_dir="$2" - shift 2 - ;; - --no-edit) - local no_edit="true" - shift 1 - ;; - -h|--help) - print_help - return - ;; - *) - echo "$1 is unrecognized" - print_help - return 1 - ;; - esac - done - - - - case $(uname -s) in - Darwin) - local host_arch=darwin-x86 - ;; - Linux) - local host_arch=linux-x86 - ;; - *) - >&2 echo Unknown host $(uname -s) - return - ;; - esac - - if [[ -z "${release_config_dir}" ]]; then - echo "Please provide release configuration path by --release-config" - exit 1 - elif [ ! -d "${release_config_dir}" ]; then - echo "${release_config_dir} is an invalid directory" - exit 1 - fi - local T="$(gettop)" - local aconfig_dir="${T}"/build/make/tools/aconfig/ - local overrideflag_py="${aconfig_dir}"/overrideflags/overrideflags.py - local overridefile="${release_config_dir}/aconfig/override_values.textproto" - - # Edit override file - if [[ -z "${no_edit}" ]]; then - editor="${EDITOR:-$(which vim)}" - - eval "${editor} ${overridefile}" - if [ $? -ne 0 ]; then - echo "Fail to set override values" - return 1 - fi - fi - - ${T}/prebuilts/build-tools/${host_arch}/bin/py3-cmd -u "${overrideflag_py}" \ - --overrides "${overridefile}" \ - --out "${release_config_dir}/aconfig" -} - - -main "$@" diff --git a/tools/perf/format_benchmarks b/tools/perf/format_benchmarks index 162c5770a9..807e546a17 100755 --- a/tools/perf/format_benchmarks +++ b/tools/perf/format_benchmarks @@ -25,6 +25,7 @@ import os import pathlib import statistics import zoneinfo +import csv import pretty import utils @@ -103,7 +104,7 @@ class Table: def SetFixedCol(self, row_key, columns): self._fixed_cols[row_key] = columns - def Write(self, out): + def Write(self, out, fmt): table = [] # Expand the column items for row in zip(*self._cols): @@ -114,26 +115,33 @@ class Table: # Update the last row of the header with title and add separator for i in range(len(self._titles)): table[len(table)-1][i] = self._titles[i] - table.append(pretty.SEPARATOR) + if fmt == "table": + table.append(pretty.SEPARATOR) # Populate the data for row in self._rows: table.append([str(row)] + self._fixed_cols[row] + [str(self._data.get((col, row), "")) for col in self._cols]) - out.write(pretty.FormatTable(table, alignments="LL")) + if fmt == "csv": + csv.writer(sys.stdout, quoting=csv.QUOTE_MINIMAL).writerows(table) + else: + out.write(pretty.FormatTable(table, alignments="LL")) -def format_duration_sec(ns): +def format_duration_sec(ns, fmt_sec): "Format a duration in ns to second precision" sec = round(ns / 1000000000) - h, sec = divmod(sec, 60*60) - m, sec = divmod(sec, 60) - result = "" - if h > 0: - result += f"{h:2d}h " - if h > 0 or m > 0: - result += f"{m:2d}m " - return result + f"{sec:2d}s" + if fmt_sec: + return f"{sec}" + else: + h, sec = divmod(sec, 60*60) + m, sec = divmod(sec, 60) + result = "" + if h > 0: + result += f"{h:2d}h " + if h > 0 or m > 0: + result += f"{m:2d}m " + return result + f"{sec:2d}s" def main(argv): @@ -142,6 +150,12 @@ def main(argv): allow_abbrev=False, # Don't let people write unsupportable scripts. description="Print analysis tables for benchmarks") + parser.add_argument("--csv", action="store_true", + help="Print in CSV instead of table.") + + parser.add_argument("--sec", action="store_true", + help="Print in seconds instead of minutes and seconds") + parser.add_argument("--tags", nargs="*", help="The tags to print, in order.") @@ -188,14 +202,17 @@ def main(argv): for key, column in summary["columns"]: for id, cell in column: duration_ns = statistics.median([b["duration_ns"] for b in cell]) - table.SetFixedCol(cell[0]["title"], [" ".join(cell[0]["modules"])]) + modules = cell[0]["modules"] + if not modules: + modules = ["---"] + table.SetFixedCol(cell[0]["title"], [" ".join(modules)]) table.Set(tuple([summary["date"].strftime("%Y-%m-%d"), summary["branch"], summary["tag"]] + list(key)), - cell[0]["title"], format_duration_sec(duration_ns)) + cell[0]["title"], format_duration_sec(duration_ns, args.sec)) - table.Write(sys.stdout) + table.Write(sys.stdout, "csv" if args.csv else "table") if __name__ == "__main__": main(sys.argv) diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp index 9385f0ccab..9b134f22d4 100644 --- a/tools/releasetools/Android.bp +++ b/tools/releasetools/Android.bp @@ -632,7 +632,6 @@ python_defaults { data: [ "testdata/**/*", ":com.android.apex.compressed.v1", - ":com.android.apex.compressed.v1_original", ":com.android.apex.vendor.foo.with_vintf" ], target: { diff --git a/tools/releasetools/create_brick_ota.py b/tools/releasetools/create_brick_ota.py index 9e040a53d4..bf50f71049 100644 --- a/tools/releasetools/create_brick_ota.py +++ b/tools/releasetools/create_brick_ota.py @@ -45,10 +45,10 @@ def CreateBrickOta(product_name: str, output_path: Path, extra_wipe_partitions: partitions_to_wipe = PARTITIONS_TO_WIPE if extra_wipe_partitions is not None: partitions_to_wipe = PARTITIONS_TO_WIPE + extra_wipe_partitions.split(",") - ota_metadata = ["ota-type=BRICK", "post-timestamp=9999999999", - "pre-device=" + product_name] - if serialno is not None: - ota_metadata.append("serialno=" + serialno) + ota_metadata = ["ota-type=BRICK", "post-timestamp=9999999999", + "pre-device=" + product_name] + if serialno is not None: + ota_metadata.append("serialno=" + serialno) # recovery requiers product name to be a | separated list product_name = product_name.replace(",", "|") with zipfile.ZipFile(output_path, "w") as zfp: diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py index 432ea199bb..5a024cec54 100755 --- a/tools/releasetools/ota_from_target_files.py +++ b/tools/releasetools/ota_from_target_files.py @@ -914,12 +914,13 @@ def GenerateAbOtaPackage(target_file, output_file, source_file=None): # and install time performance. All OTA's with # both the source build and target build with VIRTUAL_AB_COW_VERSION = 3 # can support the new format. Otherwise, fallback on older versions - if not source_info.vabc_cow_version or not target_info.vabc_cow_version: - logger.info("Source or Target doesn't have VABC_COW_VERSION specified, default to version 2") - OPTIONS.vabc_cow_version = 2 - elif source_info.vabc_cow_version != target_info.vabc_cow_version: - logger.info("Source and Target have different cow VABC_COW_VERSION specified, default to minimum version") - OPTIONS.vabc_cow_version = min(source_info.vabc_cow_version, target_info.vabc_cow_version) + if not OPTIONS.vabc_cow_version: + if not source_info.vabc_cow_version or not target_info.vabc_cow_version: + logger.info("Source or Target doesn't have VABC_COW_VERSION specified, default to version 2") + OPTIONS.vabc_cow_version = 2 + elif source_info.vabc_cow_version != target_info.vabc_cow_version: + logger.info("Source and Target have different cow VABC_COW_VERSION specified, default to minimum version") + OPTIONS.vabc_cow_version = min(source_info.vabc_cow_version, target_info.vabc_cow_version) # Virtual AB Compression was introduced in Androd S. # Later, we backported VABC to Android R. But verity support was not @@ -933,19 +934,20 @@ def GenerateAbOtaPackage(target_file, output_file, source_file=None): assert "ab_partitions" in OPTIONS.info_dict, \ "META/ab_partitions.txt is required for ab_update." source_info = None - if not target_info.vabc_cow_version: + if not OPTIONS.vabc_cow_version: + if not target_info.vabc_cow_version: + OPTIONS.vabc_cow_version = 2 + elif target_info.vabc_cow_version >= "3" and target_info.vendor_api_level < 35: + logger.warning( + "This full OTA is configured to use VABC cow version" + " 3 which is supported since" + " Android API level 35, but device is " + "launched with {} . If this full OTA is" + " served to a device running old build, OTA might fail due to " + "unsupported vabc cow version. For safety, version 2 is used because " + "it's supported since day 1.".format( + target_info.vendor_api_level)) OPTIONS.vabc_cow_version = 2 - elif target_info.vabc_cow_version >= "3" and target_info.vendor_api_level < 35: - logger.warning( - "This full OTA is configured to use VABC cow version" - " 3 which is supported since" - " Android API level 35, but device is " - "launched with {} . If this full OTA is" - " served to a device running old build, OTA might fail due to " - "unsupported vabc cow version. For safety, version 2 is used because " - "it's supported since day 1.".format( - target_info.vendor_api_level)) - OPTIONS.vabc_cow_version = 2 if OPTIONS.vabc_compression_param is None and vabc_compression_param: minimum_api_level_required = VABC_COMPRESSION_PARAM_SUPPORT[ vabc_compression_param] diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py index 048a497585..81b53dce36 100644 --- a/tools/releasetools/ota_utils.py +++ b/tools/releasetools/ota_utils.py @@ -1111,9 +1111,10 @@ def CopyTargetFilesDir(input_dir): relative_path = path.removeprefix(input_dir).removeprefix("/") if not Fnmatch(relative_path, UNZIP_PATTERN): continue - if filename.endswith(".prop") or filename == "prop.default" or "/etc/vintf/" in relative_path: - target_path = os.path.join( - output_dir, relative_path) - os.makedirs(os.path.dirname(target_path), exist_ok=True) - shutil.copy(path, target_path) + target_path = os.path.join( + output_dir, relative_path) + if os.path.exists(target_path): + continue + os.makedirs(os.path.dirname(target_path), exist_ok=True) + shutil.copy(path, target_path) return output_dir diff --git a/tools/whichgit b/tools/whichgit index 8cf84f5629..55c8c6fb5a 100755 --- a/tools/whichgit +++ b/tools/whichgit @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import argparse +import itertools import os import subprocess import sys @@ -10,15 +11,34 @@ def get_build_var(var): check=True, capture_output=True, text=True).stdout.strip() +def get_all_modules(): + product_out = subprocess.run(["build/soong/soong_ui.bash", "--dumpvar-mode", "--abs", "PRODUCT_OUT"], + check=True, capture_output=True, text=True).stdout.strip() + result = subprocess.run(["cat", product_out + "/all_modules.txt"], check=True, capture_output=True, text=True) + return result.stdout.strip().split("\n") + + +def batched(iterable, n): + # introduced in itertools 3.12, could delete once that's universally available + if n < 1: + raise ValueError('n must be at least one') + it = iter(iterable) + while batch := tuple(itertools.islice(it, n)): + yield batch + + def get_sources(modules): - result = subprocess.run(["./prebuilts/build-tools/linux-x86/bin/ninja", "-f", - "out/combined-" + os.environ["TARGET_PRODUCT"] + ".ninja", - "-t", "inputs", "-d", ] + modules, - stderr=subprocess.STDOUT, stdout=subprocess.PIPE, check=False, text=True) - if result.returncode != 0: - sys.stderr.write(result.stdout) - sys.exit(1) - return set([f for f in result.stdout.split("\n") if not f.startswith("out/")]) + sources = set() + for module_group in batched(modules, 40_000): + result = subprocess.run(["./prebuilts/build-tools/linux-x86/bin/ninja", "-f", + "out/combined-" + os.environ["TARGET_PRODUCT"] + ".ninja", + "-t", "inputs", "-d", ] + list(module_group), + stderr=subprocess.STDOUT, stdout=subprocess.PIPE, check=False, text=True) + if result.returncode != 0: + sys.stderr.write(result.stdout) + sys.exit(1) + sources.update(set([f for f in result.stdout.split("\n") if not f.startswith("out/")])) + return sources def m_nothing(): @@ -57,13 +77,13 @@ def main(argv): # Argument parsing ap = argparse.ArgumentParser(description="List the required git projects for the given modules") ap.add_argument("--products", nargs="*", - help="The TARGET_PRODUCT to check. If not provided just uses whatever has" - + " already been built") + help="One or more TARGET_PRODUCT to check, or \"*\" for all. If not provided" + + "just uses whatever has already been built") ap.add_argument("--variants", nargs="*", help="The TARGET_BUILD_VARIANTS to check. If not provided just uses whatever has" + " already been built, or eng if --products is supplied") ap.add_argument("--modules", nargs="*", - help="The build modules to check, or droid if not supplied") + help="The build modules to check, or \"*\" for all, or droid if not supplied") ap.add_argument("--why", nargs="*", help="Also print the input files used in these projects, or \"*\" for all") ap.add_argument("--unused", help="List the unused git projects for the given modules rather than" @@ -72,22 +92,33 @@ def main(argv): modules = args.modules if args.modules else ["droid"] + match args.products: + case ["*"]: + products = get_build_var("all_named_products").split(" ") + case _: + products = args.products + # Get the list of sources for all of the requested build combos - if not args.products and not args.variants: + if not products and not args.variants: + m_nothing() + if args.modules == ["*"]: + modules = get_all_modules() sources = get_sources(modules) else: - if not args.products: + if not products: sys.stderr.write("Error: --products must be supplied if --variants is supplied") sys.exit(1) sources = set() build_num = 1 - for product in args.products: + for product in products: os.environ["TARGET_PRODUCT"] = product variants = args.variants if args.variants else ["user", "userdebug", "eng"] for variant in variants: - sys.stderr.write(f"Analyzing build {build_num} of {len(args.products)*len(variants)}\r") + sys.stderr.write(f"Analyzing build {build_num} of {len(products)*len(variants)}\r") os.environ["TARGET_BUILD_VARIANT"] = variant m_nothing() + if args.modules == ["*"]: + modules = get_all_modules() sources.update(get_sources(modules)) build_num += 1 sys.stderr.write("\n\n") |