Merge "Add BOARD_SUPER_PARTITION_*"
diff --git a/Changes.md b/Changes.md
index 21a0abe..7440220 100644
--- a/Changes.md
+++ b/Changes.md
@@ -1,5 +1,80 @@
# Build System Changes for Android.mk Writers
+### `export` and `unexport` deprecation {#export_keyword}
+
+The `export` and `unexport` keywords have been deprecated, and will throw
+warnings or errors depending on where they are used.
+
+Early in the make system, during product configuration and BoardConfig.mk
+reading: these will throw a warnings, and will be an error in the future.
+Device specific configuration should not be able to affect common core build
+steps -- we're looking at triggering build steps to be invalidated if the set
+of environment variables they can access changes. If device specific
+configuration is allowed to change those, switching devices with the same
+output directory could become significantly more expensive than it already can
+be.
+
+Later, during Android.mk files, and later tasks: these will throw errors, since
+it is increasingly likely that they are being used incorrectly, attempting to
+change the environment for a single build step, and instead setting it for
+hundreds of thousands.
+
+It is not recommended to just move the environment variable setting outside of
+the build (in vendorsetup.sh, or some other configuration script or wrapper).
+We expect to limit the environment variables that the build respects in the
+future, others will be cleared. (There will be methods to get custom variables
+into the build, just not to every build step)
+
+Instead, write the export commands into the rule command lines themselves:
+
+``` make
+$(intermediates)/generated_output.img:
+ rm -rf $@
+ export MY_ENV_A="$(MY_A)"; make ...
+```
+
+If you want to set many environment variables, and/or use them many times,
+write them out to a script and source the script:
+
+``` make
+envsh := $(intermediates)/env.sh
+$(envsh):
+ rm -rf $@
+ echo 'export MY_ENV_A="$(MY_A)"' >$@
+ echo 'export MY_ENV_B="$(MY_B)"' >>$@
+
+$(intermediates)/generated_output.img: PRIVATE_ENV := $(envsh)
+$(intermediates)/generated_output.img: $(envsh) a/b/c/package.sh
+ rm -rf $@
+ source $(PRIVATE_ENV); make ...
+ source $(PRIVATE_ENV); a/b/c/package.sh ...
+```
+
+## Implicit make rules are obsolete {#implicit_rules}
+
+Implicit rules look something like the following:
+
+``` make
+$(TARGET_OUT_SHARED_LIBRARIES)/%_vendor.so: $(TARGET_OUT_SHARED_LIBRARIES)/%.so
+ ...
+
+%.o : %.foo
+ ...
+```
+
+These can have wide ranging effects across unrelated modules, so they're now obsolete. Instead, use static pattern rules, which are similar, but explicitly match the specified outputs:
+
+``` make
+libs := $(foreach lib,libfoo libbar,$(TARGET_OUT_SHARED_LIBRARIES)/$(lib)_vendor.so)
+$(libs): %_vendor.so: %.so
+ ...
+
+files := $(wildcard $(LOCAL_PATH)/*.foo)
+gen := $(patsubst $(LOCAL_PATH)/%.foo,$(intermediates)/%.o,$(files))
+$(gen): %.o : %.foo
+ ...
+```
+
## Removing '/' from Valid Module Names {#name_slash}
The build system uses module names in path names in many places. Having an
diff --git a/core/android_manifest.mk b/core/android_manifest.mk
index 0215106..3af81ff 100644
--- a/core/android_manifest.mk
+++ b/core/android_manifest.mk
@@ -18,18 +18,14 @@
ifndef LOCAL_DONT_MERGE_MANIFESTS
my_full_libs_manifest_files += $(LOCAL_FULL_LIBS_MANIFEST_FILES)
- ifdef LOCAL_STATIC_JAVA_AAR_LIBRARIES
- my_full_libs_manifest_files += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
- $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/AndroidManifest.xml)
- endif
+ my_full_libs_manifest_files += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES) $(LOCAL_STATIC_ANDROID_LIBRARIES),\
+ $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/manifest/AndroidManifest.xml)
endif
-ifdef LOCAL_STATIC_JAVA_AAR_LIBRARIES
- # With aapt2, we'll link in the built resource from the AAR.
- ifneq ($(LOCAL_USE_AAPT2),true)
- LOCAL_RESOURCE_DIR += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
- $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/res)
- endif
+# With aapt2, we'll link in the built resource from the AAR.
+ifneq ($(LOCAL_USE_AAPT2),true)
+ LOCAL_RESOURCE_DIR += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
+ $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/res)
endif
full_android_manifest := $(intermediates.COMMON)/manifest/AndroidManifest.xml
diff --git a/core/binary.mk b/core/binary.mk
index 2899d4d..60f78dd 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1602,10 +1602,15 @@
# libraries have already been linked into the module at that point.
# We do, however, care about the NOTICE files for any static
# libraries that we use. (see notice_files.mk)
-
+#
+# Don't do this in mm, since many of the targets won't exist.
+ifeq ($(ONE_SHOT_MAKEFILE),)
installed_static_library_notice_file_targets := \
$(foreach lib,$(my_static_libraries) $(my_whole_static_libraries), \
NOTICE-$(if $(LOCAL_IS_HOST_MODULE),HOST,TARGET)-STATIC_LIBRARIES-$(lib))
+else
+installed_static_library_notice_file_targets :=
+endif
# Default is -fno-rtti.
ifeq ($(strip $(LOCAL_RTTI_FLAG)),)
diff --git a/core/ccache.mk b/core/ccache.mk
index 893c985..d10aceb 100644
--- a/core/ccache.mk
+++ b/core/ccache.mk
@@ -32,24 +32,24 @@
ifneq ($(filter-out false,$(USE_CCACHE)),)
# The default check uses size and modification time, causing false misses
# since the mtime depends when the repo was checked out
- export CCACHE_COMPILERCHECK ?= content
+ CCACHE_COMPILERCHECK ?= content
# See man page, optimizations to get more cache hits
# implies that __DATE__ and __TIME__ are not critical for functionality.
# Ignore include file modification time since it will depend on when
# the repo was checked out
- export CCACHE_SLOPPINESS := time_macros,include_file_mtime,file_macro
+ CCACHE_SLOPPINESS := time_macros,include_file_mtime,file_macro
# Turn all preprocessor absolute paths into relative paths.
# Fixes absolute paths in preprocessed source due to use of -g.
# We don't really use system headers much so the rootdir is
# fine; ensures these paths are relative for all Android trees
# on a workstation.
- export CCACHE_BASEDIR := /
+ CCACHE_BASEDIR := /
# Workaround for ccache with clang.
# See http://petereisentraut.blogspot.com/2011/09/ccache-and-clang-part-2.html
- export CCACHE_CPP2 := true
+ CCACHE_CPP2 := true
ifndef CC_WRAPPER
CC_WRAPPER := $(CCACHE_EXEC)
diff --git a/core/config.mk b/core/config.mk
index 17c9eab..3045929 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -85,6 +85,9 @@
$(KATI_obsolete_var PRODUCT_COMPATIBILITY_MATRIX_LEVEL_OVERRIDE,Set FCM Version in device manifest instead. See $(CHANGES_URL)#PRODUCT_COMPATIBILITY_MATRIX_LEVEL_OVERRIDE)
$(KATI_obsolete_var USE_CLANG_PLATFORM_BUILD,Clang is the only supported Android compiler. See $(CHANGES_URL)#USE_CLANG_PLATFORM_BUILD)
+# This is marked as obsolete in envsetup.mk after reading the BoardConfig.mk
+$(KATI_deprecate_export It is a global setting. See $(CHANGES_URL)#export_keyword)
+
CHANGES_URL :=
# Used to force goals to build. Only use for conditionally defined goals.
@@ -208,8 +211,10 @@
# ###############################################################
# Broken build defaults
# ###############################################################
-# Assume that all boards have duplicate rules right now.
-BUILD_BROKEN_DUP_RULES := true
+BUILD_BROKEN_ANDROIDMK_EXPORTS :=
+BUILD_BROKEN_DUP_COPY_HEADERS :=
+BUILD_BROKEN_DUP_RULES :=
+BUILD_BROKEN_PHONY_TARGETS :=
# ###############################################################
# Include sub-configuration files
@@ -356,10 +361,6 @@
ifeq ($(CALLED_FROM_SETUP),true)
include $(BUILD_SYSTEM)/ccache.mk
include $(BUILD_SYSTEM)/goma.mk
-
-export CC_WRAPPER
-export CXX_WRAPPER
-export JAVAC_WRAPPER
endif
ifdef TARGET_PREFER_32_BIT
@@ -730,21 +731,13 @@
COLUMN:= column
-ifeq ($(EXPERIMENTAL_USE_OPENJDK9),)
-ifeq ($(RUN_ERROR_PRONE),true)
-USE_OPENJDK9 :=
-else
USE_OPENJDK9 := true
-endif
-TARGET_OPENJDK9 :=
-else ifeq ($(EXPERIMENTAL_USE_OPENJDK9),false)
-USE_OPENJDK9 :=
+
+ifeq ($(EXPERIMENTAL_USE_OPENJDK9),)
TARGET_OPENJDK9 :=
else ifeq ($(EXPERIMENTAL_USE_OPENJDK9),1.8)
-USE_OPENJDK9 := true
TARGET_OPENJDK9 :=
else ifeq ($(EXPERIMENTAL_USE_OPENJDK9),true)
-USE_OPENJDK9 := true
TARGET_OPENJDK9 := true
endif
diff --git a/core/definitions.mk b/core/definitions.mk
index 9d4c532..9f958fa 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2662,9 +2662,14 @@
# $(1): source file
# $(2): destination file
define copy-init-script-file-checked
+# Host init verifier doesn't exist on darwin.
+ifneq ($(HOST_OS),darwin)
$(2): $(1) $(HOST_INIT_VERIFIER) $(call intermediates-dir-for,ETC,passwd)/passwd
- @echo "Copy init script: $$@"
$(hide) $(HOST_INIT_VERIFIER) $$< $(call intermediates-dir-for,ETC,passwd)/passwd
+else
+$(2): $(1)
+endif
+ @echo "Copy init script: $$@"
$$(copy-file-to-target)
endef
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index cd48316..deaee56 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -232,16 +232,11 @@
##
##
-ifdef USE_OPENJDK9
# For OpenJDK 9 we use --patch-module to define the core libraries code.
# TODO(tobiast): Reorganize this when adding proper support for OpenJDK 9
# modules. Here we treat all code in core libraries as being in java.base
# to work around the OpenJDK 9 module system. http://b/62049770
$(full_target): PRIVATE_BOOTCLASSPATH_ARG := --patch-module=java.base=$(PRIVATE_BOOTCLASSPATH)
-else
-# For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
-$(full_target): PRIVATE_BOOTCLASSPATH_ARG := $(addprefix -bootclasspath ,$(PRIVATE_BOOTCLASSPATH))
-endif
$(full_target): $(full_src_files) $(LOCAL_GENERATED_SOURCES) $(full_java_libs) $(ZIPSYNC) $(LOCAL_SRCJARS) $(LOCAL_ADDITIONAL_DEPENDENCIES)
@echo Docs javadoc: $(PRIVATE_OUT_DIR)
@mkdir -p $(dir $@)
diff --git a/core/envsetup.mk b/core/envsetup.mk
index a3e78e7..874ea91 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -273,6 +273,31 @@
board_config_mk :=
###########################################
+# Handle BUILD_BROKEN_* settings
+vars := \
+ BUILD_BROKEN_ANDROIDMK_EXPORTS \
+ BUILD_BROKEN_DUP_COPY_HEADERS \
+ BUILD_BROKEN_DUP_RULES \
+ BUILD_BROKEN_PHONY_TARGETS
+
+$(foreach var,$(vars),$(eval $(var) := $$(strip $$($(var)))))
+
+$(foreach var,$(vars), \
+ $(if $(filter-out true false,$($(var))), \
+ $(error Valid values of $(var) are "true", "false", and "". Not "$($(var))")))
+
+.KATI_READONLY := $(vars)
+
+CHANGES_URL := https://android.googlesource.com/platform/build/+/master/Changes.md
+
+# "" is equivalent to true currently.
+ifeq ($(BUILD_BROKEN_ANDROIDMK_EXPORTS),false)
+$(KATI_obsolete_export It is a global setting. See $(CHANGES_URL)#export_keyword)
+endif
+
+CHANGES_URL :=
+
+###########################################
# Now we can substitute with the real value of TARGET_COPY_OUT_VENDOR
ifeq ($(TARGET_COPY_OUT_VENDOR),$(_vendor_path_placeholder))
TARGET_COPY_OUT_VENDOR := system/vendor
diff --git a/core/goma.mk b/core/goma.mk
index 2fb37a7..3787dfd 100644
--- a/core/goma.mk
+++ b/core/goma.mk
@@ -14,9 +14,6 @@
# limitations under the License.
#
-# Used by the compiler wrapper, but should only be set by gomacc
-unexport GOMACC_PATH
-
# Notice: this works only with Google's Goma build infrastructure.
ifneq ($(filter-out false,$(USE_GOMA)),)
# Goma requires a lot of processes and file descriptors.
diff --git a/core/host_java_library_common.mk b/core/host_java_library_common.mk
index 51e2d94..8df4b37 100644
--- a/core/host_java_library_common.mk
+++ b/core/host_java_library_common.mk
@@ -48,8 +48,3 @@
LOCAL_INTERMEDIATE_SOURCE_DIR := $(intermediates.COMMON)/src
LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES))
-
-# If error prone is enabled then add LOCAL_ERROR_PRONE_FLAGS to LOCAL_JAVACFLAGS
-ifeq ($(RUN_ERROR_PRONE),true)
-LOCAL_JAVACFLAGS += $(LOCAL_ERROR_PRONE_FLAGS)
-endif
diff --git a/core/java.mk b/core/java.mk
index 19e6377..78b492d 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -227,11 +227,6 @@
# Deps for generated source files must be handled separately,
# via deps on the target that generates the sources.
-# If error prone is enabled then add LOCAL_ERROR_PRONE_FLAGS to LOCAL_JAVACFLAGS
-ifeq ($(RUN_ERROR_PRONE),true)
-LOCAL_JAVACFLAGS += $(LOCAL_ERROR_PRONE_FLAGS)
-endif
-
# For user / userdebug builds, strip the local variable table and the local variable
# type table. This has no bearing on stack traces, but will leave less information
# available via JDWP.
diff --git a/core/java_common.mk b/core/java_common.mk
index 5dfbc5f..486f087 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -193,16 +193,25 @@
annotation_processor_flags :=
annotation_processor_deps :=
+annotation_processor_jars :=
+
+# If error prone is enabled then add LOCAL_ERROR_PRONE_FLAGS to LOCAL_JAVACFLAGS
+ifeq ($(RUN_ERROR_PRONE),true)
+annotation_processor_jars += $(ERROR_PRONE_JARS)
+LOCAL_JAVACFLAGS += $(ERROR_PRONE_FLAGS)
+LOCAL_JAVACFLAGS += '-Xplugin:ErrorProne $(ERROR_PRONE_CHECKS) $(LOCAL_ERROR_PRONE_FLAGS)'
+endif
ifdef LOCAL_ANNOTATION_PROCESSORS
- annotation_processor_jars := $(call java-lib-files,$(LOCAL_ANNOTATION_PROCESSORS),true)
- annotation_processor_flags += -processorpath $(call normalize-path-list,$(annotation_processor_jars))
- annotation_processor_deps += $(annotation_processor_jars)
+ annotation_processor_jars += $(call java-lib-files,$(LOCAL_ANNOTATION_PROCESSORS),true)
# b/25860419: annotation processors must be explicitly specified for grok
annotation_processor_flags += $(foreach class,$(LOCAL_ANNOTATION_PROCESSOR_CLASSES),-processor $(class))
+endif
- annotation_processor_jars :=
+ifneq (,$(strip $(annotation_processor_jars)))
+annotation_processor_flags += -processorpath $(call normalize-path-list,$(annotation_processor_jars))
+annotation_processor_deps += $(annotation_processor_jars)
endif
full_static_java_libs := $(call java-lib-files,$(LOCAL_STATIC_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
diff --git a/core/main.mk b/core/main.mk
index a08e0df..c440f55 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -416,10 +416,6 @@
# would have been with a normal make.
CUSTOM_MODULES := $(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS)))
FULL_BUILD :=
-# Stub out the notice targets, which probably aren't defined
-# when using ONE_SHOT_MAKEFILE.
-NOTICE-HOST-%: ;
-NOTICE-TARGET-%: ;
# A helper goal printing out install paths
define register_module_install_path
@@ -1270,6 +1266,16 @@
ifeq ($(EMMA_INSTRUMENT),true)
$(JACOCO_REPORT_CLASSES_ALL) : $(INSTALLED_SYSTEMIMAGE)
$(call dist-for-goals, dist_files, $(JACOCO_REPORT_CLASSES_ALL))
+
+ # Put XML formatted API files in the dist dir.
+ api_xmls := $(addprefix $(TARGET_OUT_COMMON_INTERMEDIATES)/,api.xml system-api.xml test-api.xml)
+ $(api_xmls): $(TARGET_OUT_COMMON_INTERMEDIATES)/%api.xml : frameworks/base/api/%current.txt $(APICHECK)
+ $(hide) echo "Converting API file to XML: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) $(APICHECK_COMMAND) -convert2xml $< $@
+
+ $(call dist-for-goals, dist_files, $(api_xmls))
+ api_xmls :=
endif
# Building a full system-- the default is to build droidcore
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 1a5b389..d5b7877 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -598,6 +598,10 @@
$(hide) touch $(dir $@)/proguard.txt
$(hide) touch $(dir $@)/AndroidManifest.xml
+my_prebuilt_android_manifest := $(intermediates.COMMON)/manifest/AndroidManifest.xml
+$(eval $(call copy-one-file,$(my_src_android_manifest),$(my_prebuilt_android_manifest)))
+$(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_prebuilt_android_manifest))
+
endif
$(common_classes_jar) : $(my_src_jar)
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index eeaab31..0ba2c7a 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -64,6 +64,10 @@
my_static_library_extra_packages := $(intermediates.COMMON)/extra_packages
$(eval $(call copy-one-file,$(LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES),$(my_static_library_extra_packages)))
$(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_static_library_extra_packages))
+
+ my_static_library_android_manifest := $(intermediates.COMMON)/manifest/AndroidManifest.xml
+ $(eval $(call copy-one-file,$(LOCAL_FULL_MANIFEST_FILE),$(my_static_library_android_manifest)))
+ $(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_static_library_android_manifest))
endif # LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE
ifneq ($(TURBINE_ENABLED),false)
diff --git a/target/product/sdk_phone_x86.mk b/target/product/sdk_phone_x86.mk
index b34e5b6..abb46ac 100644
--- a/target/product/sdk_phone_x86.mk
+++ b/target/product/sdk_phone_x86.mk
@@ -20,6 +20,10 @@
-include sdk/build/product_sdk.mk
-include development/build/product_sdk.mk
+# keep this apk for sdk targets for now
+PRODUCT_PACKAGES += \
+ EmulatorSmokeTests
+
# Overrides
PRODUCT_BRAND := Android
PRODUCT_NAME := sdk_phone_x86
diff --git a/target/product/sdk_phone_x86_64.mk b/target/product/sdk_phone_x86_64.mk
index 37c078e..828b744 100644
--- a/target/product/sdk_phone_x86_64.mk
+++ b/target/product/sdk_phone_x86_64.mk
@@ -20,6 +20,10 @@
-include sdk/build/product_sdk.mk
-include development/build/product_sdk.mk
+# keep this apk for sdk targets for now
+PRODUCT_PACKAGES += \
+ EmulatorSmokeTests
+
# Overrides
PRODUCT_BRAND := Android
PRODUCT_NAME := sdk_phone_x86_64
diff --git a/target/product/vndk/Android.mk b/target/product/vndk/Android.mk
index b9ae116..5d009f9 100644
--- a/target/product/vndk/Android.mk
+++ b/target/product/vndk/Android.mk
@@ -1,4 +1,3 @@
-ifneq ($(BOARD_VNDK_VERSION),)
LOCAL_PATH:= $(call my-dir)
#####################################################################
@@ -39,7 +38,13 @@
droidcore: check-vndk-list
check-vndk-list-timestamp := $(call intermediates-dir-for,PACKAGING,vndk)/check-list-timestamp
+
+ifeq ($(TARGET_IS_64_BIT)|$(TARGET_2ND_ARCH),true|)
+# TODO(b/110429754) remove this condition when we support 64-bit-only device
+check-vndk-list: ;
+else
check-vndk-list: $(check-vndk-list-timestamp)
+endif
_vndk_check_failure_message := " error: VNDK library list has been changed.\n"
ifeq (REL,$(PLATFORM_VERSION_CODENAME))
@@ -86,6 +91,8 @@
endif
@chmod a+x $@
+ifneq ($(BOARD_VNDK_VERSION),)
+
include $(CLEAR_VARS)
LOCAL_MODULE := vndk_package
LOCAL_REQUIRED_MODULES := \
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 756bc8a..393c33d 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -27,6 +27,12 @@
in the apkcerts.txt file. Option may be repeated to give
multiple extra packages.
+ --skip_apks_with_path_prefix <prefix>
+ Skip signing an APK if it has the matching prefix in its path. The prefix
+ should be matching the entry name, which has partition names in upper
+ case, e.g. "VENDOR/app/", or "SYSTEM_OTHER/preloads/". Option may be
+ repeated to give multiple prefixes.
+
-k (--key_mapping) <src_key=dest_key>
Add a mapping from the key name as specified in apkcerts.txt (the
src_key) to the real key you wish to sign the package with
@@ -118,6 +124,7 @@
OPTIONS = common.OPTIONS
OPTIONS.extra_apks = {}
+OPTIONS.skip_apks_with_path_prefix = set()
OPTIONS.key_map = {}
OPTIONS.rebuild_recovery = False
OPTIONS.replace_ota_keys = False
@@ -144,39 +151,53 @@
return certmap
-def GetApkFileInfo(filename, compressed_extension):
+def GetApkFileInfo(filename, compressed_extension, skipped_prefixes):
"""Returns the APK info based on the given filename.
Checks if the given filename (with path) looks like an APK file, by taking the
- compressed extension into consideration.
+ compressed extension into consideration. If it appears to be an APK file,
+ further checks if the APK file should be skipped when signing, based on the
+ given path prefixes.
Args:
filename: Path to the file.
compressed_extension: The extension string of compressed APKs (e.g. ".gz"),
or None if there's no compressed APKs.
+ skipped_prefixes: A set/list/tuple of the path prefixes to be skipped.
Returns:
- (is_apk, is_compressed): is_apk indicates whether the given filename is an
- APK file. is_compressed indicates whether the APK file is compressed (only
- meaningful when is_apk is True).
+ (is_apk, is_compressed, should_be_skipped): is_apk indicates whether the
+ given filename is an APK file. is_compressed indicates whether the APK file
+ is compressed (only meaningful when is_apk is True). should_be_skipped
+ indicates whether the filename matches any of the given prefixes to be
+ skipped.
Raises:
- AssertionError: On invalid compressed_extension input.
+ AssertionError: On invalid compressed_extension or skipped_prefixes inputs.
"""
assert compressed_extension is None or compressed_extension.startswith('.'), \
"Invalid compressed_extension arg: '{}'".format(compressed_extension)
+ # skipped_prefixes should be one of set/list/tuple types. Other types such as
+ # str shouldn't be accepted.
+ assert (isinstance(skipped_prefixes, tuple) or
+ isinstance(skipped_prefixes, set) or
+ isinstance(skipped_prefixes, list)), \
+ "Invalid skipped_prefixes input type: {}".format(
+ type(skipped_prefixes))
+
compressed_apk_extension = (
".apk" + compressed_extension if compressed_extension else None)
is_apk = (filename.endswith(".apk") or
(compressed_apk_extension and
filename.endswith(compressed_apk_extension)))
if not is_apk:
- return (False, False)
+ return (False, False, False)
is_compressed = (compressed_apk_extension and
filename.endswith(compressed_apk_extension))
- return (True, is_compressed)
+ should_be_skipped = filename.startswith(tuple(skipped_prefixes))
+ return (True, is_compressed, should_be_skipped)
def CheckAllApksSigned(input_tf_zip, apk_key_map, compressed_extension):
@@ -193,9 +214,9 @@
"""
unknown_apks = []
for info in input_tf_zip.infolist():
- (is_apk, is_compressed) = GetApkFileInfo(
- info.filename, compressed_extension)
- if not is_apk:
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ info.filename, compressed_extension, OPTIONS.skip_apks_with_path_prefix)
+ if not is_apk or should_be_skipped:
continue
name = os.path.basename(info.filename)
if is_compressed:
@@ -276,9 +297,11 @@
apk_key_map, key_passwords, platform_api_level,
codename_to_api_level_map,
compressed_extension):
+ # maxsize measures the maximum filename length, including the ones to be
+ # skipped.
maxsize = max(
[len(os.path.basename(i.filename)) for i in input_tf_zip.infolist()
- if GetApkFileInfo(i.filename, compressed_extension)[0]])
+ if GetApkFileInfo(i.filename, compressed_extension, [])[0]])
system_root_image = misc_info.get("system_root_image") == "true"
for info in input_tf_zip.infolist():
@@ -288,10 +311,18 @@
data = input_tf_zip.read(filename)
out_info = copy.copy(info)
- (is_apk, is_compressed) = GetApkFileInfo(filename, compressed_extension)
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ filename, compressed_extension, OPTIONS.skip_apks_with_path_prefix)
+
+ if is_apk and should_be_skipped:
+ # Copy skipped APKs verbatim.
+ print(
+ "NOT signing: %s\n"
+ " (skipped due to matching prefix)" % (filename,))
+ common.ZipWriteStr(output_tf_zip, out_info, data)
# Sign APKs.
- if is_apk:
+ elif is_apk:
name = os.path.basename(filename)
if is_compressed:
name = name[:-len(compressed_extension)]
@@ -304,7 +335,9 @@
common.ZipWriteStr(output_tf_zip, out_info, signed_data)
else:
# an APK we're not supposed to sign.
- print("NOT signing: %s" % (name,))
+ print(
+ "NOT signing: %s\n"
+ " (skipped due to special cert string)" % (name,))
common.ZipWriteStr(output_tf_zip, out_info, data)
# System properties.
@@ -794,6 +827,12 @@
names = names.split(",")
for n in names:
OPTIONS.extra_apks[n] = key
+ elif o == "--skip_apks_with_path_prefix":
+ # Sanity check the prefix, which must be in all upper case.
+ prefix = a.split('/')[0]
+ if not prefix or prefix != prefix.upper():
+ raise ValueError("Invalid path prefix '%s'" % (a,))
+ OPTIONS.skip_apks_with_path_prefix.add(a)
elif o in ("-d", "--default_key_mappings"):
key_mapping_options.append((None, a))
elif o in ("-k", "--key_mapping"):
@@ -853,6 +892,7 @@
extra_opts="e:d:k:ot:",
extra_long_opts=[
"extra_apks=",
+ "skip_apks_with_path_prefix=",
"default_key_mappings=",
"key_mapping=",
"replace_ota_keys",
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index 71bd259..ac1b567 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -237,25 +237,116 @@
AssertionError, CheckAllApksSigned, input_zip, apk_key_map, '.gz')
def test_GetApkFileInfo(self):
- (is_apk, is_compressed) = GetApkFileInfo("PRODUCT/apps/Chats.apk", None)
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ "PRODUCT/apps/Chats.apk", None, [])
self.assertTrue(is_apk)
self.assertFalse(is_compressed)
+ self.assertFalse(should_be_skipped)
- (is_apk, is_compressed) = GetApkFileInfo("PRODUCT/apps/Chats.dat", None)
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ "PRODUCT/apps/Chats.apk", None, [])
+ self.assertTrue(is_apk)
+ self.assertFalse(is_compressed)
+ self.assertFalse(should_be_skipped)
+
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ "PRODUCT/apps/Chats.dat", None, [])
self.assertFalse(is_apk)
self.assertFalse(is_compressed)
+ self.assertFalse(should_be_skipped)
def test_GetApkFileInfo_withCompressedApks(self):
- (is_apk, is_compressed) = GetApkFileInfo("PRODUCT/apps/Chats.apk.gz", ".gz")
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ "PRODUCT/apps/Chats.apk.gz", ".gz", [])
self.assertTrue(is_apk)
self.assertTrue(is_compressed)
+ self.assertFalse(should_be_skipped)
- (is_apk, is_compressed) = GetApkFileInfo("PRODUCT/apps/Chats.apk.gz", ".xz")
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ "PRODUCT/apps/Chats.apk.gz", ".xz", [])
self.assertFalse(is_apk)
self.assertFalse(is_compressed)
+ self.assertFalse(should_be_skipped)
self.assertRaises(
- AssertionError, GetApkFileInfo, "PRODUCT/apps/Chats.apk", "")
+ AssertionError, GetApkFileInfo, "PRODUCT/apps/Chats.apk", "", [])
self.assertRaises(
- AssertionError, GetApkFileInfo, "PRODUCT/apps/Chats.apk", "apk")
+ AssertionError, GetApkFileInfo, "PRODUCT/apps/Chats.apk", "apk", [])
+
+ def test_GetApkFileInfo_withSkippedPrefixes(self):
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ "PRODUCT/preloads/apps/Chats.apk", None, set())
+ self.assertTrue(is_apk)
+ self.assertFalse(is_compressed)
+ self.assertFalse(should_be_skipped)
+
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ "PRODUCT/preloads/apps/Chats.apk",
+ None,
+ set(["PRODUCT/preloads/"]))
+ self.assertTrue(is_apk)
+ self.assertFalse(is_compressed)
+ self.assertTrue(should_be_skipped)
+
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ "SYSTEM_OTHER/preloads/apps/Chats.apk",
+ None,
+ set(["SYSTEM/preloads/", "SYSTEM_OTHER/preloads/"]))
+ self.assertTrue(is_apk)
+ self.assertFalse(is_compressed)
+ self.assertTrue(should_be_skipped)
+
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ "SYSTEM_OTHER/preloads/apps/Chats.apk.gz",
+ ".gz",
+ set(["PRODUCT/prebuilts/", "SYSTEM_OTHER/preloads/"]))
+ self.assertTrue(is_apk)
+ self.assertTrue(is_compressed)
+ self.assertTrue(should_be_skipped)
+
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ "SYSTEM_OTHER/preloads/apps/Chats.dat",
+ None,
+ set(["SYSTEM_OTHER/preloads/"]))
+ self.assertFalse(is_apk)
+ self.assertFalse(is_compressed)
+ self.assertFalse(should_be_skipped)
+
+ def test_GetApkFileInfo_checkSkippedPrefixesInput(self):
+ # set
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ "SYSTEM_OTHER/preloads/apps/Chats.apk",
+ None,
+ set(["SYSTEM_OTHER/preloads/"]))
+ self.assertTrue(is_apk)
+ self.assertFalse(is_compressed)
+ self.assertTrue(should_be_skipped)
+
+ # tuple
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ "SYSTEM_OTHER/preloads/apps/Chats.apk",
+ None,
+ ("SYSTEM_OTHER/preloads/",))
+ self.assertTrue(is_apk)
+ self.assertFalse(is_compressed)
+ self.assertTrue(should_be_skipped)
+
+ # list
+ (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
+ "SYSTEM_OTHER/preloads/apps/Chats.apk",
+ None,
+ ["SYSTEM_OTHER/preloads/"])
+ self.assertTrue(is_apk)
+ self.assertFalse(is_compressed)
+ self.assertTrue(should_be_skipped)
+
+ # str is invalid.
+ self.assertRaises(
+ AssertionError, GetApkFileInfo, "SYSTEM_OTHER/preloads/apps/Chats.apk",
+ None, "SYSTEM_OTHER/preloads/")
+
+ # None is invalid.
+ self.assertRaises(
+ AssertionError, GetApkFileInfo, "SYSTEM_OTHER/preloads/apps/Chats.apk",
+ None, None)