Merge "Create aconfig_flags for all containers." into main
diff --git a/Changes.md b/Changes.md
index 9f2449c..eddec04 100644
--- a/Changes.md
+++ b/Changes.md
@@ -40,14 +40,8 @@
## Python 2 to 3 migration
-The path set when running builds now makes the `python` executable point to python 3,
-whereas on previous versions it pointed to python 2. If you still have python 2 scripts,
-you can change the shebang line to use `python2` explicitly. This only applies for
-scripts run directly from makefiles, or from soong genrules.
-
-In addition, `python_*` soong modules no longer allow python 2.
-
-Python 2 is slated for complete removal in V.
+Python 2 has been completely removed from the build. Please migrate any remaining usages to
+Python 3, and remove any version-specific properties from bp files.
## Stop referencing sysprop_library directly from cc modules
diff --git a/ci/Android.bp b/ci/Android.bp
index 3f28be4..757767c 100644
--- a/ci/Android.bp
+++ b/ci/Android.bp
@@ -35,11 +35,6 @@
data: [
":py3-cmd",
],
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
}
// This test is only intended to be run locally since it's slow, not hermetic,
@@ -64,11 +59,6 @@
test_options: {
unit_test: false,
},
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
}
python_test_host {
@@ -88,11 +78,6 @@
data: [
":py3-cmd",
],
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
}
python_binary_host {
diff --git a/core/Makefile b/core/Makefile
index 447dcb6..1a81b36 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -280,11 +280,6 @@
.PHONY: ndk-docs
endif
-ifeq ($(HOST_OS),linux)
-$(call dist-for-goals,sdk,$(API_FINGERPRINT))
-$(call dist-for-goals,droidcore,$(API_FINGERPRINT))
-endif
-
INSTALLED_RECOVERYIMAGE_TARGET :=
# Build recovery image if
# BUILDING_RECOVERY_IMAGE && !BOARD_USES_RECOVERY_AS_BOOT && !BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT.
@@ -758,10 +753,7 @@
# $5 partition tag
# $6 output file
define _apkcerts_write_line
-$(hide) echo -n 'name="$(1).apk" certificate="$2" private_key="$3"' >> $6
-$(if $(4), $(hide) echo -n ' compressed="$4"' >> $6)
-$(if $(5), $(hide) echo -n ' partition="$5"' >> $6)
-$(hide) echo '' >> $6
+$(hide) echo 'name="$(1).apk" certificate="$2" private_key="$3"$(if $(4), compressed="$4")$(if $(5), partition="$5")' >> $6
endef
@@ -832,16 +824,6 @@
# -----------------------------------------------------------------
-# build system stats
-BUILD_SYSTEM_STATS := $(PRODUCT_OUT)/build_system_stats.txt
-$(BUILD_SYSTEM_STATS):
- @rm -f $@
- @$(foreach s,$(STATS.MODULE_TYPE),echo "modules_type_make,$(s),$(words $(STATS.MODULE_TYPE.$(s)))" >>$@;)
- @$(foreach s,$(STATS.SOONG_MODULE_TYPE),echo "modules_type_soong,$(s),$(STATS.SOONG_MODULE_TYPE.$(s))" >>$@;)
-$(call declare-1p-target,$(BUILD_SYSTEM_STATS),build)
-$(call dist-for-goals,droidcore-unbundled,$(BUILD_SYSTEM_STATS))
-
-# -----------------------------------------------------------------
# build /product/etc/security/avb/system_other.avbpubkey if needed
ifdef BUILDING_SYSTEM_OTHER_IMAGE
ifeq ($(BOARD_AVB_ENABLE),true)
@@ -916,18 +898,6 @@
$(call dist-for-goals,droidcore-unbundled,$(WALL_WERROR))
-# -----------------------------------------------------------------
-# Modules missing profile files
-PGO_PROFILE_MISSING := $(PRODUCT_OUT)/pgo_profile_file_missing.txt
-$(PGO_PROFILE_MISSING):
- @rm -f $@
- echo "# Modules missing PGO profile files" >> $@
- for m in $(SOONG_MODULES_MISSING_PGO_PROFILE_FILE); do echo $$m >> $@; done
-
-$(call declare-0p-target,$(PGO_PROFILE_MISSING))
-
-$(call dist-for-goals,droidcore,$(PGO_PROFILE_MISSING))
-
CERTIFICATE_VIOLATION_MODULES_FILENAME := $(PRODUCT_OUT)/certificate_violation_modules.txt
$(CERTIFICATE_VIOLATION_MODULES_FILENAME):
rm -f $@
@@ -1213,55 +1183,6 @@
endif # BOARD_PREBUILT_DTBOIMAGE_16KB
-ifneq ($(BOARD_KERNEL_PATH_16K),)
-BUILT_KERNEL_16K_TARGET := $(PRODUCT_OUT)/kernel_16k
-
-$(eval $(call copy-one-file,$(BOARD_KERNEL_PATH_16K),$(BUILT_KERNEL_16K_TARGET)))
-
-# Copies BOARD_KERNEL_PATH_16K to output directory as is
-kernel_16k: $(BUILT_KERNEL_16K_TARGET)
-.PHONY: kernel_16k
-
-BUILT_BOOTIMAGE_16K_TARGET := $(PRODUCT_OUT)/boot_16k.img
-
-BOARD_KERNEL_16K_BOOTIMAGE_PARTITION_SIZE := $(BOARD_BOOTIMAGE_PARTITION_SIZE)
-
-$(BUILT_BOOTIMAGE_16K_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH) $(BUILT_KERNEL_16K_TARGET)
- $(call pretty,"Target boot 16k image: $@")
- $(call build_boot_from_kernel_avb_enabled,$@,$(BUILT_KERNEL_16K_TARGET))
-
-
-bootimage_16k: $(BUILT_BOOTIMAGE_16K_TARGET)
-.PHONY: bootimage_16k
-
-BUILT_BOOT_OTA_PACKAGE_16K := $(PRODUCT_OUT)/boot_ota_16k.zip
-$(BUILT_BOOT_OTA_PACKAGE_16K): $(OTA_FROM_RAW_IMG) \
- $(BUILT_BOOTIMAGE_16K_TARGET) \
- $(INSTALLED_BOOTIMAGE_TARGET) \
- $(DEFAULT_SYSTEM_DEV_CERTIFICATE).pk8 \
- $(INSTALLED_DTBOIMAGE_16KB_TARGET) \
- $(INSTALLED_DTBOIMAGE_TARGET)
- $(OTA_FROM_RAW_IMG) --package_key $(DEFAULT_SYSTEM_DEV_CERTIFICATE) \
- --max_timestamp `cat $(BUILD_DATETIME_FILE)` \
- --path $(HOST_OUT) \
- --partition_name $(if $(and $(INSTALLED_DTBOIMAGE_TARGET),\
- $(INSTALLED_DTBOIMAGE_16KB_TARGET)),\
- boot$(comma)dtbo,\
- boot) \
- --output $@ \
- $(if $(BOARD_16K_OTA_USE_INCREMENTAL),\
- $(INSTALLED_BOOTIMAGE_TARGET):$(BUILT_BOOTIMAGE_16K_TARGET),\
- $(BUILT_BOOTIMAGE_16K_TARGET)\
- )\
- $(if $(and $(INSTALLED_DTBOIMAGE_TARGET),$(INSTALLED_DTBOIMAGE_16KB_TARGET)),\
- $(INSTALLED_DTBOIMAGE_16KB_TARGET))
-
-boototapackage_16k: $(BUILT_BOOT_OTA_PACKAGE_16K)
-.PHONY: boototapackage_16k
-
-endif
-
-
ramdisk_intermediates :=$= $(call intermediates-dir-for,PACKAGING,ramdisk)
$(eval $(call write-partition-file-list,$(ramdisk_intermediates)/file_list.txt,$(TARGET_RAMDISK_OUT),$(INTERNAL_RAMDISK_FILES)))
@@ -1498,6 +1419,55 @@
endif # my_installed_prebuilt_gki_apex not defined
ifneq ($(BOARD_KERNEL_PATH_16K),)
+
+BUILT_KERNEL_16K_TARGET := $(PRODUCT_OUT)/kernel_16k
+
+$(eval $(call copy-one-file,$(BOARD_KERNEL_PATH_16K),$(BUILT_KERNEL_16K_TARGET)))
+
+# Copies BOARD_KERNEL_PATH_16K to output directory as is
+kernel_16k: $(BUILT_KERNEL_16K_TARGET)
+.PHONY: kernel_16k
+
+BUILT_BOOTIMAGE_16K_TARGET := $(PRODUCT_OUT)/boot_16k.img
+
+BOARD_KERNEL_16K_BOOTIMAGE_PARTITION_SIZE := $(BOARD_BOOTIMAGE_PARTITION_SIZE)
+
+$(BUILT_BOOTIMAGE_16K_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH) $(BUILT_KERNEL_16K_TARGET)
+ $(call pretty,"Target boot 16k image: $@")
+ $(call build_boot_from_kernel_avb_enabled,$@,$(BUILT_KERNEL_16K_TARGET))
+
+
+bootimage_16k: $(BUILT_BOOTIMAGE_16K_TARGET)
+.PHONY: bootimage_16k
+
+BUILT_BOOT_OTA_PACKAGE_16K := $(PRODUCT_OUT)/boot_ota_16k.zip
+$(BUILT_BOOT_OTA_PACKAGE_16K): PRIVATE_BOOTIMAGE_TARGET := $(INSTALLED_BOOTIMAGE_TARGET)
+$(BUILT_BOOT_OTA_PACKAGE_16K): PRIVATE_BOOTIMAGE_16KB_TARGET := $(BUILT_BOOTIMAGE_16K_TARGET)
+$(BUILT_BOOT_OTA_PACKAGE_16K): $(OTA_FROM_RAW_IMG) \
+ $(DEFAULT_SYSTEM_DEV_CERTIFICATE).pk8 \
+ $(INSTALLED_BOOTIMAGE_TARGET) \
+ $(BUILT_BOOTIMAGE_16K_TARGET) \
+ $(INSTALLED_DTBOIMAGE_16KB_TARGET) \
+ $(INSTALLED_DTBOIMAGE_TARGET)
+ $(OTA_FROM_RAW_IMG) --package_key $(DEFAULT_SYSTEM_DEV_CERTIFICATE) \
+ --max_timestamp `cat $(BUILD_DATETIME_FILE)` \
+ --path $(HOST_OUT) \
+ --partition_name $(if $(and $(INSTALLED_DTBOIMAGE_TARGET),\
+ $(INSTALLED_DTBOIMAGE_16KB_TARGET)),\
+ boot$(comma)dtbo,\
+ boot) \
+ --output $@ \
+ $(if $(BOARD_16K_OTA_USE_INCREMENTAL),\
+ $(PRIVATE_BOOTIMAGE_TARGET):$(PRIVATE_BOOTIMAGE_16KB_TARGET),\
+ $(PRIVATE_BOOTIMAGE_16KB_TARGET)\
+ )\
+ $(if $(and $(INSTALLED_DTBOIMAGE_TARGET),$(INSTALLED_DTBOIMAGE_16KB_TARGET)),\
+ $(INSTALLED_DTBOIMAGE_16KB_TARGET))
+
+boototapackage_16k: $(BUILT_BOOT_OTA_PACKAGE_16K)
+.PHONY: boototapackage_16k
+
+
BUILT_BOOT_OTA_PACKAGE_4K := $(PRODUCT_OUT)/boot_ota_4k.zip
$(BUILT_BOOT_OTA_PACKAGE_4K): $(OTA_FROM_RAW_IMG) \
$(INSTALLED_BOOTIMAGE_TARGET) \
@@ -1526,11 +1496,26 @@
ifeq ($(BOARD_16K_OTA_MOVE_VENDOR),true)
$(eval $(call copy-one-file,$(BUILT_BOOT_OTA_PACKAGE_4K),$(TARGET_OUT_VENDOR)/boot_otas/boot_ota_4k.zip))
$(eval $(call copy-one-file,$(BUILT_BOOT_OTA_PACKAGE_16K),$(TARGET_OUT_VENDOR)/boot_otas/boot_ota_16k.zip))
+
ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_OUT_VENDOR)/boot_otas/boot_ota_4k.zip
ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_OUT_VENDOR)/boot_otas/boot_ota_16k.zip
+
+ifneq ($(BOARD_VENDOR_KERNEL_MODULES_2ND_STAGE_16KB_MODE),)
+# Add the modules that need to be loaded in the Second Boot Stage
+# to /vendor_dlkm/lib/modules/16k-mode
+VENDOR_DLKM_16K_MODE_DIR := lib/modules/16k-mode
+$(foreach module,$(BOARD_VENDOR_KERNEL_MODULES_2ND_STAGE_16KB_MODE), \
+ $(eval $(call copy-one-file,$(TARGET_KERNEL_DIR_16K)/$(module),\
+ $(TARGET_OUT_VENDOR_DLKM)/$(VENDOR_DLKM_16K_MODE_DIR)/$(module))))
+
+ALL_DEFAULT_INSTALLED_MODULES += $(foreach module,$(BOARD_VENDOR_KERNEL_MODULES_2ND_STAGE_16KB_MODE),\
+ $(TARGET_OUT_VENDOR_DLKM)/$(VENDOR_DLKM_16K_MODE_DIR)/$(module))
+endif # BOARD_VENDOR_KERNEL_MODULES_2ND_STAGE_16KB_MODE not empty
+
else
$(eval $(call copy-one-file,$(BUILT_BOOT_OTA_PACKAGE_4K),$(TARGET_OUT)/boot_otas/boot_ota_4k.zip))
$(eval $(call copy-one-file,$(BUILT_BOOT_OTA_PACKAGE_16K),$(TARGET_OUT)/boot_otas/boot_ota_16k.zip))
+
ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_OUT)/boot_otas/boot_ota_4k.zip
ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_OUT)/boot_otas/boot_ota_16k.zip
endif # BOARD_16K_OTA_MOVE_VENDOR == true
@@ -1787,6 +1772,7 @@
INTERNAL_VENDOR_KERNEL_RAMDISK_TARGET := $(call intermediates-dir-for,PACKAGING,vendor_kernel_boot)/vendor_kernel_ramdisk.cpio$(RAMDISK_EXT)
$(INTERNAL_VENDOR_KERNEL_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_VENDOR_KERNEL_RAMDISK_FILES) | $(COMPRESSION_COMMAND_DEPS)
+ $(hide) : $(words $(INTERNAL_VENDOR_KERNEL_RAMDISK_FILES))
$(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_VENDOR_KERNEL_RAMDISK_OUT) | $(COMPRESSION_COMMAND) > $@
INSTALLED_VENDOR_KERNEL_RAMDISK_TARGET := $(PRODUCT_OUT)/vendor_kernel_ramdisk.img
@@ -1925,15 +1911,6 @@
# need no associated notice file on the device UI.
exclude_target_dirs := apex
-# TODO(b/69865032): Make PRODUCT_NOTICE_SPLIT the default behavior.
-ifneq ($(PRODUCT_NOTICE_SPLIT),true)
-#target_notice_file_html := $(TARGET_OUT_INTERMEDIATES)/NOTICE.html
-target_notice_file_html_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE.html.gz
-installed_notice_html_or_xml_gz := $(TARGET_OUT)/etc/NOTICE.html.gz
-
-$(call declare-0p-target,$(target_notice_file_html_gz))
-$(call declare-0p-target,$(installed_notice_html_or_xml_gz))
-else
# target_notice_file_xml := $(TARGET_OUT_INTERMEDIATES)/NOTICE.xml
target_notice_file_xml_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE.xml.gz
installed_notice_html_or_xml_gz := $(TARGET_OUT)/etc/NOTICE.xml.gz
@@ -2053,8 +2030,6 @@
system_notice_file_message := "Notices for files contained in the system filesystem image in this directory:"
endif
-endif # PRODUCT_NOTICE_SPLIT
-
ALL_DEFAULT_INSTALLED_MODULES += $(installed_notice_html_or_xml_gz)
need_vendor_notice:=false
@@ -3584,7 +3559,6 @@
ifeq ($(PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE),)
$(error PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE must be set if USE_SOONG_DEFINED_SYSTEM_IMAGE is true)
endif
-SOONG_DEFINED_SYSTEM_IMAGE_PATH := $(call intermediates-dir-for,ETC,$(PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE))/$(PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE)
SOONG_DEFINED_SYSTEM_IMAGE_BASE := $(dir $(ALL_MODULES.$(PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE).FILESYSTEM_FILELIST))
$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE) $(systemimage_intermediates)/file_list.txt $(SOONG_DEFINED_SYSTEM_IMAGE_PATH)
$(eval $(call copy-one-file, $(SOONG_DEFINED_SYSTEM_IMAGE_PATH), $(BUILT_SYSTEMIMAGE)))
@@ -5354,7 +5328,7 @@
lz4:$(HOST_OUT_EXECUTABLES)/lz4 \
-# BOARD_KERNEL_CONFIG_FILE and BOARD_KERNEL_VERSION can be used to override the values extracted
+# BOARD_KERNEL_VERSION can be used to override the values extracted
# from INSTALLED_KERNEL_TARGET.
ifdef BOARD_KERNEL_VERSION
$(BUILT_KERNEL_VERSION_FILE): PRIVATE_DECOMPRESS_TOOLS := $(my_decompress_tools)
@@ -5366,15 +5340,8 @@
echo "Specified kernel version '$(BOARD_KERNEL_VERSION)' does not match actual kernel version '$$KERNEL_RELEASE' " ; exit 1; fi;
echo '$(BOARD_KERNEL_VERSION)' > $@
-ifdef BOARD_KERNEL_CONFIG_FILE
-$(BUILT_KERNEL_CONFIGS_FILE): $(BOARD_KERNEL_CONFIG_FILE)
- cp $< $@
-
-$(call declare-license-metadata,$(BUILT_KERNEL_CONFIGS_FILE),SPDX-license-identifier-GPL-2.0-only,restricted,$(BUILD_SYSTEM)/LINUX_KERNEL_COPYING,"Kernel",kernel)
$(call declare-license-metadata,$(BUILT_KERNEL_VERSION_FILE),SPDX-license-identifier-GPL-2.0-only,restricted,$(BUILD_SYSTEM)/LINUX_KERNEL_COPYING,"Kernel",kernel)
-my_board_extracted_kernel := true
-endif # BOARD_KERNEL_CONFIG_FILE
endif # BOARD_KERNEL_VERSION
@@ -5885,7 +5852,10 @@
endif # BOARD_AVB_ENABLE
ifneq (,$(strip $(BOARD_CUSTOMIMAGES_PARTITION_LIST)))
$(hide) $(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
- echo "flash $(partition)" >> $@;)
+ $(if $(BOARD_$(call to-upper,$(partition))_IMAGE_NO_FLASHALL),, \
+ echo "flash $(partition)" >> $@; \
+ ) \
+ )
endif
$(hide) echo "reboot fastboot" >> $@
$(hide) echo "update-super" >> $@
@@ -7309,29 +7279,6 @@
$(call dist-for-goals,droidcore-unbundled apps_only,$(LLVM_COVERAGE_TOOLS_ZIP))
endif
-# -----------------------------------------------------------------
-# A zip of the Android Apps. Not keeping full path so that we don't
-# include product names when distributing
-#
-name := $(TARGET_PRODUCT)
-ifeq ($(TARGET_BUILD_TYPE),debug)
- name := $(name)_debug
-endif
-name := $(name)-apps
-
-APPS_ZIP := $(PRODUCT_OUT)/$(name).zip
-$(APPS_ZIP): $(FULL_SYSTEMIMAGE_DEPS)
- @echo "Package apps: $@"
- $(hide) rm -rf $@
- $(hide) mkdir -p $(dir $@)
- $(hide) apps_to_zip=`find $(TARGET_OUT_APPS) $(TARGET_OUT_APPS_PRIVILEGED) -mindepth 2 -maxdepth 3 -name "*.apk"`; \
- if [ -z "$$apps_to_zip" ]; then \
- echo "No apps to zip up. Generating empty apps archive." ; \
- a=$$(mktemp /tmp/XXXXXXX) && touch $$a && zip $@ $$a && zip -d $@ $$a; \
- else \
- zip -qjX $@ $$apps_to_zip; \
- fi
-
ifeq (true,$(EMMA_INSTRUMENT))
#------------------------------------------------------------------
# An archive of classes for use in generating code-coverage reports
@@ -7973,6 +7920,18 @@
$(INSTALLED_USERDATAIMAGE_TARGET)
# -----------------------------------------------------------------
+# Desktop generated firmware filesystem.
+TARGET_PRODUCT_FW_IMAGE_PACKAGE := prebuilt-$(TARGET_PRODUCT)-firmware-image
+GENERATED_FW_IMAGE := $(PRODUCT_OUT)/product/etc/$(TARGET_PRODUCT)-firmware.img
+
+generated_fw_image_found := $(strip $(foreach pp,$(PRODUCT_PACKAGES),\
+ $(if $(findstring $(TARGET_PRODUCT_FW_IMAGE_PACKAGE),$(pp)),$(pp))))
+
+ifneq (,$(generated_fw_image_found))
+$(call dist-for-goals,dist_files,$(GENERATED_FW_IMAGE))
+endif
+
+# -----------------------------------------------------------------
# Desktop pack image hook.
ifneq (,$(strip $(PACK_DESKTOP_FILESYSTEM_IMAGES)))
PACK_IMAGE_TARGET := $(PRODUCT_OUT)/android-desktop_image.bin
@@ -8064,6 +8023,46 @@
endif # ANDROID_DESKTOP_MIGRATION_IMAGE
+ifdef SOONG_ONLY_ALL_IMAGES_ZIP
+
+allimages_soong_zip_args :=
+allimages_deps :=
+
+define include_image
+$(if $(1), \
+ $(eval allimages_soong_zip_args += -e $(notdir $(1)) -f $(1)) \
+ $(eval allimages_deps += $(1)))
+endef
+
+$(call include_image,$(INSTALLED_SUPERIMAGE_TARGET))
+$(call include_image,$(INSTALLED_BOOTIMAGE_TARGET))
+$(call include_image,$(INSTALLED_INIT_BOOT_IMAGE_TARGET))
+$(call include_image,$(INSTALLED_VENDOR_BOOTIMAGE_TARGET))
+$(call include_image,$(INSTALLED_USERDATAIMAGE_TARGET))
+$(call include_image,$(INSTALLED_RECOVERYIMAGE_TARGET))
+$(call include_image,$(INSTALLED_VBMETAIMAGE_TARGET))
+$(call include_image,$(INSTALLED_VBMETA_SYSTEMIMAGE_TARGET))
+$(call include_image,$(INSTALLED_VBMETA_VENDORIMAGE_TARGET))
+$(foreach partition,$(call to-upper,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)), \
+ $(call include_image,$(INSTALLED_VBMETA_$(partition)IMAGE_TARGET)))
+
+allimages_zip := $(PRODUCT_OUT)/all_images.zip
+$(allimages_zip): PRIVATE_SOONG_ZIP_ARGUMENTS := $(allimages_soong_zip_args)
+$(allimages_zip): $(SOONG_ZIP) $(allimages_deps)
+ $(SOONG_ZIP) -o $@ $(PRIVATE_SOONG_ZIP_ARGUMENTS)
+
+.PHONY: soong_only_diff_test
+soong_only_diff_test: PRIVATE_ALLIMAGES_ZIP := $(allimages_zip)
+soong_only_diff_test: $(allimages_zip) $(SOONG_ONLY_ALL_IMAGES_ZIP)
+ diff $(PRIVATE_ALLIMAGES_ZIP) $(SOONG_ONLY_ALL_IMAGES_ZIP)
+
+allimages_soong_zip_args :=
+allimages_deps :=
+allimages_zip :=
+include_image :=
+
+endif # ifdef SOONG_ONLY_ALL_IMAGES_ZIP
+
# -----------------------------------------------------------------
# OS Licensing
diff --git a/core/OWNERS b/core/OWNERS
index 35ea83d..d8aa237 100644
--- a/core/OWNERS
+++ b/core/OWNERS
@@ -9,5 +9,5 @@
per-file version_defaults.mk = amhk@google.com,gurpreetgs@google.com,mkhokhlova@google.com,robertogil@google.com
# For Ravenwood test configs
-per-file ravenwood_test_config_template.xml = jsharkey@google.com,omakoto@google.com
+per-file ravenwood_test_config_template.xml =omakoto@google.com
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index a205ab5..6aea680 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -45,6 +45,7 @@
$(call soong_config_set_bool,ANDROID,PRODUCT_FSVERITY_GENERATE_METADATA,$(if $(filter true,$(PRODUCT_FSVERITY_GENERATE_METADATA)),true,false))
$(call add_soong_config_var,ANDROID,ADDITIONAL_M4DEFS,$(if $(BOARD_SEPOLICY_M4DEFS),$(addprefix -D,$(BOARD_SEPOLICY_M4DEFS))))
+$(call add_soong_config_var,ANDROID,TARGET_ADD_ROOT_EXTRA_VENDOR_SYMLINKS)
# For BUILDING_GSI
$(call soong_config_set_bool,gsi,building_gsi,$(if $(filter true,$(BUILDING_GSI)),true,false))
@@ -324,3 +325,8 @@
# Variables for extra branches
# TODO(b/383238397): Use bootstrap_go_package to enable extra flags.
-include vendor/google/build/extra_soong_config_vars.mk
+
+# Variable for CI test packages
+ifneq ($(filter arm x86 true,$(TARGET_ARCH) $(TARGET_2ND_ARCH) $(TARGET_ENABLE_MEDIADRM_64)),)
+ $(call soong_config_set_bool,ci_tests,uses_widevine_tests, true)
+endif
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 5363e0f..9ffe518 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -861,13 +861,6 @@
$(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
$(LOCAL_PATH)/DynamicConfig.xml:$(dir)/$(LOCAL_MODULE).dynamic)))
endif
-
- ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config))
- $(foreach extra_config, $(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config), \
- $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
- $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
- $(extra_config):$(dir)/$(notdir $(extra_config))))))
- endif
endif # $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
@@ -938,12 +931,6 @@
my_supported_variant := DEVICE
endif
endif
-###########################################################
-## Add test module to ALL_DISABLED_PRESUBMIT_TESTS if LOCAL_PRESUBMIT_DISABLED is set to true.
-###########################################################
-ifeq ($(LOCAL_PRESUBMIT_DISABLED),true)
- ALL_DISABLED_PRESUBMIT_TESTS += $(LOCAL_MODULE)
-endif # LOCAL_PRESUBMIT_DISABLED
###########################################################
## Register with ALL_MODULES
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index fed19e6..2e67aff 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -204,7 +204,6 @@
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES:=
LOCAL_USE_EMBEDDED_DEX:=
LOCAL_USE_EMBEDDED_NATIVE_LIBS:=
-LOCAL_PRESUBMIT_DISABLED:=
LOCAL_PRIVATE_PLATFORM_APIS:=
LOCAL_PRIVILEGED_MODULE:=
LOCAL_PROC_MACRO_LIBRARIES:=
diff --git a/core/config.mk b/core/config.mk
index b892924..47018aa 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -765,7 +765,6 @@
# TODO: remove all code referencing these, and remove override variables
PRODUCT_FULL_TREBLE := true
-PRODUCT_NOTICE_SPLIT := true
PRODUCT_TREBLE_LINKER_NAMESPACES := true
PRODUCT_ENFORCE_VINTF_MANIFEST := true
@@ -774,7 +773,6 @@
PRODUCT_FULL_TREBLE \
PRODUCT_TREBLE_LINKER_NAMESPACES \
PRODUCT_ENFORCE_VINTF_MANIFEST \
- PRODUCT_NOTICE_SPLIT \
# TODO(b/114488870): remove all sets of these everwhere, and disallow them to be used
$(KATI_obsolete_var PRODUCT_TREBLE_LINKER_NAMESPACES_OVERRIDE,Deprecated.)
diff --git a/core/cxx_stl_setup.mk b/core/cxx_stl_setup.mk
index 0d557c7..5e8ca7f 100644
--- a/core/cxx_stl_setup.mk
+++ b/core/cxx_stl_setup.mk
@@ -78,7 +78,7 @@
my_static_libraries += libc++demangle
ifeq ($(my_link_type),static)
- my_static_libraries += libm libc libunwind
+ my_static_libraries += libm libc libunwind libstatic_rustlibs_for_make
endif
endif
else ifeq ($(my_cxx_stl),ndk)
diff --git a/core/definitions.mk b/core/definitions.mk
index 1ab6388..60034cd 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -90,9 +90,6 @@
# All installed vintf manifest fragments for a partition at
ALL_VINTF_MANIFEST_FRAGMENTS_LIST:=
-# All tests that should be skipped in presubmit check.
-ALL_DISABLED_PRESUBMIT_TESTS :=
-
# All compatibility suites mentioned in LOCAL_COMPATIBILITY_SUITE
ALL_COMPATIBILITY_SUITES :=
@@ -839,18 +836,6 @@
endef
###########################################################
-## Declare that non-module targets copied from project $(1) and
-## optionally ending in $(2) are non-copyrightable files.
-##
-## e.g. an information-only file merely listing other files.
-###########################################################
-define declare-0p-copy-files
-$(strip \
- $(foreach _pair,$(filter $(1)%$(2),$(PRODUCT_COPY_FILES)),$(eval $(call declare-0p-target,$(PRODUCT_OUT)/$(call word-colon,2,$(_pair))))) \
-)
-endef
-
-###########################################################
## Declare non-module target $(1) to have a first-party license
## (Android Apache 2.0)
##
@@ -3286,7 +3271,7 @@
$(hide) mkdir -p "$$(dir $$@)"
$(hide) rm -f "$$@"
$(hide) \
- if $(LLVM_READOBJ) -h "$$<" >/dev/null 2>&1; then \
+ if $(LLVM_READOBJ) -h "$$<" 2>/dev/null | grep -q "^Format: elf"; then \
$(call echo-error,$(2),$(3)); \
$(call echo-error,$(2),found ELF file: $$<); \
false; \
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index 88e0cc7..b78c10c 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -13,34 +13,10 @@
install-on-system-other = $(filter-out $(PRODUCT_DEXPREOPT_SPEED_APPS) $(PRODUCT_SYSTEM_SERVER_APPS),$(basename $(notdir $(filter $(foreach f,$(SYSTEM_OTHER_ODEX_FILTER),$(TARGET_OUT)/$(f)),$(1)))))
endif
-# Build the boot.zip which contains the boot jars and their compilation output
-# We can do this only if preopt is enabled and if the product uses libart config (which sets the
-# default properties for preopting).
-# At the time of writing, this is only for ART Cloud.
ifeq ($(WITH_DEXPREOPT), true)
ifneq ($(WITH_DEXPREOPT_ART_BOOT_IMG_ONLY), true)
ifeq ($(PRODUCT_USES_DEFAULT_ART_CONFIG), true)
-boot_zip := $(PRODUCT_OUT)/boot.zip
-bootclasspath_jars := $(DEXPREOPT_BOOTCLASSPATH_DEX_FILES)
-
-# TODO remove system_server_jars usages from boot.zip and depend directly on system_server.zip file.
-
-# Use "/system" path for JARs with "platform:" prefix.
-# These JARs counterintuitively use "platform" prefix but they will
-# be actually installed to /system partition.
-platform_system_server_jars = $(filter platform:%, $(PRODUCT_SYSTEM_SERVER_JARS))
-system_server_jars := \
- $(foreach m,$(platform_system_server_jars),\
- $(PRODUCT_OUT)/system/framework/$(call word-colon,2,$(m)).jar)
-
-# For the remaining system server JARs use the partition signified by the prefix.
-# For example, prefix "system_ext:" will use "/system_ext" path.
-other_system_server_jars = $(filter-out $(platform_system_server_jars), $(PRODUCT_SYSTEM_SERVER_JARS))
-system_server_jars += \
- $(foreach m,$(other_system_server_jars),\
- $(PRODUCT_OUT)/$(call word-colon,1,$(m))/framework/$(call word-colon,2,$(m)).jar)
-
# Infix can be 'art' (ART image for testing), 'boot' (primary), or 'mainline' (mainline extension).
# Soong creates a set of variables for Make, one or each boot image. The only reason why the ART
# image is exposed to Make is testing (art gtests) and benchmarking (art golem benchmarks). Install
@@ -48,76 +24,6 @@
# is always 'boot' or 'mainline'.
DEXPREOPT_INFIX := $(if $(filter true,$(DEX_PREOPT_WITH_UPDATABLE_BCP)),mainline,boot)
-# The input variables are written by build/soong/java/dexpreopt_bootjars.go. Examples can be found
-# at the bottom of build/soong/java/dexpreopt_config_testing.go.
-dexpreopt_root_dir := $(dir $(patsubst %/,%,$(dir $(firstword $(bootclasspath_jars)))))
-bootclasspath_arg := $(subst $(space),:,$(patsubst $(dexpreopt_root_dir)%,%,$(DEXPREOPT_BOOTCLASSPATH_DEX_FILES)))
-bootclasspath_locations_arg := $(subst $(space),:,$(DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS))
-boot_images := $(subst :,$(space),$(DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICE$(DEXPREOPT_INFIX)))
-boot_image_arg := $(subst $(space),:,$(patsubst /%,%,$(boot_images)))
-uffd_gc_flag_txt := $(OUT_DIR)/soong/dexpreopt/uffd_gc_flag.txt
-
-boot_zip_metadata_txt := $(dir $(boot_zip))boot_zip/METADATA.txt
-$(boot_zip_metadata_txt): $(uffd_gc_flag_txt)
-$(boot_zip_metadata_txt):
- rm -f $@
- echo "bootclasspath = $(bootclasspath_arg)" >> $@
- echo "bootclasspath-locations = $(bootclasspath_locations_arg)" >> $@
- echo "boot-image = $(boot_image_arg)" >> $@
- echo "extra-args = `cat $(uffd_gc_flag_txt)`" >> $@
-
-$(call dist-for-goals, droidcore, $(boot_zip_metadata_txt))
-
-$(boot_zip): PRIVATE_BOOTCLASSPATH_JARS := $(bootclasspath_jars)
-$(boot_zip): PRIVATE_SYSTEM_SERVER_JARS := $(system_server_jars)
-$(boot_zip): $(bootclasspath_jars) $(system_server_jars) $(SOONG_ZIP) $(MERGE_ZIPS) $(DEXPREOPT_IMAGE_ZIP_boot) $(DEXPREOPT_IMAGE_ZIP_art) $(DEXPREOPT_IMAGE_ZIP_mainline) $(boot_zip_metadata_txt)
- @echo "Create boot package: $@"
- rm -f $@
- $(SOONG_ZIP) -o $@.tmp \
- -C $(dir $(firstword $(PRIVATE_BOOTCLASSPATH_JARS)))/.. $(addprefix -f ,$(PRIVATE_BOOTCLASSPATH_JARS)) \
- -C $(PRODUCT_OUT) $(addprefix -f ,$(PRIVATE_SYSTEM_SERVER_JARS)) \
- -j -f $(boot_zip_metadata_txt)
- $(MERGE_ZIPS) $@ $@.tmp $(DEXPREOPT_IMAGE_ZIP_boot) $(DEXPREOPT_IMAGE_ZIP_art) $(DEXPREOPT_IMAGE_ZIP_mainline)
- rm -f $@.tmp
-
-$(call dist-for-goals, droidcore, $(boot_zip))
-
-# Build the system_server.zip which contains the Apex system server jars and standalone system server jars
-system_server_dex2oat_dir := $(SOONG_OUT_DIR)/system_server_dexjars
-system_server_zip := $(PRODUCT_OUT)/system_server.zip
-# non_updatable_system_server_jars contains jars in /system and /system_ext that are not part of an apex.
-non_updatable_system_server_jars := \
- $(foreach m,$(PRODUCT_SYSTEM_SERVER_JARS),\
- $(system_server_dex2oat_dir)/$(call word-colon,2,$(m)).jar)
-
-apex_system_server_jars := \
- $(foreach m,$(PRODUCT_APEX_SYSTEM_SERVER_JARS),\
- $(system_server_dex2oat_dir)/$(call word-colon,2,$(m)).jar)
-
-apex_standalone_system_server_jars := \
- $(foreach m,$(PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS),\
- $(system_server_dex2oat_dir)/$(call word-colon,2,$(m)).jar)
-
-standalone_system_server_jars := \
- $(foreach m,$(PRODUCT_STANDALONE_SYSTEM_SERVER_JARS),\
- $(system_server_dex2oat_dir)/$(call word-colon,2,$(m)).jar)
-
-$(system_server_zip): PRIVATE_SYSTEM_SERVER_DEX2OAT_DIR := $(system_server_dex2oat_dir)
-$(system_server_zip): PRIVATE_SYSTEM_SERVER_JARS := $(non_updatable_system_server_jars)
-$(system_server_zip): PRIVATE_APEX_SYSTEM_SERVER_JARS := $(apex_system_server_jars)
-$(system_server_zip): PRIVATE_APEX_STANDALONE_SYSTEM_SERVER_JARS := $(apex_standalone_system_server_jars)
-$(system_server_zip): PRIVATE_STANDALONE_SYSTEM_SERVER_JARS := $(standalone_system_server_jars)
-$(system_server_zip): $(system_server_jars) $(apex_system_server_jars) $(apex_standalone_system_server_jars) $(standalone_system_server_jars) $(SOONG_ZIP)
- @echo "Create system server package: $@"
- rm -f $@
- $(SOONG_ZIP) -o $@ \
- -C $(PRIVATE_SYSTEM_SERVER_DEX2OAT_DIR) $(addprefix -f ,$(PRIVATE_SYSTEM_SERVER_JARS)) \
- -C $(PRIVATE_SYSTEM_SERVER_DEX2OAT_DIR) $(addprefix -f ,$(PRIVATE_APEX_SYSTEM_SERVER_JARS)) \
- -C $(PRIVATE_SYSTEM_SERVER_DEX2OAT_DIR) $(addprefix -f ,$(PRIVATE_APEX_STANDALONE_SYSTEM_SERVER_JARS)) \
- -C $(PRIVATE_SYSTEM_SERVER_DEX2OAT_DIR) $(addprefix -f ,$(PRIVATE_STANDALONE_SYSTEM_SERVER_JARS))
-
-$(call dist-for-goals, droidcore, $(system_server_zip))
-
endif #PRODUCT_USES_DEFAULT_ART_CONFIG
endif #WITH_DEXPREOPT_ART_BOOT_IMG_ONLY
endif #WITH_DEXPREOPT
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index e7086b7..6fe9d38 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -152,7 +152,7 @@
# this dexpreopt.config is generated. So it's necessary to add file-level
# dependencies between dexpreopt.config files.
my_dexpreopt_dep_configs := $(foreach lib, \
- $(filter-out $(my_dexpreopt_libs_compat),$(LOCAL_USES_LIBRARIES) $(my_filtered_optional_uses_libraries)), \
+ $(filter-out $(my_dexpreopt_libs_compat) $(FRAMEWORK_LIBRARIES),$(LOCAL_USES_LIBRARIES) $(my_filtered_optional_uses_libraries)), \
$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,)/dexpreopt.config)
# 1: SDK version
diff --git a/core/main.mk b/core/main.mk
index d670397..9710dc8 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1195,8 +1195,9 @@
ifneq ($(TARGET_BUILD_APPS),)
# If this build is just for apps, only build apps and not the full system by default.
ifneq ($(filter all,$(TARGET_BUILD_APPS)),)
- # If they used the magic goal "all" then build all apps in the source tree.
- unbundled_build_modules := $(foreach m,$(sort $(ALL_MODULES)),$(if $(filter APPS,$(ALL_MODULES.$(m).CLASS)),$(m)))
+ # The magic goal "all" used to build all apps in the source tree. This was deprecated
+ # so that we can know all TARGET_BUILD_APPS apps are built with soong for soong-only builds.
+ $(error TARGET_BUILD_APPS=all is deprecated)
else
unbundled_build_modules := $(sort $(TARGET_BUILD_APPS))
endif
@@ -1466,7 +1467,6 @@
# dist_files only for putting your library into the dist directory with a full build.
.PHONY: dist_files
-$(call dist-for-goals, dist_files, $(SOONG_OUT_DIR)/module_bp_java_deps.json)
$(call dist-for-goals, dist_files, $(PRODUCT_OUT)/module-info.json)
.PHONY: apps_only
@@ -1620,7 +1620,6 @@
ifneq ($(ANDROID_BUILD_EMBEDDED),true)
$(call dist-for-goals-with-filenametag, droidcore, \
- $(APPS_ZIP) \
$(INTERNAL_EMULATOR_PACKAGE_TARGET) \
)
endif
@@ -1667,24 +1666,6 @@
$(call dist-for-goals, dist_files, $(JACOCO_REPORT_CLASSES_ALL))
endif
- # Put XML formatted API files in the dist dir.
- $(TARGET_OUT_COMMON_INTERMEDIATES)/api.xml: $(call java-lib-files,$(ANDROID_PUBLIC_STUBS)) $(APICHECK)
- $(TARGET_OUT_COMMON_INTERMEDIATES)/system-api.xml: $(call java-lib-files,$(ANDROID_SYSTEM_STUBS)) $(APICHECK)
- $(TARGET_OUT_COMMON_INTERMEDIATES)/module-lib-api.xml: $(call java-lib-files,$(ANDROID_MODULE_LIB_STUBS)) $(APICHECK)
- $(TARGET_OUT_COMMON_INTERMEDIATES)/system-server-api.xml: $(call java-lib-files,$(ANDROID_SYSTEM_SERVER_STUBS)) $(APICHECK)
- $(TARGET_OUT_COMMON_INTERMEDIATES)/test-api.xml: $(call java-lib-files,$(ANDROID_TEST_STUBS)) $(APICHECK)
-
- api_xmls := $(addprefix $(TARGET_OUT_COMMON_INTERMEDIATES)/,api.xml system-api.xml module-lib-api.xml system-server-api.xml test-api.xml)
- $(api_xmls):
- $(hide) echo "Converting API file to XML: $@"
- $(hide) mkdir -p $(dir $@)
- $(hide) $(APICHECK_COMMAND) jar-to-jdiff $< $@
-
- $(foreach xml,$(sort $(api_xmls)),$(call declare-1p-target,$(xml),))
-
- $(call dist-for-goals, dist_files, $(api_xmls))
- api_xmls :=
-
ifdef CLANG_COVERAGE
$(foreach f,$(SOONG_NDK_API_XML), \
$(call dist-for-goals,droidcore,$(f):ndk_apis/$(notdir $(f))))
diff --git a/core/ninja_config.mk b/core/ninja_config.mk
index a1fff4d..27b4190 100644
--- a/core/ninja_config.mk
+++ b/core/ninja_config.mk
@@ -19,7 +19,6 @@
build-art% \
build_kernel-nodeps \
clean-oat% \
- cts \
custom_images \
dicttool_aosp \
docs \
diff --git a/core/os_licensing.mk b/core/os_licensing.mk
index 97e55a7..bebaca1 100644
--- a/core/os_licensing.mk
+++ b/core/os_licensing.mk
@@ -7,12 +7,6 @@
SYSTEM_NOTICE_DEPS += $(UNMOUNTED_NOTICE_DEPS) $(UNMOUNTED_NOTICE_VENDOR_DEPS)
-ifneq ($(PRODUCT_NOTICE_SPLIT),true)
-$(eval $(call html-notice-rule,$(target_notice_file_html_gz),"System image",$(system_notice_file_message),$(SYSTEM_NOTICE_DEPS),$(SYSTEM_NOTICE_DEPS)))
-
-$(installed_notice_html_or_xml_gz): $(target_notice_file_html_gz)
- $(copy-file-to-target)
-else
$(eval $(call xml-notice-rule,$(target_notice_file_xml_gz),"System image",$(system_notice_file_message),$(SYSTEM_NOTICE_DEPS),$(SYSTEM_NOTICE_DEPS)))
$(eval $(call text-notice-rule,$(target_notice_file_txt),"System image",$(system_notice_file_message),$(SYSTEM_NOTICE_DEPS),$(SYSTEM_NOTICE_DEPS)))
@@ -21,7 +15,6 @@
$(installed_notice_html_or_xml_gz): $(target_notice_file_xml_gz)
$(copy-file-to-target)
endif
-endif
$(call declare-1p-target,$(target_notice_file_xml_gz))
ifneq ($(PRODUCT_USE_SOONG_NOTICE_XML),true)
diff --git a/core/proguard.flags b/core/proguard.flags
index dc32e15..76655ca 100644
--- a/core/proguard.flags
+++ b/core/proguard.flags
@@ -30,12 +30,12 @@
# Needed to ensure callback field references are kept in their respective
# owning classes when the downstream callback registrars only store weak refs.
-if @com.android.internal.annotations.WeaklyReferencedCallback class *
--keepclassmembers,allowaccessmodification class * {
- <1> *;
+-keepclassmembers,allowaccessmodification,allowobfuscation,allowshrinking class * {
+ !synthetic <1> *;
}
-if class * extends @com.android.internal.annotations.WeaklyReferencedCallback **
--keepclassmembers,allowaccessmodification class * {
- <1> *;
+-keepclassmembers,allowaccessmodification,allowobfuscation,allowshrinking class * {
+ !synthetic <1> *;
}
# Understand the common @Keep annotation from various Android packages:
diff --git a/core/proguard/checknotnull.flags b/core/proguard/checknotnull.flags
new file mode 100644
index 0000000..1e1e5ce
--- /dev/null
+++ b/core/proguard/checknotnull.flags
@@ -0,0 +1,25 @@
+# Tell R8 that the following methods are check not null methods, and to
+# replace invocations to them with a more concise nullness check that produces
+# (slightly) less informative error messages
+
+-convertchecknotnull class com.google.common.base.Preconditions {
+ ** checkNotNull(...);
+}
+
+-convertchecknotnull class java.util.Objects {
+ ** requireNonNull(...);
+}
+
+-convertchecknotnull class kotlin.jvm.internal.Intrinsics {
+ void checkNotNull(...);
+ void checkExpressionValueIsNotNull(...);
+ void checkNotNullExpressionValue(...);
+ void checkReturnedValueIsNotNull(...);
+ void checkFieldIsNotNull(...);
+ void checkParameterIsNotNull(...);
+ void checkNotNullParameter(...);
+}
+
+-convertchecknotnull class dagger.internal.Preconditions {
+ ** checkNotNull*(...);
+}
diff --git a/core/release_config.mk b/core/release_config.mk
index 68e115f..c6986c7 100644
--- a/core/release_config.mk
+++ b/core/release_config.mk
@@ -156,20 +156,6 @@
_used_files :=
ifeq (,$(_must_protobuf)$(RELEASE_BUILD_FLAGS_IN_PROTOBUF))
_use_protobuf :=
- else
- _base_all_release := all_release_configs-$(TARGET_PRODUCT)
- $(call dist-for-goals,droid,\
- $(_flags_dir)/$(_base_all_release).pb:build_flags/all_release_configs.pb \
- $(_flags_dir)/$(_base_all_release).textproto:build_flags/all_release_configs.textproto \
- $(_flags_dir)/$(_base_all_release).json:build_flags/all_release_configs.json \
- $(_flags_dir)/inheritance_graph-$(TARGET_PRODUCT).dot:build_flags/inheritance_graph-$(TARGET_PRODUCT).dot \
- )
-# These are always created, add an empty rule for them to keep ninja happy.
-$(_flags_dir)/inheritance_graph-$(TARGET_PRODUCT).dot:
- : created by $(OUT_DIR)/release-config
-$(_flags_dir)/$(_base_all_release).pb $(_flags_dir)/$(_base_all_release).textproto $(_flags_dir)/$(_base_all_release).json:
- : created by $(OUT_DIR)/release-config
- _base_all_release :=
endif
_flags_dir:=
_flags_file:=
diff --git a/core/soong_config.mk b/core/soong_config.mk
index dcd654d..c3cbaf3 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -485,6 +485,10 @@
$(call add_json_str, ProductVirtualAbCompressionFactor, $(PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR))
$(call add_json_str, ProductVirtualAbCowVersion, $(PRODUCT_VIRTUAL_AB_COW_VERSION))
$(call add_json_bool, AbOtaUpdater, $(filter true,$(AB_OTA_UPDATER)))
+ $(call add_json_list, AbOtaPartitions, $(AB_OTA_PARTITIONS))
+ $(call add_json_list, AbOtaKeys, $(PRODUCT_OTA_PUBLIC_KEYS))
+ $(call add_json_list, AbOtaPostInstallConfig, $(AB_OTA_POSTINSTALL_CONFIG))
+ $(call add_json_bool, BoardSuperImageInUpdatePackage, $(filter true,$(BOARD_SUPER_IMAGE_IN_UPDATE_PACKAGE)))
# Avb (android verified boot) stuff
$(call add_json_bool, BoardAvbEnable, $(filter true,$(BOARD_AVB_ENABLE)))
@@ -563,6 +567,11 @@
$(call add_json_str, ProductQuotaProjid, $(PRODUCT_QUOTA_PROJID))
$(call add_json_str, ProductFsCompression, $(PRODUCT_FS_COMPRESSION))
+ $(call add_json_str, ReleaseToolsExtensionDir, $(firstword $(TARGET_RELEASETOOLS_EXTENSIONS) $($(TARGET_DEVICE_DIR)/../common)))
+
+ # Fastboot
+ $(call add_json_str, BoardFastbootInfoFile, $(TARGET_BOARD_FASTBOOT_INFO_FILE))
+
$(call end_json_map)
# For converting vintf_data
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
index d9f6150..1321c69 100644
--- a/core/tasks/cts.mk
+++ b/core/tasks/cts.mk
@@ -98,7 +98,7 @@
api_map_out := $(HOST_OUT)/cts-api-map
cts_jar_files := $(api_map_out)/cts_jar_files.txt
-cts_interactive_jar_files := $(api_map_out)/cts_interactive_jar_files.txt
+cts_v_host_jar_files := $(api_map_out)/cts_v_host_jar_files.txt
cts_all_jar_files := $(api_map_out)/cts_all_jar_files.txt
$(cts_jar_files): PRIVATE_API_MAP_FILES := $(sort $(COMPATIBILITY.cts.API_MAP_FILES))
@@ -106,14 +106,14 @@
mkdir -p $(dir $@)
echo $(PRIVATE_API_MAP_FILES) > $@
-$(cts_interactive_jar_files): PRIVATE_API_MAP_FILES := $(sort $(COMPATIBILITY.cts-interactive.API_MAP_FILES))
-$(cts_interactive_jar_files): $(SOONG_ANDROID_CTS_VERIFIER_APP_LIST)
+$(cts_v_host_jar_files): PRIVATE_API_MAP_FILES := $(sort $(COMPATIBILITY.cts-v-host.API_MAP_FILES))
+$(cts_v_host_jar_files): $(SOONG_ANDROID_CTS_VERIFIER_APP_LIST)
mkdir -p $(dir $@)
cp $< $@
echo $(PRIVATE_API_MAP_FILES) >> $@
$(cts_all_jar_files): PRIVATE_API_MAP_FILES := $(sort $(COMPATIBILITY.cts.API_MAP_FILES) \
- $(COMPATIBILITY.cts-interactive.API_MAP_FILES))
+ $(COMPATIBILITY.cts-v-host.API_MAP_FILES))
$(cts_all_jar_files): $(SOONG_ANDROID_CTS_VERIFIER_APP_LIST)
mkdir -p $(dir $@)
cp $< $@
@@ -129,6 +129,13 @@
$(hide) $(ACP) $< $@
system_api_xml_description := $(TARGET_OUT_COMMON_INTERMEDIATES)/system-api.xml
+module_lib_api_xml_description := $(TARGET_OUT_COMMON_INTERMEDIATES)/module-lib-api.xml
+system_service_api_description := $(TARGET_OUT_COMMON_INTERMEDIATES)/system-server-api.xml
+
+combined_api_xml_description := $(api_xml_description) \
+ $(system_api_xml_description) \
+ $(module_lib_api_xml_description) \
+ $(system_service_api_description)
cts-test-coverage-report := $(coverage_out)/test-coverage.html
cts-system-api-coverage-report := $(coverage_out)/system-api-coverage.html
@@ -140,14 +147,15 @@
cts_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(api_xml_description) $(napi_xml_description)
cts_system_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(system_api_xml_description)
-cts-system-api-map-xml-report := $(api_map_out)/cts-system-api-map.xml
-cts-interactive-system-api-map-xml-report := $(api_map_out)/cts-interactive-system-api-map.xml
-cts-combined-system-api-map-xml-report := $(api_map_out)/cts-combined-system-api-map.xml
-cts-combined-system-api-map-html-report := $(api_map_out)/cts-combined-system-api-map.html
+cts-api-map-xml-report := $(api_map_out)/cts-api-map.xml
+cts-v-host-api-map-xml-report := $(api_map_out)/cts-v-host-api-map.xml
+cts-combined-api-map-xml-report := $(api_map_out)/cts-combined-api-map.xml
+cts-combined-api-map-html-report := $(api_map_out)/cts-combined-api-map.html
+cts-combined-api-inherit-xml-report := $(api_map_out)/cts-combined-api-inherit.xml
-cts_system_api_map_dependencies := $(cts_api_map_exe) $(system_api_xml_description) $(cts_jar_files)
-cts_interactive_system_api_map_dependencies := $(cts_api_map_exe) $(system_api_xml_description) $(cts_interactive_jar_files)
-cts_combined_system_api_map_dependencies := $(cts_api_map_exe) $(system_api_xml_description) $(cts_all_jar_files)
+cts_api_map_dependencies := $(cts_api_map_exe) $(combined_api_xml_description) $(cts_jar_files)
+cts_v_host_api_map_dependencies := $(cts_api_map_exe) $(combined_api_xml_description) $(cts_v_host_jar_files)
+cts_combined_api_map_dependencies := $(cts_api_map_exe) $(combined_api_xml_description) $(cts_all_jar_files)
android_cts_zip := $(HOST_OUT)/cts/android-cts.zip
cts_verifier_apk := $(call intermediates-dir-for,APPS,CtsVerifier)/package.apk
@@ -227,42 +235,52 @@
.PHONY: cts-coverage-report-all cts-api-coverage
cts-coverage-report-all: cts-test-coverage cts-verifier-coverage cts-combined-coverage cts-combined-xml-coverage
-$(cts-system-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
-$(cts-system-api-map-xml-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
-$(cts-system-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_jar_files)
-$(cts-system-api-map-xml-report) : $(android_cts_zip) $(cts_system_api_map_dependencies) | $(ACP)
- $(call generate-api-map-report-cts,"CTS System API MAP Report - XML",\
+$(cts-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
+$(cts-api-map-xml-report): PRIVATE_API_XML_DESC := $(combined_api_xml_description)
+$(cts-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_jar_files)
+$(cts-api-map-xml-report) : $(android_cts_zip) $(cts_api_map_dependencies) | $(ACP)
+ $(call generate-api-map-report-cts,"CTS API MAP Report - XML",\
$(PRIVATE_JAR_FILES),xml)
-$(cts-interactive-system-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
-$(cts-interactive-system-api-map-xml-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
-$(cts-interactive-system-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_interactive_jar_files)
-$(cts-interactive-system-api-map-xml-report) : $(verifier_zip) $(cts_interactive_system_api_map_dependencies) | $(ACP)
- $(call generate-api-map-report-cts,"CTS Interactive System API MAP Report - XML",\
+$(cts-v-host-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
+$(cts-v-host-api-map-xml-report): PRIVATE_API_XML_DESC := $(combined_api_xml_description)
+$(cts-v-host-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_v_host_jar_files)
+$(cts-v-host-api-map-xml-report) : $(verifier_zip) $(cts_v_host_api_map_dependencies) | $(ACP)
+ $(call generate-api-map-report-cts,"CTS-V-HOST API MAP Report - XML",\
$(PRIVATE_JAR_FILES),xml)
-$(cts-combined-system-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
-$(cts-combined-system-api-map-xml-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
-$(cts-combined-system-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_all_jar_files)
-$(cts-combined-system-api-map-xml-report) : $(verifier_zip) $(android_cts_zip) $(cts_combined_system_api_map_dependencies) | $(ACP)
- $(call generate-api-map-report-cts,"CTS Combined System API MAP Report - XML",\
+$(cts-combined-api-map-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
+$(cts-combined-api-map-xml-report): PRIVATE_API_XML_DESC := $(combined_api_xml_description)
+$(cts-combined-api-map-xml-report): PRIVATE_JAR_FILES := $(cts_all_jar_files)
+$(cts-combined-api-map-xml-report) : $(verifier_zip) $(android_cts_zip) $(cts_combined_api_map_dependencies) | $(ACP)
+ $(call generate-api-map-report-cts,"CTS Combined API MAP Report - XML",\
$(PRIVATE_JAR_FILES),xml)
-$(cts-combined-system-api-map-html-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
-$(cts-combined-system-api-map-html-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
-$(cts-combined-system-api-map-html-report): PRIVATE_JAR_FILES := $(cts_all_jar_files)
-$(cts-combined-system-api-map-html-report) : $(verifier_zip) $(android_cts_zip) $(cts_combined_system_api_map_dependencies) | $(ACP)
- $(call generate-api-map-report-cts,"CTS Combined System API MAP Report - HTML",\
+$(cts-combined-api-map-html-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
+$(cts-combined-api-map-html-report): PRIVATE_API_XML_DESC := $(combined_api_xml_description)
+$(cts-combined-api-map-html-report): PRIVATE_JAR_FILES := $(cts_all_jar_files)
+$(cts-combined-api-map-html-report) : $(verifier_zip) $(android_cts_zip) $(cts_combined_api_map_dependencies) | $(ACP)
+ $(call generate-api-map-report-cts,"CTS Combined API MAP Report - HTML",\
$(PRIVATE_JAR_FILES),html)
-.PHONY: cts-system-api-map-xml
-cts-system-api-map-xml : $(cts-system-api-map-xml-report)
+$(cts-combined-api-inherit-xml-report): PRIVATE_CTS_API_MAP_EXE := $(cts_api_map_exe)
+$(cts-combined-api-inherit-xml-report): PRIVATE_API_XML_DESC := $(combined_api_xml_description)
+$(cts-combined-api-inherit-xml-report): PRIVATE_JAR_FILES := $(cts_all_jar_files)
+$(cts-combined-api-inherit-xml-report) : $(verifier_zip) $(android_cts_zip) $(cts_combined_api_map_dependencies) | $(ACP)
+ $(call generate-api-inherit-report-cts,"CTS Combined API Inherit Report - XML",\
+ $(PRIVATE_JAR_FILES),xml)
-.PHONY: cts-interactive-system-api-map-xml
-cts-interactive-system-api-map-xml: $(cts-interactive-system-api-map-xml-report)
+.PHONY: cts-api-map-xml
+cts-api-map-xml : $(cts-api-map-xml-report)
-.PHONY: cts-combined-system-api-map-xml
-cts-combined-system-api-map-xml : $(cts-combined-system-api-map-xml-report)
+.PHONY: cts-v-host-api-map-xml
+cts-v-host-api-map-xml: $(cts-v-host-api-map-xml-report)
+
+.PHONY: cts-combined-api-map-xml
+cts-combined-api-map-xml : $(cts-combined-api-map-xml-report)
+
+.PHONY: cts-combined-api-inherit-xml
+cts-combined-api-inherit-xml : $(cts-combined-api-inherit-xml-report)
.PHONY: cts-api-map-all
@@ -282,13 +300,15 @@
ALL_TARGETS.$(cts-combined-xml-coverage-report).META_LIC:=$(module_license_metadata)
# Put the test api map report in the dist dir if "cts-api-map-all" is among the build goals.
-$(call dist-for-goals, cts-api-map-all, $(cts-combined-system-api-map-xml-report):cts-api-map-report.xml)
-$(call dist-for-goals, cts-api-map-all, $(cts-combined-system-api-map-html-report):cts-api-map-report.html)
+$(call dist-for-goals, cts-api-map-all, $(cts-combined-api-map-xml-report):cts-api-map-report.xml)
+$(call dist-for-goals, cts-api-map-all, $(cts-combined-api-map-html-report):cts-api-map-report.html)
+$(call dist-for-goals, cts-api-map-all, $(cts-combined-api-inherit-xml-report):cts-api-inherit-report.xml)
-ALL_TARGETS.$(cts-system-api-map-xml-report).META_LIC:=$(module_license_metadata)
-ALL_TARGETS.$(cts-interactive-system-api-map-xml-report).META_LIC:=$(module_license_metadata)
-ALL_TARGETS.$(cts-combined-system-api-map-xml-report).META_LIC:=$(module_license_metadata)
-ALL_TARGETS.$(cts-combined-system-api-map-html-report).META_LIC:=$(module_license_metadata)
+ALL_TARGETS.$(cts-api-map-xml-report).META_LIC:=$(module_license_metadata)
+ALL_TARGETS.$(cts-v-host-api-map-xml-report).META_LIC:=$(module_license_metadata)
+ALL_TARGETS.$(cts-combined-api-map-xml-report).META_LIC:=$(module_license_metadata)
+ALL_TARGETS.$(cts-combined-api-map-html-report).META_LIC:=$(module_license_metadata)
+ALL_TARGETS.$(cts-combined-api-map-inherit-report).META_LIC:=$(module_license_metadata)
# Arguments;
# 1 - Name of the report printed out on the screen
@@ -306,29 +326,42 @@
# 3 - Format of the report
define generate-api-map-report-cts
$(hide) mkdir -p $(dir $@)
- $(hide) $(PRIVATE_CTS_API_MAP_EXE) -j 8 -a $(PRIVATE_API_XML_DESC) -i $(2) -f $(3) -o $@
+ $(hide) $(PRIVATE_CTS_API_MAP_EXE) -j 8 -m api_map -m xts_annotation -a $(shell echo "$(PRIVATE_API_XML_DESC)" | tr ' ' ',') -i $(2) -f $(3) -o $@
+ @ echo $(1): file://$$(cd $(dir $@); pwd)/$(notdir $@)
+endef
+
+
+# Arguments;
+# 1 - Name of the report printed out on the screen
+# 2 - A file containing list of files that to be analyzed
+# 3 - Format of the report
+define generate-api-inherit-report-cts
+ $(hide) mkdir -p $(dir $@)
+ $(hide) $(PRIVATE_CTS_API_MAP_EXE) -j 8 -m xts_api_inherit -a $(shell echo "$(PRIVATE_API_XML_DESC)" | tr ' ' ',') -i $(2) -f $(3) -o $@
@ echo $(1): file://$$(cd $(dir $@); pwd)/$(notdir $@)
endef
# Reset temp vars
cts_api_coverage_dependencies :=
cts_system_api_coverage_dependencies :=
-cts_system_api_map_dependencies :=
-cts_interactive_system_api_map_dependencies :=
-cts_combined_system_api_map_dependencies :=
+cts_api_map_dependencies :=
+cts_v_host_api_map_dependencies :=
+cts_combined_api_map_dependencies :=
cts-combined-coverage-report :=
cts-combined-xml-coverage-report :=
cts-verifier-coverage-report :=
cts-test-coverage-report :=
cts-system-api-coverage-report :=
cts-system-api-xml-coverage-report :=
-cts-system-api-map-xml-report :=
-cts-interactive-system-api-map-xml-report :=
-cts-combined-system-api-map-xml-report :=
-cts-combined-system-api-map-html-report :=
+cts-api-map-xml-report :=
+cts-v-host-api-map-xml-report :=
+cts-combined-api-map-xml-report :=
+cts-combined-api-map-html-report :=
+cts-combined-api-map-inherit-report :=
api_xml_description :=
api_text_description :=
system_api_xml_description :=
+combined_api_xml_description :=
napi_xml_description :=
napi_text_description :=
coverage_out :=
diff --git a/core/tasks/device-tests.mk b/core/tasks/device-tests.mk
index 6164c2e..062ac23 100644
--- a/core/tasks/device-tests.mk
+++ b/core/tasks/device-tests.mk
@@ -14,7 +14,6 @@
.PHONY: device-tests
-.PHONY: device-tests-host-shared-libs
device-tests-zip := $(PRODUCT_OUT)/device-tests.zip
# Create an artifact to include a list of test config files in device-tests.
@@ -22,7 +21,6 @@
# Create an artifact to include all test config files in device-tests.
device-tests-configs-zip := $(PRODUCT_OUT)/device-tests_configs.zip
my_host_shared_lib_for_device_tests := $(call copy-many-files,$(COMPATIBILITY.device-tests.HOST_SHARED_LIBRARY.FILES))
-device_tests_host_shared_libs_zip := $(PRODUCT_OUT)/device-tests_host-shared-libs.zip
$(device-tests-zip) : .KATI_IMPLICIT_OUTPUTS := $(device-tests-list-zip) $(device-tests-configs-zip)
$(device-tests-zip) : PRIVATE_device_tests_list := $(PRODUCT_OUT)/device-tests_list
@@ -47,22 +45,9 @@
rm -f $@.list $@-host.list $@-target.list $@-host-test-configs.list $@-target-test-configs.list \
$(PRIVATE_device_tests_list)
-$(device_tests_host_shared_libs_zip) : PRIVATE_device_host_shared_libs_zip := $(device_tests_host_shared_libs_zip)
-$(device_tests_host_shared_libs_zip) : PRIVATE_HOST_SHARED_LIBS := $(my_host_shared_lib_for_device_tests)
-$(device_tests_host_shared_libs_zip) : $(my_host_shared_lib_for_device_tests) $(SOONG_ZIP)
- rm -f $@-shared-libs.list
- $(hide) for shared_lib in $(PRIVATE_HOST_SHARED_LIBS); do \
- echo $$shared_lib >> $@-shared-libs.list; \
- done
- grep $(HOST_OUT_TESTCASES) $@-shared-libs.list > $@-host-shared-libs.list || true
- $(SOONG_ZIP) -d -o $(PRIVATE_device_host_shared_libs_zip) \
- -P host -C $(HOST_OUT) -l $@-host-shared-libs.list
-
device-tests: $(device-tests-zip)
-device-tests-host-shared-libs: $(device_tests_host_shared_libs_zip)
-$(call dist-for-goals, device-tests, $(device-tests-zip) $(device-tests-list-zip) $(device-tests-configs-zip) $(device_tests_host_shared_libs_zip))
-$(call dist-for-goals, device-tests-host-shared-libs, $(device_tests_host_shared_libs_zip))
+$(call dist-for-goals, device-tests, $(device-tests-zip) $(device-tests-list-zip) $(device-tests-configs-zip))
$(call declare-1p-container,$(device-tests-zip),)
$(call declare-container-license-deps,$(device-tests-zip),$(COMPATIBILITY.device-tests.FILES) $(my_host_shared_lib_for_device_tests),$(PRODUCT_OUT)/:/)
diff --git a/core/tasks/mke2fs-dist.mk b/core/tasks/mke2fs-dist.mk
deleted file mode 100644
index 3540c1f..0000000
--- a/core/tasks/mke2fs-dist.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2024 Google Inc.
-#
-# 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.
-
-# TODO: After Soong's recovery partition variation can be set to selectable
-# and the meta_lic file duplication issue is resolved, move it to the
-# dist section of the corresponding module's Android.bp.
-my_dist_files := $(HOST_OUT_EXECUTABLES)/mke2fs
-my_dist_files += $(HOST_OUT_EXECUTABLES)/make_f2fs
-my_dist_files += $(HOST_OUT_EXECUTABLES)/make_f2fs_casefold
-$(call dist-for-goals,dist_files sdk,$(my_dist_files))
-my_dist_files :=
diff --git a/core/tasks/test_mapping.mk b/core/tasks/test_mapping.mk
deleted file mode 100644
index eb2a585..0000000
--- a/core/tasks/test_mapping.mk
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (C) 2017 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.
-
-# Create an artifact to include TEST_MAPPING files in source tree. Also include
-# a file (out/disabled-presubmit-tests) containing the tests that should be
-# skipped in presubmit check.
-
-.PHONY: test_mapping
-
-intermediates := $(call intermediates-dir-for,PACKAGING,test_mapping)
-test_mappings_zip := $(intermediates)/test_mappings.zip
-test_mapping_list := $(OUT_DIR)/.module_paths/TEST_MAPPING.list
-$(test_mappings_zip) : PRIVATE_all_disabled_presubmit_tests := $(ALL_DISABLED_PRESUBMIT_TESTS)
-$(test_mappings_zip) : PRIVATE_test_mapping_list := $(test_mapping_list)
-
-$(test_mappings_zip) : .KATI_DEPFILE := $(test_mappings_zip).d
-$(test_mappings_zip) : $(test_mapping_list) $(SOONG_ZIP)
- @echo "Building artifact to include TEST_MAPPING files and tests to skip in presubmit check."
- rm -rf $@ $(dir $@)/disabled-presubmit-tests
- echo $(sort $(PRIVATE_all_disabled_presubmit_tests)) | tr " " "\n" > $(dir $@)/disabled-presubmit-tests
- $(SOONG_ZIP) -o $@ -C . -l $(PRIVATE_test_mapping_list) -C $(dir $@) -f $(dir $@)/disabled-presubmit-tests
- echo "$@ : " $$(cat $(PRIVATE_test_mapping_list)) > $@.d
- rm -f $(dir $@)/disabled-presubmit-tests
-
-test_mapping : $(test_mappings_zip)
-
-$(call dist-for-goals, dist_files test_mapping,$(test_mappings_zip))
-
-$(call declare-1p-target,$(test_mappings_zip),)
diff --git a/core/tasks/tradefed-tests-list.mk b/core/tasks/tradefed-tests-list.mk
index 47c360d..e437f89 100644
--- a/core/tasks/tradefed-tests-list.mk
+++ b/core/tasks/tradefed-tests-list.mk
@@ -18,11 +18,19 @@
COMPATIBILITY.tradefed_tests_dir := \
$(COMPATIBILITY.tradefed_tests_dir) \
tools/tradefederation/core/res/config \
- tools/tradefederation/core/javatests/res/config
+ tools/tradefederation/core/javatests/res/config \
+ vendor/google_tradefederation/contrib/res/config \
+ vendor/google_tradefederation/core/res/config \
+ vendor/google_tradefederation/core/javatests/res/config \
+ vendor/google_tradefederation/core/prod_tests/res/config
tradefed_tests :=
$(foreach dir, $(COMPATIBILITY.tradefed_tests_dir), \
- $(eval tradefed_tests += $(shell find $(dir) -type f -name "*.xml")))
+ $(if $(wildcard $(dir)/*), \
+ $(eval tradefed_tests += $(shell find $(dir) -type f -name "*.xml")) \
+ ) \
+)
+
tradefed_tests_list_intermediates := $(call intermediates-dir-for,PACKAGING,tradefed_tests_list,HOST,COMMON)
tradefed_tests_list_zip := $(tradefed_tests_list_intermediates)/tradefed-tests_list.zip
all_tests :=
diff --git a/envsetup.sh b/envsetup.sh
index 554a220..c040311 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -438,68 +438,6 @@
echo
}
-function lunch()
-{
- local answer
- setup_cog_env_if_needed
-
- if [[ $# -gt 1 ]]; then
- echo "usage: lunch [target]" >&2
- return 1
- fi
-
- local used_lunch_menu=0
-
- if [ "$1" ]; then
- answer=$1
- else
- print_lunch_menu
- echo "Which would you like? [aosp_cf_x86_64_phone-trunk_staging-eng]"
- echo -n "Pick from common choices above (e.g. 13) or specify your own (e.g. aosp_barbet-trunk_staging-eng): "
- read answer
- used_lunch_menu=1
- fi
-
- local selection=
-
- if [ -z "$answer" ]
- then
- selection=aosp_cf_x86_64_phone-trunk_staging-eng
- elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
- then
- local choices=($(TARGET_BUILD_APPS= TARGET_PRODUCT= TARGET_RELEASE= TARGET_BUILD_VARIANT= _get_build_var_cached COMMON_LUNCH_CHOICES 2>/dev/null))
- if [ $answer -le ${#choices[@]} ]
- then
- # array in zsh starts from 1 instead of 0.
- if [ -n "$ZSH_VERSION" ]
- then
- selection=${choices[$(($answer))]}
- else
- selection=${choices[$(($answer-1))]}
- fi
- fi
- else
- selection=$answer
- fi
-
- export TARGET_BUILD_APPS=
-
- # This must be <product>-<release>-<variant>
- local product release variant
- # Split string on the '-' character.
- IFS="-" read -r product release variant <<< "$selection"
-
- if [[ -z "$product" ]] || [[ -z "$release" ]] || [[ -z "$variant" ]]
- then
- echo
- echo "Invalid lunch combo: $selection"
- echo "Valid combos must be of the form <product>-<release>-<variant>"
- return 1
- fi
-
- _lunch_meat $product $release $variant
-}
-
function _lunch_meat()
{
local product=$1
@@ -582,13 +520,13 @@
echo "Note that the previous interactive menu and list of hard-coded"
echo "list of curated targets has been removed. If you would like the"
echo "list of products, release configs for a particular product, or"
- echo "variants, run list_products, list_release_configs, list_variants"
+ echo "variants, run list_products list_releases or list_variants"
echo "respectively."
echo
) 1>&2
}
-function lunch2()
+function lunch()
{
if [[ $# -eq 1 && $1 = "--help" ]]; then
_lunch_usage
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index e2d5fb4..1a05549 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -23,14 +23,14 @@
TARGET_2ND_CPU_ABI := armeabi-v7a
TARGET_2ND_CPU_ABI2 := armeabi
-ifneq ($(TARGET_BUILD_APPS)$(filter cts sdk,$(MAKECMDGOALS)),)
+ifneq ($(TARGET_BUILD_APPS)$(filter sdk,$(MAKECMDGOALS)),)
# DO NOT USE
# DO NOT USE
#
# This architecture / CPU variant must NOT be used for any 64 bit
# platform builds. It is the lowest common denominator required
# to build an unbundled application or cts for all supported 32 and 64 bit
-# platforms.
+# platforms. It now recommended to use generic_arm64_plus_armv7 to achieve this.
#
# If you're building a 64 bit platform (and not an application) the
# ARM-v8 specification allows you to assume all the features available in an
@@ -66,6 +66,8 @@
BOARD_ROOT_EXTRA_SYMLINKS += /vendor/lib/dsp:/dsp
BOARD_ROOT_EXTRA_SYMLINKS += /mnt/vendor/persist:/persist
BOARD_ROOT_EXTRA_SYMLINKS += /vendor/firmware_mnt:/firmware
+# for Android.bp
+TARGET_ADD_ROOT_EXTRA_VENDOR_SYMLINKS := true
# TODO(b/36764215): remove this setting when the generic system image
# no longer has QCOM-specific directories under /.
diff --git a/target/board/generic_arm64_plus_armv7/BoardConfig.mk b/target/board/generic_arm64_plus_armv7/BoardConfig.mk
new file mode 100644
index 0000000..2dca04f
--- /dev/null
+++ b/target/board/generic_arm64_plus_armv7/BoardConfig.mk
@@ -0,0 +1,55 @@
+# Copyright (C) 2025 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.
+#
+
+# arm64 emulator specific definitions
+TARGET_ARCH := arm64
+TARGET_ARCH_VARIANT := armv8-a
+TARGET_CPU_VARIANT := generic
+TARGET_CPU_ABI := arm64-v8a
+
+TARGET_2ND_ARCH := arm
+TARGET_2ND_CPU_ABI := armeabi-v7a
+TARGET_2ND_CPU_ABI2 := armeabi
+
+# DO NOT USE
+# DO NOT USE
+#
+# This architecture / CPU variant must NOT be used for any 64 bit
+# platform builds. It is the lowest common denominator required
+# to build an unbundled application or cts for all supported 32 and 64 bit
+# platforms.
+#
+# If you're building a 64 bit platform (and not an application) the
+# ARM-v8 specification allows you to assume all the features available in an
+# armv7-a-neon CPU. You should set the following as 2nd arch/cpu variant:
+#
+# TARGET_2ND_ARCH_VARIANT := armv8-a
+# TARGET_2ND_CPU_VARIANT := generic
+#
+# DO NOT USE
+# DO NOT USE
+TARGET_2ND_ARCH_VARIANT := armv7-a-neon
+# DO NOT USE
+# DO NOT USE
+TARGET_2ND_CPU_VARIANT := generic
+# DO NOT USE
+# DO NOT USE
+
+# Include 64-bit mediaserver to support 64-bit only devices
+TARGET_DYNAMIC_64_32_MEDIASERVER := true
+# Include 64-bit drmserver to support 64-bit only devices
+TARGET_DYNAMIC_64_32_DRMSERVER := true
+
+include build/make/target/board/BoardConfigGsiCommon.mk
diff --git a/target/board/generic_arm64_plus_armv7/README.txt b/target/board/generic_arm64_plus_armv7/README.txt
new file mode 100644
index 0000000..284bdc2
--- /dev/null
+++ b/target/board/generic_arm64_plus_armv7/README.txt
@@ -0,0 +1,7 @@
+The "generic_arm64_plus_armv7" product defines a non-hardware-specific arm64
+target with armv7 compatible arm32. It is used for building CTS and other
+test suites for which the 32-bit binaries may be run on older devices with
+armv7 CPUs.
+
+It is not a product "base class"; no other products inherit
+from it or use it in any way.
diff --git a/target/board/generic_arm64_plus_armv7/device.mk b/target/board/generic_arm64_plus_armv7/device.mk
new file mode 100644
index 0000000..a9586f3
--- /dev/null
+++ b/target/board/generic_arm64_plus_armv7/device.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (C) 2025 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.
+#
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index 07eb96d..5a7414e 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -36,6 +36,7 @@
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/aosp_arm64.mk \
$(LOCAL_DIR)/aosp_arm64_fullmte.mk \
+ $(LOCAL_DIR)/aosp_arm64_plus_armv7.mk \
$(LOCAL_DIR)/aosp_arm.mk \
$(LOCAL_DIR)/aosp_riscv64.mk \
$(LOCAL_DIR)/aosp_x86_64.mk \
@@ -48,6 +49,7 @@
$(LOCAL_DIR)/aosp_64bitonly_x86_64.mk \
$(LOCAL_DIR)/aosp_arm64.mk \
$(LOCAL_DIR)/aosp_arm64_fullmte.mk \
+ $(LOCAL_DIR)/aosp_arm64_plus_armv7.mk \
$(LOCAL_DIR)/aosp_arm.mk \
$(LOCAL_DIR)/aosp_riscv64.mk \
$(LOCAL_DIR)/aosp_x86_64.mk \
diff --git a/target/product/OWNERS b/target/product/OWNERS
index 48d3f2a..276c885 100644
--- a/target/product/OWNERS
+++ b/target/product/OWNERS
@@ -8,3 +8,6 @@
per-file go_defaults.mk = gkaiser@google.com, kushg@google.com, rajekumar@google.com
per-file go_defaults_512.mk = gkaiser@google.com, kushg@google.com, rajekumar@google.com
per-file go_defaults_common.mk = gkaiser@google.com, kushg@google.com, rajekumar@google.com
+
+# Translation
+per-file languages_default.mk = aapple@google.com
diff --git a/target/product/aosp_arm.mk b/target/product/aosp_arm.mk
index d9c362e..595c3db 100644
--- a/target/product/aosp_arm.mk
+++ b/target/product/aosp_arm.mk
@@ -60,8 +60,12 @@
MODULE_BUILD_FROM_SOURCE ?= true
$(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_release.mk)
-endif
+PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE := aosp_system_image
+USE_SOONG_DEFINED_SYSTEM_IMAGE := true
+PRODUCT_USE_SOONG_NOTICE_XML := true
+
+endif
PRODUCT_NAME := aosp_arm
PRODUCT_DEVICE := generic
diff --git a/target/product/aosp_arm64.mk b/target/product/aosp_arm64.mk
index 7a9325d..cd3de51 100644
--- a/target/product/aosp_arm64.mk
+++ b/target/product/aosp_arm64.mk
@@ -66,8 +66,12 @@
MODULE_BUILD_FROM_SOURCE ?= true
$(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_release.mk)
-endif
+PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE := aosp_system_image
+USE_SOONG_DEFINED_SYSTEM_IMAGE := true
+PRODUCT_USE_SOONG_NOTICE_XML := true
+
+endif
PRODUCT_NAME := aosp_arm64
PRODUCT_DEVICE := generic_arm64
diff --git a/target/product/aosp_arm64_plus_armv7.mk b/target/product/aosp_arm64_plus_armv7.mk
new file mode 100644
index 0000000..7322629
--- /dev/null
+++ b/target/product/aosp_arm64_plus_armv7.mk
@@ -0,0 +1,64 @@
+#
+# Copyright (C) 2025 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.
+#
+
+# aosp_arm64_plus_armv7 is for building CTS and other test suites with
+# arm64 as the primary architecture and armv7 arm32 as the secondary
+# architecture.
+
+#
+# All components inherited here go to system image
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_system.mk)
+
+PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := relaxed
+
+#
+# All components inherited here go to system_ext image
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system_ext.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system_ext.mk)
+
+# pKVM
+$(call inherit-product-if-exists, packages/modules/Virtualization/apex/product_packages.mk)
+
+#
+# All components inherited here go to product image
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_product.mk)
+
+#
+# All components inherited here go to vendor or vendor_boot image
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_arm64/device.mk)
+AB_OTA_UPDATER := true
+AB_OTA_PARTITIONS ?= system
+
+#
+# Special settings for GSI releasing
+#
+# Build modules from source if this has not been pre-configured
+MODULE_BUILD_FROM_SOURCE ?= true
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_release.mk)
+
+
+PRODUCT_NAME := aosp_arm64_plus_armv7
+PRODUCT_DEVICE := generic_arm64_plus_armv7
+PRODUCT_BRAND := Android
+PRODUCT_MODEL := AOSP on ARM64 with ARMV7
+
+PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
diff --git a/target/product/aosp_x86.mk b/target/product/aosp_x86.mk
index c26a8bf..d14abc2 100644
--- a/target/product/aosp_x86.mk
+++ b/target/product/aosp_x86.mk
@@ -58,8 +58,12 @@
MODULE_BUILD_FROM_SOURCE ?= true
$(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_release.mk)
-endif
+PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE := aosp_system_image
+USE_SOONG_DEFINED_SYSTEM_IMAGE := true
+PRODUCT_USE_SOONG_NOTICE_XML := true
+
+endif
PRODUCT_NAME := aosp_x86
PRODUCT_DEVICE := generic_x86
diff --git a/target/product/aosp_x86_64.mk b/target/product/aosp_x86_64.mk
index 595940d..bd121e3 100644
--- a/target/product/aosp_x86_64.mk
+++ b/target/product/aosp_x86_64.mk
@@ -68,8 +68,12 @@
MODULE_BUILD_FROM_SOURCE ?= true
$(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_release.mk)
-endif
+PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE := aosp_system_image
+USE_SOONG_DEFINED_SYSTEM_IMAGE := true
+PRODUCT_USE_SOONG_NOTICE_XML := true
+
+endif
PRODUCT_NAME := aosp_x86_64
PRODUCT_DEVICE := generic_x86_64
diff --git a/target/product/generic/Android.bp b/target/product/generic/Android.bp
index 82b6e76..5bfff66 100644
--- a/target/product/generic/Android.bp
+++ b/target/product/generic/Android.bp
@@ -126,6 +126,23 @@
},
]
+extra_vendor_symlinks = [
+ // Some vendors still haven't cleaned up all device specific directories under root!
+ // TODO(b/111434759, b/111287060) SoC specific hacks
+ {
+ target: "/vendor/lib/dsp",
+ name: "dsp",
+ },
+ {
+ target: "/mnt/vendor/persist",
+ name: "persist",
+ },
+ {
+ target: "/vendor/firmware_mnt",
+ name: "firmware",
+ },
+]
+
filegroup {
name: "generic_system_sign_key",
srcs: [":avb_testkey_rsa4096"],
@@ -376,8 +393,8 @@
"charger",
] + select(release_flag("RELEASE_APPFUNCTION_SIDECAR"), {
true: [
- "com.android.extensions.appfunctions",
- "appfunctions.extension.xml",
+ "com.google.android.appfunctions.sidecar",
+ "appfunctions.sidecar.xml",
],
default: [],
}),
@@ -429,13 +446,40 @@
libs: [":framework-res{.export-package.apk}"],
}
-android_filesystem_defaults {
+soong_config_module_type {
+ name: "system_image_defaults",
+ module_type: "android_filesystem_defaults",
+ config_namespace: "ANDROID",
+ bool_variables: ["TARGET_ADD_ROOT_EXTRA_VENDOR_SYMLINKS"],
+ properties: ["symlinks"],
+}
+
+genrule {
+ name: "plat_and_vendor_file_contexts",
+ device_common_srcs: [
+ ":plat_file_contexts",
+ ":vendor_file_contexts",
+ ],
+ out: ["file_contexts"],
+ cmd: "cat $(in) > $(out)",
+}
+
+system_image_defaults {
name: "system_image_defaults",
partition_name: "system",
base_dir: "system",
+ stem: "system.img",
+ no_full_install: true,
dirs: generic_rootdirs,
- symlinks: generic_symlinks,
- file_contexts: ":plat_file_contexts",
+ soong_config_variables: {
+ TARGET_ADD_ROOT_EXTRA_VENDOR_SYMLINKS: {
+ symlinks: generic_symlinks + extra_vendor_symlinks,
+ conditions_default: {
+ symlinks: generic_symlinks,
+ },
+ },
+ },
+ file_contexts: ":plat_and_vendor_file_contexts",
linker_config: {
gen_linker_config: true,
linker_config_srcs: [":system_linker_config_json_file"],
@@ -467,6 +511,7 @@
avb_private_key: ":generic_system_sign_key",
avb_algorithm: "SHA256_RSA4096",
avb_hash_algorithm: "sha256",
+ rollback_index_location: 1,
deps: [
"abx",
@@ -707,6 +752,11 @@
"update_engine_client",
],
default: [],
+ }) + select(release_flag("RELEASE_UPROBESTATS_MODULE"), {
+ true: [],
+ default: [
+ "uprobestats", // base_system internal
+ ],
}),
multilib: {
common: {
@@ -830,11 +880,6 @@
default: [
"framework-connectivity-b", // base_system
],
- }) + select(release_flag("RELEASE_AVATAR_PICKER_APP"), {
- true: [
- "AvatarPicker", // generic_system (RELEASE_AVATAR_PICKER_APP)
- ],
- default: [],
}) + select(release_flag("RELEASE_UPROBESTATS_MODULE"), {
true: [
"com.android.uprobestats", // base_system (RELEASE_UPROBESTATS_MODULE)
@@ -854,12 +899,7 @@
"android.system.virtualizationservice-ndk",
"libgsi",
"servicemanager",
- ] + select(release_flag("RELEASE_UPROBESTATS_MODULE"), {
- true: [],
- default: [
- "uprobestats", // base_system internal
- ],
- }),
+ ],
},
both: {
deps: [
diff --git a/target/product/gsi/Android.bp b/target/product/gsi/Android.bp
index 97b3895..8c200a1 100644
--- a/target/product/gsi/Android.bp
+++ b/target/product/gsi/Android.bp
@@ -81,8 +81,8 @@
},
]
-android_system_image {
- name: "android_gsi",
+android_filesystem_defaults {
+ name: "android_gsi_defaults",
defaults: [
"system_image_defaults",
"system_ext_image_defaults",
@@ -105,11 +105,6 @@
// telephony packages
"CarrierConfig",
- // Install a copy of the debug policy to the system_ext partition, and allow
- // init-second-stage to load debug policy from system_ext.
- // This option is only meant to be set by compliance GSI targets.
- "system_ext_userdebug_plat_sepolicy.cil",
-
///////////////////////////////////////////
// gsi_release
///////////////////////////////////////////
@@ -154,9 +149,74 @@
deps: ["android.hidl.memory@1.0-impl"],
},
},
+ type: "ext4",
+}
+
+// system.img for gsi_{arch} targets
+android_system_image {
+ name: "android_gsi",
+ defaults: ["android_gsi_defaults"],
enabled: select(soong_config_variable("ANDROID", "PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT"), {
"true": true,
default: false,
}),
- type: "ext4",
+ deps: [
+ // Install a copy of the debug policy to the system_ext partition, and allow
+ // init-second-stage to load debug policy from system_ext.
+ // This option is only meant to be set by compliance GSI targets.
+ "system_ext_userdebug_plat_sepolicy.cil",
+ ],
+}
+
+// system.img for aosp_{arch} targets
+android_system_image {
+ name: "aosp_system_image",
+ defaults: ["android_gsi_defaults"],
+ deps: [
+ // handheld_system_ext
+ "AccessibilityMenu",
+ "WallpaperCropper",
+
+ // telephony_system_ext
+ "EmergencyInfo",
+
+ // handheld_product
+ "Calendar",
+ "Contacts",
+ "DeskClock",
+ "Gallery2",
+ "Music",
+ "preinstalled-packages-platform-handheld-product.xml",
+ "QuickSearchBox",
+ "SettingsIntelligence",
+ "frameworks-base-overlays",
+
+ // telephony_product
+ "ImsServiceEntitlement",
+ "preinstalled-packages-platform-telephony-product.xml",
+
+ // more AOSP packages
+ "initial-package-stopped-states-aosp.xml",
+ "messaging",
+ "PhotoTable",
+ "preinstalled-packages-platform-aosp-product.xml",
+ "ThemePicker",
+ ] + select(product_variable("debuggable"), {
+ true: ["frameworks-base-overlays-debug"],
+ default: [],
+ }),
+ enabled: select(soong_config_variable("gsi", "building_gsi"), {
+ true: true,
+ default: false,
+ }),
+ multilib: {
+ common: {
+ deps: select(release_flag("RELEASE_AVATAR_PICKER_APP"), {
+ true: [
+ "AvatarPicker", // handheld_system_ext (RELEASE_AVATAR_PICKER_APP)
+ ],
+ default: [],
+ }),
+ },
+ },
}
diff --git a/target/product/handheld_system.mk b/target/product/handheld_system.mk
index 6799066..2b055c7 100644
--- a/target/product/handheld_system.mk
+++ b/target/product/handheld_system.mk
@@ -34,7 +34,6 @@
PRODUCT_PACKAGES += \
android.software.window_magnification.prebuilt.xml \
- $(if $(RELEASE_AVATAR_PICKER_APP), AvatarPicker,) \
BasicDreams \
BlockedNumberProvider \
BluetoothMidiService \
diff --git a/target/product/handheld_system_ext.mk b/target/product/handheld_system_ext.mk
index 187b627..6d686c5 100644
--- a/target/product/handheld_system_ext.mk
+++ b/target/product/handheld_system_ext.mk
@@ -23,6 +23,7 @@
# /system_ext packages
PRODUCT_PACKAGES += \
AccessibilityMenu \
+ $(if $(RELEASE_AVATAR_PICKER_APP), AvatarPicker,) \
Launcher3QuickStep \
Provision \
Settings \
diff --git a/teams/Android.bp b/teams/Android.bp
index 7e0795f..8689267 100644
--- a/teams/Android.bp
+++ b/teams/Android.bp
@@ -931,7 +931,7 @@
}
team {
- name: "trendy_team_camerax",
+ name: "trendy_team_android_camera_innovation_team",
// go/trendy/manage/engineers/5272590669479936
trendy_team_id: "5272590669479936",
diff --git a/tools/Android.bp b/tools/Android.bp
index 243cb56..f1ff1c4 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -85,11 +85,6 @@
srcs: [
"list_files.py",
],
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
}
python_test_host {
@@ -109,11 +104,6 @@
python_binary_host {
name: "characteristics_rro_generator",
srcs: ["characteristics_rro_generator.py"],
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
}
python_binary_host {
diff --git a/tools/aconfig/Cargo.toml b/tools/aconfig/Cargo.toml
index bf5e1a9..a031b7f 100644
--- a/tools/aconfig/Cargo.toml
+++ b/tools/aconfig/Cargo.toml
@@ -8,7 +8,8 @@
"aconfig_storage_read_api",
"aconfig_storage_write_api",
"aflags",
- "printflags"
+ "printflags",
+ "convert_finalized_flags"
]
resolver = "2"
diff --git a/tools/aconfig/aconfig/Android.bp b/tools/aconfig/aconfig/Android.bp
index cce0ca9..7bdec58 100644
--- a/tools/aconfig/aconfig/Android.bp
+++ b/tools/aconfig/aconfig/Android.bp
@@ -7,7 +7,10 @@
edition: "2021",
clippy_lints: "android",
lints: "android",
- srcs: ["src/main.rs"],
+ srcs: [
+ "src/main.rs",
+ ":finalized_flags_record.json",
+ ],
rustlibs: [
"libaconfig_protos",
"libaconfig_storage_file",
@@ -18,6 +21,7 @@
"libserde",
"libserde_json",
"libtinytemplate",
+ "libconvert_finalized_flags",
],
}
diff --git a/tools/aconfig/aconfig/Cargo.toml b/tools/aconfig/aconfig/Cargo.toml
index abd3ee0..7e4bdf2 100644
--- a/tools/aconfig/aconfig/Cargo.toml
+++ b/tools/aconfig/aconfig/Cargo.toml
@@ -17,3 +17,11 @@
tinytemplate = "1.2.1"
aconfig_protos = { path = "../aconfig_protos" }
aconfig_storage_file = { path = "../aconfig_storage_file" }
+convert_finalized_flags = { path = "../convert_finalized_flags" }
+
+[build-dependencies]
+anyhow = "1.0.69"
+itertools = "0.10.5"
+serde = { version = "1.0.152", features = ["derive"] }
+serde_json = "1.0.93"
+convert_finalized_flags = { path = "../convert_finalized_flags" }
diff --git a/tools/aconfig/aconfig/build.rs b/tools/aconfig/aconfig/build.rs
new file mode 100644
index 0000000..8aaec3c
--- /dev/null
+++ b/tools/aconfig/aconfig/build.rs
@@ -0,0 +1,93 @@
+use anyhow::{anyhow, Result};
+use std::env;
+use std::fs;
+use std::fs::File;
+use std::io::Write;
+use std::path::{Path, PathBuf};
+
+use convert_finalized_flags::read_files_to_map_using_path;
+use convert_finalized_flags::FinalizedFlagMap;
+
+// This fn makes assumptions about the working directory which we should not rely
+// on for actual (Soong) builds. It is reasonable to assume that this is being
+// called from the aconfig directory as cargo is used for local development and
+// the cargo workspace for our project is build/make/tools/aconfig.
+// This is meant to get the list of finalized flag
+// files provided by the filegroup + "locations" in soong.
+// Cargo-only usage is asserted via implementation of
+// read_files_to_map_using_env, the only public cargo-only fn.
+fn read_files_to_map_using_env() -> Result<FinalizedFlagMap> {
+ let mut current_dir = std::env::current_dir()?;
+
+ // Path of aconfig from the top of tree.
+ let aconfig_path = PathBuf::from("build/make/tools/aconfig");
+
+ // Path of SDK files from the top of tree.
+ let sdk_dir_path = PathBuf::from("prebuilts/sdk");
+
+ // Iterate up the directory structure until we have the base aconfig dir.
+ while !current_dir.canonicalize()?.ends_with(&aconfig_path) {
+ if let Some(parent) = current_dir.parent() {
+ current_dir = parent.to_path_buf();
+ } else {
+ return Err(anyhow!("Cannot execute outside of aconfig."));
+ }
+ }
+
+ // Remove the aconfig path, leaving the top of the tree.
+ for _ in 0..aconfig_path.components().count() {
+ current_dir.pop();
+ }
+
+ // Get the absolute path of the sdk files.
+ current_dir.push(sdk_dir_path);
+
+ let mut flag_files = Vec::new();
+
+ // Search all sub-dirs in prebuilts/sdk for finalized-flags.txt files.
+ // The files are in prebuilts/sdk/<api level>/finalized-flags.txt.
+ let api_level_dirs = fs::read_dir(current_dir)?;
+ for api_level_dir in api_level_dirs {
+ if api_level_dir.is_err() {
+ eprintln!("Error opening directory: {}", api_level_dir.err().unwrap());
+ continue;
+ }
+
+ // Skip non-directories.
+ let api_level_dir_path = api_level_dir.unwrap().path();
+ if !api_level_dir_path.is_dir() {
+ continue;
+ }
+
+ // Some directories were created before trunk stable and don't have
+ // flags, or aren't api level directories at all.
+ let flag_file_path = api_level_dir_path.join("finalized-flags.txt");
+ if !flag_file_path.exists() {
+ continue;
+ }
+
+ if let Some(path) = flag_file_path.to_str() {
+ flag_files.push(path.to_string());
+ } else {
+ eprintln!("Error converting path to string: {:?}", flag_file_path);
+ }
+ }
+
+ read_files_to_map_using_path(flag_files)
+}
+
+fn main() {
+ let out_dir = env::var_os("OUT_DIR").unwrap();
+ let dest_path = Path::new(&out_dir).join("finalized_flags_record.json");
+
+ let finalized_flags_map: Result<FinalizedFlagMap> = read_files_to_map_using_env();
+ if finalized_flags_map.is_err() {
+ return;
+ }
+ let json_str = serde_json::to_string(&finalized_flags_map.unwrap()).unwrap();
+
+ let mut f = File::create(&dest_path).unwrap();
+ f.write_all(json_str.as_bytes()).unwrap();
+
+ //println!("cargo:rerun-if-changed=input.txt");
+}
diff --git a/tools/aconfig/aconfig/data/Android.bp b/tools/aconfig/aconfig/data/Android.bp
deleted file mode 100644
index 1b5eef0..0000000
--- a/tools/aconfig/aconfig/data/Android.bp
+++ /dev/null
@@ -1,14 +0,0 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-python_binary_host {
- name: "convert_finalized_flags_to_proto",
- srcs: ["convert_finalized_flags_to_proto.py"],
- libs: ["aconfig_internal_proto_python"],
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
-}
diff --git a/tools/aconfig/aconfig/data/convert_finalized_flags_to_proto.py b/tools/aconfig/aconfig/data/convert_finalized_flags_to_proto.py
deleted file mode 100644
index 15ff03c..0000000
--- a/tools/aconfig/aconfig/data/convert_finalized_flags_to_proto.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env python3
-#
-# 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.
-
-import collections
-import sys
-import os
-
-from io import TextIOWrapper
-from protos import aconfig_internal_pb2
-from typing import Dict, List, Set
-
-def extract_finalized_flags(flag_file: TextIOWrapper):
- finalized_flags_for_sdk = list()
-
- for line in f:
- flag_name = line.strip()
- if flag_name:
- finalized_flags_for_sdk.append(flag_name)
-
- return finalized_flags_for_sdk
-
-def remove_duplicate_flags(all_flags_with_duplicates: Dict[int, List]):
- result_flags = collections.defaultdict(set)
-
- for api_level in sorted(all_flags_with_duplicates.keys(), key=int):
- for flag in all_flags_with_duplicates[api_level]:
- if not any(flag in value_set for value_set in result_flags.values()):
- result_flags[api_level].add(flag)
-
- return result_flags
-
-def build_proto(all_flags: Set):
- finalized_flags = aconfig_internal_pb2.finalized_flags()
- for api_level, qualified_name_list in all_flags.items():
- for qualified_name in qualified_name_list:
- package_name, flag_name = qualified_name.rsplit('.', 1)
- finalized_flag = aconfig_internal_pb2.finalized_flag()
- finalized_flag.name = flag_name
- finalized_flag.package = package_name
- finalized_flag.min_sdk = api_level
- finalized_flags.finalized_flag.append(finalized_flag)
- return finalized_flags
-
-if __name__ == '__main__':
- if len(sys.argv) == 1:
- sys.exit('No prebuilts/sdk directory provided.')
- all_api_info_dir = sys.argv[1]
-
- all_flags_with_duplicates = {}
- for sdk_dir in os.listdir(all_api_info_dir):
- api_level = sdk_dir.rsplit('/', 1)[0].rstrip('0').rstrip('.')
-
- # No support for minor versions yet. This also removes non-numeric dirs.
- # Update once floats are acceptable.
- if not api_level.isdigit():
- continue
-
- flag_file_path = os.path.join(all_api_info_dir, sdk_dir, 'finalized-flags.txt')
- try:
- with open(flag_file_path, 'r') as f:
- finalized_flags_for_sdk = extract_finalized_flags(f)
- all_flags_with_duplicates[int(api_level)] = finalized_flags_for_sdk
- except FileNotFoundError:
- # Either this version is not finalized yet or looking at a
- # /prebuilts/sdk/version before finalized-flags.txt was introduced.
- continue
-
- all_flags = remove_duplicate_flags(all_flags_with_duplicates)
- finalized_flags = build_proto(all_flags)
- sys.stdout.buffer.write(finalized_flags.SerializeToString())
diff --git a/tools/aconfig/aconfig/src/codegen/cpp.rs b/tools/aconfig/aconfig/src/codegen/cpp.rs
index 30e1a89..b855d78 100644
--- a/tools/aconfig/aconfig/src/codegen/cpp.rs
+++ b/tools/aconfig/aconfig/src/codegen/cpp.rs
@@ -234,11 +234,11 @@
return provider_->disabled_rw_in_other_namespace();
}
-inline bool enabled_fixed_ro() {
+constexpr inline bool enabled_fixed_ro() {
return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
}
-inline bool enabled_fixed_ro_exported() {
+constexpr inline bool enabled_fixed_ro_exported() {
return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO_EXPORTED;
}
@@ -496,7 +496,7 @@
return false;
}
-inline bool enabled_fixed_ro() {
+constexpr inline bool enabled_fixed_ro() {
return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
}
@@ -1189,7 +1189,7 @@
extern std::unique_ptr<flag_provider_interface> provider_;
-inline bool disabled_fixed_ro() {
+constexpr inline bool disabled_fixed_ro() {
return COM_ANDROID_ACONFIG_TEST_DISABLED_FIXED_RO;
}
@@ -1197,7 +1197,7 @@
return false;
}
-inline bool enabled_fixed_ro() {
+constexpr inline bool enabled_fixed_ro() {
return COM_ANDROID_ACONFIG_TEST_ENABLED_FIXED_RO;
}
diff --git a/tools/aconfig/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index 8588a72..550ab5f 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -24,6 +24,7 @@
use crate::codegen::CodegenMode;
use crate::commands::{should_include_flag, OutputFile};
use aconfig_protos::{ProtoFlagPermission, ProtoFlagState, ProtoParsedFlag};
+use convert_finalized_flags::{FinalizedFlag, FinalizedFlagMap};
use std::collections::HashMap;
// Arguments to configure codegen for generate_java_code.
@@ -33,7 +34,8 @@
pub allow_instrumentation: bool,
pub package_fingerprint: u64,
pub new_exported: bool,
- pub check_api_level: bool,
+ pub single_exported_file: bool,
+ pub finalized_flags: FinalizedFlagMap,
}
pub fn generate_java_code<I>(
@@ -46,7 +48,7 @@
{
let flag_elements: Vec<FlagElement> = parsed_flags_iter
.map(|pf| {
- create_flag_element(package, &pf, config.flag_ids.clone(), config.check_api_level)
+ create_flag_element(package, &pf, config.flag_ids.clone(), &config.finalized_flags)
})
.collect();
let namespace_flags = gen_flags_by_namespace(&flag_elements);
@@ -71,8 +73,15 @@
is_platform_container,
package_fingerprint: format!("0x{:X}L", config.package_fingerprint),
new_exported: config.new_exported,
+ single_exported_file: config.single_exported_file,
};
let mut template = TinyTemplate::new();
+ if library_exported && config.single_exported_file {
+ template.add_template(
+ "ExportedFlags.java",
+ include_str!("../../templates/ExportedFlags.java.template"),
+ )?;
+ }
template.add_template("Flags.java", include_str!("../../templates/Flags.java.template"))?;
add_feature_flags_impl_template(&context, &mut template)?;
template.add_template(
@@ -89,18 +98,25 @@
)?;
let path: PathBuf = package.split('.').collect();
- [
+ let mut files = vec![
"Flags.java",
"FeatureFlags.java",
"FeatureFlagsImpl.java",
"CustomFeatureFlags.java",
"FakeFeatureFlagsImpl.java",
- ]
- .iter()
- .map(|file| {
- Ok(OutputFile { contents: template.render(file, &context)?.into(), path: path.join(file) })
- })
- .collect::<Result<Vec<OutputFile>>>()
+ ];
+ if library_exported && config.single_exported_file {
+ files.push("ExportedFlags.java");
+ }
+ files
+ .iter()
+ .map(|file| {
+ Ok(OutputFile {
+ contents: template.render(file, &context)?.into(),
+ path: path.join(file),
+ })
+ })
+ .collect::<Result<Vec<OutputFile>>>()
}
fn gen_flags_by_namespace(flags: &[FlagElement]) -> Vec<NamespaceFlags> {
@@ -138,6 +154,7 @@
pub is_platform_container: bool,
pub package_fingerprint: String,
pub new_exported: bool,
+ pub single_exported_file: bool,
}
#[derive(Serialize, Debug)]
@@ -166,7 +183,7 @@
package: &str,
pf: &ProtoParsedFlag,
flag_offsets: HashMap<String, u16>,
- check_api_level: bool,
+ finalized_flags: &FinalizedFlagMap,
) -> FlagElement {
let device_config_flag = codegen::create_device_config_ident(package, pf.name())
.expect("values checked at flag parse time");
@@ -188,6 +205,18 @@
}
};
+ // An empty map is provided if check_api_level is disabled.
+ let mut finalized_sdk_present: bool = false;
+ let mut finalized_sdk_value: i32 = 0;
+ if !finalized_flags.is_empty() {
+ let finalized_sdk = finalized_flags.get_finalized_level(&FinalizedFlag {
+ flag_name: pf.name().to_string(),
+ package_name: package.to_string(),
+ });
+ finalized_sdk_present = finalized_sdk.is_some();
+ finalized_sdk_value = finalized_sdk.map(|f| f.0).unwrap_or_default();
+ }
+
FlagElement {
container: pf.container().to_string(),
default_value: pf.state() == ProtoFlagState::ENABLED,
@@ -199,8 +228,8 @@
is_read_write: pf.permission() == ProtoFlagPermission::READ_WRITE,
method_name: format_java_method_name(pf.name()),
properties: format_property_name(pf.namespace()),
- finalized_sdk_present: check_api_level,
- finalized_sdk_value: i32::MAX, // TODO: b/378936061 - Read value from artifact.
+ finalized_sdk_present,
+ finalized_sdk_value,
}
}
@@ -259,7 +288,7 @@
(true, false, _) => {
template.add_template(
"FeatureFlagsImpl.java",
- include_str!("../../templates/FeatureFlagsImpl.java.template"),
+ include_str!("../../templates/FeatureFlagsImpl.deviceConfig.java.template"),
)?;
}
@@ -275,7 +304,7 @@
(false, _, false) => {
template.add_template(
"FeatureFlagsImpl.java",
- include_str!("../../templates/FeatureFlagsImpl.java.template"),
+ include_str!("../../templates/FeatureFlagsImpl.deviceConfig.java.template"),
)?;
}
};
@@ -284,6 +313,8 @@
#[cfg(test)]
mod tests {
+ use convert_finalized_flags::ApiLevel;
+
use super::*;
use crate::commands::assign_flag_ids;
use std::collections::HashMap;
@@ -592,7 +623,8 @@
allow_instrumentation: true,
package_fingerprint: 5801144784618221668,
new_exported: false,
- check_api_level: false,
+ single_exported_file: false,
+ finalized_flags: FinalizedFlagMap::new(),
};
let generated_files = generate_java_code(
crate::test::TEST_PACKAGE,
@@ -752,7 +784,8 @@
allow_instrumentation: true,
package_fingerprint: 5801144784618221668,
new_exported: false,
- check_api_level: false,
+ single_exported_file: false,
+ finalized_flags: FinalizedFlagMap::new(),
};
let generated_files = generate_java_code(
crate::test::TEST_PACKAGE,
@@ -763,6 +796,7 @@
let expect_flags_content = r#"
package com.android.aconfig.test;
+ import android.os.Build;
/** @hide */
public final class Flags {
/** @hide */
@@ -956,7 +990,8 @@
allow_instrumentation: true,
package_fingerprint: 5801144784618221668,
new_exported: true,
- check_api_level: false,
+ single_exported_file: false,
+ finalized_flags: FinalizedFlagMap::new(),
};
let generated_files = generate_java_code(
crate::test::TEST_PACKAGE,
@@ -967,6 +1002,7 @@
let expect_flags_content = r#"
package com.android.aconfig.test;
+ import android.os.Build;
/** @hide */
public final class Flags {
/** @hide */
@@ -1022,7 +1058,214 @@
} catch (LinkageError e) {
// for mainline module running on older devices.
// This should be replaces to version check, after the version bump.
+ Log.w(TAG, e.toString());
+ }
+ isCached = true;
+ }
+ @Override
+ public boolean disabledRwExported() {
+ if (!isCached) {
+ init();
+ }
+ return disabledRwExported;
+ }
+ @Override
+ public boolean enabledFixedRoExported() {
+ if (!isCached) {
+ init();
+ }
+ return enabledFixedRoExported;
+ }
+ @Override
+ public boolean enabledRoExported() {
+ if (!isCached) {
+ init();
+ }
+ return enabledRoExported;
+ }
+ }"#;
+
+ let expect_custom_feature_flags_content = r#"
+ package com.android.aconfig.test;
+
+ import java.util.Arrays;
+ import java.util.HashSet;
+ import java.util.List;
+ import java.util.Set;
+ import java.util.function.BiPredicate;
+ import java.util.function.Predicate;
+
+ /** @hide */
+ public class CustomFeatureFlags implements FeatureFlags {
+
+ private BiPredicate<String, Predicate<FeatureFlags>> mGetValueImpl;
+
+ public CustomFeatureFlags(BiPredicate<String, Predicate<FeatureFlags>> getValueImpl) {
+ mGetValueImpl = getValueImpl;
+ }
+
+ @Override
+ public boolean disabledRwExported() {
+ return getValue(Flags.FLAG_DISABLED_RW_EXPORTED,
+ FeatureFlags::disabledRwExported);
+ }
+ @Override
+ public boolean enabledFixedRoExported() {
+ return getValue(Flags.FLAG_ENABLED_FIXED_RO_EXPORTED,
+ FeatureFlags::enabledFixedRoExported);
+ }
+ @Override
+ public boolean enabledRoExported() {
+ return getValue(Flags.FLAG_ENABLED_RO_EXPORTED,
+ FeatureFlags::enabledRoExported);
+ }
+
+ protected boolean getValue(String flagName, Predicate<FeatureFlags> getter) {
+ return mGetValueImpl.test(flagName, getter);
+ }
+
+ public List<String> getFlagNames() {
+ return Arrays.asList(
+ Flags.FLAG_DISABLED_RW_EXPORTED,
+ Flags.FLAG_ENABLED_FIXED_RO_EXPORTED,
+ Flags.FLAG_ENABLED_RO_EXPORTED
+ );
+ }
+
+ private Set<String> mReadOnlyFlagsSet = new HashSet<>(
+ Arrays.asList(
+ ""
+ )
+ );
+ }
+ "#;
+
+ let mut file_set = HashMap::from([
+ ("com/android/aconfig/test/Flags.java", expect_flags_content),
+ ("com/android/aconfig/test/FeatureFlags.java", expect_feature_flags_content),
+ ("com/android/aconfig/test/FeatureFlagsImpl.java", expect_feature_flags_impl_content),
+ (
+ "com/android/aconfig/test/CustomFeatureFlags.java",
+ expect_custom_feature_flags_content,
+ ),
+ (
+ "com/android/aconfig/test/FakeFeatureFlagsImpl.java",
+ EXPECTED_FAKEFEATUREFLAGSIMPL_CONTENT,
+ ),
+ ]);
+
+ for file in generated_files {
+ let file_path = file.path.to_str().unwrap();
+ assert!(file_set.contains_key(file_path), "Cannot find {}", file_path);
+ assert_eq!(
+ None,
+ crate::test::first_significant_code_diff(
+ file_set.get(file_path).unwrap(),
+ &String::from_utf8(file.contents).unwrap()
+ ),
+ "File {} content is not correct",
+ file_path
+ );
+ file_set.remove(file_path);
+ }
+
+ assert!(file_set.is_empty());
+ }
+
+ #[test]
+ fn test_generate_java_code_new_exported_with_sdk_check() {
+ let parsed_flags = crate::test::parse_test_flags();
+ let mode = CodegenMode::Exported;
+ let modified_parsed_flags =
+ crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode).unwrap();
+ let flag_ids =
+ assign_flag_ids(crate::test::TEST_PACKAGE, modified_parsed_flags.iter()).unwrap();
+ let mut finalized_flags = FinalizedFlagMap::new();
+ finalized_flags.insert_if_new(
+ ApiLevel(36),
+ FinalizedFlag {
+ flag_name: "disabled_rw_exported".to_string(),
+ package_name: "com.android.aconfig.test".to_string(),
+ },
+ );
+ let config = JavaCodegenConfig {
+ codegen_mode: mode,
+ flag_ids,
+ allow_instrumentation: true,
+ package_fingerprint: 5801144784618221668,
+ new_exported: true,
+ single_exported_file: false,
+ finalized_flags,
+ };
+ let generated_files = generate_java_code(
+ crate::test::TEST_PACKAGE,
+ modified_parsed_flags.into_iter(),
+ config,
+ )
+ .unwrap();
+
+ let expect_flags_content = r#"
+ package com.android.aconfig.test;
+ import android.os.Build;
+ /** @hide */
+ public final class Flags {
+ /** @hide */
+ public static final String FLAG_DISABLED_RW_EXPORTED = "com.android.aconfig.test.disabled_rw_exported";
+ /** @hide */
+ public static final String FLAG_ENABLED_FIXED_RO_EXPORTED = "com.android.aconfig.test.enabled_fixed_ro_exported";
+ /** @hide */
+ public static final String FLAG_ENABLED_RO_EXPORTED = "com.android.aconfig.test.enabled_ro_exported";
+ public static boolean disabledRwExported() {
+ if (Build.VERSION.SDK_INT >= 36) {
+ return true;
+ }
+ return FEATURE_FLAGS.disabledRwExported();
+ }
+ public static boolean enabledFixedRoExported() {
+ return FEATURE_FLAGS.enabledFixedRoExported();
+ }
+ public static boolean enabledRoExported() {
+ return FEATURE_FLAGS.enabledRoExported();
+ }
+ private static FeatureFlags FEATURE_FLAGS = new FeatureFlagsImpl();
+ }
+ "#;
+
+ let expect_feature_flags_content = r#"
+ package com.android.aconfig.test;
+ /** @hide */
+ public interface FeatureFlags {
+ boolean disabledRwExported();
+ boolean enabledFixedRoExported();
+ boolean enabledRoExported();
+ }
+ "#;
+
+ let expect_feature_flags_impl_content = r#"
+ package com.android.aconfig.test;
+ import android.os.Build;
+ import android.os.flagging.AconfigPackage;
+ import android.util.Log;
+ /** @hide */
+ public final class FeatureFlagsImpl implements FeatureFlags {
+ private static final String TAG = "FeatureFlagsImplExport";
+ private static volatile boolean isCached = false;
+ private static boolean disabledRwExported = false;
+ private static boolean enabledFixedRoExported = false;
+ private static boolean enabledRoExported = false;
+ private void init() {
+ try {
+ AconfigPackage reader = AconfigPackage.load("com.android.aconfig.test");
+ disabledRwExported = Build.VERSION.SDK_INT >= 36 ? true : reader.getBooleanFlagValue("disabled_rw_exported", false);
+ enabledFixedRoExported = reader.getBooleanFlagValue("enabled_fixed_ro_exported", false);
+ enabledRoExported = reader.getBooleanFlagValue("enabled_ro_exported", false);
+ } catch (Exception e) {
+ // pass
Log.e(TAG, e.toString());
+ } catch (LinkageError e) {
+ // for mainline module running on older devices.
+ // This should be replaces to version check, after the version bump.
+ Log.w(TAG, e.toString());
}
isCached = true;
}
@@ -1150,7 +1393,8 @@
allow_instrumentation: true,
package_fingerprint: 5801144784618221668,
new_exported: false,
- check_api_level: false,
+ single_exported_file: false,
+ finalized_flags: FinalizedFlagMap::new(),
};
let generated_files = generate_java_code(
crate::test::TEST_PACKAGE,
@@ -1277,7 +1521,8 @@
allow_instrumentation: true,
package_fingerprint: 5801144784618221668,
new_exported: false,
- check_api_level: false,
+ single_exported_file: false,
+ finalized_flags: FinalizedFlagMap::new(),
};
let generated_files = generate_java_code(
crate::test::TEST_PACKAGE,
@@ -1549,6 +1794,109 @@
}
#[test]
+ fn test_generate_java_code_exported_flags() {
+ let parsed_flags = crate::test::parse_test_flags();
+ let mode = CodegenMode::Exported;
+ let modified_parsed_flags =
+ crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode).unwrap();
+ let flag_ids =
+ assign_flag_ids(crate::test::TEST_PACKAGE, modified_parsed_flags.iter()).unwrap();
+ let mut finalized_flags = FinalizedFlagMap::new();
+ finalized_flags.insert_if_new(
+ ApiLevel(36),
+ FinalizedFlag {
+ flag_name: "disabled_rw_exported".to_string(),
+ package_name: "com.android.aconfig.test".to_string(),
+ },
+ );
+ let config = JavaCodegenConfig {
+ codegen_mode: mode,
+ flag_ids,
+ allow_instrumentation: true,
+ package_fingerprint: 5801144784618221668,
+ new_exported: true,
+ single_exported_file: true,
+ finalized_flags,
+ };
+ let generated_files = generate_java_code(
+ crate::test::TEST_PACKAGE,
+ modified_parsed_flags.into_iter(),
+ config,
+ )
+ .unwrap();
+
+ let expect_exported_flags_content = r#"
+ package com.android.aconfig.test;
+
+ import android.os.Build;
+ import android.os.flagging.AconfigPackage;
+ import android.util.Log;
+ public final class ExportedFlags {
+
+ public static final String FLAG_DISABLED_RW_EXPORTED = "com.android.aconfig.test.disabled_rw_exported";
+ public static final String FLAG_ENABLED_FIXED_RO_EXPORTED = "com.android.aconfig.test.enabled_fixed_ro_exported";
+ public static final String FLAG_ENABLED_RO_EXPORTED = "com.android.aconfig.test.enabled_ro_exported";
+ private static final String TAG = "ExportedFlags";
+ private static volatile boolean isCached = false;
+
+ private static boolean disabledRwExported = false;
+ private static boolean enabledFixedRoExported = false;
+ private static boolean enabledRoExported = false;
+ private ExportedFlags() {}
+
+ private void init() {
+ try {
+ AconfigPackage reader = AconfigPackage.load("com.android.aconfig.test");
+ disabledRwExported = reader.getBooleanFlagValue("disabled_rw_exported", false);
+ enabledFixedRoExported = reader.getBooleanFlagValue("enabled_fixed_ro_exported", false);
+ enabledRoExported = reader.getBooleanFlagValue("enabled_ro_exported", false);
+ } catch (Exception e) {
+ // pass
+ Log.e(TAG, e.toString());
+ } catch (LinkageError e) {
+ // for mainline module running on older devices.
+ // This should be replaces to version check, after the version bump.
+ Log.w(TAG, e.toString());
+ }
+ isCached = true;
+ }
+ public static boolean disabledRwExported() {
+ if (Build.VERSION.SDK_INT >= 36) {
+ return true;
+ }
+
+ if (!featureFlags.isCached) {
+ featureFlags.init();
+ }
+ return featureFlags.disabledRwExported;
+ }
+ public static boolean enabledFixedRoExported() {
+ if (!featureFlags.isCached) {
+ featureFlags.init();
+ }
+ return featureFlags.enabledFixedRoExported;
+ }
+ public static boolean enabledRoExported() {
+ if (!featureFlags.isCached) {
+ featureFlags.init();
+ }
+ return featureFlags.enabledRoExported;
+ }
+ private static ExportedFlags featureFlags = new ExportedFlags();
+ }"#;
+
+ let file = generated_files.iter().find(|f| f.path.ends_with("ExportedFlags.java")).unwrap();
+ assert_eq!(
+ None,
+ crate::test::first_significant_code_diff(
+ expect_exported_flags_content,
+ &String::from_utf8(file.contents.clone()).unwrap()
+ ),
+ "ExportedFlags content is not correct"
+ );
+ }
+
+ #[test]
fn test_format_java_method_name() {
let expected = "someSnakeName";
let input = "____some_snake___name____";
diff --git a/tools/aconfig/aconfig/src/commands.rs b/tools/aconfig/aconfig/src/commands.rs
index 64fb2b6..14a98f0 100644
--- a/tools/aconfig/aconfig/src/commands.rs
+++ b/tools/aconfig/aconfig/src/commands.rs
@@ -15,6 +15,7 @@
*/
use anyhow::{bail, ensure, Context, Result};
+use convert_finalized_flags::FinalizedFlagMap;
use itertools::Itertools;
use protobuf::Message;
use std::collections::HashMap;
@@ -209,7 +210,8 @@
codegen_mode: CodegenMode,
allow_instrumentation: bool,
new_exported: bool,
- check_api_level: bool,
+ single_exported_file: bool,
+ finalized_flags: FinalizedFlagMap,
) -> Result<Vec<OutputFile>> {
let parsed_flags = input.try_parse_flags()?;
let modified_parsed_flags =
@@ -227,7 +229,8 @@
allow_instrumentation,
package_fingerprint,
new_exported,
- check_api_level,
+ single_exported_file,
+ finalized_flags,
};
generate_java_code(&package, modified_parsed_flags.into_iter(), config)
}
diff --git a/tools/aconfig/aconfig/src/main.rs b/tools/aconfig/aconfig/src/main.rs
index ef3b7ab..6b29423 100644
--- a/tools/aconfig/aconfig/src/main.rs
+++ b/tools/aconfig/aconfig/src/main.rs
@@ -33,6 +33,7 @@
use aconfig_storage_file::StorageFileType;
use codegen::CodegenMode;
+use convert_finalized_flags::FinalizedFlagMap;
use dump::DumpFormat;
#[cfg(test)]
@@ -158,11 +159,19 @@
.default_value("production"),
)
.arg(
+ Arg::new("single-exported-file")
+ .long("single-exported-file")
+ .value_parser(clap::value_parser!(bool))
+ .default_value("false"),
+ )
+ // TODO: b/395899938 - clean up flags for switching to new storage
+ .arg(
Arg::new("allow-instrumentation")
.long("allow-instrumentation")
.value_parser(clap::value_parser!(bool))
.default_value("false"),
)
+ // TODO: b/395899938 - clean up flags for switching to new storage
.arg(
Arg::new("new-exported")
.long("new-exported")
@@ -340,6 +349,12 @@
Ok(())
}
+fn load_finalized_flags() -> Result<FinalizedFlagMap> {
+ let json_str = include_str!(concat!(env!("OUT_DIR"), "/finalized_flags_record.json"));
+ let map = serde_json::from_str(json_str)?;
+ Ok(map)
+}
+
fn main() -> Result<()> {
let matches = cli().get_matches();
match matches.subcommand() {
@@ -373,13 +388,20 @@
let allow_instrumentation =
get_required_arg::<bool>(sub_matches, "allow-instrumentation")?;
let new_exported = get_required_arg::<bool>(sub_matches, "new-exported")?;
+ let single_exported_file =
+ get_required_arg::<bool>(sub_matches, "single-exported-file")?;
+
let check_api_level = get_required_arg::<bool>(sub_matches, "check-api-level")?;
+ let finalized_flags: FinalizedFlagMap =
+ if *check_api_level { load_finalized_flags()? } else { FinalizedFlagMap::new() };
+
let generated_files = commands::create_java_lib(
cache,
*mode,
*allow_instrumentation,
*new_exported,
- *check_api_level,
+ *single_exported_file,
+ finalized_flags,
)
.context("failed to create java lib")?;
let dir = PathBuf::from(get_required_arg::<String>(sub_matches, "out")?);
diff --git a/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template b/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template
index b82b9cb..ef18367 100644
--- a/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template
+++ b/tools/aconfig/aconfig/templates/CustomFeatureFlags.java.template
@@ -11,7 +11,13 @@
import java.util.function.BiPredicate;
import java.util.function.Predicate;
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
/** @hide */
+{{ -endif }}
public class CustomFeatureFlags implements FeatureFlags \{
private BiPredicate<String, Predicate<FeatureFlags>> mGetValueImpl;
diff --git a/tools/aconfig/aconfig/templates/ExportedFlags.java.template b/tools/aconfig/aconfig/templates/ExportedFlags.java.template
new file mode 100644
index 0000000..176da18
--- /dev/null
+++ b/tools/aconfig/aconfig/templates/ExportedFlags.java.template
@@ -0,0 +1,51 @@
+package {package_name}; {#- CODEGEN FOR EXPORTED MODE FOR NEW STORAGE SINGLE EXPORTED FILE#}
+
+import android.os.Build;
+import android.os.flagging.AconfigPackage;
+import android.util.Log;
+public final class ExportedFlags \{
+{{ -for item in flag_elements}}
+ public static final String FLAG_{item.flag_name_constant_suffix} = "{item.device_config_flag}";
+{{- endfor }}
+ private static final String TAG = "ExportedFlags";
+ private static volatile boolean isCached = false;
+{{ for flag in flag_elements }}
+ private static boolean {flag.method_name} = false;
+{{ -endfor }} {#- end flag_elements #}
+ private ExportedFlags() \{}
+
+ private void init() \{
+ try \{
+ AconfigPackage reader = AconfigPackage.load("{package_name}");
+ {{ -for namespace_with_flags in namespace_flags }}
+ {{ -for flag in namespace_with_flags.flags }}
+ {flag.method_name} = reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
+
+ {{ -endfor }} {#- end namespace_with_flags.flags #}
+ {{ -endfor }} {#- end namespace_flags #}
+ } catch (Exception e) \{
+ // pass
+ Log.e(TAG, e.toString());
+ } catch (LinkageError e) \{
+ // for mainline module running on older devices.
+ // This should be replaces to version check, after the version bump.
+ Log.w(TAG, e.toString());
+ }
+ isCached = true;
+ }
+
+{{ -for flag in flag_elements }}
+ public static boolean {flag.method_name}() \{
+ {{ -if flag.finalized_sdk_present }}
+ if (Build.VERSION.SDK_INT >= {flag.finalized_sdk_value}) \{
+ return true;
+ }
+ {{ -endif}} {#- end finalized_sdk_present#}
+ if (!featureFlags.isCached) \{
+ featureFlags.init();
+ }
+ return featureFlags.{flag.method_name};
+ }
+{{ -endfor }}
+ private static ExportedFlags featureFlags = new ExportedFlags();
+}
diff --git a/tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template
index 290d2c4..ed277ae 100644
--- a/tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template
+++ b/tools/aconfig/aconfig/templates/FakeFeatureFlagsImpl.java.template
@@ -4,7 +4,13 @@
import java.util.Map;
import java.util.function.Predicate;
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
/** @hide */
+{{ -endif }}
public class FakeFeatureFlagsImpl extends CustomFeatureFlags \{
private final Map<String, Boolean> mFlagMap = new HashMap<>();
private final FeatureFlags mDefaults;
diff --git a/tools/aconfig/aconfig/templates/FeatureFlags.java.template b/tools/aconfig/aconfig/templates/FeatureFlags.java.template
index d2799b2..c8b9b7f 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlags.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlags.java.template
@@ -3,7 +3,16 @@
// TODO(b/303773055): Remove the annotation after access issue is resolved.
import android.compat.annotation.UnsupportedAppUsage;
{{ -endif }}
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+/**
+ * @deprecated Use \{@link ExportedFlags} instead.
+ */
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
/** @hide */
+{{ -endif }}
public interface FeatureFlags \{
{{ for item in flag_elements }}
{{ -if not item.is_read_write }}
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.deviceConfig.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.deviceConfig.java.template
new file mode 100644
index 0000000..44d5cc0
--- /dev/null
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.deviceConfig.java.template
@@ -0,0 +1,68 @@
+package {package_name};
+{{ if not library_exported- }}
+// TODO(b/303773055): Remove the annotation after access issue is resolved.
+import android.compat.annotation.UnsupportedAppUsage;
+{{ -endif }} {#- end of not library_exported#}
+{{ -if runtime_lookup_required }}
+import android.os.Binder;
+import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.Properties;
+{{ -endif }} {#- end of runtime_lookup_required#}
+/** @hide */
+public final class FeatureFlagsImpl implements FeatureFlags \{
+{{ -if runtime_lookup_required }}
+{{ -for namespace_with_flags in namespace_flags }}
+ private static volatile boolean {namespace_with_flags.namespace}_is_cached = false;
+{{ -endfor- }}
+{{ for flag in flag_elements }}
+{{- if flag.is_read_write }}
+ private static boolean {flag.method_name} = {flag.default_value};
+{{ -endif }} {#- end of is_read_write#}
+{{ -endfor }}
+{{ for namespace_with_flags in namespace_flags }}
+ private void load_overrides_{namespace_with_flags.namespace}() \{
+ final long ident = Binder.clearCallingIdentity();
+ try \{
+ Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}");
+{{ -for flag in namespace_with_flags.flags }}
+{{ -if flag.is_read_write }}
+ {flag.method_name} =
+ properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value});
+{{ -endif }} {#- end of is_read_write#}
+{{ -endfor }}
+ } catch (NullPointerException e) \{
+ throw new RuntimeException(
+ "Cannot read value from namespace {namespace_with_flags.namespace} "
+ + "from DeviceConfig. It could be that the code using flag "
+ + "executed before SettingsProvider initialization. Please use "
+ + "fixed read-only flag by adding is_fixed_read_only: true in "
+ + "flag declaration.",
+ e
+ );
+ } catch (SecurityException e) \{
+ // for isolated process case, skip loading flag value from the storage, use the default
+ } finally \{
+ Binder.restoreCallingIdentity(ident);
+ }
+ {namespace_with_flags.namespace}_is_cached = true;
+}
+{{ endfor- }}
+{{ -endif }}{#- end of runtime_lookup_required #}
+{{ -for flag in flag_elements }}
+ @Override
+{{ -if not library_exported }}
+ @com.android.aconfig.annotations.AconfigFlagAccessor
+ @UnsupportedAppUsage
+{{ -endif }}{#- end of not library_exported #}
+ public boolean {flag.method_name}() \{
+{{ -if flag.is_read_write }}
+ if (!{flag.device_config_namespace}_is_cached) \{
+ load_overrides_{flag.device_config_namespace}();
+ }
+ return {flag.method_name};
+{{ -else }} {#- else is_read_write #}
+ return {flag.default_value};
+{{ -endif }}{#- end of is_read_write #}
+ }
+{{ endfor }}
+}
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template
index 8b60824..b843ec2 100644
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template
+++ b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.exported.java.template
@@ -3,7 +3,16 @@
import android.os.Build;
import android.os.flagging.AconfigPackage;
import android.util.Log;
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+/**
+ * @deprecated Use \{@link ExportedFlags} instead.
+ */
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
/** @hide */
+{{ -endif }}
public final class FeatureFlagsImpl implements FeatureFlags \{
private static final String TAG = "FeatureFlagsImplExport";
private static volatile boolean isCached = false;
@@ -28,7 +37,7 @@
} catch (LinkageError e) \{
// for mainline module running on older devices.
// This should be replaces to version check, after the version bump.
- Log.e(TAG, e.toString());
+ Log.w(TAG, e.toString());
}
isCached = true;
}
diff --git a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template b/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
deleted file mode 100644
index ea2a2ee..0000000
--- a/tools/aconfig/aconfig/templates/FeatureFlagsImpl.java.template
+++ /dev/null
@@ -1,248 +0,0 @@
-package {package_name};
-{{ -if not is_test_mode }}
-{{ -if allow_instrumentation }}
-{{ if not library_exported- }}{#- only new storage for prod mode #}
-// TODO(b/303773055): Remove the annotation after access issue is resolved.
-import android.compat.annotation.UnsupportedAppUsage;
-{{ -if runtime_lookup_required }}
-import android.os.Build;
-{{ if is_platform_container }}
-import android.os.flagging.PlatformAconfigPackageInternal;
-{{ -else }} {#- else is_platform_container #}
-import android.os.flagging.AconfigPackageInternal;
-{{ -endif }} {#- end of is_platform_container#}
-import android.util.Log;
-{{ -endif }} {#- end of runtime_lookup_required#}
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ -if runtime_lookup_required }}
- private static final String TAG = "FeatureFlagsImpl";
- private static volatile boolean isCached = false;
-{{ for flag in flag_elements }}
-{{ -if flag.is_read_write }}
- private static boolean {flag.method_name} = {flag.default_value};
-{{ -endif }} {#- end of is_read_write#}
-{{ -endfor }}
-
- private void init() \{
- try \{
-{{ if is_platform_container }}
- PlatformAconfigPackageInternal reader = PlatformAconfigPackageInternal.load("{package_name}", {package_fingerprint});
-{{ -else }} {#- else is_platform_container #}
- AconfigPackageInternal reader = AconfigPackageInternal.load("{package_name}", {package_fingerprint});
-{{ -endif }} {#- end of is_platform_container#}
- {{ -for namespace_with_flags in namespace_flags }}
- {{ -for flag in namespace_with_flags.flags }}
- {{ -if flag.is_read_write }}
- {flag.method_name} = reader.getBooleanFlagValue({flag.flag_offset});
- {{ -endif }} {#- is_read_write#}
- {{ -endfor }}
- {{ -endfor }}
- } catch (Exception e) \{
- Log.e(TAG, e.toString());
- } catch (LinkageError e) \{
- // for mainline module running on older devices.
- // This should be replaces to version check, after the version bump.
- Log.e(TAG, e.toString());
- }
- isCached = true;
- }
-{{ -endif }}{#- end of runtime_lookup_required #}
-{{ -for flag in flag_elements }}
- @Override
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
- public boolean {flag.method_name}() \{
-{{ -if flag.is_read_write }}
- if (!isCached) \{
- init();
- }
- return {flag.method_name};
-{{ -else }}{#- else is_read_write #}
- return {flag.default_value};
-{{ -endif }} {#- end of is_read_write#}
- }
-{{ endfor }}
-}
-{{ -else- }}{#- device config for exproted mode #}
-{{ -if new_exported }}
-import android.os.Build;
-import android.os.flagging.AconfigPackage;
-import android.util.Log;
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
- private static final String TAG = "FeatureFlagsImplExport";
- private static volatile boolean isCached = false;
-{{ for flag in flag_elements }}
- private static boolean {flag.method_name} = false;
-{{ -endfor }}
- private void init() \{
- try \{
- AconfigPackage reader = AconfigPackage.load("{package_name}");
- {{ -for namespace_with_flags in namespace_flags }}
- {{ -for flag in namespace_with_flags.flags }}
- {{ -if flag.finalized_sdk_present }}
- {flag.method_name} = Build.VERSION.SDK_INT >= {flag.finalized_sdk_value} ? true : reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
- {{ - else }} {#- else finalized_sdk_present #}
- {flag.method_name} = reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
- {{ -endif}} {#- end of finalized_sdk_present#}
- {{ -endfor }}
- {{ -endfor }}
- } catch (Exception e) \{
- // pass
- Log.e(TAG, e.toString());
- } catch (LinkageError e) \{
- // for mainline module running on older devices.
- // This should be replaces to version check, after the version bump.
- Log.e(TAG, e.toString());
- }
- isCached = true;
- }
-{{ -for flag in flag_elements }}
- @Override
- public boolean {flag.method_name}() \{
- if (!isCached) \{
- init();
- }
- return {flag.method_name};
- }
-{{ endfor }}
-}
-{{ else }}
-import android.os.Binder;
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.Properties;
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ -for namespace_with_flags in namespace_flags }}
- private static volatile boolean {namespace_with_flags.namespace}_is_cached = false;
-{{ -endfor- }}
-{{ for flag in flag_elements }}
-{{ -if flag.is_read_write }}
- private static boolean {flag.method_name} = {flag.default_value};
-{{ -endif }} {#- end of is_read_write#}
-{{ -endfor }}
-{{ for namespace_with_flags in namespace_flags }}
- private void load_overrides_{namespace_with_flags.namespace}() \{
- final long ident = Binder.clearCallingIdentity();
- try \{
- Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}");
-{{ -for flag in namespace_with_flags.flags }}
-{{ -if flag.is_read_write }}
- {flag.method_name} =
- properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value});
-{{ -endif }} {#- end of is_read_write#}
-{{ -endfor }}
- } catch (NullPointerException e) \{
- throw new RuntimeException(
- "Cannot read value from namespace {namespace_with_flags.namespace} "
- + "from DeviceConfig. It could be that the code using flag "
- + "executed before SettingsProvider initialization. Please use "
- + "fixed read-only flag by adding is_fixed_read_only: true in "
- + "flag declaration.",
- e
- );
- } catch (SecurityException e) \{
- // for isolated process case, skip loading flag value from the storage, use the default
- } finally \{
- Binder.restoreCallingIdentity(ident);
- }
- {namespace_with_flags.namespace}_is_cached = true;
- }
-{{ endfor- }}
-{{ -for flag in flag_elements }}
- @Override
- public boolean {flag.method_name}() \{
- if (!{flag.device_config_namespace}_is_cached) \{
- load_overrides_{flag.device_config_namespace}();
- }
- return {flag.method_name};
- }
-{{ endfor }}
-}
-{{ -endif- }} {#- end new_exported mode #}
-{{ -endif- }} {#- end exported mode #}
-{{ else }} {#- else for allow_instrumentation is not enabled #}
-{{ if not library_exported- }}
-// TODO(b/303773055): Remove the annotation after access issue is resolved.
-import android.compat.annotation.UnsupportedAppUsage;
-{{ -endif }} {#- end of not library_exported#}
-
-{{ -if runtime_lookup_required }}
-import android.os.Binder;
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.Properties;
-{{ -endif }} {#- end of runtime_lookup_required#}
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ -if runtime_lookup_required }}
-{{ -for namespace_with_flags in namespace_flags }}
- private static volatile boolean {namespace_with_flags.namespace}_is_cached = false;
-{{ -endfor- }}
-
-{{ for flag in flag_elements }}
-{{- if flag.is_read_write }}
- private static boolean {flag.method_name} = {flag.default_value};
-{{ -endif }} {#- end of is_read_write#}
-{{ -endfor }}
-{{ for namespace_with_flags in namespace_flags }}
- private void load_overrides_{namespace_with_flags.namespace}() \{
- final long ident = Binder.clearCallingIdentity();
- try \{
- Properties properties = DeviceConfig.getProperties("{namespace_with_flags.namespace}");
-{{ -for flag in namespace_with_flags.flags }}
-{{ -if flag.is_read_write }}
- {flag.method_name} =
- properties.getBoolean(Flags.FLAG_{flag.flag_name_constant_suffix}, {flag.default_value});
-{{ -endif }} {#- end of is_read_write#}
-{{ -endfor }}
- } catch (NullPointerException e) \{
- throw new RuntimeException(
- "Cannot read value from namespace {namespace_with_flags.namespace} "
- + "from DeviceConfig. It could be that the code using flag "
- + "executed before SettingsProvider initialization. Please use "
- + "fixed read-only flag by adding is_fixed_read_only: true in "
- + "flag declaration.",
- e
- );
- } finally \{
- Binder.restoreCallingIdentity(ident);
- }
- {namespace_with_flags.namespace}_is_cached = true;
-}
-{{ endfor- }}
-{{ -endif }}{#- end of runtime_lookup_required #}
-{{ -for flag in flag_elements }}
- @Override
-{{ -if not library_exported }}
- @com.android.aconfig.annotations.AconfigFlagAccessor
- @UnsupportedAppUsage
-{{ -endif }}{#- end of not library_exported #}
- public boolean {flag.method_name}() \{
-{{ -if flag.is_read_write }}
- if (!{flag.device_config_namespace}_is_cached) \{
- load_overrides_{flag.device_config_namespace}();
- }
- return {flag.method_name};
-{{ -else }} {#- else is_read_write #}
- return {flag.default_value};
-{{ -endif }}{#- end of is_read_write #}
- }
-{{ endfor }}
-}
-{{ endif}} {#- endif for allow_instrumentation #}
-{{ else }} {#- Generate only stub if in test mode #}
-/** @hide */
-public final class FeatureFlagsImpl implements FeatureFlags \{
-{{ for flag in flag_elements }}
- @Override
-{{ -if not library_exported }}
- @com.android.aconfig.annotations.AconfigFlagAccessor
-{{ -endif }}
- public boolean {flag.method_name}() \{
- throw new UnsupportedOperationException(
- "Method is not implemented.");
- }
-{{ endfor- }}
-}
-{{ endif }}
diff --git a/tools/aconfig/aconfig/templates/Flags.java.template b/tools/aconfig/aconfig/templates/Flags.java.template
index e2f70b9..6fa2701 100644
--- a/tools/aconfig/aconfig/templates/Flags.java.template
+++ b/tools/aconfig/aconfig/templates/Flags.java.template
@@ -2,8 +2,19 @@
{{ if not library_exported- }}
// TODO(b/303773055): Remove the annotation after access issue is resolved.
import android.compat.annotation.UnsupportedAppUsage;
+{{ else }}
+import android.os.Build;
{{ -endif }}
+{{ -if single_exported_file }}
+{{ -if library_exported }}
+/**
+ * @deprecated Use \{@link ExportedFlags} instead.
+ */
+@Deprecated {#- PREFER ExportedFlags #}
+{{ -endif }}
+{{ -else }}
/** @hide */
+{{ -endif }}
public final class Flags \{
{{ -for item in flag_elements}}
/** @hide */
@@ -22,6 +33,11 @@
@UnsupportedAppUsage
{{ -endif }}
public static boolean {item.method_name}() \{
+ {{ -if item.finalized_sdk_present }}
+ if (Build.VERSION.SDK_INT >= {item.finalized_sdk_value}) \{
+ return true;
+ }
+ {{ -endif}} {#- end finalized_sdk_present#}
return FEATURE_FLAGS.{item.method_name}();
}
{{ -endfor }}
diff --git a/tools/aconfig/aconfig/templates/cpp_exported_header.template b/tools/aconfig/aconfig/templates/cpp_exported_header.template
index 4643c97..f6f576a 100644
--- a/tools/aconfig/aconfig/templates/cpp_exported_header.template
+++ b/tools/aconfig/aconfig/templates/cpp_exported_header.template
@@ -41,6 +41,7 @@
extern std::unique_ptr<flag_provider_interface> provider_;
{{ for item in class_elements}}
+{{ if not is_test_mode }}{{ if item.is_fixed_read_only }}constexpr {{ endif }}{{ endif -}}
inline bool {item.flag_name}() \{
{{ -if is_test_mode }}
return provider_->{item.flag_name}();
diff --git a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/ByteBufferReader.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/ByteBufferReader.java
index 1fbcb85..14fc468 100644
--- a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/ByteBufferReader.java
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/ByteBufferReader.java
@@ -19,10 +19,12 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
+import java.util.Objects;
public class ByteBufferReader {
private ByteBuffer mByteBuffer;
+ private int mPosition;
public ByteBufferReader(ByteBuffer byteBuffer) {
this.mByteBuffer = byteBuffer;
@@ -30,19 +32,19 @@
}
public int readByte() {
- return Byte.toUnsignedInt(mByteBuffer.get());
+ return Byte.toUnsignedInt(mByteBuffer.get(nextGetIndex(1)));
}
public int readShort() {
- return Short.toUnsignedInt(mByteBuffer.getShort());
+ return Short.toUnsignedInt(mByteBuffer.getShort(nextGetIndex(2)));
}
public int readInt() {
- return this.mByteBuffer.getInt();
+ return this.mByteBuffer.getInt(nextGetIndex(4));
}
public long readLong() {
- return this.mByteBuffer.getLong();
+ return this.mByteBuffer.getLong(nextGetIndex(8));
}
public String readString() {
@@ -52,7 +54,7 @@
"String length exceeds maximum allowed size (1024 bytes): " + length);
}
byte[] bytes = new byte[length];
- mByteBuffer.get(bytes, 0, length);
+ getArray(nextGetIndex(length), bytes, 0, length);
return new String(bytes, StandardCharsets.UTF_8);
}
@@ -61,10 +63,26 @@
}
public void position(int newPosition) {
- mByteBuffer.position(newPosition);
+ mPosition = newPosition;
}
public int position() {
- return mByteBuffer.position();
+ return mPosition;
+ }
+
+ private int nextGetIndex(int nb) {
+ int p = mPosition;
+ mPosition += nb;
+ return p;
+ }
+
+ private void getArray(int index, byte[] dst, int offset, int length) {
+ Objects.checkFromIndexSize(index, length, mByteBuffer.limit());
+ Objects.checkFromIndexSize(offset, length, dst.length);
+
+ int end = offset + length;
+ for (int i = offset, j = index; i < end; i++, j++) {
+ dst[i] = mByteBuffer.get(j);
+ }
}
}
diff --git a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagTable.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagTable.java
index 757844a..ee60b18 100644
--- a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagTable.java
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagTable.java
@@ -24,12 +24,12 @@
public class FlagTable {
private Header mHeader;
- private ByteBufferReader mReader;
+ private ByteBuffer mBuffer;
public static FlagTable fromBytes(ByteBuffer bytes) {
FlagTable flagTable = new FlagTable();
- flagTable.mReader = new ByteBufferReader(bytes);
- flagTable.mHeader = Header.fromBytes(flagTable.mReader);
+ flagTable.mBuffer = bytes;
+ flagTable.mHeader = Header.fromBytes(new ByteBufferReader(bytes));
return flagTable;
}
@@ -41,16 +41,16 @@
if (newPosition >= mHeader.mNodeOffset) {
return null;
}
-
- mReader.position(newPosition);
- int nodeIndex = mReader.readInt();
+ ByteBufferReader reader = new ByteBufferReader(mBuffer) ;
+ reader.position(newPosition);
+ int nodeIndex = reader.readInt();
if (nodeIndex < mHeader.mNodeOffset || nodeIndex >= mHeader.mFileSize) {
return null;
}
while (nodeIndex != -1) {
- mReader.position(nodeIndex);
- Node node = Node.fromBytes(mReader);
+ reader.position(nodeIndex);
+ Node node = Node.fromBytes(reader);
if (Objects.equals(flagName, node.mFlagName) && packageId == node.mPackageId) {
return node;
}
diff --git a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/PackageTable.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/PackageTable.java
index 1e7c2ca..215616e 100644
--- a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/PackageTable.java
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/PackageTable.java
@@ -30,12 +30,12 @@
private static final int NODE_SKIP_BYTES = 12;
private Header mHeader;
- private ByteBufferReader mReader;
+ private ByteBuffer mBuffer;
public static PackageTable fromBytes(ByteBuffer bytes) {
PackageTable packageTable = new PackageTable();
- packageTable.mReader = new ByteBufferReader(bytes);
- packageTable.mHeader = Header.fromBytes(packageTable.mReader);
+ packageTable.mBuffer = bytes;
+ packageTable.mHeader = Header.fromBytes(new ByteBufferReader(bytes));
return packageTable;
}
@@ -47,16 +47,17 @@
if (newPosition >= mHeader.mNodeOffset) {
return null;
}
- mReader.position(newPosition);
- int nodeIndex = mReader.readInt();
+ ByteBufferReader reader = new ByteBufferReader(mBuffer);
+ reader.position(newPosition);
+ int nodeIndex = reader.readInt();
if (nodeIndex < mHeader.mNodeOffset || nodeIndex >= mHeader.mFileSize) {
return null;
}
while (nodeIndex != -1) {
- mReader.position(nodeIndex);
- Node node = Node.fromBytes(mReader, mHeader.mVersion);
+ reader.position(nodeIndex);
+ Node node = Node.fromBytes(reader, mHeader.mVersion);
if (Objects.equals(packageName, node.mPackageName)) {
return node;
}
@@ -68,12 +69,13 @@
public List<String> getPackageList() {
List<String> list = new ArrayList<>(mHeader.mNumPackages);
- mReader.position(mHeader.mNodeOffset);
+ ByteBufferReader reader = new ByteBufferReader(mBuffer);
+ reader.position(mHeader.mNodeOffset);
int fingerprintBytes = mHeader.mVersion == 1 ? 0 : FINGERPRINT_BYTES;
int skipBytes = fingerprintBytes + NODE_SKIP_BYTES;
for (int i = 0; i < mHeader.mNumPackages; i++) {
- list.add(mReader.readString());
- mReader.position(mReader.position() + skipBytes);
+ list.add(reader.readString());
+ reader.position(reader.position() + skipBytes);
}
return list;
}
diff --git a/tools/aconfig/aconfig_storage_file/tests/srcs/PackageTableTest.java b/tools/aconfig/aconfig_storage_file/tests/srcs/PackageTableTest.java
index 812ce35..4b68e5b 100644
--- a/tools/aconfig/aconfig_storage_file/tests/srcs/PackageTableTest.java
+++ b/tools/aconfig/aconfig_storage_file/tests/srcs/PackageTableTest.java
@@ -28,7 +28,9 @@
import org.junit.runners.JUnit4;
import java.util.HashSet;
+import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.CyclicBarrier;
@RunWith(JUnit4.class)
public class PackageTableTest {
@@ -142,4 +144,46 @@
assertTrue(packages.contains("com.android.aconfig.storage.test_2"));
assertTrue(packages.contains("com.android.aconfig.storage.test_4"));
}
+
+ @Test
+ public void testPackageTable_multithreadsRead() throws Exception {
+ PackageTable packageTable =
+ PackageTable.fromBytes(TestDataUtils.getTestPackageMapByteBuffer(2));
+ int numberOfThreads = 3;
+ Thread[] threads = new Thread[numberOfThreads];
+ final CyclicBarrier gate = new CyclicBarrier(numberOfThreads + 1);
+ String[] expects = {
+ "com.android.aconfig.storage.test_1",
+ "com.android.aconfig.storage.test_2",
+ "com.android.aconfig.storage.test_4"
+ };
+
+ for (int i = 0; i < numberOfThreads; i++) {
+ final String packageName = expects[i];
+ threads[i] =
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ gate.await();
+ } catch (Exception e) {
+ }
+ for (int j = 0; j < 10; j++) {
+ if (!Objects.equals(
+ packageName,
+ packageTable.get(packageName).getPackageName())) {
+ throw new RuntimeException();
+ }
+ }
+ }
+ };
+ threads[i].start();
+ }
+
+ gate.await();
+
+ for (int i = 0; i < numberOfThreads; i++) {
+ threads[i].join();
+ }
+ }
}
diff --git a/tools/aconfig/convert_finalized_flags/Android.bp b/tools/aconfig/convert_finalized_flags/Android.bp
new file mode 100644
index 0000000..5b39560
--- /dev/null
+++ b/tools/aconfig/convert_finalized_flags/Android.bp
@@ -0,0 +1,56 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_defaults {
+ name: "convert_finalized_flags.defaults",
+ edition: "2021",
+ clippy_lints: "android",
+ lints: "android",
+ rustlibs: [
+ "libanyhow",
+ "libclap",
+ "libitertools",
+ "libprotobuf",
+ "libserde",
+ "libserde_json",
+ "libtempfile",
+ "libtinytemplate",
+ ],
+}
+
+rust_library_host {
+ name: "libconvert_finalized_flags",
+ crate_name: "convert_finalized_flags",
+ defaults: ["convert_finalized_flags.defaults"],
+ srcs: [
+ "src/lib.rs",
+ ],
+}
+
+rust_binary_host {
+ name: "convert_finalized_flags",
+ defaults: ["convert_finalized_flags.defaults"],
+ srcs: ["src/main.rs"],
+ rustlibs: [
+ "libconvert_finalized_flags",
+ "libserde_json",
+ ],
+}
+
+rust_test_host {
+ name: "convert_finalized_flags.test",
+ defaults: ["convert_finalized_flags.defaults"],
+ test_suites: ["general-tests"],
+ srcs: ["src/lib.rs"],
+}
+
+genrule {
+ name: "finalized_flags_record.json",
+ srcs: [
+ "//prebuilts/sdk:finalized-api-flags",
+ ],
+ out: ["finalized_flags_record.json"],
+ tools: ["convert_finalized_flags"],
+ cmd: "args=\"\" && for f in $(locations //prebuilts/sdk:finalized-api-flags); do args=\"$$args --flag_file_path $$f\"; done && $(location convert_finalized_flags) $$args > $(out)",
+}
diff --git a/tools/aconfig/convert_finalized_flags/Cargo.toml b/tools/aconfig/convert_finalized_flags/Cargo.toml
new file mode 100644
index 0000000..e34e030
--- /dev/null
+++ b/tools/aconfig/convert_finalized_flags/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "convert_finalized_flags"
+version = "0.1.0"
+edition = "2021"
+
+[features]
+default = ["cargo"]
+cargo = []
+
+[dependencies]
+anyhow = "1.0.69"
+clap = { version = "4.1.8", features = ["derive"] }
+serde = { version = "1.0.152", features = ["derive"] }
+serde_json = "1.0.93"
+tempfile = "3.13.0"
diff --git a/tools/aconfig/convert_finalized_flags/src/lib.rs b/tools/aconfig/convert_finalized_flags/src/lib.rs
new file mode 100644
index 0000000..10faa39
--- /dev/null
+++ b/tools/aconfig/convert_finalized_flags/src/lib.rs
@@ -0,0 +1,395 @@
+/*
+* Copyright (C) 2025 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.
+*/
+//! Functions to extract finalized flag information from
+//! /prebuilts/sdk/#/finalized-flags.txt.
+//! These functions are very specific to that file setup as well as the format
+//! of the files (just a list of the fully-qualified flag names).
+//! There are also some helper functions for local building using cargo. These
+//! functions are only invoked via cargo for quick local testing and will not
+//! be used during actual soong building. They are marked as such.
+use anyhow::{anyhow, Result};
+use serde::{Deserialize, Serialize};
+use std::collections::{HashMap, HashSet};
+use std::fs;
+use std::io::{self, BufRead};
+
+/// Just the fully qualified flag name (package_name.flag_name).
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
+pub struct FinalizedFlag {
+ /// Name of the flag.
+ pub flag_name: String,
+ /// Name of the package.
+ pub package_name: String,
+}
+
+/// API level in which the flag was finalized.
+#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
+pub struct ApiLevel(pub i32);
+
+/// Contains all flags finalized for a given API level.
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)]
+pub struct FinalizedFlagMap(HashMap<ApiLevel, HashSet<FinalizedFlag>>);
+
+impl FinalizedFlagMap {
+ /// Creates a new, empty instance.
+ pub fn new() -> Self {
+ Self(HashMap::new())
+ }
+
+ /// Convenience method for is_empty on the underlying map.
+ pub fn is_empty(&self) -> bool {
+ self.0.is_empty()
+ }
+
+ /// Returns the API level in which the flag was finalized .
+ pub fn get_finalized_level(&self, flag: &FinalizedFlag) -> Option<ApiLevel> {
+ for (api_level, flags_for_level) in &self.0 {
+ if flags_for_level.contains(flag) {
+ return Some(*api_level);
+ }
+ }
+ None
+ }
+
+ /// Insert the flag into the map for the given level if the flag is not
+ /// present in the map already - for *any* level (not just the one given).
+ pub fn insert_if_new(&mut self, level: ApiLevel, flag: FinalizedFlag) {
+ if self.contains(&flag) {
+ return;
+ }
+ self.0.entry(level).or_default().insert(flag);
+ }
+
+ fn contains(&self, flag: &FinalizedFlag) -> bool {
+ self.0.values().any(|flags_set| flags_set.contains(flag))
+ }
+}
+
+/// Converts a string to an int. Will parse to int even if the string is "X.0".
+/// Returns error for "X.1".
+fn str_to_api_level(numeric_string: &str) -> Result<ApiLevel> {
+ let float_value = numeric_string.parse::<f64>()?;
+
+ if float_value.fract() == 0.0 {
+ Ok(ApiLevel(float_value as i32))
+ } else {
+ Err(anyhow!("Numeric string is float, can't parse to int."))
+ }
+}
+
+/// For each file, extracts the qualified flag names into a FinalizedFlag, then
+/// enters them in a map at the API level corresponding to their directory.
+/// Ex: /prebuilts/sdk/35/finalized-flags.txt -> {36, [flag1, flag2]}.
+pub fn read_files_to_map_using_path(flag_files: Vec<String>) -> Result<FinalizedFlagMap> {
+ let mut data_map = FinalizedFlagMap::new();
+
+ for flag_file in flag_files {
+ // Split /path/sdk/<int.int>/finalized-flags.txt -> ['/path/sdk', 'int.int', 'finalized-flags.txt'].
+ let flag_file_split: Vec<String> =
+ flag_file.clone().rsplitn(3, '/').map(|s| s.to_string()).collect();
+
+ if &flag_file_split[0] != "finalized-flags.txt" {
+ return Err(anyhow!("Provided incorrect file, must be finalized-flags.txt"));
+ }
+
+ let api_level_string = &flag_file_split[1];
+
+ // For now, skip any directory with full API level, e.g. "36.1". The
+ // finalized flag files each contain all flags finalized *up to* that
+ // level (including prior levels), so skipping intermediate levels means
+ // the flags will be included at the next full number.
+ // TODO: b/378936061 - Support full SDK version.
+ // In the future, we should error if provided a non-numeric directory.
+ let Ok(api_level) = str_to_api_level(api_level_string) else {
+ continue;
+ };
+
+ let file = fs::File::open(flag_file)?;
+ let reader = io::BufReader::new(file);
+
+ for qualified_flag_name in reader.lines() {
+ // Split the qualified flag name into package and flag name:
+ // com.my.package.name.my_flag_name -> ['com.my.package.name', 'my_flag_name'].
+ let mut flag: Vec<String> =
+ qualified_flag_name?.rsplitn(2, '.').map(|s| s.to_string()).collect();
+
+ if flag.len() != 2 {
+ continue;
+ }
+
+ let package_name = flag.pop().ok_or(anyhow!("Missing flag package."))?;
+ let flag_name = flag.pop().ok_or(anyhow!("Missing flag name."))?;
+
+ // Only add the flag if it wasn't added in a prior file.
+ data_map.insert_if_new(api_level, FinalizedFlag { flag_name, package_name });
+ }
+ }
+
+ Ok(data_map)
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::fs::File;
+ use std::io::Write;
+ use tempfile::tempdir;
+
+ const FLAG_FILE_NAME: &str = "finalized-flags.txt";
+
+ // Creates some flags for testing.
+ fn create_test_flags() -> Vec<FinalizedFlag> {
+ vec![
+ FinalizedFlag { flag_name: "name1".to_string(), package_name: "package1".to_string() },
+ FinalizedFlag { flag_name: "name2".to_string(), package_name: "package2".to_string() },
+ FinalizedFlag { flag_name: "name3".to_string(), package_name: "package3".to_string() },
+ ]
+ }
+
+ // Writes the fully qualified flag names in the given file.
+ fn add_flags_to_file(flag_file: &mut File, flags: &[FinalizedFlag]) {
+ for flag in flags {
+ let _unused = writeln!(flag_file, "{}.{}", flag.package_name, flag.flag_name);
+ }
+ }
+
+ #[test]
+ fn test_read_flags_one_file() {
+ let flags = create_test_flags();
+
+ // Create the file <temp_dir>/35/finalized-flags.txt.
+ let temp_dir = tempdir().unwrap();
+ let mut file_path = temp_dir.path().to_path_buf();
+ file_path.push("35");
+ fs::create_dir_all(&file_path).unwrap();
+ file_path.push(FLAG_FILE_NAME);
+ let mut file = File::create(&file_path).unwrap();
+
+ // Write all flags to the file.
+ add_flags_to_file(&mut file, &[flags[0].clone(), flags[1].clone()]);
+ let flag_file_path = file_path.to_string_lossy().to_string();
+
+ // Convert to map.
+ let map = read_files_to_map_using_path(vec![flag_file_path]).unwrap();
+
+ assert_eq!(map.0.len(), 1);
+ assert!(map.0.get(&ApiLevel(35)).unwrap().contains(&flags[0]));
+ assert!(map.0.get(&ApiLevel(35)).unwrap().contains(&flags[1]));
+ }
+
+ #[test]
+ fn test_read_flags_two_files() {
+ let flags = create_test_flags();
+
+ // Create the file <temp_dir>/35/finalized-flags.txt and for 36.
+ let temp_dir = tempdir().unwrap();
+ let mut file_path1 = temp_dir.path().to_path_buf();
+ file_path1.push("35");
+ fs::create_dir_all(&file_path1).unwrap();
+ file_path1.push(FLAG_FILE_NAME);
+ let mut file1 = File::create(&file_path1).unwrap();
+
+ let mut file_path2 = temp_dir.path().to_path_buf();
+ file_path2.push("36");
+ fs::create_dir_all(&file_path2).unwrap();
+ file_path2.push(FLAG_FILE_NAME);
+ let mut file2 = File::create(&file_path2).unwrap();
+
+ // Write all flags to the files.
+ add_flags_to_file(&mut file1, &[flags[0].clone()]);
+ add_flags_to_file(&mut file2, &[flags[0].clone(), flags[1].clone(), flags[2].clone()]);
+ let flag_file_path1 = file_path1.to_string_lossy().to_string();
+ let flag_file_path2 = file_path2.to_string_lossy().to_string();
+
+ // Convert to map.
+ let map = read_files_to_map_using_path(vec![flag_file_path1, flag_file_path2]).unwrap();
+
+ // Assert there are two API levels, 35 and 36.
+ assert_eq!(map.0.len(), 2);
+ assert!(map.0.get(&ApiLevel(35)).unwrap().contains(&flags[0]));
+
+ // 36 should not have the first flag in the set, as it was finalized in
+ // an earlier API level.
+ assert!(map.0.get(&ApiLevel(36)).unwrap().contains(&flags[1]));
+ assert!(map.0.get(&ApiLevel(36)).unwrap().contains(&flags[2]));
+ }
+
+ #[test]
+ fn test_read_flags_full_numbers() {
+ let flags = create_test_flags();
+
+ // Create the file <temp_dir>/35/finalized-flags.txt and for 36.
+ let temp_dir = tempdir().unwrap();
+ let mut file_path1 = temp_dir.path().to_path_buf();
+ file_path1.push("35.0");
+ fs::create_dir_all(&file_path1).unwrap();
+ file_path1.push(FLAG_FILE_NAME);
+ let mut file1 = File::create(&file_path1).unwrap();
+
+ let mut file_path2 = temp_dir.path().to_path_buf();
+ file_path2.push("36.0");
+ fs::create_dir_all(&file_path2).unwrap();
+ file_path2.push(FLAG_FILE_NAME);
+ let mut file2 = File::create(&file_path2).unwrap();
+
+ // Write all flags to the files.
+ add_flags_to_file(&mut file1, &[flags[0].clone()]);
+ add_flags_to_file(&mut file2, &[flags[0].clone(), flags[1].clone(), flags[2].clone()]);
+ let flag_file_path1 = file_path1.to_string_lossy().to_string();
+ let flag_file_path2 = file_path2.to_string_lossy().to_string();
+
+ // Convert to map.
+ let map = read_files_to_map_using_path(vec![flag_file_path1, flag_file_path2]).unwrap();
+
+ assert_eq!(map.0.len(), 2);
+ assert!(map.0.get(&ApiLevel(35)).unwrap().contains(&flags[0]));
+ assert!(map.0.get(&ApiLevel(36)).unwrap().contains(&flags[1]));
+ assert!(map.0.get(&ApiLevel(36)).unwrap().contains(&flags[2]));
+ }
+
+ #[test]
+ fn test_read_flags_fractions_round_up() {
+ let flags = create_test_flags();
+
+ // Create the file <temp_dir>/35/finalized-flags.txt and for 36.
+ let temp_dir = tempdir().unwrap();
+ let mut file_path1 = temp_dir.path().to_path_buf();
+ file_path1.push("35.1");
+ fs::create_dir_all(&file_path1).unwrap();
+ file_path1.push(FLAG_FILE_NAME);
+ let mut file1 = File::create(&file_path1).unwrap();
+
+ let mut file_path2 = temp_dir.path().to_path_buf();
+ file_path2.push("36.0");
+ fs::create_dir_all(&file_path2).unwrap();
+ file_path2.push(FLAG_FILE_NAME);
+ let mut file2 = File::create(&file_path2).unwrap();
+
+ // Write all flags to the files.
+ add_flags_to_file(&mut file1, &[flags[0].clone()]);
+ add_flags_to_file(&mut file2, &[flags[0].clone(), flags[1].clone(), flags[2].clone()]);
+ let flag_file_path1 = file_path1.to_string_lossy().to_string();
+ let flag_file_path2 = file_path2.to_string_lossy().to_string();
+
+ // Convert to map.
+ let map = read_files_to_map_using_path(vec![flag_file_path1, flag_file_path2]).unwrap();
+
+ // No flags were added in 35. All 35.1 flags were rolled up to 36.
+ assert_eq!(map.0.len(), 1);
+ assert!(!map.0.contains_key(&ApiLevel(35)));
+ assert!(map.0.get(&ApiLevel(36)).unwrap().contains(&flags[0]));
+ assert!(map.0.get(&ApiLevel(36)).unwrap().contains(&flags[1]));
+ assert!(map.0.get(&ApiLevel(36)).unwrap().contains(&flags[2]));
+ }
+
+ #[test]
+ fn test_read_flags_non_numeric() {
+ let flags = create_test_flags();
+
+ // Create the file <temp_dir>/35/finalized-flags.txt.
+ let temp_dir = tempdir().unwrap();
+ let mut file_path = temp_dir.path().to_path_buf();
+ file_path.push("35");
+ fs::create_dir_all(&file_path).unwrap();
+ file_path.push(FLAG_FILE_NAME);
+ let mut flag_file = File::create(&file_path).unwrap();
+
+ let mut invalid_path = temp_dir.path().to_path_buf();
+ invalid_path.push("sdk-annotations");
+ fs::create_dir_all(&invalid_path).unwrap();
+ invalid_path.push(FLAG_FILE_NAME);
+ File::create(&invalid_path).unwrap();
+
+ // Write all flags to the file.
+ add_flags_to_file(&mut flag_file, &[flags[0].clone(), flags[1].clone()]);
+ let flag_file_path = file_path.to_string_lossy().to_string();
+
+ // Convert to map.
+ let map = read_files_to_map_using_path(vec![
+ flag_file_path,
+ invalid_path.to_string_lossy().to_string(),
+ ])
+ .unwrap();
+
+ // No set should be created for sdk-annotations.
+ assert_eq!(map.0.len(), 1);
+ assert!(map.0.get(&ApiLevel(35)).unwrap().contains(&flags[0]));
+ assert!(map.0.get(&ApiLevel(35)).unwrap().contains(&flags[1]));
+ }
+
+ #[test]
+ fn test_read_flags_wrong_file_err() {
+ let flags = create_test_flags();
+
+ // Create the file <temp_dir>/35/finalized-flags.txt.
+ let temp_dir = tempdir().unwrap();
+ let mut file_path = temp_dir.path().to_path_buf();
+ file_path.push("35");
+ fs::create_dir_all(&file_path).unwrap();
+ file_path.push(FLAG_FILE_NAME);
+ let mut flag_file = File::create(&file_path).unwrap();
+
+ let mut pre_flag_path = temp_dir.path().to_path_buf();
+ pre_flag_path.push("18");
+ fs::create_dir_all(&pre_flag_path).unwrap();
+ pre_flag_path.push("some_random_file.txt");
+ File::create(&pre_flag_path).unwrap();
+
+ // Write all flags to the file.
+ add_flags_to_file(&mut flag_file, &[flags[0].clone(), flags[1].clone()]);
+ let flag_file_path = file_path.to_string_lossy().to_string();
+
+ // Convert to map.
+ let map = read_files_to_map_using_path(vec![
+ flag_file_path,
+ pre_flag_path.to_string_lossy().to_string(),
+ ]);
+
+ assert!(map.is_err());
+ }
+
+ #[test]
+ fn test_flags_map_insert_if_new() {
+ let flags = create_test_flags();
+ let mut map = FinalizedFlagMap::new();
+ let l35 = ApiLevel(35);
+ let l36 = ApiLevel(36);
+
+ map.insert_if_new(l35, flags[0].clone());
+ map.insert_if_new(l35, flags[1].clone());
+ map.insert_if_new(l35, flags[2].clone());
+ map.insert_if_new(l36, flags[0].clone());
+
+ assert!(map.0.get(&l35).unwrap().contains(&flags[0]));
+ assert!(map.0.get(&l35).unwrap().contains(&flags[1]));
+ assert!(map.0.get(&l35).unwrap().contains(&flags[2]));
+ assert!(!map.0.contains_key(&l36));
+ }
+
+ #[test]
+ fn test_flags_map_get_level() {
+ let flags = create_test_flags();
+ let mut map = FinalizedFlagMap::new();
+ let l35 = ApiLevel(35);
+ let l36 = ApiLevel(36);
+
+ map.insert_if_new(l35, flags[0].clone());
+ map.insert_if_new(l36, flags[1].clone());
+
+ assert_eq!(map.get_finalized_level(&flags[0]).unwrap(), l35);
+ assert_eq!(map.get_finalized_level(&flags[1]).unwrap(), l36);
+ }
+}
diff --git a/tools/aconfig/convert_finalized_flags/src/main.rs b/tools/aconfig/convert_finalized_flags/src/main.rs
new file mode 100644
index 0000000..38300f6
--- /dev/null
+++ b/tools/aconfig/convert_finalized_flags/src/main.rs
@@ -0,0 +1,57 @@
+/*
+* Copyright (C) 2025 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.
+*/
+//! convert_finalized_flags is a build time tool used to convert the finalized
+//! flags text files under prebuilts/sdk into structured data (FinalizedFlag
+//! struct).
+//! This binary is intended to run as part of a genrule to create a json file
+//! which is provided to the aconfig binary that creates the codegen.
+//! Usage:
+//! cargo run -- --flag-files-path path/to/prebuilts/sdk/finalized-flags.txt file2.txt etc
+use anyhow::Result;
+use clap::Parser;
+
+use convert_finalized_flags::read_files_to_map_using_path;
+
+const ABOUT_TEXT: &str = "Tool for processing finalized-flags.txt files.
+
+These files contain the list of qualified flag names that have been finalized,
+each on a newline. The directory of the flag file is the finalized API level.
+
+The output is a json map of API level to set of FinalizedFlag objects. The only
+supported use case for this tool is via a genrule at build time for aconfig
+codegen.
+
+Args:
+* `flag-files-path`: Space-separated list of absolute paths for the finalized
+flags files.
+";
+
+#[derive(Parser, Debug)]
+#[clap(long_about=ABOUT_TEXT, bin_name="convert-finalized-flags")]
+struct Cli {
+ /// Flags files.
+ #[arg(long = "flag_file_path")]
+ flag_file_path: Vec<String>,
+}
+
+fn main() -> Result<()> {
+ let cli = Cli::parse();
+ let finalized_flags_map = read_files_to_map_using_path(cli.flag_file_path)?;
+
+ let json_str = serde_json::to_string(&finalized_flags_map)?;
+ println!("{}", json_str);
+ Ok(())
+}
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 e07ac1d..5acb54a 100644
--- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
+++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
@@ -34,7 +34,7 @@
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 <T,U> 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);
}
diff --git a/tools/compliance/Android.bp b/tools/compliance/Android.bp
index ef5c760..33f515b 100644
--- a/tools/compliance/Android.bp
+++ b/tools/compliance/Android.bp
@@ -39,16 +39,6 @@
}
blueprint_go_binary {
- name: "compliancenotice_bom",
- srcs: ["cmd/bom/bom.go"],
- deps: [
- "compliance-module",
- "soong-response",
- ],
- testSrcs: ["cmd/bom/bom_test.go"],
-}
-
-blueprint_go_binary {
name: "compliancenotice_shippedlibs",
srcs: ["cmd/shippedlibs/shippedlibs.go"],
deps: [
@@ -131,22 +121,6 @@
testSrcs: ["cmd/xmlnotice/xmlnotice_test.go"],
}
-blueprint_go_binary {
- name: "compliance_sbom",
- srcs: ["cmd/sbom/sbom.go"],
- deps: [
- "compliance-module",
- "blueprint-deptools",
- "soong-response",
- "spdx-tools-spdxv2_2",
- "spdx-tools-builder2v2",
- "spdx-tools-spdxcommon",
- "spdx-tools-spdx-json",
- "spdx-tools-spdxlib",
- ],
- testSrcs: ["cmd/sbom/sbom_test.go"],
-}
-
bootstrap_go_package {
name: "compliance-module",
srcs: [
diff --git a/tools/compliance/cmd/bom/bom.go b/tools/compliance/cmd/bom/bom.go
deleted file mode 100644
index 187f828..0000000
--- a/tools/compliance/cmd/bom/bom.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 main
-
-import (
- "bytes"
- "flag"
- "fmt"
- "io"
- "io/fs"
- "os"
- "path/filepath"
- "strings"
-
- "android/soong/response"
- "android/soong/tools/compliance"
-)
-
-var (
- failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
- failNoLicenses = fmt.Errorf("No licenses found")
-)
-
-type context struct {
- stdout io.Writer
- stderr io.Writer
- rootFS fs.FS
- stripPrefix []string
-}
-
-func (ctx context) strip(installPath string) string {
- for _, prefix := range ctx.stripPrefix {
- if strings.HasPrefix(installPath, prefix) {
- p := strings.TrimPrefix(installPath, prefix)
- if 0 == len(p) {
- continue
- }
- return p
- }
- }
- return installPath
-}
-
-// newMultiString creates a flag that allows multiple values in an array.
-func newMultiString(flags *flag.FlagSet, name, usage string) *multiString {
- var f multiString
- flags.Var(&f, name, usage)
- return &f
-}
-
-// multiString implements the flag `Value` interface for multiple strings.
-type multiString []string
-
-func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
-func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
-
-func main() {
- var expandedArgs []string
- for _, arg := range os.Args[1:] {
- if strings.HasPrefix(arg, "@") {
- f, err := os.Open(strings.TrimPrefix(arg, "@"))
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(1)
- }
-
- respArgs, err := response.ReadRspFile(f)
- f.Close()
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(1)
- }
- expandedArgs = append(expandedArgs, respArgs...)
- } else {
- expandedArgs = append(expandedArgs, arg)
- }
- }
-
- flags := flag.NewFlagSet("flags", flag.ExitOnError)
-
- flags.Usage = func() {
- fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
-
-Outputs a bill of materials. i.e. the list of installed paths.
-
-Options:
-`, filepath.Base(os.Args[0]))
- flags.PrintDefaults()
- }
-
- outputFile := flags.String("o", "-", "Where to write the bill of materials. (default stdout)")
- stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
-
- flags.Parse(expandedArgs)
-
- // Must specify at least one root target.
- if flags.NArg() == 0 {
- flags.Usage()
- os.Exit(2)
- }
-
- if len(*outputFile) == 0 {
- flags.Usage()
- fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
- os.Exit(2)
- } else {
- dir, err := filepath.Abs(filepath.Dir(*outputFile))
- if err != nil {
- fmt.Fprintf(os.Stderr, "cannot determine path to %q: %s\n", *outputFile, err)
- os.Exit(1)
- }
- fi, err := os.Stat(dir)
- if err != nil {
- fmt.Fprintf(os.Stderr, "cannot read directory %q of %q: %s\n", dir, *outputFile, err)
- os.Exit(1)
- }
- if !fi.IsDir() {
- fmt.Fprintf(os.Stderr, "parent %q of %q is not a directory\n", dir, *outputFile)
- os.Exit(1)
- }
- }
-
- var ofile io.Writer
- ofile = os.Stdout
- if *outputFile != "-" {
- ofile = &bytes.Buffer{}
- }
-
- ctx := &context{ofile, os.Stderr, compliance.FS, *stripPrefix}
-
- err := billOfMaterials(ctx, flags.Args()...)
- if err != nil {
- if err == failNoneRequested {
- flags.Usage()
- }
- fmt.Fprintf(os.Stderr, "%s\n", err.Error())
- os.Exit(1)
- }
- if *outputFile != "-" {
- err := os.WriteFile(*outputFile, ofile.(*bytes.Buffer).Bytes(), 0666)
- if err != nil {
- fmt.Fprintf(os.Stderr, "could not write output to %q: %s\n", *outputFile, err)
- os.Exit(1)
- }
- }
- os.Exit(0)
-}
-
-// billOfMaterials implements the bom utility.
-func billOfMaterials(ctx *context, files ...string) error {
- // Must be at least one root file.
- if len(files) < 1 {
- return failNoneRequested
- }
-
- // Read the license graph from the license metadata files (*.meta_lic).
- licenseGraph, err := compliance.ReadLicenseGraph(ctx.rootFS, ctx.stderr, files)
- if err != nil {
- return fmt.Errorf("Unable to read license metadata file(s) %q: %v\n", files, err)
- }
- if licenseGraph == nil {
- return failNoLicenses
- }
-
- // rs contains all notice resolutions.
- rs := compliance.ResolveNotices(licenseGraph)
-
- ni, err := compliance.IndexLicenseTexts(ctx.rootFS, licenseGraph, rs)
- if err != nil {
- return fmt.Errorf("Unable to read license text file(s) for %q: %v\n", files, err)
- }
-
- for path := range ni.InstallPaths() {
- fmt.Fprintln(ctx.stdout, ctx.strip(path))
- }
- return nil
-}
diff --git a/tools/compliance/cmd/bom/bom_test.go b/tools/compliance/cmd/bom/bom_test.go
deleted file mode 100644
index 87a3b50..0000000
--- a/tools/compliance/cmd/bom/bom_test.go
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 main
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "os"
- "strings"
- "testing"
-
- "android/soong/tools/compliance"
-)
-
-func TestMain(m *testing.M) {
- // Change into the parent directory before running the tests
- // so they can find the testdata directory.
- if err := os.Chdir(".."); err != nil {
- fmt.Printf("failed to change to testdata directory: %s\n", err)
- os.Exit(1)
- }
- os.Exit(m.Run())
-}
-
-func Test(t *testing.T) {
- tests := []struct {
- condition string
- name string
- outDir string
- roots []string
- stripPrefix string
- expectedOut []string
- }{
- {
- condition: "firstparty",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
- stripPrefix: "out/target/product/fictional",
- expectedOut: []string{
- "/system/apex/highest.apex",
- "/system/apex/highest.apex/bin/bin1",
- "/system/apex/highest.apex/bin/bin2",
- "/system/apex/highest.apex/lib/liba.so",
- "/system/apex/highest.apex/lib/libb.so",
- },
- },
- {
- condition: "firstparty",
- name: "container",
- roots: []string{"container.zip.meta_lic"},
- stripPrefix: "out/target/product/fictional/data/",
- expectedOut: []string{
- "container.zip",
- "container.zip/bin1",
- "container.zip/bin2",
- "container.zip/liba.so",
- "container.zip/libb.so",
- },
- },
- {
- condition: "firstparty",
- name: "application",
- roots: []string{"application.meta_lic"},
- stripPrefix: "out/target/product/fictional/bin/",
- expectedOut: []string{"application"},
- },
- {
- condition: "firstparty",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
- stripPrefix: "out/target/product/fictional/system/",
- expectedOut: []string{"bin/bin1"},
- },
- {
- condition: "firstparty",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
- stripPrefix: "out/target/product/fictional/system/",
- expectedOut: []string{"lib/libd.so"},
- },
- {
- condition: "notice",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
- expectedOut: []string{
- "out/target/product/fictional/system/apex/highest.apex",
- "out/target/product/fictional/system/apex/highest.apex/bin/bin1",
- "out/target/product/fictional/system/apex/highest.apex/bin/bin2",
- "out/target/product/fictional/system/apex/highest.apex/lib/liba.so",
- "out/target/product/fictional/system/apex/highest.apex/lib/libb.so",
- },
- },
- {
- condition: "notice",
- name: "container",
- roots: []string{"container.zip.meta_lic"},
- expectedOut: []string{
- "out/target/product/fictional/data/container.zip",
- "out/target/product/fictional/data/container.zip/bin1",
- "out/target/product/fictional/data/container.zip/bin2",
- "out/target/product/fictional/data/container.zip/liba.so",
- "out/target/product/fictional/data/container.zip/libb.so",
- },
- },
- {
- condition: "notice",
- name: "application",
- roots: []string{"application.meta_lic"},
- expectedOut: []string{"out/target/product/fictional/bin/application"},
- },
- {
- condition: "notice",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
- expectedOut: []string{"out/target/product/fictional/system/bin/bin1"},
- },
- {
- condition: "notice",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
- expectedOut: []string{"out/target/product/fictional/system/lib/libd.so"},
- },
- {
- condition: "reciprocal",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
- stripPrefix: "out/target/product/fictional/system/apex/",
- expectedOut: []string{
- "highest.apex",
- "highest.apex/bin/bin1",
- "highest.apex/bin/bin2",
- "highest.apex/lib/liba.so",
- "highest.apex/lib/libb.so",
- },
- },
- {
- condition: "reciprocal",
- name: "container",
- roots: []string{"container.zip.meta_lic"},
- stripPrefix: "out/target/product/fictional/data/",
- expectedOut: []string{
- "container.zip",
- "container.zip/bin1",
- "container.zip/bin2",
- "container.zip/liba.so",
- "container.zip/libb.so",
- },
- },
- {
- condition: "reciprocal",
- name: "application",
- roots: []string{"application.meta_lic"},
- stripPrefix: "out/target/product/fictional/bin/",
- expectedOut: []string{"application"},
- },
- {
- condition: "reciprocal",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
- stripPrefix: "out/target/product/fictional/system/",
- expectedOut: []string{"bin/bin1"},
- },
- {
- condition: "reciprocal",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
- stripPrefix: "out/target/product/fictional/system/",
- expectedOut: []string{"lib/libd.so"},
- },
- {
- condition: "restricted",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
- stripPrefix: "out/target/product/fictional/system/apex/",
- expectedOut: []string{
- "highest.apex",
- "highest.apex/bin/bin1",
- "highest.apex/bin/bin2",
- "highest.apex/lib/liba.so",
- "highest.apex/lib/libb.so",
- },
- },
- {
- condition: "restricted",
- name: "container",
- roots: []string{"container.zip.meta_lic"},
- stripPrefix: "out/target/product/fictional/data/",
- expectedOut: []string{
- "container.zip",
- "container.zip/bin1",
- "container.zip/bin2",
- "container.zip/liba.so",
- "container.zip/libb.so",
- },
- },
- {
- condition: "restricted",
- name: "application",
- roots: []string{"application.meta_lic"},
- stripPrefix: "out/target/product/fictional/bin/",
- expectedOut: []string{"application"},
- },
- {
- condition: "restricted",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
- stripPrefix: "out/target/product/fictional/system/",
- expectedOut: []string{"bin/bin1"},
- },
- {
- condition: "restricted",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
- stripPrefix: "out/target/product/fictional/system/",
- expectedOut: []string{"lib/libd.so"},
- },
- {
- condition: "proprietary",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
- stripPrefix: "out/target/product/fictional/system/apex/",
- expectedOut: []string{
- "highest.apex",
- "highest.apex/bin/bin1",
- "highest.apex/bin/bin2",
- "highest.apex/lib/liba.so",
- "highest.apex/lib/libb.so",
- },
- },
- {
- condition: "proprietary",
- name: "container",
- roots: []string{"container.zip.meta_lic"},
- stripPrefix: "out/target/product/fictional/data/",
- expectedOut: []string{
- "container.zip",
- "container.zip/bin1",
- "container.zip/bin2",
- "container.zip/liba.so",
- "container.zip/libb.so",
- },
- },
- {
- condition: "proprietary",
- name: "application",
- roots: []string{"application.meta_lic"},
- stripPrefix: "out/target/product/fictional/bin/",
- expectedOut: []string{"application"},
- },
- {
- condition: "proprietary",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
- stripPrefix: "out/target/product/fictional/system/",
- expectedOut: []string{"bin/bin1"},
- },
- {
- condition: "proprietary",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
- stripPrefix: "out/target/product/fictional/system/",
- expectedOut: []string{"lib/libd.so"},
- },
- }
- for _, tt := range tests {
- t.Run(tt.condition+" "+tt.name, func(t *testing.T) {
- stdout := &bytes.Buffer{}
- stderr := &bytes.Buffer{}
-
- rootFiles := make([]string, 0, len(tt.roots))
- for _, r := range tt.roots {
- rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r)
- }
-
- ctx := context{stdout, stderr, compliance.GetFS(tt.outDir), []string{tt.stripPrefix}}
-
- err := billOfMaterials(&ctx, rootFiles...)
- if err != nil {
- t.Fatalf("bom: error = %v, stderr = %v", err, stderr)
- return
- }
- if stderr.Len() > 0 {
- t.Errorf("bom: gotStderr = %v, want none", stderr)
- }
-
- t.Logf("got stdout: %s", stdout.String())
-
- t.Logf("want stdout: %s", strings.Join(tt.expectedOut, "\n"))
-
- out := bufio.NewScanner(stdout)
- lineno := 0
- for out.Scan() {
- line := out.Text()
- if strings.TrimLeft(line, " ") == "" {
- continue
- }
- if len(tt.expectedOut) <= lineno {
- t.Errorf("bom: unexpected output at line %d: got %q, want nothing (wanted %d lines)", lineno+1, line, len(tt.expectedOut))
- } else if tt.expectedOut[lineno] != line {
- t.Errorf("bom: unexpected output at line %d: got %q, want %q", lineno+1, line, tt.expectedOut[lineno])
- }
- lineno++
- }
- for ; lineno < len(tt.expectedOut); lineno++ {
- t.Errorf("bom: missing output line %d: ended early, want %q", lineno+1, tt.expectedOut[lineno])
- }
- })
- }
-}
diff --git a/tools/compliance/cmd/sbom/sbom.go b/tools/compliance/cmd/sbom/sbom.go
deleted file mode 100644
index a53741f..0000000
--- a/tools/compliance/cmd/sbom/sbom.go
+++ /dev/null
@@ -1,547 +0,0 @@
-// Copyright 2022 Google LLC
-//
-// 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 main
-
-import (
- "bytes"
- "crypto/sha1"
- "encoding/hex"
- "flag"
- "fmt"
- "io"
- "io/fs"
- "os"
- "path/filepath"
- "sort"
- "strings"
- "time"
-
- "android/soong/response"
- "android/soong/tools/compliance"
- "android/soong/tools/compliance/projectmetadata"
-
- "github.com/google/blueprint/deptools"
-
- "github.com/spdx/tools-golang/builder/builder2v2"
- spdx_json "github.com/spdx/tools-golang/json"
- "github.com/spdx/tools-golang/spdx/common"
- spdx "github.com/spdx/tools-golang/spdx/v2_2"
- "github.com/spdx/tools-golang/spdxlib"
-)
-
-var (
- failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
- failNoLicenses = fmt.Errorf("No licenses found")
-)
-
-const NOASSERTION = "NOASSERTION"
-
-type context struct {
- stdout io.Writer
- stderr io.Writer
- rootFS fs.FS
- product string
- stripPrefix []string
- creationTime creationTimeGetter
- buildid string
-}
-
-func (ctx context) strip(installPath string) string {
- for _, prefix := range ctx.stripPrefix {
- if strings.HasPrefix(installPath, prefix) {
- p := strings.TrimPrefix(installPath, prefix)
- if 0 == len(p) {
- p = ctx.product
- }
- if 0 == len(p) {
- continue
- }
- return p
- }
- }
- return installPath
-}
-
-// newMultiString creates a flag that allows multiple values in an array.
-func newMultiString(flags *flag.FlagSet, name, usage string) *multiString {
- var f multiString
- flags.Var(&f, name, usage)
- return &f
-}
-
-// multiString implements the flag `Value` interface for multiple strings.
-type multiString []string
-
-func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
-func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
-
-func main() {
- var expandedArgs []string
- for _, arg := range os.Args[1:] {
- if strings.HasPrefix(arg, "@") {
- f, err := os.Open(strings.TrimPrefix(arg, "@"))
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(1)
- }
-
- respArgs, err := response.ReadRspFile(f)
- f.Close()
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(1)
- }
- expandedArgs = append(expandedArgs, respArgs...)
- } else {
- expandedArgs = append(expandedArgs, arg)
- }
- }
-
- flags := flag.NewFlagSet("flags", flag.ExitOnError)
-
- flags.Usage = func() {
- fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
-
-Outputs an SBOM.spdx.
-
-Options:
-`, filepath.Base(os.Args[0]))
- flags.PrintDefaults()
- }
-
- outputFile := flags.String("o", "-", "Where to write the SBOM spdx file. (default stdout)")
- depsFile := flags.String("d", "", "Where to write the deps file")
- product := flags.String("product", "", "The name of the product for which the notice is generated.")
- stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
- buildid := flags.String("build_id", "", "Uniquely identifies the build. (default timestamp)")
-
- flags.Parse(expandedArgs)
-
- // Must specify at least one root target.
- if flags.NArg() == 0 {
- flags.Usage()
- os.Exit(2)
- }
-
- if len(*outputFile) == 0 {
- flags.Usage()
- fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
- os.Exit(2)
- } else {
- dir, err := filepath.Abs(filepath.Dir(*outputFile))
- if err != nil {
- fmt.Fprintf(os.Stderr, "cannot determine path to %q: %s\n", *outputFile, err)
- os.Exit(1)
- }
- fi, err := os.Stat(dir)
- if err != nil {
- fmt.Fprintf(os.Stderr, "cannot read directory %q of %q: %s\n", dir, *outputFile, err)
- os.Exit(1)
- }
- if !fi.IsDir() {
- fmt.Fprintf(os.Stderr, "parent %q of %q is not a directory\n", dir, *outputFile)
- os.Exit(1)
- }
- }
-
- var ofile io.Writer
- ofile = os.Stdout
- var obuf *bytes.Buffer
- if *outputFile != "-" {
- obuf = &bytes.Buffer{}
- ofile = obuf
- }
-
- ctx := &context{ofile, os.Stderr, compliance.FS, *product, *stripPrefix, actualTime, *buildid}
-
- spdxDoc, deps, err := sbomGenerator(ctx, flags.Args()...)
-
- if err != nil {
- if err == failNoneRequested {
- flags.Usage()
- }
- fmt.Fprintf(os.Stderr, "%s\n", err.Error())
- os.Exit(1)
- }
-
- // writing the spdx Doc created
- if err := spdx_json.Save2_2(spdxDoc, ofile); err != nil {
- fmt.Fprintf(os.Stderr, "failed to write document to %v: %v", *outputFile, err)
- os.Exit(1)
- }
-
- if *outputFile != "-" {
- err := os.WriteFile(*outputFile, obuf.Bytes(), 0666)
- if err != nil {
- fmt.Fprintf(os.Stderr, "could not write output to %q: %s\n", *outputFile, err)
- os.Exit(1)
- }
- }
-
- if *depsFile != "" {
- err := deptools.WriteDepFile(*depsFile, *outputFile, deps)
- if err != nil {
- fmt.Fprintf(os.Stderr, "could not write deps to %q: %s\n", *depsFile, err)
- os.Exit(1)
- }
- }
- os.Exit(0)
-}
-
-type creationTimeGetter func() string
-
-// actualTime returns current time in UTC
-func actualTime() string {
- t := time.Now().UTC()
- return t.UTC().Format("2006-01-02T15:04:05Z")
-}
-
-// replaceSlashes replaces "/" by "-" for the library path to be used for packages & files SPDXID
-func replaceSlashes(x string) string {
- return strings.ReplaceAll(x, "/", "-")
-}
-
-// stripDocName removes the outdir prefix and meta_lic suffix from a target Name
-func stripDocName(name string) string {
- // remove outdir prefix
- if strings.HasPrefix(name, "out/") {
- name = name[4:]
- }
-
- // remove suffix
- if strings.HasSuffix(name, ".meta_lic") {
- name = name[:len(name)-9]
- } else if strings.HasSuffix(name, "/meta_lic") {
- name = name[:len(name)-9] + "/"
- }
-
- return name
-}
-
-// getPackageName returns a package name of a target Node
-func getPackageName(_ *context, tn *compliance.TargetNode) string {
- return replaceSlashes(tn.Name())
-}
-
-// getDocumentName returns a package name of a target Node
-func getDocumentName(ctx *context, tn *compliance.TargetNode, pm *projectmetadata.ProjectMetadata) string {
- if len(ctx.product) > 0 {
- return replaceSlashes(ctx.product)
- }
- if len(tn.ModuleName()) > 0 {
- if pm != nil {
- return replaceSlashes(pm.Name() + ":" + tn.ModuleName())
- }
- return replaceSlashes(tn.ModuleName())
- }
-
- return stripDocName(replaceSlashes(tn.Name()))
-}
-
-// getDownloadUrl returns the download URL if available (GIT, SVN, etc..),
-// or NOASSERTION if not available, none determined or ambiguous
-func getDownloadUrl(_ *context, pm *projectmetadata.ProjectMetadata) string {
- if pm == nil {
- return NOASSERTION
- }
-
- urlsByTypeName := pm.UrlsByTypeName()
- if urlsByTypeName == nil {
- return NOASSERTION
- }
-
- url := urlsByTypeName.DownloadUrl()
- if url == "" {
- return NOASSERTION
- }
- return url
-}
-
-// getProjectMetadata returns the optimal project metadata for the target node
-func getProjectMetadata(_ *context, pmix *projectmetadata.Index,
- tn *compliance.TargetNode) (*projectmetadata.ProjectMetadata, error) {
- pms, err := pmix.MetadataForProjects(tn.Projects()...)
- if err != nil {
- return nil, fmt.Errorf("Unable to read projects for %q: %w\n", tn.Name(), err)
- }
- if len(pms) == 0 {
- return nil, nil
- }
-
- // Getting the project metadata that contains most of the info needed for sbomGenerator
- score := -1
- index := -1
- for i := 0; i < len(pms); i++ {
- tempScore := 0
- if pms[i].Name() != "" {
- tempScore += 1
- }
- if pms[i].Version() != "" {
- tempScore += 1
- }
- if pms[i].UrlsByTypeName().DownloadUrl() != "" {
- tempScore += 1
- }
-
- if tempScore == score {
- if pms[i].Project() < pms[index].Project() {
- index = i
- }
- } else if tempScore > score {
- score = tempScore
- index = i
- }
- }
- return pms[index], nil
-}
-
-// inputFiles returns the complete list of files read
-func inputFiles(lg *compliance.LicenseGraph, pmix *projectmetadata.Index, licenseTexts []string) []string {
- projectMeta := pmix.AllMetadataFiles()
- targets := lg.TargetNames()
- files := make([]string, 0, len(licenseTexts)+len(targets)+len(projectMeta))
- files = append(files, licenseTexts...)
- files = append(files, targets...)
- files = append(files, projectMeta...)
- return files
-}
-
-// generateSPDXNamespace generates a unique SPDX Document Namespace using a SHA1 checksum
-func generateSPDXNamespace(buildid string, created string, files ...string) string {
-
- seed := strings.Join(files, "")
-
- if buildid == "" {
- seed += created
- } else {
- seed += buildid
- }
-
- // Compute a SHA1 checksum of the seed.
- hash := sha1.Sum([]byte(seed))
- uuid := hex.EncodeToString(hash[:])
-
- namespace := fmt.Sprintf("SPDXRef-DOCUMENT-%s", uuid)
-
- return namespace
-}
-
-// sbomGenerator implements the spdx bom utility
-
-// SBOM is part of the new government regulation issued to improve national cyber security
-// and enhance software supply chain and transparency, see https://www.cisa.gov/sbom
-
-// sbomGenerator uses the SPDX standard, see the SPDX specification (https://spdx.github.io/spdx-spec/)
-// sbomGenerator is also following the internal google SBOM styleguide (http://goto.google.com/spdx-style-guide)
-func sbomGenerator(ctx *context, files ...string) (*spdx.Document, []string, error) {
- // Must be at least one root file.
- if len(files) < 1 {
- return nil, nil, failNoneRequested
- }
-
- pmix := projectmetadata.NewIndex(ctx.rootFS)
-
- lg, err := compliance.ReadLicenseGraph(ctx.rootFS, ctx.stderr, files)
-
- if err != nil {
- return nil, nil, fmt.Errorf("Unable to read license text file(s) for %q: %v\n", files, err)
- }
-
- // creating the packages section
- pkgs := []*spdx.Package{}
-
- // creating the relationship section
- relationships := []*spdx.Relationship{}
-
- // creating the license section
- otherLicenses := []*spdx.OtherLicense{}
-
- // spdx document name
- var docName string
-
- // main package name
- var mainPkgName string
-
- // implementing the licenses references for the packages
- licenses := make(map[string]string)
- concludedLicenses := func(licenseTexts []string) string {
- licenseRefs := make([]string, 0, len(licenseTexts))
- for _, licenseText := range licenseTexts {
- license := strings.SplitN(licenseText, ":", 2)[0]
- if _, ok := licenses[license]; !ok {
- licenseRef := "LicenseRef-" + replaceSlashes(license)
- licenses[license] = licenseRef
- }
-
- licenseRefs = append(licenseRefs, licenses[license])
- }
- if len(licenseRefs) > 1 {
- return "(" + strings.Join(licenseRefs, " AND ") + ")"
- } else if len(licenseRefs) == 1 {
- return licenseRefs[0]
- }
- return "NONE"
- }
-
- isMainPackage := true
- visitedNodes := make(map[*compliance.TargetNode]struct{})
-
- // performing a Breadth-first top down walk of licensegraph and building package information
- compliance.WalkTopDownBreadthFirst(nil, lg,
- func(lg *compliance.LicenseGraph, tn *compliance.TargetNode, path compliance.TargetEdgePath) bool {
- if err != nil {
- return false
- }
- var pm *projectmetadata.ProjectMetadata
- pm, err = getProjectMetadata(ctx, pmix, tn)
- if err != nil {
- return false
- }
-
- if isMainPackage {
- docName = getDocumentName(ctx, tn, pm)
- mainPkgName = replaceSlashes(getPackageName(ctx, tn))
- isMainPackage = false
- }
-
- if len(path) == 0 {
- // Add the describe relationship for the main package
- rln := &spdx.Relationship{
- RefA: common.MakeDocElementID("" /* this document */, "DOCUMENT"),
- RefB: common.MakeDocElementID("", mainPkgName),
- Relationship: "DESCRIBES",
- }
- relationships = append(relationships, rln)
-
- } else {
- // Check parent and identify annotation
- parent := path[len(path)-1]
- targetEdge := parent.Edge()
- if targetEdge.IsRuntimeDependency() {
- // Adding the dynamic link annotation RUNTIME_DEPENDENCY_OF relationship
- rln := &spdx.Relationship{
- RefA: common.MakeDocElementID("", replaceSlashes(getPackageName(ctx, tn))),
- RefB: common.MakeDocElementID("", replaceSlashes(getPackageName(ctx, targetEdge.Target()))),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- }
- relationships = append(relationships, rln)
-
- } else if targetEdge.IsDerivation() {
- // Adding the derivation annotation as a CONTAINS relationship
- rln := &spdx.Relationship{
- RefA: common.MakeDocElementID("", replaceSlashes(getPackageName(ctx, targetEdge.Target()))),
- RefB: common.MakeDocElementID("", replaceSlashes(getPackageName(ctx, tn))),
- Relationship: "CONTAINS",
- }
- relationships = append(relationships, rln)
-
- } else if targetEdge.IsBuildTool() {
- // Adding the toolchain annotation as a BUILD_TOOL_OF relationship
- rln := &spdx.Relationship{
- RefA: common.MakeDocElementID("", replaceSlashes(getPackageName(ctx, tn))),
- RefB: common.MakeDocElementID("", replaceSlashes(getPackageName(ctx, targetEdge.Target()))),
- Relationship: "BUILD_TOOL_OF",
- }
- relationships = append(relationships, rln)
-
- } else {
- panic(fmt.Errorf("Unknown dependency type: %v", targetEdge.Annotations()))
- }
- }
-
- if _, alreadyVisited := visitedNodes[tn]; alreadyVisited {
- return false
- }
- visitedNodes[tn] = struct{}{}
- pkgName := getPackageName(ctx, tn)
-
- // Making an spdx package and adding it to pkgs
- pkg := &spdx.Package{
- PackageName: replaceSlashes(pkgName),
- PackageDownloadLocation: getDownloadUrl(ctx, pm),
- PackageSPDXIdentifier: common.ElementID(replaceSlashes(pkgName)),
- PackageLicenseConcluded: concludedLicenses(tn.LicenseTexts()),
- }
-
- if pm != nil && pm.Version() != "" {
- pkg.PackageVersion = pm.Version()
- } else {
- pkg.PackageVersion = NOASSERTION
- }
-
- pkgs = append(pkgs, pkg)
-
- return true
- })
-
- // Adding Non-standard licenses
-
- licenseTexts := make([]string, 0, len(licenses))
-
- for licenseText := range licenses {
- licenseTexts = append(licenseTexts, licenseText)
- }
-
- sort.Strings(licenseTexts)
-
- for _, licenseText := range licenseTexts {
- // open the file
- f, err := ctx.rootFS.Open(filepath.Clean(licenseText))
- if err != nil {
- return nil, nil, fmt.Errorf("error opening license text file %q: %w", licenseText, err)
- }
-
- // read the file
- text, err := io.ReadAll(f)
- if err != nil {
- return nil, nil, fmt.Errorf("error reading license text file %q: %w", licenseText, err)
- }
- // Making an spdx License and adding it to otherLicenses
- otherLicenses = append(otherLicenses, &spdx.OtherLicense{
- LicenseName: strings.Replace(licenses[licenseText], "LicenseRef-", "", -1),
- LicenseIdentifier: string(licenses[licenseText]),
- ExtractedText: string(text),
- })
- }
-
- deps := inputFiles(lg, pmix, licenseTexts)
- sort.Strings(deps)
-
- // Making the SPDX doc
- ci, err := builder2v2.BuildCreationInfoSection2_2("Organization", "Google LLC", nil)
- if err != nil {
- return nil, nil, fmt.Errorf("Unable to build creation info section for SPDX doc: %v\n", err)
- }
-
- ci.Created = ctx.creationTime()
-
- doc := &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: docName,
- DocumentNamespace: generateSPDXNamespace(ctx.buildid, ci.Created, files...),
- CreationInfo: ci,
- Packages: pkgs,
- Relationships: relationships,
- OtherLicenses: otherLicenses,
- }
-
- if err := spdxlib.ValidateDocument2_2(doc); err != nil {
- return nil, nil, fmt.Errorf("Unable to validate the SPDX doc: %v\n", err)
- }
-
- return doc, deps, nil
-}
diff --git a/tools/compliance/cmd/sbom/sbom_test.go b/tools/compliance/cmd/sbom/sbom_test.go
deleted file mode 100644
index 13ba66d..0000000
--- a/tools/compliance/cmd/sbom/sbom_test.go
+++ /dev/null
@@ -1,2558 +0,0 @@
-// Copyright 2022 Google LLC
-//
-// 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 main
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "os"
- "reflect"
- "strings"
- "testing"
- "time"
-
- "android/soong/tools/compliance"
-
- "github.com/spdx/tools-golang/builder/builder2v2"
- "github.com/spdx/tools-golang/spdx/common"
- spdx "github.com/spdx/tools-golang/spdx/v2_2"
-)
-
-func TestMain(m *testing.M) {
- // Change into the parent directory before running the tests
- // so they can find the testdata directory.
- if err := os.Chdir(".."); err != nil {
- fmt.Printf("failed to change to testdata directory: %s\n", err)
- os.Exit(1)
- }
- os.Exit(m.Run())
-}
-
-func Test(t *testing.T) {
- tests := []struct {
- condition string
- name string
- outDir string
- roots []string
- stripPrefix string
- expectedOut *spdx.Document
- expectedDeps []string
- }{
- {
- condition: "firstparty",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-firstparty-highest.apex",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/firstparty/highest.apex.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-firstparty-highest.apex.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-highest.apex.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-bin-bin2.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-bin-bin2.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-lib-libb.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-lib-libb.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-highest.apex.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-bin-bin2.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-lib-libb.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-lib-libb.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-lib-libd.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/firstparty/bin/bin1.meta_lic",
- "testdata/firstparty/bin/bin2.meta_lic",
- "testdata/firstparty/highest.apex.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/libb.so.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
- "testdata/firstparty/lib/libd.so.meta_lic",
- },
- },
- {
- condition: "firstparty",
- name: "application",
- roots: []string{"application.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-firstparty-application",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/firstparty/application.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-firstparty-application.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-application.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-bin-bin3.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-bin-bin3.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-lib-libb.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-lib-libb.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-application.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-bin-bin3.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-application.meta_lic"),
- Relationship: "BUILD_TOOL_OF",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-application.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-lib-libb.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-application.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/firstparty/application.meta_lic",
- "testdata/firstparty/bin/bin3.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/libb.so.meta_lic",
- },
- },
- {
- condition: "firstparty",
- name: "container",
- roots: []string{"container.zip.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-firstparty-container.zip",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/firstparty/container.zip.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-firstparty-container.zip.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-container.zip.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-bin-bin2.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-bin-bin2.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-lib-libb.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-lib-libb.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-container.zip.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-bin-bin2.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-lib-libb.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-lib-libb.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-lib-libd.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/firstparty/bin/bin1.meta_lic",
- "testdata/firstparty/bin/bin2.meta_lic",
- "testdata/firstparty/container.zip.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/libb.so.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
- "testdata/firstparty/lib/libd.so.meta_lic",
- },
- },
- {
- condition: "firstparty",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-firstparty-bin-bin1",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/firstparty/bin/bin1.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-firstparty-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-firstparty-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-firstparty-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/firstparty/bin/bin1.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
- },
- },
- {
- condition: "firstparty",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-firstparty-lib-libd.so",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/firstparty/lib/libd.so.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-firstparty-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-firstparty-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-firstparty-lib-libd.so.meta_lic"),
- Relationship: "DESCRIBES",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/firstparty/lib/libd.so.meta_lic",
- },
- },
- {
- condition: "notice",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-notice-highest.apex",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/notice/highest.apex.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-notice-highest.apex.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-highest.apex.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-notice-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-notice-bin-bin2.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-bin-bin2.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-notice-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- {
- PackageName: "testdata-notice-lib-libb.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-lib-libb.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-notice-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- {
- PackageName: "testdata-notice-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-notice-highest.apex.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-bin-bin2.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-lib-libb.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-lib-libb.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-lib-libd.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/notice/NOTICE_LICENSE",
- "testdata/notice/bin/bin1.meta_lic",
- "testdata/notice/bin/bin2.meta_lic",
- "testdata/notice/highest.apex.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/libb.so.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
- "testdata/notice/lib/libd.so.meta_lic",
- },
- },
- {
- condition: "notice",
- name: "container",
- roots: []string{"container.zip.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-notice-container.zip",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/notice/container.zip.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-notice-container.zip.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-container.zip.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-notice-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-notice-bin-bin2.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-bin-bin2.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-notice-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- {
- PackageName: "testdata-notice-lib-libb.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-lib-libb.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-notice-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- {
- PackageName: "testdata-notice-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-notice-container.zip.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-bin-bin2.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-lib-libb.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-lib-libb.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-lib-libd.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/notice/NOTICE_LICENSE",
- "testdata/notice/bin/bin1.meta_lic",
- "testdata/notice/bin/bin2.meta_lic",
- "testdata/notice/container.zip.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/libb.so.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
- "testdata/notice/lib/libd.so.meta_lic",
- },
- },
- {
- condition: "notice",
- name: "application",
- roots: []string{"application.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-notice-application",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/notice/application.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-notice-application.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-application.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-notice-bin-bin3.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-bin-bin3.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- {
- PackageName: "testdata-notice-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- {
- PackageName: "testdata-notice-lib-libb.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-lib-libb.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-notice-application.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-bin-bin3.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-application.meta_lic"),
- Relationship: "BUILD_TOOL_OF",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-application.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-lib-libb.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-application.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/notice/NOTICE_LICENSE",
- "testdata/notice/application.meta_lic",
- "testdata/notice/bin/bin3.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/libb.so.meta_lic",
- },
- },
- {
- condition: "notice",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-notice-bin-bin1",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/notice/bin/bin1.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-notice-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-notice-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- {
- PackageName: "testdata-notice-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-notice-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-notice-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/notice/NOTICE_LICENSE",
- "testdata/notice/bin/bin1.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
- },
- },
- {
- condition: "notice",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-notice-lib-libd.so",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/notice/lib/libd.so.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-notice-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-notice-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-notice-lib-libd.so.meta_lic"),
- Relationship: "DESCRIBES",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/notice/NOTICE_LICENSE",
- "testdata/notice/lib/libd.so.meta_lic",
- },
- },
- {
- condition: "reciprocal",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-reciprocal-highest.apex",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/reciprocal/highest.apex.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-reciprocal-highest.apex.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-highest.apex.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-reciprocal-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-reciprocal-bin-bin2.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-bin-bin2.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-reciprocal-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- {
- PackageName: "testdata-reciprocal-lib-libb.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-lib-libb.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-reciprocal-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- {
- PackageName: "testdata-reciprocal-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-highest.apex.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-reciprocal-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-bin-bin1.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-reciprocal-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-bin-bin2.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-reciprocal-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-reciprocal-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-lib-libb.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-reciprocal-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-reciprocal-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-reciprocal-lib-libb.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-reciprocal-lib-libd.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- ExtractedText: "$$$Reciprocal License$$$\n",
- LicenseName: "testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/notice/NOTICE_LICENSE",
- "testdata/reciprocal/RECIPROCAL_LICENSE",
- "testdata/reciprocal/bin/bin1.meta_lic",
- "testdata/reciprocal/bin/bin2.meta_lic",
- "testdata/reciprocal/highest.apex.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/libb.so.meta_lic",
- "testdata/reciprocal/lib/libc.a.meta_lic",
- "testdata/reciprocal/lib/libd.so.meta_lic",
- },
- },
- {
- condition: "reciprocal",
- name: "application",
- roots: []string{"application.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-reciprocal-application",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/reciprocal/application.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-reciprocal-application.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-application.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-reciprocal-bin-bin3.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-bin-bin3.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- {
- PackageName: "testdata-reciprocal-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- {
- PackageName: "testdata-reciprocal-lib-libb.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-lib-libb.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-application.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-reciprocal-bin-bin3.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-application.meta_lic"),
- Relationship: "BUILD_TOOL_OF",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-reciprocal-application.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-reciprocal-lib-libb.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-application.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- ExtractedText: "$$$Reciprocal License$$$\n",
- LicenseName: "testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/notice/NOTICE_LICENSE",
- "testdata/reciprocal/RECIPROCAL_LICENSE",
- "testdata/reciprocal/application.meta_lic",
- "testdata/reciprocal/bin/bin3.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/libb.so.meta_lic",
- },
- },
- {
- condition: "reciprocal",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-reciprocal-bin-bin1",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/reciprocal/bin/bin1.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-reciprocal-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-reciprocal-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- {
- PackageName: "testdata-reciprocal-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-bin-bin1.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-reciprocal-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-reciprocal-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- ExtractedText: "$$$Reciprocal License$$$\n",
- LicenseName: "testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/reciprocal/RECIPROCAL_LICENSE",
- "testdata/reciprocal/bin/bin1.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/libc.a.meta_lic",
- },
- },
- {
- condition: "reciprocal",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-reciprocal-lib-libd.so",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/reciprocal/lib/libd.so.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-reciprocal-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-reciprocal-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-reciprocal-lib-libd.so.meta_lic"),
- Relationship: "DESCRIBES",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/notice/NOTICE_LICENSE",
- "testdata/reciprocal/lib/libd.so.meta_lic",
- },
- },
- {
- condition: "restricted",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-restricted-highest.apex",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/restricted/highest.apex.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-restricted-highest.apex.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-highest.apex.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-restricted-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-restricted-bin-bin2.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-bin-bin2.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-restricted-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- },
- {
- PackageName: "testdata-restricted-lib-libb.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-lib-libb.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- },
- {
- PackageName: "testdata-restricted-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- {
- PackageName: "testdata-restricted-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-restricted-highest.apex.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-bin-bin2.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-lib-libb.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-lib-libb.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-lib-libd.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- ExtractedText: "$$$Reciprocal License$$$\n",
- LicenseName: "testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- ExtractedText: "###Restricted License###\n",
- LicenseName: "testdata-restricted-RESTRICTED_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/notice/NOTICE_LICENSE",
- "testdata/reciprocal/RECIPROCAL_LICENSE",
- "testdata/restricted/RESTRICTED_LICENSE",
- "testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/highest.apex.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libd.so.meta_lic",
- },
- },
- {
- condition: "restricted",
- name: "container",
- roots: []string{"container.zip.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-restricted-container.zip",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/restricted/container.zip.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-restricted-container.zip.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-container.zip.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-restricted-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-restricted-bin-bin2.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-bin-bin2.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-restricted-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- },
- {
- PackageName: "testdata-restricted-lib-libb.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-lib-libb.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- },
- {
- PackageName: "testdata-restricted-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- {
- PackageName: "testdata-restricted-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-restricted-container.zip.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-bin-bin2.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-lib-libb.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-lib-libb.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-lib-libd.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- ExtractedText: "$$$Reciprocal License$$$\n",
- LicenseName: "testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- ExtractedText: "###Restricted License###\n",
- LicenseName: "testdata-restricted-RESTRICTED_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/notice/NOTICE_LICENSE",
- "testdata/reciprocal/RECIPROCAL_LICENSE",
- "testdata/restricted/RESTRICTED_LICENSE",
- "testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/container.zip.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libd.so.meta_lic",
- },
- },
- {
- condition: "restricted",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-restricted-bin-bin1",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/restricted/bin/bin1.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-restricted-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-restricted-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- },
- {
- PackageName: "testdata-restricted-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-restricted-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-restricted-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-reciprocal-RECIPROCAL_LICENSE",
- ExtractedText: "$$$Reciprocal License$$$\n",
- LicenseName: "testdata-reciprocal-RECIPROCAL_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- ExtractedText: "###Restricted License###\n",
- LicenseName: "testdata-restricted-RESTRICTED_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/reciprocal/RECIPROCAL_LICENSE",
- "testdata/restricted/RESTRICTED_LICENSE",
- "testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- },
- },
- {
- condition: "restricted",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-restricted-lib-libd.so",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/restricted/lib/libd.so.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-restricted-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-restricted-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-restricted-lib-libd.so.meta_lic"),
- Relationship: "DESCRIBES",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/notice/NOTICE_LICENSE",
- "testdata/restricted/lib/libd.so.meta_lic",
- },
- },
- {
- condition: "proprietary",
- name: "apex",
- roots: []string{"highest.apex.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-proprietary-highest.apex",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/proprietary/highest.apex.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-proprietary-highest.apex.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-highest.apex.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-bin-bin2.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-bin-bin2.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-lib-libb.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-lib-libb.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-highest.apex.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-bin-bin2.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-highest.apex.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-lib-libb.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-lib-libb.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-lib-libd.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
- ExtractedText: "@@@Proprietary License@@@\n",
- LicenseName: "testdata-proprietary-PROPRIETARY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- ExtractedText: "###Restricted License###\n",
- LicenseName: "testdata-restricted-RESTRICTED_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/notice/NOTICE_LICENSE",
- "testdata/proprietary/PROPRIETARY_LICENSE",
- "testdata/proprietary/bin/bin1.meta_lic",
- "testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/highest.apex.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
- "testdata/proprietary/lib/libd.so.meta_lic",
- "testdata/restricted/RESTRICTED_LICENSE",
- },
- },
- {
- condition: "proprietary",
- name: "container",
- roots: []string{"container.zip.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-proprietary-container.zip",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/proprietary/container.zip.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-proprietary-container.zip.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-container.zip.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-bin-bin2.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-bin-bin2.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-lib-libb.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-lib-libb.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-container.zip.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-bin-bin2.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-container.zip.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-lib-libb.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-lib-libb.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-lib-libd.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-bin-bin2.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
- ExtractedText: "@@@Proprietary License@@@\n",
- LicenseName: "testdata-proprietary-PROPRIETARY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- ExtractedText: "###Restricted License###\n",
- LicenseName: "testdata-restricted-RESTRICTED_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/notice/NOTICE_LICENSE",
- "testdata/proprietary/PROPRIETARY_LICENSE",
- "testdata/proprietary/bin/bin1.meta_lic",
- "testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/container.zip.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
- "testdata/proprietary/lib/libd.so.meta_lic",
- "testdata/restricted/RESTRICTED_LICENSE",
- },
- },
- {
- condition: "proprietary",
- name: "application",
- roots: []string{"application.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-proprietary-application",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/proprietary/application.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-proprietary-application.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-application.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-bin-bin3.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-bin-bin3.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-lib-libb.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-lib-libb.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-application.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-bin-bin3.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-application.meta_lic"),
- Relationship: "BUILD_TOOL_OF",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-application.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-lib-libb.so.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-application.meta_lic"),
- Relationship: "RUNTIME_DEPENDENCY_OF",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
- ExtractedText: "@@@Proprietary License@@@\n",
- LicenseName: "testdata-proprietary-PROPRIETARY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-restricted-RESTRICTED_LICENSE",
- ExtractedText: "###Restricted License###\n",
- LicenseName: "testdata-restricted-RESTRICTED_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/proprietary/PROPRIETARY_LICENSE",
- "testdata/proprietary/application.meta_lic",
- "testdata/proprietary/bin/bin3.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "testdata/restricted/RESTRICTED_LICENSE",
- },
- },
- {
- condition: "proprietary",
- name: "binary",
- roots: []string{"bin/bin1.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-proprietary-bin-bin1",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/proprietary/bin/bin1.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-proprietary-bin-bin1.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-bin-bin1.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-lib-liba.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-lib-liba.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
- },
- {
- PackageName: "testdata-proprietary-lib-libc.a.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-lib-libc.a.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
- Relationship: "DESCRIBES",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-lib-liba.so.meta_lic"),
- Relationship: "CONTAINS",
- },
- {
- RefA: common.MakeDocElementID("", "testdata-proprietary-bin-bin1.meta_lic"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-lib-libc.a.meta_lic"),
- Relationship: "CONTAINS",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-firstparty-FIRST_PARTY_LICENSE",
- ExtractedText: "&&&First Party License&&&\n",
- LicenseName: "testdata-firstparty-FIRST_PARTY_LICENSE",
- },
- {
- LicenseIdentifier: "LicenseRef-testdata-proprietary-PROPRIETARY_LICENSE",
- ExtractedText: "@@@Proprietary License@@@\n",
- LicenseName: "testdata-proprietary-PROPRIETARY_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/firstparty/FIRST_PARTY_LICENSE",
- "testdata/proprietary/PROPRIETARY_LICENSE",
- "testdata/proprietary/bin/bin1.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
- },
- },
- {
- condition: "proprietary",
- name: "library",
- roots: []string{"lib/libd.so.meta_lic"},
- expectedOut: &spdx.Document{
- SPDXVersion: "SPDX-2.2",
- DataLicense: "CC0-1.0",
- SPDXIdentifier: "DOCUMENT",
- DocumentName: "testdata-proprietary-lib-libd.so",
- DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/proprietary/lib/libd.so.meta_lic"),
- CreationInfo: getCreationInfo(t),
- Packages: []*spdx.Package{
- {
- PackageName: "testdata-proprietary-lib-libd.so.meta_lic",
- PackageVersion: "NOASSERTION",
- PackageDownloadLocation: "NOASSERTION",
- PackageSPDXIdentifier: common.ElementID("testdata-proprietary-lib-libd.so.meta_lic"),
- PackageLicenseConcluded: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- },
- },
- Relationships: []*spdx.Relationship{
- {
- RefA: common.MakeDocElementID("", "DOCUMENT"),
- RefB: common.MakeDocElementID("", "testdata-proprietary-lib-libd.so.meta_lic"),
- Relationship: "DESCRIBES",
- },
- },
- OtherLicenses: []*spdx.OtherLicense{
- {
- LicenseIdentifier: "LicenseRef-testdata-notice-NOTICE_LICENSE",
- ExtractedText: "%%%Notice License%%%\n",
- LicenseName: "testdata-notice-NOTICE_LICENSE",
- },
- },
- },
- expectedDeps: []string{
- "testdata/notice/NOTICE_LICENSE",
- "testdata/proprietary/lib/libd.so.meta_lic",
- },
- },
- }
- for _, tt := range tests {
- t.Run(tt.condition+" "+tt.name, func(t *testing.T) {
- stdout := &bytes.Buffer{}
- stderr := &bytes.Buffer{}
-
- rootFiles := make([]string, 0, len(tt.roots))
- for _, r := range tt.roots {
- rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r)
- }
-
- ctx := context{stdout, stderr, compliance.GetFS(tt.outDir), "", []string{tt.stripPrefix}, fakeTime, ""}
-
- spdxDoc, deps, err := sbomGenerator(&ctx, rootFiles...)
- if err != nil {
- t.Fatalf("sbom: error = %v, stderr = %v", err, stderr)
- return
- }
- if stderr.Len() > 0 {
- t.Errorf("sbom: gotStderr = %v, want none", stderr)
- }
-
- if err := validate(spdxDoc); err != nil {
- t.Fatalf("sbom: document fails to validate: %v", err)
- }
-
- gotData, err := json.Marshal(spdxDoc)
- if err != nil {
- t.Fatalf("sbom: failed to marshal spdx doc: %v", err)
- return
- }
-
- t.Logf("Got SPDX Doc: %s", string(gotData))
-
- expectedData, err := json.Marshal(tt.expectedOut)
- if err != nil {
- t.Fatalf("sbom: failed to marshal spdx doc: %v", err)
- return
- }
-
- t.Logf("Want SPDX Doc: %s", string(expectedData))
-
- // compare the spdx Docs
- compareSpdxDocs(t, spdxDoc, tt.expectedOut)
-
- // compare deps
- t.Logf("got deps: %q", deps)
-
- t.Logf("want deps: %q", tt.expectedDeps)
-
- if g, w := deps, tt.expectedDeps; !reflect.DeepEqual(g, w) {
- t.Errorf("unexpected deps, wanted:\n%s\ngot:\n%s\n",
- strings.Join(w, "\n"), strings.Join(g, "\n"))
- }
- })
- }
-}
-
-func TestGenerateSPDXNamespace(t *testing.T) {
-
- buildID1 := "example-1"
- buildID2 := "example-2"
- files1 := "file1"
- timestamp1 := "2022-05-01"
- timestamp2 := "2022-05-02"
- files2 := "file2"
-
- // Test case 1: different timestamps, same files
- nsh1 := generateSPDXNamespace("", timestamp1, files1)
- nsh2 := generateSPDXNamespace("", timestamp2, files1)
-
- if nsh1 == "" {
- t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", "", timestamp1, files1)
- }
-
- if nsh2 == "" {
- t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", "", timestamp2, files1)
- }
-
- if nsh1 == nsh2 {
- t.Errorf("generateSPDXNamespace(%s, %s, %s) and generateSPDXNamespace(%s, %s, %s): expected different namespace hashes, but got the same", "", timestamp1, files1, "", timestamp2, files1)
- }
-
- // Test case 2: different build ids, same timestamps and files
- nsh1 = generateSPDXNamespace(buildID1, timestamp1, files1)
- nsh2 = generateSPDXNamespace(buildID2, timestamp1, files1)
-
- if nsh1 == "" {
- t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", buildID1, timestamp1, files1)
- }
-
- if nsh2 == "" {
- t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", buildID2, timestamp1, files1)
- }
-
- if nsh1 == nsh2 {
- t.Errorf("generateSPDXNamespace(%s, %s, %s) and generateSPDXNamespace(%s, %s, %s): expected different namespace hashes, but got the same", buildID1, timestamp1, files1, buildID2, timestamp1, files1)
- }
-
- // Test case 3: same build ids and files, different timestamps
- nsh1 = generateSPDXNamespace(buildID1, timestamp1, files1)
- nsh2 = generateSPDXNamespace(buildID1, timestamp2, files1)
-
- if nsh1 == "" {
- t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", buildID1, timestamp1, files1)
- }
-
- if nsh2 == "" {
- t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", buildID1, timestamp2, files1)
- }
-
- if nsh1 != nsh2 {
- t.Errorf("generateSPDXNamespace(%s, %s, %s) and generateSPDXNamespace(%s, %s, %s): expected same namespace hashes, but got different: %s and %s", buildID1, timestamp1, files1, buildID2, timestamp1, files1, nsh1, nsh2)
- }
-
- // Test case 4: same build ids and timestamps, different files
- nsh1 = generateSPDXNamespace(buildID1, timestamp1, files1)
- nsh2 = generateSPDXNamespace(buildID1, timestamp1, files2)
-
- if nsh1 == "" {
- t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", buildID1, timestamp1, files1)
- }
-
- if nsh2 == "" {
- t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", buildID1, timestamp1, files2)
- }
-
- if nsh1 == nsh2 {
- t.Errorf("generateSPDXNamespace(%s, %s, %s) and generateSPDXNamespace(%s, %s, %s): expected different namespace hashes, but got the same", buildID1, timestamp1, files1, buildID1, timestamp1, files2)
- }
-
- // Test case 5: empty build ids, same timestamps and different files
- nsh1 = generateSPDXNamespace("", timestamp1, files1)
- nsh2 = generateSPDXNamespace("", timestamp1, files2)
-
- if nsh1 == "" {
- t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", "", timestamp1, files1)
- }
-
- if nsh2 == "" {
- t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", "", timestamp1, files2)
- }
-
- if nsh1 == nsh2 {
- t.Errorf("generateSPDXNamespace(%s, %s, %s) and generateSPDXNamespace(%s, %s, %s): expected different namespace hashes, but got the same", "", timestamp1, files1, "", timestamp1, files2)
- }
-}
-
-func getCreationInfo(t *testing.T) *spdx.CreationInfo {
- ci, err := builder2v2.BuildCreationInfoSection2_2("Organization", "Google LLC", nil)
- if err != nil {
- t.Errorf("Unable to get creation info: %v", err)
- return nil
- }
- return ci
-}
-
-// validate returns an error if the Document is found to be invalid
-func validate(doc *spdx.Document) error {
- if doc.SPDXVersion == "" {
- return fmt.Errorf("SPDXVersion: got nothing, want spdx version")
- }
- if doc.DataLicense == "" {
- return fmt.Errorf("DataLicense: got nothing, want Data License")
- }
- if doc.SPDXIdentifier == "" {
- return fmt.Errorf("SPDXIdentifier: got nothing, want SPDX Identifier")
- }
- if doc.DocumentName == "" {
- return fmt.Errorf("DocumentName: got nothing, want Document Name")
- }
- if c := fmt.Sprintf("%v", doc.CreationInfo.Creators[1].Creator); c != "Google LLC" {
- return fmt.Errorf("Creator: got %v, want 'Google LLC'", c)
- }
- _, err := time.Parse(time.RFC3339, doc.CreationInfo.Created)
- if err != nil {
- return fmt.Errorf("Invalid time spec: %q: got error %q, want no error", doc.CreationInfo.Created, err)
- }
-
- for _, license := range doc.OtherLicenses {
- if license.ExtractedText == "" {
- return fmt.Errorf("License file: %q: got nothing, want license text", license.LicenseName)
- }
- }
- return nil
-}
-
-// compareSpdxDocs deep-compares two spdx docs by going through the info section, packages, relationships and licenses
-func compareSpdxDocs(t *testing.T, actual, expected *spdx.Document) {
-
- if actual == nil || expected == nil {
- t.Errorf("SBOM: SPDX Doc is nil! Got %v: Expected %v", actual, expected)
- }
-
- if actual.DocumentName != expected.DocumentName {
- t.Errorf("sbom: unexpected SPDX Document Name got %q, want %q", actual.DocumentName, expected.DocumentName)
- }
-
- if actual.SPDXVersion != expected.SPDXVersion {
- t.Errorf("sbom: unexpected SPDX Version got %s, want %s", actual.SPDXVersion, expected.SPDXVersion)
- }
-
- if actual.DataLicense != expected.DataLicense {
- t.Errorf("sbom: unexpected SPDX DataLicense got %s, want %s", actual.DataLicense, expected.DataLicense)
- }
-
- if actual.SPDXIdentifier != expected.SPDXIdentifier {
- t.Errorf("sbom: unexpected SPDX Identified got %s, want %s", actual.SPDXIdentifier, expected.SPDXIdentifier)
- }
-
- if actual.DocumentNamespace != expected.DocumentNamespace {
- t.Errorf("sbom: unexpected SPDX Document Namespace got %s, want %s", actual.DocumentNamespace, expected.DocumentNamespace)
- }
-
- // compare creation info
- compareSpdxCreationInfo(t, actual.CreationInfo, expected.CreationInfo)
-
- // compare packages
- if len(actual.Packages) != len(expected.Packages) {
- t.Errorf("SBOM: Number of Packages is different! Got %d: Expected %d", len(actual.Packages), len(expected.Packages))
- }
-
- for i, pkg := range actual.Packages {
- if !compareSpdxPackages(t, i, pkg, expected.Packages[i]) {
- break
- }
- }
-
- // compare licenses
- if len(actual.OtherLicenses) != len(expected.OtherLicenses) {
- t.Errorf("SBOM: Number of Licenses in actual is different! Got %d: Expected %d", len(actual.OtherLicenses), len(expected.OtherLicenses))
- }
- for i, license := range actual.OtherLicenses {
- if !compareLicenses(t, i, license, expected.OtherLicenses[i]) {
- break
- }
- }
-
- //compare Relationships
- if len(actual.Relationships) != len(expected.Relationships) {
- t.Errorf("SBOM: Number of Licenses in actual is different! Got %d: Expected %d", len(actual.Relationships), len(expected.Relationships))
- }
- for i, rl := range actual.Relationships {
- if !compareRelationShips(t, i, rl, expected.Relationships[i]) {
- break
- }
- }
-}
-
-func compareSpdxCreationInfo(t *testing.T, actual, expected *spdx.CreationInfo) {
- if actual == nil || expected == nil {
- t.Errorf("SBOM: Creation info is nil! Got %q: Expected %q", actual, expected)
- }
-
- if actual.LicenseListVersion != expected.LicenseListVersion {
- t.Errorf("SBOM: Creation info license version Error! Got %s: Expected %s", actual.LicenseListVersion, expected.LicenseListVersion)
- }
-
- if len(actual.Creators) != len(expected.Creators) {
- t.Errorf("SBOM: Creation info creators Error! Got %d: Expected %d", len(actual.Creators), len(expected.Creators))
- }
-
- for i, info := range actual.Creators {
- if info != expected.Creators[i] {
- t.Errorf("SBOM: Creation info creators Error! Got %q: Expected %q", info, expected.Creators[i])
- }
- }
-}
-
-func compareSpdxPackages(t *testing.T, i int, actual, expected *spdx.Package) bool {
- if actual == nil || expected == nil {
- t.Errorf("SBOM: Packages are nil at index %d! Got %v: Expected %v", i, actual, expected)
- return false
- }
- if actual.PackageName != expected.PackageName {
- t.Errorf("SBOM: Package name Error at index %d! Got %s: Expected %s", i, actual.PackageName, expected.PackageName)
- return false
- }
-
- if actual.PackageVersion != expected.PackageVersion {
- t.Errorf("SBOM: Package version Error at index %d! Got %s: Expected %s", i, actual.PackageVersion, expected.PackageVersion)
- return false
- }
-
- if actual.PackageSPDXIdentifier != expected.PackageSPDXIdentifier {
- t.Errorf("SBOM: Package identifier Error at index %d! Got %s: Expected %s", i, actual.PackageSPDXIdentifier, expected.PackageSPDXIdentifier)
- return false
- }
-
- if actual.PackageDownloadLocation != expected.PackageDownloadLocation {
- t.Errorf("SBOM: Package download location Error at index %d! Got %s: Expected %s", i, actual.PackageDownloadLocation, expected.PackageDownloadLocation)
- return false
- }
-
- if actual.PackageLicenseConcluded != expected.PackageLicenseConcluded {
- t.Errorf("SBOM: Package license concluded Error at index %d! Got %s: Expected %s", i, actual.PackageLicenseConcluded, expected.PackageLicenseConcluded)
- return false
- }
- return true
-}
-
-func compareRelationShips(t *testing.T, i int, actual, expected *spdx.Relationship) bool {
- if actual == nil || expected == nil {
- t.Errorf("SBOM: Relationships is nil at index %d! Got %v: Expected %v", i, actual, expected)
- return false
- }
-
- if actual.RefA != expected.RefA {
- t.Errorf("SBOM: Relationship RefA Error at index %d! Got %s: Expected %s", i, actual.RefA, expected.RefA)
- return false
- }
-
- if actual.RefB != expected.RefB {
- t.Errorf("SBOM: Relationship RefB Error at index %d! Got %s: Expected %s", i, actual.RefB, expected.RefB)
- return false
- }
-
- if actual.Relationship != expected.Relationship {
- t.Errorf("SBOM: Relationship type Error at index %d! Got %s: Expected %s", i, actual.Relationship, expected.Relationship)
- return false
- }
- return true
-}
-
-func compareLicenses(t *testing.T, i int, actual, expected *spdx.OtherLicense) bool {
- if actual == nil || expected == nil {
- t.Errorf("SBOM: Licenses is nil at index %d! Got %v: Expected %v", i, actual, expected)
- return false
- }
-
- if actual.LicenseName != expected.LicenseName {
- t.Errorf("SBOM: License Name Error at index %d! Got %s: Expected %s", i, actual.LicenseName, expected.LicenseName)
- return false
- }
-
- if actual.LicenseIdentifier != expected.LicenseIdentifier {
- t.Errorf("SBOM: License Identifier Error at index %d! Got %s: Expected %s", i, actual.LicenseIdentifier, expected.LicenseIdentifier)
- return false
- }
-
- if actual.ExtractedText != expected.ExtractedText {
- t.Errorf("SBOM: License Extracted Text Error at index %d! Got: %q want: %q", i, actual.ExtractedText, expected.ExtractedText)
- return false
- }
- return true
-}
-
-func fakeTime() string {
- t := time.UnixMicro(0)
- return t.UTC().Format("2006-01-02T15:04:05Z")
-}
diff --git a/tools/edit_monitor/daemon_manager_test.py b/tools/edit_monitor/daemon_manager_test.py
index be28965..a7c175d 100644
--- a/tools/edit_monitor/daemon_manager_test.py
+++ b/tools/edit_monitor/daemon_manager_test.py
@@ -494,8 +494,8 @@
def _assert_error_event_logged(self, fake_cclient, error_type):
error_events = fake_cclient.get_sent_events()
- self.assertEquals(len(error_events), 1)
- self.assertEquals(
+ self.assertEqual(len(error_events), 1)
+ self.assertEqual(
edit_event_pb2.EditEvent.FromString(
error_events[0].source_extension
).edit_monitor_error_event.error_type,
diff --git a/tools/edit_monitor/edit_monitor_test.py b/tools/edit_monitor/edit_monitor_test.py
index 64a3871..deb73e7 100644
--- a/tools/edit_monitor/edit_monitor_test.py
+++ b/tools/edit_monitor/edit_monitor_test.py
@@ -260,7 +260,7 @@
# Wait until observer started.
received_data = receiver.recv()
- self.assertEquals(received_data, 'Observer started.')
+ self.assertEqual(received_data, 'Observer started.')
receiver.close()
return p
diff --git a/tools/perf/benchmarks b/tools/perf/benchmarks
index 8c24e12..228c1d0 100755
--- a/tools/perf/benchmarks
+++ b/tools/perf/benchmarks
@@ -337,6 +337,12 @@
def Run(self):
"""Run all of the user-selected benchmarks."""
+
+ # With `--list`, just list the benchmarks available.
+ if self._options.List():
+ print(" ".join(self._options.BenchmarkIds()))
+ return
+
# Clean out the log dir or create it if necessary
prepare_log_dir(self._options.LogDir())
@@ -546,6 +552,8 @@
parser.add_argument("--benchmark", nargs="*", default=[b.id for b in self._benchmarks],
metavar="BENCHMARKS",
help="Benchmarks to run. Default suite will be run if omitted.")
+ parser.add_argument("--list", action="store_true",
+ help="list the available benchmarks. No benchmark is run.")
parser.add_argument("--dist-one", action="store_true",
help="Copy logs and metrics to the given dist dir. Requires that only"
+ " one benchmark be supplied. Postroll steps will be skipped.")
@@ -615,6 +623,12 @@
def DryRun(self):
return self._args.dry_run
+ def List(self):
+ return self._args.list
+
+ def BenchmarkIds(self) :
+ return [benchmark.id for benchmark in self._benchmarks]
+
def _lunches(self):
def parse_lunch(lunch):
parts = lunch.split("-")
diff --git a/tools/protos/Android.bp b/tools/protos/Android.bp
index c6ad19e..65f13cb 100644
--- a/tools/protos/Android.bp
+++ b/tools/protos/Android.bp
@@ -18,11 +18,6 @@
python_library_host {
name: "metadata_file_proto_py",
- version: {
- py3: {
- enabled: true,
- },
- },
srcs: [
"metadata_file.proto",
],
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index e371b23..3467152 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -296,11 +296,6 @@
python_defaults {
name: "releasetools_binary_defaults",
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
// TODO (b/140144201) Build imgdiff from releasetools_common
required: [
"aapt2",
@@ -338,11 +333,6 @@
python_binary_host {
name: "merge_ota",
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
srcs: [
"merge_ota.py",
],
@@ -357,11 +347,6 @@
python_binary_host {
name: "create_brick_ota",
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
srcs: [
"create_brick_ota.py",
],
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 30a6acc..180bf15 100644
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -572,7 +572,7 @@
default = os.path.join(OPTIONS.input_tmp, "IMAGES", partition_name + ".img")
assert os.path.exists(default), \
- "There should be one %s.img" % (partition_name)
+ "Can't find %s for image %s" % (default, partition_name)
return default
diff --git a/tools/releasetools/fsverity_metadata_generator.py b/tools/releasetools/fsverity_metadata_generator.py
index 50e23e7..e531cca 100644
--- a/tools/releasetools/fsverity_metadata_generator.py
+++ b/tools/releasetools/fsverity_metadata_generator.py
@@ -230,12 +230,6 @@
if not output_file:
output_file = input_file + '.fsv_meta'
- if output_file != args.input + '.fsv_meta':
- sys.exit('When generating .fsv_meta files for symlinks, we assume that all fsv_meta files '
- 'are named the same as the file they protect, just with the .fsv_meta suffix appended. '
- 'We require that all .fsv_meta files follow this convention regardless of if it\'s a link or '
- 'not. However {args.input} had a different output file: {args.output}')
-
# remove the output file first, as switching between a file and a symlink can be complicated
try:
os.remove(output_file)
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index f1855a5..2fa3fb5 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -910,8 +910,11 @@
# b/384813199: handles the pre-signed com.android.virt.apex in GSI.
if payload_key == 'PRESIGNED':
- new_pubkey = GetMicrodroidVbmetaKey(virt_apex_path,
- misc_info['avb_avbtool'])
+ with tempfile.NamedTemporaryFile() as virt_apex_temp_file:
+ virt_apex_temp_file.write(input_tf_zip.read(virt_apex_path))
+ virt_apex_temp_file.flush()
+ new_pubkey = GetMicrodroidVbmetaKey(virt_apex_temp_file.name,
+ misc_info['avb_avbtool'])
else:
new_pubkey_path = common.ExtractAvbPublicKey(
misc_info['avb_avbtool'], payload_key)
diff --git a/tools/sbom/Android.bp b/tools/sbom/Android.bp
index 7e2840f..d2e6b55 100644
--- a/tools/sbom/Android.bp
+++ b/tools/sbom/Android.bp
@@ -21,11 +21,6 @@
srcs: [
"generate-sbom.py",
],
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
libs: [
"metadata_file_proto_py",
"libprotobuf-python",
@@ -45,11 +40,6 @@
srcs: [
"gen_sbom.py",
],
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
libs: [
"compliance_metadata",
"metadata_file_proto_py",
@@ -78,11 +68,6 @@
libs: [
"sbom_lib",
],
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
test_suites: ["general-tests"],
}
@@ -95,11 +80,6 @@
libs: [
"sbom_lib",
],
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
test_suites: ["general-tests"],
}
@@ -108,11 +88,6 @@
srcs: [
"generate-sbom-framework_res.py",
],
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
libs: [
"sbom_lib",
],
@@ -123,11 +98,6 @@
srcs: [
"gen_notice_xml.py",
],
- version: {
- py3: {
- embedded_launcher: true,
- },
- },
libs: [
"compliance_metadata",
"metadata_file_proto_py",
diff --git a/tools/tool_event_logger/Android.bp b/tools/tool_event_logger/Android.bp
index 7a1d2aa..d242db8 100644
--- a/tools/tool_event_logger/Android.bp
+++ b/tools/tool_event_logger/Android.bp
@@ -58,10 +58,4 @@
"asuite_cc_client",
"tool_event_proto",
],
- version: {
- py3: {
- embedded_launcher: true,
- enabled: true,
- },
- },
}
diff --git a/tools/tool_event_logger/OWNERS b/tools/tool_event_logger/OWNERS
index b692c9e..e93d20f 100644
--- a/tools/tool_event_logger/OWNERS
+++ b/tools/tool_event_logger/OWNERS
@@ -1,4 +1,3 @@
include platform/tools/asuite:/OWNERS
zhuoyao@google.com
-hzalek@google.com
\ No newline at end of file
diff --git a/tools/warn/OWNERS b/tools/warn/OWNERS
index 8551802..93ccd28 100644
--- a/tools/warn/OWNERS
+++ b/tools/warn/OWNERS
@@ -1 +1 @@
-per-file * = chh@google.com,srhines@google.com
+per-file * =srhines@google.com