Merge "Write SOONG_MODULES_MISSING_PGO_PROFILE_FILE to $DIST_DIR"
diff --git a/OWNERS b/OWNERS
index 89b446a..7a59f70 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,2 +1,3 @@
ccross@android.com
dwillemsen@google.com
+nanzhang@google.com
diff --git a/core/Makefile b/core/Makefile
index eb3298e..1aacdc6 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -423,6 +423,32 @@
$(hide) build/make/tools/post_process_props.py $@
endif # property_overrides_split_enabled
+# -----------------------------------------------------------------
+# product build.prop
+INSTALLED_PRODUCT_BUILD_PROP_TARGET := $(TARGET_OUT_PRODUCT)/build.prop
+ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_PRODUCT_BUILD_PROP_TARGET)
+
+FINAL_PRODUCT_PROPERTIES += \
+ $(call collapse-pairs, $(PRODUCT_PRODUCT_PROPERTIES))
+FINAL_PRODUCT_PROPERTIES := $(call uniq-pairs-by-first-component, \
+ $(FINAL_PRODUCT_PROPERTIES),=)
+
+$(INSTALLED_PRODUCT_BUILD_PROP_TARGET):
+ @echo Target product buildinfo: $@
+ @mkdir -p $(dir $@)
+ $(hide) echo > $@
+ifdef BOARD_USES_PRODUCTIMAGE
+ $(hide) echo ro.product.build.date=`$(DATE_FROM_FILE)`>>$@
+ $(hide) echo ro.product.build.date.utc=`$(DATE_FROM_FILE) +%s`>>$@
+ $(hide) echo ro.product.build.fingerprint="$(BUILD_FINGERPRINT_FROM_FILE)">>$@
+endif # BOARD_USES_PRODUCTIMAGE
+ $(hide) echo "#" >> $@; \
+ echo "# ADDITIONAL PRODUCT PROPERTIES" >> $@; \
+ echo "#" >> $@;
+ $(hide) $(foreach line,$(FINAL_PRODUCT_PROPERTIES), \
+ echo "$(line)" >> $@;)
+ $(hide) build/make/tools/post_process_props.py $@
+
# ----------------------------------------------------------------
# -----------------------------------------------------------------
@@ -1023,7 +1049,7 @@
ifneq (true,$(TARGET_USERIMAGES_SPARSE_SQUASHFS_DISABLED))
INTERNAL_USERIMAGES_SPARSE_SQUASHFS_FLAG := -s
endif
-ifneq ($(filter $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE) $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),squashfs),)
+ifneq ($(filter $(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE) $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE) $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),squashfs),)
INTERNAL_USERIMAGES_DEPS += $(MAKE_SQUASHFS) $(MKSQUASHFSUSERIMG) $(IMG2SIMG)
endif
@@ -1054,6 +1080,7 @@
$(if $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "system_fs_type=$(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
$(if $(BOARD_SYSTEMIMAGE_EXTFS_INODE_COUNT),$(hide) echo "system_extfs_inode_count=$(BOARD_SYSTEMIMAGE_EXTFS_INODE_COUNT)" >> $(1))
$(if $(BOARD_SYSTEMIMAGE_JOURNAL_SIZE),$(hide) echo "system_journal_size=$(BOARD_SYSTEMIMAGE_JOURNAL_SIZE)" >> $(1))
+$(if $(BOARD_EXT4_SHARE_DUP_BLOCKS),$(hide) echo "ext4_share_dup_blocks=$(BOARD_EXT4_SHARE_DUP_BLOCKS)" >> $(1))
$(if $(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "system_squashfs_compressor=$(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
$(if $(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "system_squashfs_compressor_opt=$(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
$(if $(BOARD_SYSTEMIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "system_squashfs_block_size=$(BOARD_SYSTEMIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
@@ -1075,6 +1102,15 @@
$(if $(BOARD_VENDORIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "vendor_squashfs_block_size=$(BOARD_VENDORIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
$(if $(BOARD_VENDORIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "vendor_squashfs_disable_4k_align=$(BOARD_VENDORIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH),$(hide) echo "vendor_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH)" >> $(1))
+$(if $(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "product_fs_type=$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
+$(if $(BOARD_PRODUCTIMAGE_EXTFS_INODE_COUNT),$(hide) echo "product_extfs_inode_count=$(BOARD_PRODUCTIMAGE_EXTFS_INODE_COUNT)" >> $(1))
+$(if $(BOARD_PRODUCTIMAGE_PARTITION_SIZE),$(hide) echo "product_size=$(BOARD_PRODUCTIMAGE_PARTITION_SIZE)" >> $(1))
+$(if $(BOARD_PRODUCTIMAGE_JOURNAL_SIZE),$(hide) echo "product_journal_size=$(BOARD_PRODUCTIMAGE_JOURNAL_SIZE)" >> $(1))
+$(if $(BOARD_PRODUCTIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "product_squashfs_compressor=$(BOARD_PRODUCTIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
+$(if $(BOARD_PRODUCTIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "product_squashfs_compressor_opt=$(BOARD_PRODUCTIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
+$(if $(BOARD_PRODUCTIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "product_squashfs_block_size=$(BOARD_PRODUCTIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
+$(if $(BOARD_PRODUCTIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "product_squashfs_disable_4k_align=$(BOARD_PRODUCTIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
+$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH),$(hide) echo "product_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH)" >> $(1))
$(if $(BOARD_OEMIMAGE_PARTITION_SIZE),$(hide) echo "oem_size=$(BOARD_OEMIMAGE_PARTITION_SIZE)" >> $(1))
$(if $(BOARD_OEMIMAGE_JOURNAL_SIZE),$(hide) echo "oem_journal_size=$(BOARD_OEMIMAGE_JOURNAL_SIZE)" >> $(1))
$(if $(BOARD_OEMIMAGE_EXTFS_INODE_COUNT),$(hide) echo "oem_extfs_inode_count=$(BOARD_OEMIMAGE_EXTFS_INODE_COUNT)" >> $(1))
@@ -1089,6 +1125,7 @@
$(if $(filter eng, $(TARGET_BUILD_VARIANT)),$(hide) echo "verity_disable=true" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION),$(hide) echo "system_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION),$(hide) echo "vendor_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION)" >> $(1))
+$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_VERITY_PARTITION),$(hide) echo "product_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_VERITY_PARTITION)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_key=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_subkey=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_SUBKEY)" >> $(1))
@@ -1109,6 +1146,13 @@
$(hide) echo "avb_vendor_key_path=$(BOARD_AVB_VENDOR_KEY_PATH)" >> $(1)
$(hide) echo "avb_vendor_algorithm=$(BOARD_AVB_VENDOR_ALGORITHM)" >> $(1)
$(hide) echo "avb_vendor_rollback_index_location=$(BOARD_AVB_VENDOR_ROLLBACK_INDEX_LOCATION)" >> $(1)))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "avb_product_hashtree_enable=$(BOARD_AVB_ENABLE)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "avb_product_add_hashtree_footer_args=$(BOARD_AVB_PRODUCT_ADD_HASHTREE_FOOTER_ARGS)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),\
+ $(if $(BOARD_AVB_PRODUCT_KEY_PATH),\
+ $(hide) echo "avb_product_key_path=$(BOARD_AVB_PRODUCT_KEY_PATH)" >> $(1)
+ $(hide) echo "avb_product_algorithm=$(BOARD_AVB_PRODUCT_ALGORITHM)" >> $(1)
+ $(hide) echo "avb_product_rollback_index_location=$(BOARD_AVB_PRODUCT_ROLLBACK_INDEX_LOCATION)" >> $(1)))
$(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
$(hide) echo "recovery_as_boot=true" >> $(1))
$(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),\
@@ -1160,6 +1204,9 @@
ifdef property_overrides_split_enabled
recovery_build_props += $(INSTALLED_VENDOR_BUILD_PROP_TARGET)
endif
+ifdef BOARD_USES_PRODUCTIMAGE
+recovery_build_props += $(INSTALLED_PRODUCT_BUILD_PROP_TARGET)
+endif
recovery_resources_common := $(call include-path-for, recovery)/res
# Set recovery_density to the density bucket of the device.
@@ -1452,10 +1499,26 @@
endef
endif
+# Create symlink /system/product to /product if necessary.
+ifdef BOARD_USES_PRODUCTIMAGE
+define create-system-product-symlink
+$(hide) if [ -d $(TARGET_OUT)/product ] && [ ! -h $(TARGET_OUT)/product ]; then \
+ echo 'Non-symlink $(TARGET_OUT)/product detected!' 1>&2; \
+ echo 'You cannot install files to $(TARGET_OUT)/product while building a separate product.img!' 1>&2; \
+ exit 1; \
+fi
+$(hide) ln -sf /product $(TARGET_OUT)/product
+endef
+else
+define create-system-product-symlink
+endef
+endif
+
# $(1): output file
define build-systemimage-target
@echo "Target system fs image: $(1)"
$(call create-system-vendor-symlink)
+ $(call create-system-product-symlink)
@mkdir -p $(dir $(1)) $(systemimage_intermediates) && rm -rf $(systemimage_intermediates)/system_image_info.txt
$(call generate-userimage-prop-dictionary, $(systemimage_intermediates)/system_image_info.txt, \
skip_fsck=true)
@@ -1530,6 +1593,7 @@
define build-systemtarball-target
$(call pretty,"Target system fs tarball: $(INSTALLED_SYSTEMTARBALL_TARGET)")
$(call create-system-vendor-symlink)
+ $(call create-system-product-symlink)
$(MKTARBALL) $(FS_GET_STATS) \
$(PRODUCT_OUT) system $(PRIVATE_SYSTEM_TAR) \
$(INSTALLED_SYSTEMTARBALL_TARGET) $(TARGET_OUT)
@@ -1610,6 +1674,10 @@
$(hide) cd $(dir $@) && zip -qryX $(notdir $@) \
$(TARGET_COPY_OUT_VENDOR)
endif
+ifdef BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE
+ $(hide) cd $(dir $@) && zip -qryX $(notdir $@) \
+ $(TARGET_COPY_OUT_PRODUCT)
+endif
ifneq ($(PDK_PLATFORM_JAVA_ZIP_CONTENTS),)
$(hide) cd $(OUT_DIR) && zip -qryX $(patsubst $(OUT_DIR)/%,%,$@) $(PDK_PLATFORM_JAVA_ZIP_CONTENTS)
endif
@@ -1918,6 +1986,55 @@
endif
# -----------------------------------------------------------------
+# product partition image
+ifdef BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE
+INTERNAL_PRODUCTIMAGE_FILES := \
+ $(filter $(TARGET_OUT_PRODUCT)/%,\
+ $(ALL_DEFAULT_INSTALLED_MODULES)\
+ $(ALL_PDK_FUSION_FILES))
+
+# platform.zip depends on $(INTERNAL_PRODUCTIMAGE_FILES).
+$(INSTALLED_PLATFORM_ZIP) : $(INTERNAL_PRODUCTIMAGE_FILES)
+
+INSTALLED_FILES_FILE_PRODUCT := $(PRODUCT_OUT)/installed-files-product.txt
+$(INSTALLED_FILES_FILE_PRODUCT) : $(INTERNAL_PRODUCTIMAGE_FILES) $(FILESLIST)
+ @echo Installed file list: $@
+ @mkdir -p $(dir $@)
+ @rm -f $@
+ $(hide) $(FILESLIST) $(TARGET_OUT_PRODUCT) > $(@:.txt=.json)
+ $(hide) build/tools/fileslist_util.py -c $(@:.txt=.json) > $@
+
+productimage_intermediates := \
+ $(call intermediates-dir-for,PACKAGING,product)
+BUILT_PRODUCTIMAGE_TARGET := $(PRODUCT_OUT)/product.img
+define build-productimage-target
+ $(call pretty,"Target product fs image: $(INSTALLED_PRODUCTIMAGE_TARGET)")
+ @mkdir -p $(TARGET_OUT_PRODUCT)
+ @mkdir -p $(productimage_intermediates) && rm -rf $(productimage_intermediates)/product_image_info.txt
+ $(call generate-userimage-prop-dictionary, $(productimage_intermediates)/product_image_info.txt, skip_fsck=true)
+ $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
+ ./build/tools/releasetools/build_image.py \
+ $(TARGET_OUT_PRODUCT) $(productimage_intermediates)/product_image_info.txt $(INSTALLED_PRODUCTIMAGE_TARGET) $(TARGET_OUT)
+ $(hide) $(call assert-max-image-size,$(INSTALLED_PRODUCTIMAGE_TARGET),$(BOARD_PRODUCTIMAGE_PARTITION_SIZE))
+endef
+
+# We just build this directly to the install location.
+INSTALLED_PRODUCTIMAGE_TARGET := $(BUILT_PRODUCTIMAGE_TARGET)
+$(INSTALLED_PRODUCTIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_PRODUCTIMAGE_FILES) $(INSTALLED_FILES_FILE_PRODUCT) $(BUILD_IMAGE_SRCS)
+ $(build-productimage-target)
+
+.PHONY: productimage-nodeps pnod
+productimage-nodeps pnod: | $(INTERNAL_USERIMAGES_DEPS)
+ $(build-productimage-target)
+
+sync: $(INTERNAL_PRODUCTIMAGE_FILES)
+
+else ifdef BOARD_PREBUILT_PRODUCTIMAGE
+INSTALLED_PRODUCTIMAGE_TARGET := $(PRODUCT_OUT)/product.img
+$(eval $(call copy-one-file,$(BOARD_PREBUILT_PRODUCTIMAGE),$(INSTALLED_PRODUCTIMAGE_TARGET)))
+endif
+
+# -----------------------------------------------------------------
# dtbo image
ifdef BOARD_PREBUILT_DTBOIMAGE
INSTALLED_DTBOIMAGE_TARGET := $(PRODUCT_OUT)/dtbo.img
@@ -1971,6 +2088,7 @@
SYSTEM_FOOTER_ARGS := BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS
VENDOR_FOOTER_ARGS := BOARD_AVB_VENDOR_ADD_HASHTREE_FOOTER_ARGS
RECOVERY_FOOTER_ARGS := BOARD_AVB_RECOVERY_ADD_HASH_FOOTER_ARGS
+PRODUCT_FOOTER_ARGS := BOARD_AVB_PRODUCT_ADD_HASHTREE_FOOTER_ARGS
# Check and set required build variables for a chain partition.
# $(1): the partition to enable AVB chain, e.g., BOOT or SYSTEM.
@@ -2023,6 +2141,15 @@
endif
endif
+ifdef INSTALLED_PRODUCTIMAGE_TARGET
+ifdef BOARD_AVB_PRODUCT_KEY_PATH
+$(eval $(call check-and-set-avb-chain-args,PRODUCT))
+else
+INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
+ --include_descriptors_from_image $(INSTALLED_PRODUCTIMAGE_TARGET)
+endif
+endif
+
ifdef INSTALLED_DTBOIMAGE_TARGET
ifdef BOARD_AVB_DTBO_KEY_PATH
$(eval $(call check-and-set-avb-chain-args,DTBO))
@@ -2076,6 +2203,9 @@
$(if $(BOARD_AVB_VENDOR_KEY_PATH),\
$(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_VENDOR_KEY_PATH) \
--output $(1)/vendor.avbpubkey)
+ $(if $(BOARD_AVB_PRODUCT_KEY_PATH),\
+ $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_PRODUCT_KEY_PATH) \
+ --output $(1)/product.avbpubkey)
$(if $(BOARD_AVB_DTBO_KEY_PATH),\
$(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_DTBO_KEY_PATH) \
--output $(1)/dtbo.avbpubkey)
@@ -2102,6 +2232,7 @@
$(INSTALLED_BOOTIMAGE_TARGET) \
$(INSTALLED_SYSTEMIMAGE) \
$(INSTALLED_VENDORIMAGE_TARGET) \
+ $(INSTALLED_PRODUCTIMAGE_TARGET) \
$(INSTALLED_DTBOIMAGE_TARGET) \
$(INSTALLED_RECOVERYIMAGE_TARGET) \
$(BOARD_AVB_KEY_PATH)
@@ -2365,6 +2496,7 @@
$(INSTALLED_USERDATAIMAGE_TARGET) \
$(INSTALLED_CACHEIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
+ $(INSTALLED_PRODUCTIMAGE_TARGET) \
$(INSTALLED_VBMETAIMAGE_TARGET) \
$(INSTALLED_DTBOIMAGE_TARGET) \
$(INTERNAL_SYSTEMOTHERIMAGE_FILES) \
@@ -2373,6 +2505,7 @@
$(INSTALLED_2NDBOOTLOADER_TARGET) \
$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH) \
$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH) \
+ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH) \
$(SELINUX_FC) \
$(APKCERTS_FILE) \
$(SOONG_ZIP) \
@@ -2380,11 +2513,12 @@
$(HOST_OUT_EXECUTABLES)/imgdiff \
$(HOST_OUT_EXECUTABLES)/bsdiff \
$(BUILD_IMAGE_SRCS) \
- $(INSTALLED_VENDOR_MANIFEST) \
- $(INSTALLED_VENDOR_MATRIX) \
+ $(BUILT_VENDOR_MANIFEST) \
+ $(BUILT_VENDOR_MATRIX) \
| $(ACP)
@echo "Package target files: $@"
$(call create-system-vendor-symlink)
+ $(call create-system-product-symlink)
$(hide) rm -rf $@ $@.list $(zip_root)
$(hide) mkdir -p $(dir $@) $(zip_root)
ifneq (,$(INSTALLED_RECOVERYIMAGE_TARGET)$(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)))
@@ -2450,6 +2584,11 @@
$(hide) $(call package_files-copy-root, \
$(TARGET_OUT_VENDOR),$(zip_root)/VENDOR)
endif
+ifdef BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE
+ @# Contents of the product image
+ $(hide) $(call package_files-copy-root, \
+ $(TARGET_OUT_PRODUCT),$(zip_root)/PRODUCT)
+endif
ifdef INSTALLED_SYSTEMOTHERIMAGE_TARGET
@# Contents of the system_other image
$(hide) $(call package_files-copy-root, \
@@ -2514,6 +2653,10 @@
$(hide) cp $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH) \
$(zip_root)/META/$(notdir $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH))
endif
+ifneq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH),)
+ $(hide) cp $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH) \
+ $(zip_root)/META/$(notdir $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH))
+endif
ifneq ($(strip $(SANITIZE_TARGET)),)
# We need to create userdata.img with real data because the instrumented libraries are in userdata.img.
$(hide) echo "userdata_img_with_data=true" >> $(zip_root)/META/misc_info.txt
@@ -2597,6 +2740,10 @@
$(hide) mkdir -p $(zip_root)/IMAGES
$(hide) cp $(INSTALLED_VENDORIMAGE_TARGET) $(zip_root)/IMAGES/
endif
+ifdef BOARD_PREBUILT_PRODUCTIMAGE
+ $(hide) mkdir -p $(zip_root)/IMAGES
+ $(hide) cp $(INSTALLED_PRODUCTIMAGE_TARGET) $(zip_root)/IMAGES/
+endif
ifdef BOARD_PREBUILT_BOOTIMAGE
$(hide) mkdir -p $(zip_root)/IMAGES
$(hide) cp $(INSTALLED_BOOTIMAGE_TARGET) $(zip_root)/IMAGES/
@@ -2627,6 +2774,9 @@
ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
$(hide) $(call fs_config,$(zip_root)/VENDOR,vendor/) > $(zip_root)/META/vendor_filesystem_config.txt
endif
+ifdef BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE
+ $(hide) $(call fs_config,$(zip_root)/PRODUCT,product/) > $(zip_root)/META/product_filesystem_config.txt
+endif
ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
$(hide) $(call fs_config,$(zip_root)/ROOT,) > $(zip_root)/META/root_filesystem_config.txt
endif
@@ -2744,6 +2894,7 @@
$(INSTALLED_BOOTIMAGE_TARGET) \
$(INSTALLED_USERDATAIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
+ $(INSTALLED_PRODUCTIMAGE_TARGET) \
$(updater_dep)
endif
$(SYMBOLS_ZIP): PRIVATE_LIST_FILE := $(call intermediates-dir-for,PACKAGING,symbols)/filelist
@@ -2766,7 +2917,8 @@
$(COVERAGE_ZIP): $(INSTALLED_SYSTEMIMAGE) \
$(INSTALLED_BOOTIMAGE_TARGET) \
$(INSTALLED_USERDATAIMAGE_TARGET) \
- $(INSTALLED_VENDORIMAGE_TARGET)
+ $(INSTALLED_VENDORIMAGE_TARGET) \
+ $(INSTALLED_PRODUCTIMAGE_TARGET)
endif
$(COVERAGE_ZIP): PRIVATE_LIST_FILE := $(call intermediates-dir-for,PACKAGING,coverage)/filelist
$(COVERAGE_ZIP): $(SOONG_ZIP)
@@ -2866,6 +3018,15 @@
vendorimage: $(INSTALLED_QEMU_VENDORIMAGE)
droidcore: $(INSTALLED_QEMU_VENDORIMAGE)
endif
+ifeq ($(BOARD_USES_PRODUCTIMAGE),true)
+INSTALLED_QEMU_PRODUCTIMAGE := $(PRODUCT_OUT)/product-qemu.img
+$(INSTALLED_QEMU_PRODUCTIMAGE): $(INSTALLED_PRODUCTIMAGE_TARGET) $(MK_QEMU_IMAGE_SH) $(SGDISK_HOST)
+ @echo Create product-qemu.img
+ (export SGDISK=$(SGDISK_HOST); $(MK_QEMU_IMAGE_SH) ${PRODUCT_OUT}/product.img)
+
+productimage: $(INSTALLED_QEMU_PRODUCTIMAGE)
+droidcore: $(INSTALLED_QEMU_PRODUCTIMAGE)
+endif
endif
# -----------------------------------------------------------------
# The emulator package
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 971c1ac..3ff3bd3 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -72,6 +72,8 @@
LOCAL_OEM_MODULE := true
else ifneq ($(filter $(TARGET_OUT_ODM)/%,$(_path)),)
LOCAL_ODM_MODULE := true
+else ifneq ($(filter $(TARGET_OUT_PRODUCT)/%,$(_path)),)
+LOCAL_PRODUCT_MODULE := true
endif
_path :=
@@ -200,6 +202,8 @@
partition_tag := _OEM
else ifeq (true,$(LOCAL_ODM_MODULE))
partition_tag := _ODM
+else ifeq (true,$(LOCAL_PRODUCT_MODULE))
+ partition_tag := _PRODUCT
else ifeq (NATIVE_TESTS,$(LOCAL_MODULE_CLASS))
partition_tag := _DATA
else
@@ -586,9 +590,6 @@
endif
endif # $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
-arch_dir :=
-is_native :=
-
ifneq ($(my_test_data_file_pairs),)
$(foreach pair, $(my_test_data_file_pairs), \
$(eval parts := $(subst :,$(space),$(pair))) \
@@ -599,6 +600,9 @@
$(src_path):$(call append-path,$(dir),$(file))))))
endif
+arch_dir :=
+is_native :=
+
$(call create-suite-dependencies)
endif # LOCAL_COMPATIBILITY_SUITE
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 5101e73..7d3fa75 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -197,6 +197,7 @@
LOCAL_PREBUILT_STRIP_COMMENTS:=
LOCAL_PRIVILEGED_MODULE:=
# '',full,custom,disabled,obfuscation,optimization
+LOCAL_PRODUCT_MODULE:=
LOCAL_PROGUARD_ENABLED:=
LOCAL_PROGUARD_FLAG_FILES:=
LOCAL_PROGUARD_FLAGS:=
diff --git a/core/config.mk b/core/config.mk
index b11e9fd..37ab875 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -824,6 +824,9 @@
$(error When PRODUCT_SHIPPING_API_LEVEL >= 27, TARGET_USES_MKE2FS must be true)
endif
endif
+ ifneq ($(call numbers_less_than,$(PRODUCT_SHIPPING_API_LEVEL),$(BOARD_SYSTEMSDK_VERSIONS)),)
+ $(error BOARD_SYSTEMSDK_VERSIONS ($(BOARD_SYSTEMSDK_VERSIONS)) must all be greater than or equal to PRODUCT_SHIPPING_API_LEVEL ($(PRODUCT_SHIPPING_API_LEVEL)))
+ endif
endif
# The default key if not set as LOCAL_CERTIFICATE
@@ -943,6 +946,10 @@
INTERNAL_PLATFORM_TEST_REMOVED_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/test-removed.txt
INTERNAL_PLATFORM_TEST_EXACT_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/test-exact.txt
+INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-light-greylist.txt
+INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-dark-greylist.txt
+INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-blacklist.txt
+
# This is the standard way to name a directory containing prebuilt target
# objects. E.g., prebuilt/$(TARGET_PREBUILT_TAG)/libc.so
TARGET_PREBUILT_TAG := android-$(TARGET_ARCH)
@@ -984,6 +991,7 @@
cacheimage-nodeps \
bptimage-nodeps \
vnod vendorimage-nodeps \
+ pnod productimage-nodeps \
systemotherimage-nodeps \
ramdisk-nodeps \
bootimage-nodeps \
diff --git a/core/definitions.mk b/core/definitions.mk
index 1236bf5..6ccb82b 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2241,15 +2241,17 @@
$(SOONG_JAVAC_WRAPPER) $(JAVAC_WRAPPER) $(1) -encoding UTF-8 \
$(if $(findstring true,$(PRIVATE_WARNINGS_ENABLE)),$(xlint_unchecked),) \
$(if $(PRIVATE_USE_SYSTEM_MODULES), \
- $(addprefix --system=,$(PRIVATE_SYSTEM_MODULES)), \
+ $(addprefix --system=,$(PRIVATE_SYSTEM_MODULES_DIR)), \
$(addprefix -bootclasspath ,$(strip \
$(call normalize-path-list,$(PRIVATE_BOOTCLASSPATH)) \
$(PRIVATE_EMPTY_BOOTCLASSPATH)))) \
$(if $(PRIVATE_USE_SYSTEM_MODULES), \
$(if $(PRIVATE_PATCH_MODULE), \
--patch-module=$(PRIVATE_PATCH_MODULE)=$(call normalize-path-list,. $(2)))) \
- $(addprefix -classpath ,$(strip \
- $(call normalize-path-list,$(2)))) \
+ $(addprefix -classpath ,$(call normalize-path-list,$(strip \
+ $(if $(PRIVATE_USE_SYSTEM_MODULES), \
+ $(filter-out $(PRIVATE_SYSTEM_MODULES_LIBS),$(PRIVATE_BOOTCLASSPATH))) \
+ $(2)))) \
$(if $(findstring true,$(PRIVATE_WARNINGS_ENABLE)),$(xlint_unchecked),) \
-d $(PRIVATE_CLASS_INTERMEDIATES_DIR) -s $(PRIVATE_ANNO_INTERMEDIATES_DIR) \
$(PRIVATE_JAVACFLAGS) \
diff --git a/core/envsetup.mk b/core/envsetup.mk
index f339b2f..6a7fbd1 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -179,6 +179,7 @@
TARGET_COPY_OUT_ASAN := $(TARGET_COPY_OUT_DATA)/asan
TARGET_COPY_OUT_OEM := oem
TARGET_COPY_OUT_ODM := odm
+TARGET_COPY_OUT_PRODUCT := product
TARGET_COPY_OUT_ROOT := root
TARGET_COPY_OUT_RECOVERY := recovery
@@ -198,6 +199,17 @@
TARGET_COPY_OUT_VENDOR := $(_vendor_path_placeholder)
###########################################
+###########################################
+# Define TARGET_COPY_OUT_PRODUCT to a placeholder, for at this point
+# we don't know if the device wants to build a separate product.img
+# or just build product stuff into system.img.
+# A device can set up TARGET_COPY_OUT_PRODUCT to "product" in its
+# BoardConfig.mk.
+# We'll substitute with the real value after loading BoardConfig.mk.
+_product_path_placeholder := ||PRODUCT-PATH-PH||
+TARGET_COPY_OUT_PRODUCT := $(_product_path_placeholder)
+###########################################
+
#################################################################
# Set up minimal BOOTCLASSPATH list of jars to build/execute
# java code with dalvikvm/art.
@@ -273,6 +285,29 @@
else ifdef BOARD_USES_VENDORIMAGE
$(error TARGET_COPY_OUT_VENDOR must be set to 'vendor' to use a vendor image)
endif
+
+###########################################
+# Now we can substitute with the real value of TARGET_COPY_OUT_PRODUCT
+ifeq ($(TARGET_COPY_OUT_PRODUCT),$(_product_path_placeholder))
+TARGET_COPY_OUT_PRODUCT := system/product
+else ifeq ($(filter product system/product,$(TARGET_COPY_OUT_PRODUCT)),)
+$(error TARGET_COPY_OUT_PRODUCT must be either 'product' or 'system/product', seeing '$(TARGET_COPY_OUT_PRODUCT)'.)
+endif
+PRODUCT_COPY_FILES := $(subst $(_product_path_placeholder),$(TARGET_COPY_OUT_PRODUCT),$(PRODUCT_COPY_FILES))
+
+BOARD_USES_PRODUCTIMAGE :=
+ifdef BOARD_PREBUILT_PRODUCTIMAGE
+BOARD_USES_PRODUCTIMAGE := true
+endif
+ifdef BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE
+BOARD_USES_PRODUCTIMAGE := true
+endif
+ifeq ($(TARGET_COPY_OUT_PRODUCT),product)
+BOARD_USES_PRODUCTIMAGE := true
+else ifdef BOARD_USES_PRODUCTIMAGE
+$(error TARGET_COPY_OUT_PRODUCT must be set to 'product' to use a product image)
+endif
+
###########################################
# Ensure that only TARGET_RECOVERY_UPDATER_LIBS *or* AB_OTA_UPDATER is set.
TARGET_RECOVERY_UPDATER_LIBS ?=
@@ -625,6 +660,39 @@
endif
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_APPS := $(TARGET_OUT_ODM_APPS)
+TARGET_OUT_PRODUCT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_PRODUCT)
+ifneq ($(filter address,$(SANITIZE_TARGET)),)
+target_out_product_shared_libraries_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ASAN)/system
+ifeq ($(SANITIZE_LITE),true)
+# When using SANITIZE_LITE, APKs must not be packaged with sanitized libraries, as they will not
+# work with unsanitized app_process. For simplicity, generate APKs into /data/asan/.
+target_out_product_app_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ASAN)/product
+else
+target_out_product_app_base := $(TARGET_OUT_PRODUCT)
+endif
+else
+target_out_product_shared_libraries_base := $(TARGET_OUT)
+target_out_product_app_base := $(TARGET_OUT_PRODUCT)
+endif
+
+ifeq ($(TARGET_IS_64_BIT),true)
+TARGET_OUT_PRODUCT_SHARED_LIBRARIES := $(target_out_product_shared_libraries_base)/lib64
+else
+TARGET_OUT_PRODUCT_SHARED_LIBRARIES := $(target_out_product_shared_libraries_base)/lib
+endif
+TARGET_OUT_PRODUCT_JAVA_LIBRARIES:= $(TARGET_OUT_PRODUCT)/framework
+TARGET_OUT_PRODUCT_APPS := $(target_out_product_app_base)/app
+TARGET_OUT_PRODUCT_APPS_PRIVILEGED := $(target_out_product_app_base)/priv-app
+TARGET_OUT_PRODUCT_ETC := $(TARGET_OUT_PRODUCT)/etc
+
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SHARED_LIBRARIES := $(target_out_product_shared_libraries_base)/lib/$(TARGET_2ND_ARCH)
+else
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_SHARED_LIBRARIES := $(target_out_product_shared_libraries_base)/lib
+endif
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_APPS := $(TARGET_OUT_PRODUCT_APPS)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_PRODUCT_APPS_PRIVILEGED := $(TARGET_OUT_PRODUCT_APPS_PRIVILEGED)
+
TARGET_OUT_BREAKPAD := $(PRODUCT_OUT)/breakpad
TARGET_OUT_UNSTRIPPED := $(PRODUCT_OUT)/symbols
diff --git a/core/java_common.mk b/core/java_common.mk
index 436f3a3..ac8b0d2 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -358,7 +358,9 @@
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH := $(full_java_bootclasspath_libs)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_EMPTY_BOOTCLASSPATH := $(empty_bootclasspath)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_SYSTEM_MODULES := $(my_system_modules_dir)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_SYSTEM_MODULES := $(my_system_modules)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_SYSTEM_MODULES_DIR := $(my_system_modules_dir)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_SYSTEM_MODULES_LIBS := $(call java-lib-files,$(SOONG_SYSTEM_MODULES_LIBS_$(my_system_modules)))
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_PATCH_MODULE := $(LOCAL_PATCH_MODULE)
ifndef LOCAL_IS_HOST_MODULE
diff --git a/core/main.mk b/core/main.mk
index 93c8d3b..38e9bd1 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -187,14 +187,16 @@
#
# -----------------------------------------------------------------
-# Enable dynamic linker developer warnings for userdebug, eng
-# and non-REL builds
+# Enable dynamic linker and hidden API developer warnings for
+# userdebug, eng and non-REL builds
ifneq ($(TARGET_BUILD_VARIANT),user)
- ADDITIONAL_BUILD_PROPERTIES += ro.bionic.ld.warning=1
+ ADDITIONAL_BUILD_PROPERTIES += ro.bionic.ld.warning=1 \
+ ro.art.hiddenapi.warning=1
else
# Enable it for user builds as long as they are not final.
ifneq ($(PLATFORM_VERSION_CODENAME),REL)
- ADDITIONAL_BUILD_PROPERTIES += ro.bionic.ld.warning=1
+ ADDITIONAL_BUILD_PROPERTIES += ro.bionic.ld.warning=1 \
+ ro.art.hiddenapi.warning=1
endif
endif
@@ -1041,6 +1043,9 @@
.PHONY: vendorimage
vendorimage: $(INSTALLED_VENDORIMAGE_TARGET)
+.PHONY: productimage
+productimage: $(INSTALLED_PRODUCTIMAGE_TARGET)
+
.PHONY: systemotherimage
systemotherimage: $(INSTALLED_SYSTEMOTHERIMAGE_TARGET)
@@ -1064,9 +1069,11 @@
$(INSTALLED_CACHEIMAGE_TARGET) \
$(INSTALLED_BPTIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
+ $(INSTALLED_PRODUCTIMAGE_TARGET) \
$(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
$(INSTALLED_FILES_FILE) \
$(INSTALLED_FILES_FILE_VENDOR) \
+ $(INSTALLED_FILES_FILE_PRODUCT) \
$(INSTALLED_FILES_FILE_SYSTEMOTHER) \
soong_docs
@@ -1132,6 +1139,7 @@
$(COVERAGE_ZIP) \
$(INSTALLED_FILES_FILE) \
$(INSTALLED_FILES_FILE_VENDOR) \
+ $(INSTALLED_FILES_FILE_PRODUCT) \
$(INSTALLED_FILES_FILE_SYSTEMOTHER) \
$(INSTALLED_BUILD_PROP_TARGET) \
$(BUILT_TARGET_FILES_PACKAGE) \
diff --git a/core/package_internal.mk b/core/package_internal.mk
index cdc4958..4890966 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -111,6 +111,8 @@
enforce_rro_enabled :=
else ifeq (true,$(LOCAL_ODM_MODULE))
enforce_rro_enabled :=
+ else ifeq (true,$(LOCAL_PRODUCT_MODULE))
+ enforce_rro_enabled :=
endif
else ifeq ($(filter $(TARGET_OUT)/%,$(LOCAL_MODULE_PATH)),)
enforce_rro_enabled :=
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index c7caf12..ea7fd03 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -417,11 +417,19 @@
endif # ! LOCAL_REPLACE_PREBUILT_APK_INSTALLED
###############################
-## Rule to build the odex file
+## Rule to build the odex file.
+# In case we don't strip the built module, use it, as dexpreopt
+# can do optimizations based on whether the built module only
+# contains uncompressed dex code.
ifdef LOCAL_DEX_PREOPT
+ifeq (nostripping,$(LOCAL_DEX_PREOPT))
+$(built_odex) : $(built_module)
+ $(call dexpreopt-one-file,$<,$@)
+else
$(built_odex) : $(my_prebuilt_src_file)
$(call dexpreopt-one-file,$<,$@)
endif
+endif
###############################
## Install split apks.
diff --git a/core/product-graph.mk b/core/product-graph.mk
index 666a207..576d14d 100644
--- a/core/product-graph.mk
+++ b/core/product-graph.mk
@@ -104,6 +104,7 @@
$(hide) echo 'PRODUCT_PROPERTY_OVERRIDES=$$(PRODUCTS.$(strip $(1)).PRODUCT_PROPERTY_OVERRIDES)' >> $$@
$(hide) echo 'PRODUCT_DEFAULT_PROPERTY_OVERRIDES=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEFAULT_PROPERTY_OVERRIDES)' >> $$@
$(hide) echo 'PRODUCT_SYSTEM_DEFAULT_PROPERTIES=$$(PRODUCTS.$(strip $(1)).PRODUCT_SYSTEM_DEFAULT_PROPERTIES)' >> $$@
+ $(hide) echo 'PRODUCT_PRODUCT_PROPERTIES=$$(PRODUCTS.$(strip $(1)).PRODUCT_PRODUCT_PROPERTIES)' >> $$@
$(hide) echo 'PRODUCT_CHARACTERISTICS=$$(PRODUCTS.$(strip $(1)).PRODUCT_CHARACTERISTICS)' >> $$@
$(hide) echo 'PRODUCT_COPY_FILES=$$(PRODUCTS.$(strip $(1)).PRODUCT_COPY_FILES)' >> $$@
$(hide) echo 'PRODUCT_OTA_PUBLIC_KEYS=$$(PRODUCTS.$(strip $(1)).PRODUCT_OTA_PUBLIC_KEYS)' >> $$@
diff --git a/core/product.mk b/core/product.mk
index 77f78a6..8095b27 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -88,6 +88,7 @@
PRODUCT_BRAND \
PRODUCT_PROPERTY_OVERRIDES \
PRODUCT_DEFAULT_PROPERTY_OVERRIDES \
+ PRODUCT_PRODUCT_PROPERTIES \
PRODUCT_CHARACTERISTICS \
PRODUCT_COPY_FILES \
PRODUCT_OTA_PUBLIC_KEYS \
@@ -125,6 +126,7 @@
PRODUCT_VERITY_SIGNING_KEY \
PRODUCT_SYSTEM_VERITY_PARTITION \
PRODUCT_VENDOR_VERITY_PARTITION \
+ PRODUCT_PRODUCT_VERITY_PARTITION \
PRODUCT_SYSTEM_SERVER_DEBUG_INFO \
PRODUCT_DEX_PREOPT_MODULE_CONFIGS \
PRODUCT_DEX_PREOPT_DEFAULT_FLAGS \
@@ -136,6 +138,7 @@
PRODUCT_SANITIZER_MODULE_CONFIGS \
PRODUCT_SYSTEM_BASE_FS_PATH \
PRODUCT_VENDOR_BASE_FS_PATH \
+ PRODUCT_PRODUCT_BASE_FS_PATH \
PRODUCT_SHIPPING_API_LEVEL \
VENDOR_PRODUCT_RESTRICT_VENDOR_FILES \
VENDOR_EXCEPTION_MODULES \
@@ -304,6 +307,8 @@
BOARD_FLASH_BLOCK_SIZE \
BOARD_VENDORIMAGE_PARTITION_SIZE \
BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE \
+ BOARD_PRODUCTIMAGE_PARTITION_SIZE \
+ BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE \
BOARD_INSTALLER_CMDLINE \
diff --git a/core/product_config.mk b/core/product_config.mk
index 2cd8016..bf607bb 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -365,6 +365,13 @@
$(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_DEFAULT_PROPERTIES))
.KATI_READONLY := PRODUCT_SYSTEM_DEFAULT_PROPERTIES
+# A list of property assignments, like "key = value", with zero or more
+# whitespace characters on either side of the '='.
+# used for adding properties to build.prop of product partition
+PRODUCT_PRODUCT_PROPERTIES := \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_PROPERTIES))
+.KATI_READONLY := PRODUCT_PRODUCT_PROPERTIES
+
# Should we use the default resources or add any product specific overlays
PRODUCT_PACKAGE_OVERLAYS := \
$(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGE_OVERLAYS))
@@ -482,7 +489,7 @@
$(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_CFI_INCLUDE_PATHS))
# which Soong namespaces to export to Make
-PRODUCT_SOONG_NAMESPACES :=
+PRODUCT_SOONG_NAMESPACES := \
$(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SOONG_NAMESPACES))
# A flag to override PRODUCT_COMPATIBLE_PROPERTY
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 2fa7ad4..639b019 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -124,7 +124,7 @@
$(call add_json_bool, Uml, $(filter true,$(TARGET_USER_MODE_LINUX)))
$(call add_json_str, VendorPath, $(TARGET_COPY_OUT_VENDOR))
$(call add_json_str, OdmPath, $(TARGET_COPY_OUT_ODM))
-$(call add_json_str, OemPath, $(TARGET_COPY_OUT_OEM))
+$(call add_json_str, ProductPath, $(TARGET_COPY_OUT_PRODUCT))
$(call add_json_bool, MinimizeJavaDebugInfo, $(filter true,$(PRODUCT_MINIMIZE_JAVA_DEBUG_INFO)))
$(call add_json_bool, UseGoma, $(filter-out false,$(USE_GOMA)))
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 8348349..aa1f0fa 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -88,7 +88,7 @@
LOCAL_INTERMEDIATE_TARGETS += $(my_res_package)
endif # LOCAL_USE_AAPT2
-endif # LOCAL_RESOURCE_DIR
+endif # need_compile_res
all_res_assets := $(all_resources)
diff --git a/help.sh b/help.sh
index 3f39c77..c143542 100755
--- a/help.sh
+++ b/help.sh
@@ -38,6 +38,8 @@
Stands for "System, NO Dependencies"
vnod Quickly rebuild the vendor image from built packages
Stands for "Vendor, NO Dependencies"
+ pnod Quickly rebuild the product image from built packages
+ Stands for "Product, NO Dependencies"
So, for example, you could run:
diff --git a/target/board/generic/sepolicy/genfs_contexts b/target/board/generic/sepolicy/genfs_contexts
index bdcead1..91cedf1 100644
--- a/target/board/generic/sepolicy/genfs_contexts
+++ b/target/board/generic/sepolicy/genfs_contexts
@@ -2,3 +2,16 @@
# /sys/bus/platform/devices/ANDR0001:00/properties/android/ which is a symlink to
# /sys/devices/platform/ANDR0001:00/properties/android/
genfscon sysfs /devices/platform/ANDR0001:00/properties/android u:object_r:sysfs_dt_firmware_android:s0
+
+# We expect /sys/class/power_supply/* and everything it links to to be labeled
+# as sysfs_batteryinfo.
+genfscon sysfs /devices/platform/GFSH0001:00/power_supply u:object_r:sysfs_batteryinfo:s0
+
+# /sys/class/rtc
+genfscon sysfs /devices/pnp0/00:00/rtc u:object_r:sysfs_rtc:s0
+genfscon sysfs /devices/platform/GFSH0007:00/rtc u:object_r:sysfs_rtc:s0
+
+# /sys/class/net
+genfscon sysfs /devices/pci0000:00/0000:00:08.0/virtio5/net u:object_r:sysfs_net:s0
+genfscon sysfs /devices/virtual/mac80211_hwsim/hwsim0/net u:object_r:sysfs_net:s0
+genfscon sysfs /devices/virtual/mac80211_hwsim/hwsim1/net u:object_r:sysfs_net:s0
diff --git a/target/board/generic/sepolicy/healthd.te b/target/board/generic/sepolicy/healthd.te
new file mode 100644
index 0000000..ced6704
--- /dev/null
+++ b/target/board/generic/sepolicy/healthd.te
@@ -0,0 +1,2 @@
+# Allow to read /sys/class/power_supply directory
+allow healthd sysfs:dir r_dir_perms;
diff --git a/target/product/base.mk b/target/product/base.mk
index c3eb3b2..750d3fa 100644
--- a/target/product/base.mk
+++ b/target/product/base.mk
@@ -114,6 +114,7 @@
mtpd \
ndc \
netd \
+ perfetto \
ping \
ping6 \
platform.xml \
@@ -132,6 +133,8 @@
svc \
tc \
telecom \
+ traced \
+ traced_probes \
vdc \
vold \
wm
diff --git a/target/product/treble_common.mk b/target/product/treble_common.mk
index 5880bf8..e9a97cd 100644
--- a/target/product/treble_common.mk
+++ b/target/product/treble_common.mk
@@ -70,12 +70,15 @@
PRODUCT_COPY_FILES += \
device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml
-#GSI support for the devices that disable VNDK enforcing
+# Support for the devices with no VNDK enforcing
PRODUCT_COPY_FILES += \
- system/core/rootdir/etc/ld.config.txt:system/etc/ld.config.noenforce.txt \
build/make/target/product/vndk/init.gsi.rc:system/etc/init/init.gsi.rc \
build/make/target/product/vndk/init.noenforce.rc:system/etc/init/gsi/init.noenforce.rc
-#Set current VNDK version for GSI
+# Name space configuration file for non-enforcing VNDK
+PRODUCT_PACKAGES += \
+ ld.config.noenforce.txt
+
+# Set current VNDK version for GSI
PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
ro.gsi.vndk.version=$(PLATFORM_VNDK_VERSION)
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index a9863bc..240e5c9 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -75,7 +75,7 @@
# Partitions that should have their care_map added to META/care_map.txt.
-PARTITIONS_WITH_CARE_MAP = ('system', 'vendor')
+PARTITIONS_WITH_CARE_MAP = ('system', 'vendor', 'product')
class OutputFile(object):
@@ -172,6 +172,20 @@
return img.name
+def AddProduct(output_zip, prefix="IMAGES/"):
+ """Turn the contents of PRODUCT into a product image and store it in output_zip."""
+
+ img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "product.img")
+ if os.path.exists(img.input_name):
+ print("product.img already exists in %s, no need to rebuild..." % (prefix,))
+ return img.input_name
+
+ block_list = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "product.map")
+ CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "product", img,
+ block_list=block_list)
+ return img.name
+
+
def AddDtbo(output_zip, prefix="IMAGES/"):
"""Adds the DTBO image.
@@ -621,13 +635,16 @@
print("target_files appears to already contain images.")
sys.exit(1)
- # vendor.img is unlike system.img or system_other.img. Because it could be
- # built from source, or dropped into target_files.zip as a prebuilt blob. We
- # consider either of them as vendor.img being available, which could be used
- # when generating vbmeta.img for AVB.
+ # {vendor,product}.img is unlike system.img or system_other.img. Because it could
+ # be built from source, or dropped into target_files.zip as a prebuilt blob.
+ # We consider either of them as {vendor,product}.img being available, which could
+ # be used when generating vbmeta.img for AVB.
has_vendor = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "VENDOR")) or
os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
"vendor.img")))
+ has_product = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "PRODUCT")) or
+ os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
+ "product.img")))
has_system_other = os.path.isdir(os.path.join(OPTIONS.input_tmp,
"SYSTEM_OTHER"))
@@ -715,6 +732,10 @@
banner("vendor")
partitions['vendor'] = AddVendor(output_zip)
+ if has_product:
+ banner("product")
+ partitions['product'] = AddProduct(output_zip)
+
if has_system_other:
banner("system_other")
AddSystemOther(output_zip)
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index f366853..1a7b933 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -362,6 +362,7 @@
# Double-check our work.
self.AssertSequenceGood()
+ self.AssertSha1Good()
self.ComputePatches(prefix)
self.WriteTransfers(prefix)
@@ -867,6 +868,21 @@
xf.tgt_name + " (from " + xf.src_name + ")"),
xf.tgt_ranges, xf.src_ranges))
+ def AssertSha1Good(self):
+ """Check the SHA-1 of the src & tgt blocks in the transfer list.
+
+ Double check the SHA-1 value to avoid the issue in b/71908713, where
+ SparseImage.RangeSha1() messed up with the hash calculation in multi-thread
+ environment. That specific problem has been fixed by protecting the
+ underlying generator function 'SparseImage._GetRangeData()' with lock.
+ """
+ for xf in self.transfers:
+ tgt_sha1 = self.tgt.RangeSha1(xf.tgt_ranges)
+ assert xf.tgt_sha1 == tgt_sha1
+ if xf.style == "diff":
+ src_sha1 = self.src.RangeSha1(xf.src_ranges)
+ assert xf.src_sha1 == src_sha1
+
def AssertSequenceGood(self):
# Simulate the sequences of transfers we will output, and check that:
# - we never read a block after writing it, and
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 1f5caf3..123ec7c 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -555,6 +555,8 @@
build_command.extend(["-U", prop_dict["uuid"]])
if "hash_seed" in prop_dict:
build_command.extend(["-S", prop_dict["hash_seed"]])
+ if "ext4_share_dup_blocks" in prop_dict:
+ build_command.append("-c")
if "selinux_fc" in prop_dict:
build_command.append(prop_dict["selinux_fc"])
elif fs_type.startswith("squash"):
@@ -723,6 +725,7 @@
copy_prop("system_root_image", "system_root_image")
copy_prop("ramdisk_dir", "ramdisk_dir")
copy_prop("ramdisk_fs_config", "ramdisk_fs_config")
+ copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
copy_prop("system_squashfs_compressor", "squashfs_compressor")
copy_prop("system_squashfs_compressor_opt", "squashfs_compressor_opt")
copy_prop("system_squashfs_block_size", "squashfs_block_size")
@@ -768,12 +771,29 @@
copy_prop("vendor_size", "partition_size")
copy_prop("vendor_journal_size", "journal_size")
copy_prop("vendor_verity_block_device", "verity_block_device")
+ copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
copy_prop("vendor_squashfs_compressor", "squashfs_compressor")
copy_prop("vendor_squashfs_compressor_opt", "squashfs_compressor_opt")
copy_prop("vendor_squashfs_block_size", "squashfs_block_size")
copy_prop("vendor_squashfs_disable_4k_align", "squashfs_disable_4k_align")
copy_prop("vendor_base_fs_file", "base_fs_file")
copy_prop("vendor_extfs_inode_count", "extfs_inode_count")
+ elif mount_point == "product":
+ copy_prop("avb_product_hashtree_enable", "avb_hashtree_enable")
+ copy_prop("avb_product_add_hashtree_footer_args",
+ "avb_add_hashtree_footer_args")
+ copy_prop("avb_product_key_path", "avb_key_path")
+ copy_prop("avb_product_algorithm", "avb_algorithm")
+ copy_prop("product_fs_type", "fs_type")
+ copy_prop("product_size", "partition_size")
+ copy_prop("product_journal_size", "journal_size")
+ copy_prop("product_verity_block_device", "verity_block_device")
+ copy_prop("product_squashfs_compressor", "squashfs_compressor")
+ copy_prop("product_squashfs_compressor_opt", "squashfs_compressor_opt")
+ copy_prop("product_squashfs_block_size", "squashfs_block_size")
+ copy_prop("product_squashfs_disable_4k_align", "squashfs_disable_4k_align")
+ copy_prop("product_base_fs_file", "base_fs_file")
+ copy_prop("product_extfs_inode_count", "extfs_inode_count")
elif mount_point == "oem":
copy_prop("fs_type", "fs_type")
copy_prop("oem_size", "partition_size")
@@ -827,6 +847,8 @@
mount_point = "vendor"
elif image_filename == "oem.img":
mount_point = "oem"
+ elif image_filename == "product.img":
+ mount_point = "product"
else:
print("error: unknown image file name ", image_filename, file=sys.stderr)
sys.exit(1)
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index ebebd63..632cc11 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -78,7 +78,7 @@
# The partitions allowed to be signed by AVB (Android verified boot 2.0).
-AVB_PARTITIONS = ('boot', 'recovery', 'system', 'vendor', 'dtbo')
+AVB_PARTITIONS = ('boot', 'recovery', 'system', 'vendor', 'product', 'dtbo')
class ErrorCode(object):
@@ -1385,7 +1385,7 @@
p.kill()
th.join()
- if err or p.returncode != 0:
+ if p.returncode != 0:
print("WARNING: failure running %s:\n%s\n" % (
diff_program, "".join(err)))
self.patch = None
diff --git a/tools/warn.py b/tools/warn.py
index f42fb96..01398be 100755
--- a/tools/warn.py
+++ b/tools/warn.py
@@ -509,6 +509,26 @@
{'category': 'java',
'severity': Severity.LOW,
'description':
+ 'Java: Fields that can be null should be annotated @Nullable',
+ 'patterns': [r".*: warning: \[FieldMissingNullable\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Method parameters that aren\'t checked for null shouldn\'t be annotated @Nullable',
+ 'patterns': [r".*: warning: \[ParameterNotNullable\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Methods that can return null should be annotated @Nullable',
+ 'patterns': [r".*: warning: \[ReturnMissingNullable\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Use parameter comments to document ambiguous literals',
+ 'patterns': [r".*: warning: \[BooleanParameter\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
'Java: Field name is CONSTANT CASE, but field is not static and final',
'patterns': [r".*: warning: \[ConstantField\] .+"]},
{'category': 'java',
@@ -519,11 +539,21 @@
{'category': 'java',
'severity': Severity.LOW,
'description':
+ 'Java: Use Java\'s utility functional interfaces instead of Function\u003cA, B> for primitive types.',
+ 'patterns': [r".*: warning: \[LambdaFunctionalInterface\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
'Java: Prefer \'L\' to \'l\' for the suffix to long literals',
'patterns': [r".*: warning: \[LongLiteralLowerCaseSuffix\] .+"]},
{'category': 'java',
'severity': Severity.LOW,
'description':
+ 'Java: A private method that does not reference the enclosing instance can be static',
+ 'patterns': [r".*: warning: \[MethodCanBeStatic\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
'Java: C-style array declarations should not be used',
'patterns': [r".*: warning: \[MixedArrayDimensions\] .+"]},
{'category': 'java',
@@ -539,11 +569,21 @@
{'category': 'java',
'severity': Severity.LOW,
'description':
+ 'Java: Avoid having multiple unary operators acting on the same variable in a method call',
+ 'patterns': [r".*: warning: \[MultipleUnaryOperatorsInMethodCall\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
'Java: Package names should match the directory they are declared in',
'patterns': [r".*: warning: \[PackageLocation\] .+"]},
{'category': 'java',
'severity': Severity.LOW,
'description':
+ 'Java: Non-standard parameter comment; prefer `/*paramName=*/ arg`',
+ 'patterns': [r".*: warning: \[ParameterComment\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
'Java: Utility classes (only static members) are not designed to be instantiated and should be made noninstantiable with a default constructor.',
'patterns': [r".*: warning: \[PrivateConstructorForUtilityClass\] .+"]},
{'category': 'java',
@@ -554,11 +594,31 @@
{'category': 'java',
'severity': Severity.LOW,
'description':
+ 'Java: The default case of a switch should appear at the end of the last statement group',
+ 'patterns': [r".*: warning: \[SwitchDefault\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
'Java: Unchecked exceptions do not need to be declared in the method signature.',
'patterns': [r".*: warning: \[ThrowsUncheckedException\] .+"]},
{'category': 'java',
'severity': Severity.LOW,
'description':
+ 'Java: Type parameters must be a single letter with an optional numeric suffix, or an UpperCamelCase name followed by the letter \'T\'.',
+ 'patterns': [r".*: warning: \[TypeParameterNaming\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Constructors and methods with the same name should appear sequentially with no other code in between',
+ 'patterns': [r".*: warning: \[UngroupedOverloads\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Unnecessary call to NullPointerTester#setDefault',
+ 'patterns': [r".*: warning: \[UnnecessarySetDefault\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
'Java: Using static imports for types is unnecessary',
'patterns': [r".*: warning: \[UnnecessaryStaticImport\] .+"]},
{'category': 'java',
@@ -567,6 +627,61 @@
'Java: Wildcard imports, static or otherwise, should not be used',
'patterns': [r".*: warning: \[WildcardImport\] .+"]},
{'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: ',
+ 'patterns': [r".*: warning: \[RemoveFieldPrefixes\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Prefer assertThrows to ExpectedException',
+ 'patterns': [r".*: warning: \[ExpectedExceptionMigration\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Logger instances are not constants -- they are mutable and have side effects -- and should not be named using CONSTANT CASE',
+ 'patterns': [r".*: warning: \[LoggerVariableCase\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Prefer assertThrows to @Test(expected=...)',
+ 'patterns': [r".*: warning: \[TestExceptionMigration\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Public fields must be final.',
+ 'patterns': [r".*: warning: \[NonFinalPublicFields\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Private fields that are only assigned in the initializer should be made final.',
+ 'patterns': [r".*: warning: \[PrivateFieldsNotAssigned\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Lists returned by methods should be immutable.',
+ 'patterns': [r".*: warning: \[ReturnedListNotImmutable\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Parameters to log methods should not be generated by a call to String.format() or MessageFormat.format().',
+ 'patterns': [r".*: warning: \[SaferLoggerFormat\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Parameters to log methods should not be generated by a call to toString(); see b/22986665.',
+ 'patterns': [r".*: warning: \[SaferLoggerToString\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: A call to Binder.clearCallingIdentity() should be followed by Binder.restoreCallingIdentity() in a finally block. Otherwise the wrong Binder identity may be used by subsequent code.',
+ 'patterns': [r".*: warning: \[BinderIdentityRestoredDangerously\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Classes extending PreferenceActivity must implement isValidFragment such that it does not unconditionally return true to prevent vulnerability to fragment injection attacks.',
+ 'patterns': [r".*: warning: \[FragmentInjection\] .+"]},
+ {'category': 'java',
'severity': Severity.MEDIUM,
'description':
'Java: Subclasses of Fragment must be instantiable via Class#newInstance(): the class must be public, static and have a public nullary constructor',
@@ -579,6 +694,26 @@
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: A wakelock acquired with a timeout may be released by the system before calling `release`, even after checking `isHeld()`. If so, it will throw a RuntimeException. Please wrap in a try/catch block.',
+ 'patterns': [r".*: warning: \[WakelockReleasedDangerously\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Arguments are in the wrong order or could be commented for clarity.',
+ 'patterns': [r".*: warning: \[ArgumentSelectionDefectChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Arguments are swapped in assertEquals-like call',
+ 'patterns': [r".*: warning: \[AssertEqualsArgumentOrderChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: An equality test between objects with incompatible types always returns false',
+ 'patterns': [r".*: warning: \[EqualsIncompatibleType\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: @AssistedInject and @Inject should not be used on different constructors in the same class.',
'patterns': [r".*: warning: \[AssistedInjectAndInjectOnConstructors\] .+"]},
{'category': 'java',
@@ -604,11 +739,21 @@
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: The ordering of parameters in overloaded methods should be as consistent as possible (when viewed from left to right)',
+ 'patterns': [r".*: warning: \[InconsistentOverloads\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Double-checked locking on non-volatile fields is unsafe',
'patterns': [r".*: warning: \[DoubleCheckedLocking\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: Annotations should always be immutable',
+ 'patterns': [r".*: warning: \[ImmutableAnnotationChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Enums should always be immutable',
'patterns': [r".*: warning: \[ImmutableEnumChecker\] .+"]},
{'category': 'java',
@@ -629,13 +774,13 @@
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
- 'Java: A different potential argument is more similar to the name of the parameter than the existing argument; this may be an error',
- 'patterns': [r".*: warning: \[ArgumentParameterMismatch\] .+"]},
+ 'Java: Assertions may be disabled at runtime and do not guarantee that execution will halt here; consider throwing an exception instead',
+ 'patterns': [r".*: warning: \[AssertFalse\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
- 'Java: Assertions may be disabled at runtime and do not guarantee that execution will halt here; consider throwing an exception instead',
- 'patterns': [r".*: warning: \[AssertFalse\] .+"]},
+ 'Java: This assertion throws an AssertionError if it fails, which will be caught by an enclosing try block.',
+ 'patterns': [r".*: warning: \[AssertionFailureIgnored\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
@@ -664,23 +809,63 @@
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: Duration can be expressed more clearly with different units',
+ 'patterns': [r".*: warning: \[CanonicalDuration\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Logging or rethrowing exceptions should usually be preferred to catching and calling printStackTrace',
+ 'patterns': [r".*: warning: \[CatchAndPrintStackTrace\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Ignoring exceptions and calling fail() is unnecessary, and makes test output less useful',
+ 'patterns': [r".*: warning: \[CatchFail\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Inner class is non-static but does not reference enclosing class',
'patterns': [r".*: warning: \[ClassCanBeStatic\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
- 'Java: Class.newInstance() bypasses exception checking; prefer getConstructor().newInstance()',
+ 'Java: Class.newInstance() bypasses exception checking; prefer getDeclaredConstructor().newInstance()',
'patterns': [r".*: warning: \[ClassNewInstance\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
- 'Java: Implicit use of the platform default charset, which can result in e.g. non-ASCII characters being silently replaced with \'?\' in many environments',
- 'patterns': [r".*: warning: \[DefaultCharset\] .+"]},
+ 'Java: The type of the array parameter of Collection.toArray needs to be compatible with the array type',
+ 'patterns': [r".*: warning: \[CollectionToArraySafeParameter\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
- 'Java: This code, which counts elements using a loop, can be replaced by a simpler library method',
- 'patterns': [r".*: warning: \[ElementsCountedInLoop\] .+"]},
+ 'Java: Collector.of() should not use state',
+ 'patterns': [r".*: warning: \[CollectorShouldNotUseState\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Class should not implement both `Comparable` and `Comparator`',
+ 'patterns': [r".*: warning: \[ComparableAndComparator\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Constructors should not invoke overridable methods.',
+ 'patterns': [r".*: warning: \[ConstructorInvokesOverridable\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Constructors should not pass the \'this\' reference out in method invocations, since the object may not be fully constructed.',
+ 'patterns': [r".*: warning: \[ConstructorLeaksThis\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: DateFormat is not thread-safe, and should not be used as a constant field.',
+ 'patterns': [r".*: warning: \[DateFormatConstant\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Implicit use of the platform default charset, which can result in differing behavior between JVM executions or incorrect behavior if the encoding of the data source doesn\'t match expectations.',
+ 'patterns': [r".*: warning: \[DefaultCharset\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
@@ -694,8 +879,13 @@
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
- 'Java: An equality test between objects with incompatible types always returns false',
- 'patterns': [r".*: warning: \[EqualsIncompatibleType\] .+"]},
+ 'Java: Calls to ExpectedException#expect should always be followed by exactly one statement.',
+ 'patterns': [r".*: warning: \[ExpectedExceptionChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Switch case may fall through',
+ 'patterns': [r".*: warning: \[FallThrough\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
@@ -704,26 +894,61 @@
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: Use parentheses to make the precedence explicit',
+ 'patterns': [r".*: warning: \[FloatCast\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Floating point literal loses precision',
+ 'patterns': [r".*: warning: \[FloatingPointLiteralPrecision\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Overloads will be ambiguous when passing lambda arguments',
'patterns': [r".*: warning: \[FunctionalInterfaceClash\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: Return value of methods returning Future must be checked. Ignoring returned Futures suppresses exceptions thrown from the code that completes the Future.',
+ 'patterns': [r".*: warning: \[FutureReturnValueIgnored\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Calling getClass() on an enum may return a subclass of the enum type',
'patterns': [r".*: warning: \[GetClassOnEnum\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: Hiding fields of superclasses may cause confusion and errors',
+ 'patterns': [r".*: warning: \[HidingField\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: This annotation has incompatible modifiers as specified by its @IncompatibleModifiers annotation',
'patterns': [r".*: warning: \[IncompatibleModifiers\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: This for loop increments the same variable in the header and in the body',
+ 'patterns': [r".*: warning: \[IncrementInForLoopAndHeader\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Please also override int read(byte[], int, int), otherwise multi-byte reads from this input stream are likely to be slow.',
'patterns': [r".*: warning: \[InputStreamSlowMultibyteRead\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: Casting inside an if block should be plausibly consistent with the instanceof type',
+ 'patterns': [r".*: warning: \[InstanceOfAndCastMatchWrongType\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Expression of type int may overflow before being assigned to a long',
+ 'patterns': [r".*: warning: \[IntLongMath\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Class should not implement both `Iterable` and `Iterator`',
'patterns': [r".*: warning: \[IterableAndIterator\] .+"]},
{'category': 'java',
@@ -734,16 +959,41 @@
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: Some JUnit4 construct cannot be used in a JUnit3 context. Convert your class to JUnit4 style to use them.',
+ 'patterns': [r".*: warning: \[JUnit4ClassUsedInJUnit3\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Test class inherits from JUnit 3\'s TestCase but has JUnit 4 @Test annotations.',
'patterns': [r".*: warning: \[JUnitAmbiguousTestClass\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
- 'Java: The Google Java Style Guide requires switch statements to have an explicit default',
+ 'Java: Never reuse class names from java.lang',
+ 'patterns': [r".*: warning: \[JavaLangClash\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Suggests alternatives to obsolete JDK classes.',
+ 'patterns': [r".*: warning: \[JdkObsolete\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Assignment where a boolean expression was expected; use == if this assignment wasn\'t expected or add parentheses for clarity.',
+ 'patterns': [r".*: warning: \[LogicalAssignment\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Switches on enum types should either handle all values, or have a default case.',
'patterns': [r".*: warning: \[MissingCasesInEnumSwitch\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: The Google Java Style Guide requires that each switch statement includes a default statement group, even if it contains no code. (This requirement is lifted for any switch statement that covers all values of an enum.)',
+ 'patterns': [r".*: warning: \[MissingDefault\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Not calling fail() when expecting an exception masks bugs',
'patterns': [r".*: warning: \[MissingFail\] .+"]},
{'category': 'java',
@@ -754,11 +1004,36 @@
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
- 'Java: Compound assignments to bytes, shorts, chars, and floats hide dangerous casts',
+ 'Java: Modifying a collection while iterating over it in a loop may cause a ConcurrentModificationException to be thrown.',
+ 'patterns': [r".*: warning: \[ModifyCollectionInEnhancedForLoop\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Multiple calls to either parallel or sequential are unnecessary and cause confusion.',
+ 'patterns': [r".*: warning: \[MultipleParallelOrSequentialCalls\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Constant field declarations should use the immutable type (such as ImmutableList) instead of the general collection interface type (such as List)',
+ 'patterns': [r".*: warning: \[MutableConstantField\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Method return type should use the immutable type (such as ImmutableList) instead of the general collection interface type (such as List)',
+ 'patterns': [r".*: warning: \[MutableMethodReturnType\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Compound assignments may hide dangerous casts',
'patterns': [r".*: warning: \[NarrowingCompoundAssignment\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: Nested instanceOf conditions of disjoint types create blocks of code that never execute',
+ 'patterns': [r".*: warning: \[NestedInstanceOfConditions\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: This update of a volatile variable is non-atomic',
'patterns': [r".*: warning: \[NonAtomicVolatileUpdate\] .+"]},
{'category': 'java',
@@ -794,6 +1069,31 @@
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: One should not call optional.get() inside an if statement that checks !optional.isPresent',
+ 'patterns': [r".*: warning: \[OptionalNotPresent\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: String literal contains format specifiers, but is not passed to a format method',
+ 'patterns': [r".*: warning: \[OrphanedFormatString\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: To return a custom message with a Throwable class, one should override getMessage() instead of toString() for Throwable.',
+ 'patterns': [r".*: warning: \[OverrideThrowableToString\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Varargs doesn\'t agree for overridden method',
+ 'patterns': [r".*: warning: \[Overrides\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Detects `/* name= */`-style comments on actual parameters where the name doesn\'t match the formal parameter',
+ 'patterns': [r".*: warning: \[ParameterName\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Preconditions only accepts the %s placeholder in error message strings',
'patterns': [r".*: warning: \[PreconditionsInvalidPlaceholder\] .+"]},
{'category': 'java',
@@ -809,6 +1109,16 @@
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: BugChecker has incorrect ProvidesFix tag, please update',
+ 'patterns': [r".*: warning: \[ProvidesFix\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: reachabilityFence should always be called inside a finally block',
+ 'patterns': [r".*: warning: \[ReachabilityFenceUsage\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Thrown exception is a subtype of another',
'patterns': [r".*: warning: \[RedundantThrows\] .+"]},
{'category': 'java',
@@ -824,8 +1134,18 @@
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
- 'Java: A static variable or method should not be accessed from an object instance',
- 'patterns': [r".*: warning: \[StaticAccessedFromInstance\] .+"]},
+ 'Java: Prefer the short-circuiting boolean operators \u0026\u0026 and || to \u0026 and |.',
+ 'patterns': [r".*: warning: \[ShortCircuitBoolean\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: A static variable or method should be qualified with a class name, not expression',
+ 'patterns': [r".*: warning: \[StaticQualifiedUsingExpression\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Streams that encapsulate a closeable resource should be closed using try-with-resources',
+ 'patterns': [r".*: warning: \[StreamResourceLeak\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
@@ -834,13 +1154,43 @@
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: String.split should never take only a single argument; it has surprising behavior',
+ 'patterns': [r".*: warning: \[StringSplit\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Prefer Splitter to String.split',
+ 'patterns': [r".*: warning: \[StringSplitter\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Using @Test(expected=...) is discouraged, since the test will pass if *any* statement in the test method throws the expected exception',
+ 'patterns': [r".*: warning: \[TestExceptionChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Thread.join needs to be surrounded by a loop until it succeeds, as in Uninterruptibles.joinUninterruptibly.',
+ 'patterns': [r".*: warning: \[ThreadJoinLoop\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: ThreadLocals should be stored in static fields',
+ 'patterns': [r".*: warning: \[ThreadLocalUsage\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Three-letter time zone identifiers are deprecated, may be ambiguous, and might not do what you intend; the full IANA time zone ID should be used instead.',
+ 'patterns': [r".*: warning: \[ThreeLetterTimeZoneID\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Truth Library assert is called on a constant.',
'patterns': [r".*: warning: \[TruthConstantAsserts\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
- 'Java: An object is tested for equality to itself using Truth Libraries.',
- 'patterns': [r".*: warning: \[TruthSelfEquals\] .+"]},
+ 'Java: Type parameter declaration overrides another type parameter already declared',
+ 'patterns': [r".*: warning: \[TypeParameterShadowing\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
@@ -849,11 +1199,31 @@
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: Creation of a Set/HashSet/HashMap of java.net.URL. equals() and hashCode() of java.net.URL class make blocking internet connections.',
+ 'patterns': [r".*: warning: \[URLEqualsHashCode\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Switch handles all enum values; an explicit default case is unnecessary and defeats error checking for non-exhaustive switches.',
+ 'patterns': [r".*: warning: \[UnnecessaryDefaultInEnumSwitch\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Finalizer may run before native code finishes execution',
+ 'patterns': [r".*: warning: \[UnsafeFinalization\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Unsynchronized method overrides a synchronized method.',
'patterns': [r".*: warning: \[UnsynchronizedOverridesSynchronized\] .+"]},
{'category': 'java',
'severity': Severity.MEDIUM,
'description':
+ 'Java: Java assert is used in test. For testing purposes Assert.* matchers should be used.',
+ 'patterns': [r".*: warning: \[UseCorrectAssertInTests\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
'Java: Non-constant variable missing @Var annotation',
'patterns': [r".*: warning: \[Var\] .+"]},
{'category': 'java',
@@ -862,6 +1232,151 @@
'Java: Because of spurious wakeups, Object.wait() and Condition.await() must always be called in a loop',
'patterns': [r".*: warning: \[WaitNotInLoop\] .+"]},
{'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Pluggable Type checker internal error',
+ 'patterns': [r".*: warning: \[PluggableTypeChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Invalid message format-style format specifier ({0}), expected printf-style (%s)',
+ 'patterns': [r".*: warning: \[FloggerMessageFormat\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Logger level check is already implied in the log() call. An explicit at[Level]().isEnabled() check is redundant.',
+ 'patterns': [r".*: warning: \[FloggerRedundantIsEnabled\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Calling withCause(Throwable) with an inline allocated Throwable is discouraged. Consider using withStackTrace(StackSize) instead, and specifying a reduced stack size (e.g. SMALL, MEDIUM or LARGE) instead of FULL, to improve performance.',
+ 'patterns': [r".*: warning: \[FloggerWithCause\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Use withCause to associate Exceptions with log statements',
+ 'patterns': [r".*: warning: \[FloggerWithoutCause\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: No bug exists to track an ignored test',
+ 'patterns': [r".*: warning: \[IgnoredTestWithoutBug\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: @Ignore is preferred to @Suppress for JUnit4 tests. @Suppress may silently fail in JUnit4 (that is, tests may run anyway.)',
+ 'patterns': [r".*: warning: \[JUnit4SuppressWithoutIgnore\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Medium and large test classes should document why they are medium or large',
+ 'patterns': [r".*: warning: \[JUnit4TestAttributeMissing\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: java.net.IDN implements the older IDNA2003 standard. Prefer com.google.i18n.Idn, which implements the newer UTS #46 standard',
+ 'patterns': [r".*: warning: \[JavaNetIdn\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Consider requiring strict parsing on JodaDurationFlag instances. Before adjusting existing flags, check the documentation and your existing configuration to avoid crashes!',
+ 'patterns': [r".*: warning: \[JodaDurationFlagStrictParsing\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Logging an exception and throwing it (or a new exception) for the same exceptional situation is an anti-pattern.',
+ 'patterns': [r".*: warning: \[LogAndThrow\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: FormattingLogger uses wrong or mismatched format string',
+ 'patterns': [r".*: warning: \[MisusedFormattingLogger\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Flags should be final',
+ 'patterns': [r".*: warning: \[NonFinalFlag\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Reading a flag from a static field or initializer block will cause it to always receive the default value and will cause an IllegalFlagStateException if the flag is ever set.',
+ 'patterns': [r".*: warning: \[StaticFlagUsage\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Apps must use BuildCompat.isAtLeastO to check whether they\'re running on Android O',
+ 'patterns': [r".*: warning: \[UnsafeSdkVersionCheck\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Logging tag cannot be longer than 23 characters.',
+ 'patterns': [r".*: warning: \[LogTagLength\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Relative class name passed to ComponentName constructor',
+ 'patterns': [r".*: warning: \[RelativeComponentName\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Explicitly enumerate all cases in switch statements for certain enum types.',
+ 'patterns': [r".*: warning: \[EnumerateAllCasesInEnumSwitch\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Do not call assumeTrue(tester.getExperimentValueFor(...)). Use @RequireEndToEndTestExperiment instead.',
+ 'patterns': [r".*: warning: \[JUnitAssumeExperiment\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: The accessed field or method is not visible here. Note that the default production visibility for @VisibleForTesting is Visibility.PRIVATE.',
+ 'patterns': [r".*: warning: \[VisibleForTestingChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Detects errors encountered building Error Prone plugins',
+ 'patterns': [r".*: warning: \[ErrorPronePluginCorrectness\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Parcelable CREATOR fields should be Creator\u003cT>',
+ 'patterns': [r".*: warning: \[ParcelableCreatorType\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Enforce reflected Parcelables are kept by Proguard',
+ 'patterns': [r".*: warning: \[ReflectedParcelable\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Any class that extends IntentService should have @Nullable notation on method onHandleIntent(@Nullable Intent intent) and handle the case if intent is null.',
+ 'patterns': [r".*: warning: \[OnHandleIntentNullableChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: In many cases, randomUUID is not necessary, and it slows the performance, which can be quite severe especially when this operation happens at start up time. Consider replacing it with cheaper alternatives, like object.hashCode() or IdGenerator.INSTANCE.getRandomId()',
+ 'patterns': [r".*: warning: \[UUIDChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: DynamicActivity.findViewById(int) is slow and should not be used inside View.onDraw(Canvas)!',
+ 'patterns': [r".*: warning: \[NoFindViewByIdInOnDrawChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Passing Throwable/Exception argument to the message format L.x(). Calling L.w(tag, message, ex) instead of L.w(tag, ex, message)',
+ 'patterns': [r".*: warning: \[WrongThrowableArgumentInLogChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: New splicers are disallowed on paths that are being Libsearched',
+ 'patterns': [r".*: warning: \[BlacklistedSplicerPathChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Object serialized in Bundle may have been flattened to base type.',
+ 'patterns': [r".*: warning: \[BundleDeserializationCast\] .+"]},
+ {'category': 'java',
'severity': Severity.HIGH,
'description':
'Java: Log tag too long, cannot exceed 23 characters.',
@@ -879,11 +1394,6 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: Static and default methods in interfaces are not allowed in android builds.',
- 'patterns': [r".*: warning: \[StaticOrDefaultInterfaceMethod\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
'Java: Incompatible type as argument to Object-accepting Java collections method',
'patterns': [r".*: warning: \[CollectionIncompatibleType\] .+"]},
{'category': 'java',
@@ -909,106 +1419,6 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: @AssistedInject and @Inject cannot be used on the same constructor.',
- 'patterns': [r".*: warning: \[AssistedInjectAndInjectOnSameConstructor\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: @AutoFactory and @Inject should not be used in the same type.',
- 'patterns': [r".*: warning: \[AutoFactoryAtInject\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: Injected constructors cannot be optional nor have binding annotations',
- 'patterns': [r".*: warning: \[InjectedConstructorAnnotations\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: A scoping annotation\'s Target should include TYPE and METHOD.',
- 'patterns': [r".*: warning: \[InjectInvalidTargetingOnScopingAnnotation\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: Abstract and default methods are not injectable with javax.inject.Inject',
- 'patterns': [r".*: warning: \[JavaxInjectOnAbstractMethod\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: @javax.inject.Inject cannot be put on a final field.',
- 'patterns': [r".*: warning: \[JavaxInjectOnFinalField\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: This class has more than one @Inject-annotated constructor. Please remove the @Inject annotation from all but one of them.',
- 'patterns': [r".*: warning: \[MoreThanOneInjectableConstructor\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: Using more than one qualifier annotation on the same element is not allowed.',
- 'patterns': [r".*: warning: \[InjectMoreThanOneQualifier\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: A class can be annotated with at most one scope annotation.',
- 'patterns': [r".*: warning: \[InjectMoreThanOneScopeAnnotationOnClass\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: Annotations cannot be both Scope annotations and Qualifier annotations: this causes confusion when trying to use them.',
- 'patterns': [r".*: warning: \[OverlappingQualifierAndScopeAnnotation\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: Qualifier applied to a method that isn\'t a @Provides method. This method won\'t be used for dependency injection',
- 'patterns': [r".*: warning: \[QualifierOnMethodWithoutProvides\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: Scope annotation on an interface or abstact class is not allowed',
- 'patterns': [r".*: warning: \[InjectScopeAnnotationOnInterfaceOrAbstractClass\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: Scoping and qualifier annotations must have runtime retention.',
- 'patterns': [r".*: warning: \[InjectScopeOrQualifierAnnotationRetention\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: `@Multibinds` is the new way to declare multibindings.',
- 'patterns': [r".*: warning: \[MultibindsInsteadOfMultibindings\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: Dagger @Provides methods may not return null unless annotated with @Nullable',
- 'patterns': [r".*: warning: \[DaggerProvidesNull\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: Scope annotation on implementation class of AssistedInject factory is not allowed',
- 'patterns': [r".*: warning: \[GuiceAssistedInjectScoping\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: A constructor cannot have two @Assisted parameters of the same type unless they are disambiguated with named @Assisted annotations.',
- 'patterns': [r".*: warning: \[GuiceAssistedParameters\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: Although Guice allows injecting final fields, doing so is disallowed because the injected value may not be visible to other threads.',
- 'patterns': [r".*: warning: \[GuiceInjectOnFinalField\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: This method is not annotated with @Inject, but it overrides a method that is annotated with @javax.inject.Inject. The method will not be Injected.',
- 'patterns': [r".*: warning: \[OverridesJavaxInjectableMethod\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
- 'Java: @Provides methods need to be declared in a Module to have any effect.',
- 'patterns': [r".*: warning: \[ProvidesMethodOutsideOfModule\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
'Java: Checks for unguarded accesses to fields and methods with @GuardedBy annotations',
'patterns': [r".*: warning: \[GuardedBy\] .+"]},
{'category': 'java',
@@ -1029,13 +1439,13 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: An argument is more similar to a different parameter; the arguments may have been swapped.',
- 'patterns': [r".*: warning: \[ArgumentParameterSwap\] .+"]},
+ 'Java: Reference equality used to compare arrays',
+ 'patterns': [r".*: warning: \[ArrayEquals\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: Reference equality used to compare arrays',
- 'patterns': [r".*: warning: \[ArrayEquals\] .+"]},
+ 'Java: Arrays.fill(Object[], Object) called with incompatible types.',
+ 'patterns': [r".*: warning: \[ArrayFillIncompatibleType\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
'description':
@@ -1084,6 +1494,11 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: Implementing \'Comparable\u003cT>\' where T is not compatible with the implementing class.',
+ 'patterns': [r".*: warning: \[ComparableType\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: This comparison method violates the contract',
'patterns': [r".*: warning: \[ComparisonContractViolated\] .+"]},
{'category': 'java',
@@ -1099,6 +1514,16 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: Non-trivial compile time constant boolean expressions shouldn\'t be used.',
+ 'patterns': [r".*: warning: \[ComplexBooleanConstant\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: A conditional expression with numeric operands of differing types will perform binary numeric promotion of the operands; when these operands are of reference types, the expression\'s result may not be of the expected type.',
+ 'patterns': [r".*: warning: \[ConditionalExpressionNumericPromotion\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: Compile-time constant expression overflows',
'patterns': [r".*: warning: \[ConstantOverflow\] .+"]},
{'category': 'java',
@@ -1109,11 +1534,21 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: Thread created but not started',
+ 'patterns': [r".*: warning: \[DeadThread\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: Division by integer literal zero',
'patterns': [r".*: warning: \[DivZero\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: This method should not be called.',
+ 'patterns': [r".*: warning: \[DoNotCall\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: Empty statement after if',
'patterns': [r".*: warning: \[EmptyIf\] .+"]},
{'category': 'java',
@@ -1124,7 +1559,12 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: Method annotated @ForOverride must be protected or package-private and only invoked from declaring class',
+ 'Java: == must be used in equals method to check equality to itself or an infinite loop will occur.',
+ 'patterns': [r".*: warning: \[EqualsReference\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Method annotated @ForOverride must be protected or package-private and only invoked from declaring class, or from an override of the method',
'patterns': [r".*: warning: \[ForOverride\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
@@ -1139,6 +1579,11 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: DoubleMath.fuzzyEquals should never be used in an Object.equals() method',
+ 'patterns': [r".*: warning: \[FuzzyEqualsShouldNotBeUsedInEqualsMethod\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: Calling getClass() on an annotation may return a proxy class',
'patterns': [r".*: warning: \[GetClassOnAnnotation\] .+"]},
{'category': 'java',
@@ -1149,17 +1594,12 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: An object is tested for equality to itself using Guava Libraries',
- 'patterns': [r".*: warning: \[GuavaSelfEquals\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
'Java: contains() is a legacy method that is equivalent to containsValue()',
'patterns': [r".*: warning: \[HashtableContains\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: Writing "a && a", "a || a", "a & a", or "a | a" is equivalent to "a".',
+ 'Java: A binary expression where both operands are the same is usually incorrect.',
'patterns': [r".*: warning: \[IdentityBinaryExpression\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
@@ -1169,6 +1609,16 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: The first argument to indexOf is a Unicode code point, and the second is the index to start the search from',
+ 'patterns': [r".*: warning: \[IndexOfChar\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Conditional expression in varargs call contains array and non-array arguments',
+ 'patterns': [r".*: warning: \[InexactVarargsConditional\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: This method always recurses, and will cause a StackOverflowError',
'patterns': [r".*: warning: \[InfiniteRecursion\] .+"]},
{'category': 'java',
@@ -1184,36 +1634,71 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: Invalid time zone identifier. TimeZone.getTimeZone(String) will silently return GMT instead of the time zone you intended.',
+ 'patterns': [r".*: warning: \[InvalidTimeZoneID\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: The argument to Class#isInstance(Object) should not be a Class',
'patterns': [r".*: warning: \[IsInstanceOfClass\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: Path implements Iterable\u003cPath>; prefer Collection\u003cPath> for clarity',
+ 'patterns': [r".*: warning: \[IterablePathParameter\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: jMock tests must have a @RunWith(JMock.class) annotation, or the Mockery field must have a @Rule JUnit annotation',
'patterns': [r".*: warning: \[JMockTestWithoutRunWithOrRuleAnnotation\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: Test method will not be run; please prefix name with "test"',
+ 'Java: Test method will not be run; please correct method signature (Should be public, non-static, and method name should begin with "test").',
'patterns': [r".*: warning: \[JUnit3TestNotRun\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: setUp() method will not be run; Please add a @Before annotation',
+ 'Java: This method should be static',
+ 'patterns': [r".*: warning: \[JUnit4ClassAnnotationNonStatic\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: setUp() method will not be run; please add JUnit\'s @Before annotation',
'patterns': [r".*: warning: \[JUnit4SetUpNotRun\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: tearDown() method will not be run; Please add an @After annotation',
+ 'Java: tearDown() method will not be run; please add JUnit\'s @After annotation',
'patterns': [r".*: warning: \[JUnit4TearDownNotRun\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: Test method will not be run; please add @Test annotation',
+ 'Java: This looks like a test method but is not run; please add @Test or @Ignore, or, if this is a helper method, reduce its visibility.',
'patterns': [r".*: warning: \[JUnit4TestNotRun\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: An object is tested for reference equality to itself using JUnit library.',
+ 'patterns': [r".*: warning: \[JUnitAssertSameCheck\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: This pattern will silently corrupt certain byte sequences from the serialized protocol message. Use ByteString or byte[] directly',
+ 'patterns': [r".*: warning: \[LiteByteStringUtf8\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Loop condition is never modified in loop body.',
+ 'patterns': [r".*: warning: \[LoopConditionChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Overriding method is missing a call to overridden super method',
+ 'patterns': [r".*: warning: \[MissingSuperCall\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: Use of "YYYY" (week year) in a date pattern without "ww" (week in year). You probably meant to use "yyyy" (year) instead.',
'patterns': [r".*: warning: \[MisusedWeekYear\] .+"]},
{'category': 'java',
@@ -1234,6 +1719,16 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: The result of this method must be closed.',
+ 'patterns': [r".*: warning: \[MustBeClosedChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: The first argument to nCopies is the number of copies, and the second is the item to copy',
+ 'patterns': [r".*: warning: \[NCopiesOfChar\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: @NoAllocation was specified on this method, but something was found that would trigger an allocation',
'patterns': [r".*: warning: \[NoAllocation\] .+"]},
{'category': 'java',
@@ -1254,6 +1749,11 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: This conditional expression may evaluate to null, which will result in an NPE when the result is unboxed.',
+ 'patterns': [r".*: warning: \[NullTernary\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: Numeric comparison using reference equality instead of value equality',
'patterns': [r".*: warning: \[NumericEquality\] .+"]},
{'category': 'java',
@@ -1264,11 +1764,6 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: Varargs doesn\'t agree for overridden method',
- 'patterns': [r".*: warning: \[Overrides\] .+"]},
- {'category': 'java',
- 'severity': Severity.HIGH,
- 'description':
'Java: Declaring types inside package-info.java files is very bad form',
'patterns': [r".*: warning: \[PackageInfo\] .+"]},
{'category': 'java',
@@ -1284,6 +1779,16 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: Using ::equals as an incompatible Predicate; the predicate will always return false',
+ 'patterns': [r".*: warning: \[PredicateIncompatibleType\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Access to a private protocol buffer field is forbidden. This protocol buffer carries a security contract, and can only be created using an approved library. Direct access to the fields is forbidden.',
+ 'patterns': [r".*: warning: \[PrivateSecurityContractProtoAccess\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: Protobuf fields cannot be null',
'patterns': [r".*: warning: \[ProtoFieldNullComparison\] .+"]},
{'category': 'java',
@@ -1294,6 +1799,16 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: To get the tag number of a protocol buffer enum, use getNumber() instead.',
+ 'patterns': [r".*: warning: \[ProtocolBufferOrdinal\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Casting a random number in the range [0.0, 1.0) to an integer or long always results in 0.',
+ 'patterns': [r".*: warning: \[RandomCast\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: Use Random.nextInt(int). Random.nextInt() % n can have negative results',
'patterns': [r".*: warning: \[RandomModInteger\] .+"]},
{'category': 'java',
@@ -1319,13 +1834,13 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: Variable compared to itself',
- 'patterns': [r".*: warning: \[SelfEquality\] .+"]},
+ 'Java: Testing an object for equality with itself will always be true.',
+ 'patterns': [r".*: warning: \[SelfEquals\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
'description':
- 'Java: An object is tested for equality to itself',
- 'patterns': [r".*: warning: \[SelfEquals\] .+"]},
+ 'Java: This method must be called with an even number of arguments.',
+ 'patterns': [r".*: warning: \[ShouldHaveEvenArgs\] .+"]},
{'category': 'java',
'severity': Severity.HIGH,
'description':
@@ -1354,6 +1869,16 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: Throwing \'null\' always results in a NullPointerException being thrown.',
+ 'patterns': [r".*: warning: \[ThrowNull\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: isEqualTo should not be used to test an object for equality with itself; the assertion will never fail.',
+ 'patterns': [r".*: warning: \[TruthSelfEquals\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: Catching Throwable/Error masks failures from fail() or assert*() in the try block',
'patterns': [r".*: warning: \[TryFailThrowable\] .+"]},
{'category': 'java',
@@ -1379,8 +1904,193 @@
{'category': 'java',
'severity': Severity.HIGH,
'description':
+ 'Java: `var` should not be used as a type name.',
+ 'patterns': [r".*: warning: \[VarTypeName\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
'Java: Method parameter has wrong package',
'patterns': [r".*: warning: \[ParameterPackage\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Type declaration annotated with @ThreadSafe is not thread safe',
+ 'patterns': [r".*: warning: \[ThreadSafe\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Use of class, field, or method that is not compatible with legacy Android devices',
+ 'patterns': [r".*: warning: \[AndroidApiChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Invalid use of Flogger format string',
+ 'patterns': [r".*: warning: \[AndroidFloggerFormatString\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Use TunnelException.getCauseAs(Class) instead of casting the result of TunnelException.getCause().',
+ 'patterns': [r".*: warning: \[DoNotCastTunnelExceptionCause\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Identifies undesirable mocks.',
+ 'patterns': [r".*: warning: \[DoNotMock_ForJavaBuilder\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Duration Flag should NOT have units in the variable name or the @FlagSpec\'s name or altName field.',
+ 'patterns': [r".*: warning: \[DurationFlagWithUnits\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Duration.get() only works with SECONDS or NANOS.',
+ 'patterns': [r".*: warning: \[DurationGetTemporalUnit\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Invalid printf-style format string',
+ 'patterns': [r".*: warning: \[FloggerFormatString\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Test class may not be run because it is missing a @RunWith annotation',
+ 'patterns': [r".*: warning: \[JUnit4RunWithMissing\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Use of class, field, or method that is not compatible with JDK 7',
+ 'patterns': [r".*: warning: \[Java7ApiChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Use of java.time.Duration.withNanos(int) is not allowed.',
+ 'patterns': [r".*: warning: \[JavaDurationWithNanos\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Use of java.time.Duration.withSeconds(long) is not allowed.',
+ 'patterns': [r".*: warning: \[JavaDurationWithSeconds\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: java.time APIs that silently use the default system time-zone are not allowed.',
+ 'patterns': [r".*: warning: \[JavaTimeDefaultTimeZone\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Use of new Duration(long) is not allowed. Please use Duration.millis(long) instead.',
+ 'patterns': [r".*: warning: \[JodaDurationConstructor\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Use of duration.withMillis(long) is not allowed. Please use Duration.millis(long) instead.',
+ 'patterns': [r".*: warning: \[JodaDurationWithMillis\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Use of instant.withMillis(long) is not allowed. Please use new Instant(long) instead.',
+ 'patterns': [r".*: warning: \[JodaInstantWithMillis\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Use of JodaTime\'s type.plus(long) or type.minus(long) is not allowed (where \u003ctype> = {Duration,Instant,DateTime,DateMidnight}). Please use type.plus(Duration.millis(long)) or type.minus(Duration.millis(long)) instead.',
+ 'patterns': [r".*: warning: \[JodaPlusMinusLong\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Changing JodaTime\'s current time is not allowed in non-testonly code.',
+ 'patterns': [r".*: warning: \[JodaSetCurrentMillis\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Use of Joda-Time\'s DateTime.toDateTime(), Duration.toDuration(), Instant.toInstant(), Interval.toInterval(), and Period.toPeriod() are not allowed.',
+ 'patterns': [r".*: warning: \[JodaToSelf\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Use of JodaTime\'s type.withDurationAdded(long, int) (where \u003ctype> = {Duration,Instant,DateTime}). Please use type.withDurationAdded(Duration.millis(long), int) instead.',
+ 'patterns': [r".*: warning: \[JodaWithDurationAddedLong\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: LanguageCode comparison using reference equality instead of value equality',
+ 'patterns': [r".*: warning: \[LanguageCodeEquality\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: The zero argument toString is not part of the Localizable interface and likely is just the java Object toString. You probably want to call toString(Locale).',
+ 'patterns': [r".*: warning: \[LocalizableWrongToString\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Period.get() only works with YEARS, MONTHS, or DAYS.',
+ 'patterns': [r".*: warning: \[PeriodGetTemporalUnit\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Return value of methods returning Promise must be checked. Ignoring returned Promises suppresses exceptions thrown from the code that completes the Promises.',
+ 'patterns': [r".*: warning: \[PromiseReturnValueIgnored\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: When returning a Promise, use thenChain() instead of then()',
+ 'patterns': [r".*: warning: \[PromiseThenReturningPromise\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Streams.iterating() is unsafe for use except in the header of a for-each loop; please see its Javadoc for details.',
+ 'patterns': [r".*: warning: \[StreamsIteratingNotInLoop\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: TemporalAccessor.get() only works for certain values of ChronoField.',
+ 'patterns': [r".*: warning: \[TemporalAccessorGetChronoField\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Try-with-resources is not supported in this code, use try/finally instead',
+ 'patterns': [r".*: warning: \[TryWithResources\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Adds checkOrThrow calls where needed',
+ 'patterns': [r".*: warning: \[AddCheckOrThrow\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Equality on Nano protos (== or .equals) might not be the same in Lite',
+ 'patterns': [r".*: warning: \[ForbidNanoEquality\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Submessages of a proto cannot be mutated',
+ 'patterns': [r".*: warning: \[ForbidSubmessageMutation\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Repeated fields on proto messages cannot be directly referenced',
+ 'patterns': [r".*: warning: \[NanoUnsafeRepeatedFieldUsage\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Requires that non-@enum int assignments to @enum ints is wrapped in a checkOrThrow',
+ 'patterns': [r".*: warning: \[RequireCheckOrThrow\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Assignments into repeated field elements must be sequential',
+ 'patterns': [r".*: warning: \[RequireSequentialRepeatedFields\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Future.get in Google Now Producers code',
+ 'patterns': [r".*: warning: \[FutureGetInNowProducers\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: @SimpleEnum applied to non-enum type',
+ 'patterns': [r".*: warning: \[SimpleEnumUsage\] .+"]},
# End warnings generated by Error Prone