Merge "Require a vendor_ prefix for users/groups in /vendor/etc/{passwd,group}"
diff --git a/core/android_manifest.mk b/core/android_manifest.mk
index 7d573d3..1dca7ab 100644
--- a/core/android_manifest.mk
+++ b/core/android_manifest.mk
@@ -23,7 +23,7 @@
$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/AndroidManifest.xml)
# With aapt2, we'll link in the built resource from the AAR.
-ifndef LOCAL_USE_AAPT2
+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 # LOCAL_USE_AAPT2
diff --git a/core/binary.mk b/core/binary.mk
index 39f1161..f68908b 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1724,10 +1724,19 @@
my_tidy_flags += -quiet -extra-arg-before=-fno-caret-diagnostics
endif
- # We might be using the static analyzer through clang-tidy.
- # https://bugs.llvm.org/show_bug.cgi?id=32914
ifneq ($(my_tidy_checks),)
+ # We might be using the static analyzer through clang-tidy.
+ # https://bugs.llvm.org/show_bug.cgi?id=32914
my_tidy_flags += -extra-arg-before=-D__clang_analyzer__
+
+ # A recent change in clang-tidy (r328258) enabled destructor inlining,
+ # which appears to cause a number of false positives. Until that's
+ # resolved, this turns off the effects of r328258.
+ # https://bugs.llvm.org/show_bug.cgi?id=37459
+ my_tidy_flags += -extra-arg-before=-Xclang
+ my_tidy_flags += -extra-arg-before=-analyzer-config
+ my_tidy_flags += -extra-arg-before=-Xclang
+ my_tidy_flags += -extra-arg-before=c++-temp-dtor-inlining=false
endif
endif
endif
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 292f842..4224fda 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -75,6 +75,7 @@
LOCAL_DX_FLAGS:=
LOCAL_EMMA_COVERAGE_FILTER:=
LOCAL_EMMA_INSTRUMENT:=
+LOCAL_ENFORCE_USES_LIBRARIES:=
LOCAL_ERROR_PRONE_FLAGS:=
LOCAL_EXPORT_CFLAGS:=
LOCAL_EXPORT_C_INCLUDE_DEPS:=
@@ -180,6 +181,7 @@
LOCAL_NOTICE_FILE:=
LOCAL_ODM_MODULE:=
LOCAL_OEM_MODULE:=
+LOCAL_OPTIONAL_USES_LIBRARIES:=
LOCAL_OVERRIDES_PACKAGES:=
LOCAL_OVERRIDES_MODULES:=
LOCAL_PACKAGE_NAME:=
@@ -272,6 +274,7 @@
LOCAL_USE_CLANG_LLD:=
LOCAL_USE_R8:=
LOCAL_USE_VNDK:=
+LOCAL_USES_LIBRARIES:=
LOCAL_VENDOR_MODULE:=
LOCAL_VINTF_FRAGMENTS:=
LOCAL_VTSC_FLAGS:=
diff --git a/core/combo/TARGET_linux-arm.mk b/core/combo/TARGET_linux-arm.mk
index 01cf3f5..3ce64f9 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -33,7 +33,7 @@
TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT := generic
endif
-KNOWN_ARMv8_CORES := cortex-a53 cortex-a53.a57 cortex-a73
+KNOWN_ARMv8_CORES := cortex-a53 cortex-a53.a57 cortex-a55 cortex-a73 cortex-a75
KNOWN_ARMv8_CORES += kryo denver64 exynos-m1 exynos-m2
# Many devices (incorrectly) use armv7-a-neon as the 2nd architecture variant
diff --git a/core/combo/arch/arm64/armv8-2a.mk b/core/combo/arch/arm64/armv8-2a.mk
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/core/combo/arch/arm64/armv8-2a.mk
diff --git a/core/config.mk b/core/config.mk
index 713760f..b94acd5 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -92,8 +92,6 @@
UNAME := $(shell uname -sm)
SRC_TARGET_DIR := $(TOPDIR)build/target
-SRC_SYSTEM_API_DIR := $(TOPDIR)prebuilts/sdk/system-api
-SRC_TEST_API_DIR := $(TOPDIR)prebuilts/sdk/test-api
# Some specific paths to tools
SRC_DROIDDOC_DIR := $(TOPDIR)build/make/tools/droiddoc
@@ -753,8 +751,7 @@
endif
APICHECK_CLASSPATH_ENTRIES := \
- $(HOST_OUT_JAVA_LIBRARIES)/doclava$(COMMON_JAVA_PACKAGE_SUFFIX) \
- $(HOST_OUT_JAVA_LIBRARIES)/jsilver$(COMMON_JAVA_PACKAGE_SUFFIX) \
+ $(HOST_OUT_JAVA_LIBRARIES)/apicheck$(COMMON_JAVA_PACKAGE_SUFFIX) \
$(HOST_JDK_TOOLS_JAR) \
)
APICHECK_CLASSPATH := $(subst $(space),:,$(strip $(APICHECK_CLASSPATH_ENTRIES)))
@@ -1024,6 +1021,10 @@
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
+# Missing optional uses-libraries so that the platform doesn't create build rules that depend on
+# them. See setup_one_odex.mk.
+INTERNAL_PLATFORM_MISSING_USES_LIBRARIES := com.google.android.ble com.google.android.wearable
+
# 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)
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index aa591ec..1363c8d 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -345,6 +345,7 @@
ifeq ($(filter STATIC_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
ifndef LOCAL_SDK_VERSION
my_static_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_MINIMAL_RUNTIME_LIBRARY)
+ my_ldflags += -Wl,--exclude-libs,$($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_MINIMAL_RUNTIME_LIBRARY).a
endif
endif
ifneq ($(filter unsigned-integer-overflow signed-integer-overflow integer,$(my_sanitize)),)
diff --git a/core/construct_context.sh b/core/construct_context.sh
new file mode 100755
index 0000000..b4ae519
--- /dev/null
+++ b/core/construct_context.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+# inputs:
+# $1 is PRIVATE_CONDITIONAL_USES_LIBRARIES_HOST
+# $2 is PRIVATE_CONDITIONAL_USES_LIBRARIES_TARGET
+
+# class_loader_context: library paths on the host
+# stored_class_loader_context_libs: library paths on device
+# these are both comma separated paths, example: lib1.jar:lib2.jar or /system/framework/lib1.jar:/system/framework/lib2.jar
+
+# target_sdk_version: parsed from manifest
+# my_conditional_host_libs: libraries conditionally added for non P
+# my_conditional_target_libs: target libraries conditionally added for non P
+#
+# outputs
+# class_loader_context_arg: final class loader conext arg
+# stored_class_loader_context_arg: final stored class loader context arg
+
+my_conditional_host_libs=$1
+my_conditional_target_libs=$2
+
+# Note that SDK 28 is P.
+if [[ "${target_sdk_version}" -lt "28" ]]; then
+ if [[ -z "${class_loader_context}" ]]; then
+ export class_loader_context="${my_conditional_host_libs}"
+ else
+ export class_loader_context="${my_conditional_host_libs}:${class_loader_context}"
+ fi
+ if [[ -z "${stored_class_loader_context_libs}" ]]; then
+ export stored_class_loader_context_libs="${my_conditional_target_libs}";
+ else
+ export stored_class_loader_context_libs="${my_conditional_target_libs}:${stored_class_loader_context_libs}";
+ fi
+fi
+
+# Generate the actual context string.
+export class_loader_context_arg="--class-loader-context=PCL[${class_loader_context}]"
+export stored_class_loader_context_arg="--stored-class-loader-context=PCL[${stored_class_loader_context_libs}]"
diff --git a/core/definitions.mk b/core/definitions.mk
index 092a778..a1a178b 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2092,7 +2092,7 @@
define aapt2-compile-resource-zips
@mkdir -p $(dir $@)
$(ZIPSYNC) -d $@.contents -l $@.list $(PRIVATE_SOURCE_RES_ZIPS)
-$(hide) $(AAPT2) compile -o $@ --dir $@.tmp $(PRIVATE_AAPT2_CFLAGS) --legacy
+$(hide) $(AAPT2) compile -o $@ --dir $@.contents $(PRIVATE_AAPT2_CFLAGS) --legacy
endef
# Set up rule to compile one resource file with aapt2.
@@ -2147,6 +2147,17 @@
$(EXTRACT_JAR_PACKAGES) -i $(PRIVATE_SRCJAR) -o $(PRIVATE_AAPT_EXTRA_PACKAGES) --prefix '--extra-packages '
endef
+define _create-default-manifest-file
+$(1):
+ rm -f $1
+ echo '<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="missing.manifest"></manifest>' > $1
+endef
+
+define create-default-manifest-file
+ $(eval $(call _create-default-manifest-file,$(1)))
+endef
+
+
###########################################################
xlint_unchecked := -Xlint:unchecked
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index 10522ac..3b9e4e1 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -163,12 +163,27 @@
# $(1): the input .jar or .apk file
# $(2): the output .odex file
+# In the case where LOCAL_ENFORCE_USES_LIBRARIES is true, PRIVATE_DEX2OAT_CLASS_LOADER_CONTEXT
+# contains the normalized path list of the libraries. This makes it easier to conditionally prepend
+# org.apache.http.legacy.boot based on the SDK level if required.
define dex2oat-one-file
$(hide) rm -f $(2)
$(hide) mkdir -p $(dir $(2))
-$(hide) ANDROID_LOG_TAGS="*:e" $(DEX2OAT) \
+stored_class_loader_context_libs=$(PRIVATE_DEX2OAT_STORED_CLASS_LOADER_CONTEXT_LIBS) && \
+class_loader_context_arg=--class-loader-context=$(PRIVATE_DEX2OAT_CLASS_LOADER_CONTEXT) && \
+class_loader_context=$(PRIVATE_DEX2OAT_CLASS_LOADER_CONTEXT) && \
+stored_class_loader_context_arg="" && \
+uses_library_names="$(PRIVATE_USES_LIBRARY_NAMES)" && \
+optional_uses_library_names="$(PRIVATE_OPTIONAL_USES_LIBRARY_NAMES)" && \
+aapt_binary="$(AAPT)" && \
+$(if $(filter true,$(PRIVATE_ENFORCE_USES_LIBRARIES)), \
+source build/make/core/verify_uses_libraries.sh "$(1)" && \
+source build/make/core/construct_context.sh "$(PRIVATE_CONDITIONAL_USES_LIBRARIES_HOST)" "$(PRIVATE_CONDITIONAL_USES_LIBRARIES_TARGET)" && \
+,) \
+ANDROID_LOG_TAGS="*:e" $(DEX2OAT) \
--runtime-arg -Xms$(DEX2OAT_XMS) --runtime-arg -Xmx$(DEX2OAT_XMX) \
- --class-loader-context=$(PRIVATE_DEX2OAT_CLASS_LOADER_CONTEXT) \
+ $${class_loader_context_arg} \
+ $${stored_class_loader_context_arg} \
--boot-image=$(PRIVATE_DEX_PREOPT_IMAGE_LOCATION) \
--dex-file=$(1) \
--dex-location=$(PRIVATE_DEX_LOCATION) \
diff --git a/core/force_aapt2.mk b/core/force_aapt2.mk
new file mode 100644
index 0000000..655ccf5
--- /dev/null
+++ b/core/force_aapt2.mk
@@ -0,0 +1,63 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Including this makefile will force AAPT2 on if FORCE_AAPT2==true,
+# rewriting some properties to convert standard AAPT usage to AAPT2.
+
+ifeq ($(FORCE_AAPT2),true)
+ ifneq ($(LOCAL_USE_AAPT2),true)
+ # Force AAPT2 on
+ LOCAL_USE_AAPT2 := true
+ # Move LOCAL_STATIC_JAVA_AAR_LIBRARIES to LOCAL_STATIC_ANDROID_LIBRARIES
+ LOCAL_STATIC_ANDROID_LIBRARIES := $(strip $(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES))
+ LOCAL_STATIC_JAVA_AAR_LIBRARIES :=
+ # Filter out support library resources
+ LOCAL_RESOURCE_DIR := $(filter-out \
+ prebuilts/sdk/current/% \
+ frameworks/support/%,\
+ $(LOCAL_RESOURCE_DIR))
+ # Filter out unnecessary aapt flags
+ LOCAL_AAPT_FLAGS := $(subst --extra-packages=,--extra-packages$(space), \
+ $(filter-out \
+ --extra-packages=android.support.% \
+ --extra-packages=androidx.% \
+ --auto-add-overlay,\
+ $(subst --extra-packages$(space),--extra-packages=,$(LOCAL_AAPT_FLAGS))))
+
+ # AAPT2 is pickier about missing resources. Support library may have references to resources
+ # added in current, so always treat LOCAL_SDK_VERSION as LOCAL_SDK_RES_VERSION := current.
+ ifdef LOCAL_SDK_VERSION
+ LOCAL_SDK_RES_VERSION := current
+ endif
+
+ ifeq (,$(strip $(LOCAL_MANIFEST_FILE)$(LOCAL_FULL_MANIFEST_FILE)))
+ ifeq (,$(wildcard $(LOCAL_PATH)/AndroidManifest.xml))
+ # work around missing manifests by creating a default one
+ $(call pretty-warning, Missing manifest file)
+ LOCAL_FULL_MANIFEST_FILE := $(call local-intermediates-dir,COMMON)/DefaultManifest.xml
+ $(call create-default-manifest-file,$(LOCAL_FULL_MANIFEST_FILE))
+ endif
+ endif
+ endif
+endif
+
+ifneq ($(LOCAL_USE_AAPT2),true)
+ ifneq ($(LOCAL_USE_AAPT2),false)
+ ifneq ($(LOCAL_USE_AAPT2),)
+ $(call pretty-error,Invalid value for LOCAL_USE_AAPT2: "$(LOCAL_USE_AAPT2)")
+ endif
+ endif
+endif
diff --git a/core/host_executable_internal.mk b/core/host_executable_internal.mk
index c4f9f66..e72c419 100644
--- a/core/host_executable_internal.mk
+++ b/core/host_executable_internal.mk
@@ -33,7 +33,7 @@
my_libdir := $(notdir $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_SHARED_LIBRARIES))
ifeq ($(LOCAL_MODULE_CLASS),NATIVE_TESTS)
-$(LOCAL_BUILT_MODULE): PRIVATE_RPATHS := ../../$(my_libdir)
+$(LOCAL_BUILT_MODULE): PRIVATE_RPATHS := ../../$(my_libdir) ../../../$(my_libdir)
else
$(LOCAL_BUILT_MODULE): PRIVATE_RPATHS := ../$(my_libdir) $(my_libdir)
endif
diff --git a/core/java.mk b/core/java.mk
index ad9c71f..8e5fd1d 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -444,7 +444,7 @@
common_proguard_flags += -dontshrink # don't shrink tests by default
endif # test package
ifneq ($(LOCAL_PROGUARD_ENABLED),custom)
- ifdef LOCAL_USE_AAPT2
+ ifeq ($(LOCAL_USE_AAPT2),true)
common_proguard_flag_files += $(foreach l,$(LOCAL_STATIC_ANDROID_LIBRARIES),\
$(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/export_proguard_flags)
endif
@@ -556,7 +556,7 @@
$(built_dex_intermediate): PRIVATE_PROGUARD_INJAR_FILTERS := $(proguard_injar_filters)
$(built_dex_intermediate): PRIVATE_EXTRA_INPUT_JAR := $(extra_input_jar)
$(built_dex_intermediate): PRIVATE_PROGUARD_FLAGS := $(legacy_proguard_flags) $(common_proguard_flags) $(LOCAL_PROGUARD_FLAGS)
-$(built_dex_intermediate) : $(full_classes_proguard_jar) $(extra_input_jar) $(my_support_library_sdk_raise) $(common_proguard_flag_files) $(proguard_flag_files) $(legacy_proguard_lib_deps) $(R8_COMPAT_PROGUARD)
+$(built_dex_intermediate) : $(full_classes_proguard_jar) $(extra_input_jar) $(my_proguard_sdk_raise) $(common_proguard_flag_files) $(proguard_flag_files) $(legacy_proguard_lib_deps) $(R8_COMPAT_PROGUARD)
$(transform-jar-to-dex-r8)
endif # LOCAL_USE_R8
endif # LOCAL_PROGUARD_ENABLED
diff --git a/core/java_common.mk b/core/java_common.mk
index 2695aff..d8f679a 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -477,7 +477,7 @@
ifdef LOCAL_AAPT2_ONLY
my_link_type += aapt2_only
endif
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
my_allowed_types += aapt2_only
endif
diff --git a/core/math.mk b/core/math.mk
index 44e03ce..ac3151e 100644
--- a/core/math.mk
+++ b/core/math.mk
@@ -15,44 +15,104 @@
#
###########################################################
-# Basic math functions for positive integers <= 100
+# Basic math functions for non-negative integers <= 100
#
# (SDK versions for example)
###########################################################
-__MATH_NUMBERS := 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
- 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
- 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
- 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
- 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
+__MATH_POS_NUMBERS := 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
+ 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
+ 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
+ 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
+ 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
+__MATH_NUMBERS := 0 $(__MATH_POS_NUMBERS)
-# Returns true if $(1) is a positive integer <= 100, otherwise returns nothing.
+math-error = $(call pretty-error,$(1))
+math-expect :=
+math-expect-true :=
+math-expect :=
+math-expect-error :=
+
+# Run the math tests with:
+# make -f ${ANDROID_BUILD_TOP}/build/make/core/math.mk RUN_MATH_TESTS=true
+# $(get_build_var CKATI) -f ${ANDROID_BUILD_TOP}//build/make/core/math.mk RUN_MATH_TESTS=true
+ifdef RUN_MATH_TESTS
+ MATH_TEST_FAILURE :=
+ MATH_TEST_ERROR :=
+ math-error = $(if $(MATH_TEST_ERROR),,$(eval MATH_TEST_ERROR:=$(1)))
+ define math-expect
+ $(eval got:=$$$1) \
+ $(if $(subst $(got),,$(2))$(subst $(2),,$(got))$(MATH_TEST_ERROR), \
+ $(if $(MATH_TEST_ERROR),$(warning $(MATH_TEST_ERROR)),$(warning $$$1 '$(got)' != '$(2)')) \
+ $(eval MATH_TEST_FAILURE := true)) \
+ $(eval MATH_TEST_ERROR :=) \
+ $(eval got:=)
+ endef
+ math-expect-true = $(call math-expect,$(1),true)
+ math-expect-false = $(call math-expect,$(1),)
+
+ define math-expect-error
+ $(eval got:=$$$1) \
+ $(if $(subst $(MATH_TEST_ERROR),,$(2))$(subst $(2),,$(MATH_TEST_ERROR)), \
+ $(warning '$(MATH_TEST_ERROR)' != '$(2)') \
+ $(eval MATH_TEST_FAILURE := true)) \
+ $(eval MATH_TEST_ERROR :=) \
+ $(eval got:=)
+ endef
+endif
+
+# Returns true if $(1) is a non-negative integer <= 100, otherwise returns nothing.
define math_is_number
$(strip \
- $(if $(1),,$(error Argument missing)) \
- $(if $(word 2,$(1)),$(error Multiple words in a single argument: $(1))) \
+ $(if $(1),,$(call math-error,Argument missing)) \
+ $(if $(word 2,$(1)),$(call math-error,Multiple words in a single argument: $(1))) \
$(if $(filter $(1),$(__MATH_NUMBERS)),true))
endef
-#$(warning true == $(call math_is_number,2))
-#$(warning == $(call math_is_number,foo))
-#$(call math_is_number,1 2)
-#$(call math_is_number,no 2)
+define math_is_zero
+$(strip \
+ $(if $(word 2,$(1)),$(call math-error,Multiple words in a single argument: $(1))) \
+ $(if $(filter 0,$(1)),true))
+endef
+
+$(call math-expect-true,(call math_is_number,0))
+$(call math-expect-true,(call math_is_number,2))
+$(call math-expect-false,(call math_is_number,foo))
+$(call math-expect-false,(call math_is_number,-1))
+$(call math-expect-error,(call math_is_number,1 2),Multiple words in a single argument: 1 2)
+$(call math-expect-error,(call math_is_number,no 2),Multiple words in a single argument: no 2)
+
+$(call math-expect-true,(call math_is_zero,0))
+$(call math-expect-false,(call math_is_zero,1))
+$(call math-expect-false,(call math_is_zero,foo))
+$(call math-expect-error,(call math_is_zero,1 2),Multiple words in a single argument: 1 2)
+$(call math-expect-error,(call math_is_zero,no 2),Multiple words in a single argument: no 2)
define _math_check_valid
-$(if $(call math_is_number,$(1)),,$(error Only positive integers <= 100 are supported (not $(1))))
+$(if $(call math_is_number,$(1)),,$(call math-error,Only non-negative integers <= 100 are supported (not $(1))))
endef
+$(call math-expect,(call _math_check_valid,0))
+$(call math-expect,(call _math_check_valid,1))
+$(call math-expect,(call _math_check_valid,100))
+$(call math-expect-error,(call _math_check_valid,-1),Only non-negative integers <= 100 are supported (not -1))
+$(call math-expect-error,(call _math_check_valid,101),Only non-negative integers <= 100 are supported (not 101))
+$(call math-expect-error,(call _math_check_valid,),Argument missing)
+$(call math-expect-error,(call _math_check_valid,1 2),Multiple words in a single argument: 1 2)
+
# return a list containing integers ranging from [$(1),$(2)]
define int_range_list
-$(call _math_check_valid,$(1))$(call _math_check_valid,$(2))$(wordlist $(1),$(2),$(__MATH_NUMBERS))
+$(strip \
+ $(call _math_check_valid,$(1))$(call _math_check_valid,$(2)) \
+ $(if $(call math_is_zero,$(1)),0)\
+ $(wordlist $(if $(call math_is_zero,$(1)),1,$(1)),$(2),$(__MATH_POS_NUMBERS)))
endef
-#$(call _math_check_valid,0)
-#$(call _math_check_valid,1)
-#$(call _math_check_valid,100)
-#$(call _math_check_valid,101)
-#$(call _math_check_valid,)
-#$(call _math_check_valid,1 2)
+$(call math-expect,(call int_range_list,0,1),0 1)
+$(call math-expect,(call int_range_list,1,1),1)
+$(call math-expect,(call int_range_list,1,2),1 2)
+$(call math-expect,(call int_range_list,2,1),)
+$(call math-expect-error,(call int_range_list,1,101),Only non-negative integers <= 100 are supported (not 101))
+
# Returns the greater of $1 or $2.
# If $1 or $2 is not a positive integer <= 100, then an error is generated.
@@ -61,12 +121,14 @@
$(lastword $(filter $(1) $(2),$(__MATH_NUMBERS))))
endef
-#$(call math_max)
-#$(call math_max,1)
-#$(call math_max,1 2,3)
-#$(warning 1 == $(call math_max,1,1))
-#$(warning 42 == $(call math_max,5,42))
-#$(warning 42 == $(call math_max,42,5))
+$(call math-expect-error,(call math_max),Argument missing)
+$(call math-expect-error,(call math_max,1),Argument missing)
+$(call math-expect-error,(call math_max,1 2,3),Multiple words in a single argument: 1 2)
+$(call math-expect,(call math_max,0,1),1)
+$(call math-expect,(call math_max,1,0),1)
+$(call math-expect,(call math_max,1,1),1)
+$(call math-expect,(call math_max,5,42),42)
+$(call math-expect,(call math_max,42,5),42)
define math_gt_or_eq
$(if $(filter $(1),$(call math_max,$(1),$(2))),true)
@@ -76,15 +138,23 @@
$(if $(call math_gt_or_eq,$(1),$(2)),,true)
endef
-#$(warning $(call math_gt_or_eq, 2, 1))
-#$(warning $(call math_gt_or_eq, 1, 1))
-#$(warning $(if $(call math_gt_or_eq, 1, 2),false,true))
+$(call math-expect-true,(call math_gt_or_eq, 2, 1))
+$(call math-expect-true,(call math_gt_or_eq, 1, 1))
+$(call math-expect-false,(call math_gt_or_eq, 1, 2))
# $1 is the variable name to increment
define inc_and_print
$(strip $(eval $(1) := $($(1)) .)$(words $($(1))))
endef
+ifdef RUN_MATH_TESTS
+a :=
+$(call math-expect,(call inc_and_print,a),1)
+$(call math-expect,(call inc_and_print,a),2)
+$(call math-expect,(call inc_and_print,a),3)
+$(call math-expect,(call inc_and_print,a),4)
+endif
+
# Returns the words in $2 that are numbers and are less than $1
define numbers_less_than
$(strip \
@@ -94,12 +164,19 @@
$(n)))))
endef
+$(call math-expect,(call numbers_less_than,0,0 1 2 3),)
+$(call math-expect,(call numbers_less_than,1,0 2 1 3),0)
+$(call math-expect,(call numbers_less_than,2,0 2 1 3),0 1)
+$(call math-expect,(call numbers_less_than,3,0 2 1 3),0 2 1)
+$(call math-expect,(call numbers_less_than,4,0 2 1 3),0 2 1 3)
+$(call math-expect,(call numbers_less_than,3,0 2 1 3 2),0 2 1 2)
+
_INT_LIMIT_WORDS := $(foreach a,x x,$(foreach b,x x x x x x x x x x x x x x x x,\
$(foreach c,x x x x x x x x x x x x x x x x,x x x x x x x x x x x x x x x x)))
define _int_encode
$(if $(filter $(words x $(_INT_LIMIT_WORDS)),$(words $(wordlist 1,$(1),x $(_INT_LIMIT_WORDS)))),\
- $(call pretty-error,integer greater than $(words $(_INT_LIMIT_WORDS)) is not supported!),\
+ $(call math-error,integer greater than $(words $(_INT_LIMIT_WORDS)) is not supported!),\
$(wordlist 1,$(1),$(_INT_LIMIT_WORDS)))
endef
@@ -135,18 +212,59 @@
$(words $(call _int_encode,$(1)) $(call _int_encode,$(2)))
endef
+$(call math-expect,(call int_plus,0,0),0)
+$(call math-expect,(call int_plus,0,1),1)
+$(call math-expect,(call int_plus,1,0),1)
+$(call math-expect,(call int_plus,1,100),101)
+$(call math-expect,(call int_plus,100,100),200)
+
define int_subtract
-$(if $(call _int_greater-or-equal,$(call _int_encode,$(1)),$(call _int_encode,$(2))),\
+$(strip \
+ $(if $(call _int_greater-or-equal,$(call _int_encode,$(1)),$(call _int_encode,$(2))),\
$(words $(filter-out xx,$(join $(call _int_encode,$(1)),$(call _int_encode,$(2))))),\
- $(call pretty-error,$(1) subtract underflow $(2)))
+ $(call math-error,subtract underflow $(1) - $(2))))
endef
+$(call math-expect,(call int_subtract,0,0),0)
+$(call math-expect,(call int_subtract,1,0),1)
+$(call math-expect,(call int_subtract,1,1),0)
+$(call math-expect,(call int_subtract,100,1),99)
+$(call math-expect,(call int_subtract,200,100),100)
+$(call math-expect-error,(call int_subtract,0,1),subtract underflow 0 - 1)
+
define int_multiply
$(words $(foreach a,$(call _int_encode,$(1)),$(call _int_encode,$(2))))
endef
+$(call math-expect,(call int_multiply,0,0),0)
+$(call math-expect,(call int_multiply,1,0),0)
+$(call math-expect,(call int_multiply,1,1),1)
+$(call math-expect,(call int_multiply,100,1),100)
+$(call math-expect,(call int_multiply,1,100),100)
+$(call math-expect,(call int_multiply,4,100),400)
+$(call math-expect,(call int_multiply,100,4),400)
+
define int_divide
-$(if $(filter 0,$(2)),$(call pretty-error,division by zero is not allowed!),$(strip \
+$(if $(filter 0,$(2)),$(call math-error,division by zero is not allowed!),$(strip \
$(if $(call _int_greater-or-equal,$(call _int_encode,$(1)),$(call _int_encode,$(2))), \
$(call int_plus,$(call int_divide,$(call int_subtract,$(1),$(2)),$(2)),1),0)))
endef
+
+$(call math-expect,(call int_divide,1,1),1)
+$(call math-expect,(call int_divide,200,1),200)
+$(call math-expect,(call int_divide,200,3),66)
+$(call math-expect,(call int_divide,1,2),0)
+$(call math-expect-error,(call int_divide,0,0),division by zero is not allowed!)
+$(call math-expect-error,(call int_divide,1,0),division by zero is not allowed!)
+
+ifdef RUN_MATH_TESTS
+ ifdef MATH_TEST_FAILURE
+ math-tests:
+ @echo FAIL
+ @false
+ else
+ math-tests:
+ @echo PASS
+ endif
+ .PHONY: math-tests
+endif
diff --git a/core/package_internal.mk b/core/package_internal.mk
index f8e610b..18c8f23 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -87,6 +87,8 @@
LOCAL_RESOURCE_DIR := $(foreach d,$(LOCAL_RESOURCE_DIR),$(call clean-path,$(d)))
endif
+include $(BUILD_SYSTEM)/force_aapt2.mk
+
package_resource_overlays := $(strip \
$(wildcard $(foreach dir, $(PRODUCT_PACKAGE_OVERLAYS), \
$(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))) \
@@ -153,7 +155,7 @@
endif
my_res_package :=
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
# In aapt2 the last takes precedence.
my_resource_dirs := $(call reverse-list,$(LOCAL_RESOURCE_DIR))
my_res_dir :=
@@ -357,7 +359,7 @@
###############################
## AAPT/AAPT2
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
my_compiled_res_base_dir := $(intermediates.COMMON)/flat-res
ifneq (,$(renderscript_target_api))
ifneq ($(call math_gt_or_eq,$(renderscript_target_api),21),true)
@@ -509,7 +511,7 @@
$(LOCAL_INTERMEDIATE_TARGETS): \
PRIVATE_AAPT_INCLUDES := $(all_library_res_package_exports)
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
$(my_res_package) : $(all_library_res_package_export_deps)
endif
@@ -593,7 +595,7 @@
$(LOCAL_BUILT_MODULE): PRIVATE_FULL_CLASSES_JAR := $(full_classes_jar)
$(LOCAL_BUILT_MODULE) : $(jni_shared_libraries)
$(LOCAL_BUILT_MODULE) : $(JAR_ARGS)
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
$(LOCAL_BUILT_MODULE): PRIVATE_RES_PACKAGE := $(my_res_package)
$(LOCAL_BUILT_MODULE) : $(my_res_package) $(AAPT2) | $(ACP)
else
@@ -604,7 +606,7 @@
$(LOCAL_BUILT_MODULE) : $(MINIGZIP)
endif
@echo "target Package: $(PRIVATE_MODULE) ($@)"
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
$(call copy-file-to-new-target)
else # ! LOCAL_USE_AAPT2
$(if $(PRIVATE_SOURCE_ARCHIVE),\
@@ -620,7 +622,7 @@
$(if $(PRIVATE_EXTRA_JAR_ARGS),$(call add-java-resources-to,$@))
else # full_classes_jar
$(add-dex-to-package)
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
$(call add-jar-resources-to-package,$@,$(PRIVATE_FULL_CLASSES_JAR),$(PRIVATE_RESOURCE_INTERMEDIATES_DIR))
endif
endif # full_classes_jar
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 8aa5b96..6a9916a 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -607,11 +607,13 @@
$(common_javalib_jar) : $(common_classes_jar)
$(transform-prebuilt-to-target)
+include $(BUILD_SYSTEM)/force_aapt2.mk
+
ifdef LOCAL_AAPT2_ONLY
LOCAL_USE_AAPT2 := true
endif
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
ifneq ($(my_src_aar),)
$(intermediates.COMMON)/export_proguard_flags : $(my_src_proguard_options)
diff --git a/core/setup_one_odex.mk b/core/setup_one_odex.mk
index e0d9926..5cc6085 100644
--- a/core/setup_one_odex.mk
+++ b/core/setup_one_odex.mk
@@ -25,17 +25,89 @@
my_dex_preopt_image_location := $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_LOCATION)
endif
my_dex_preopt_image_filename := $(call get-image-file-path,$($(my_2nd_arch_prefix)DEX2OAT_TARGET_ARCH),$(my_dex_preopt_image_location))
+
+# If LOCAL_ENFORCE_USES_LIBRARIES is not set, default to true if either of LOCAL_USES_LIBRARIES or
+# LOCAL_OPTIONAL_USES_LIBRARIES are specified.
+ifeq (,$(LOCAL_ENFORCE_USES_LIBRARIES))
+# Will change the default to true unconditionally in the future.
+ifneq (,$(LOCAL_OPTIONAL_USES_LIBRARIES))
+LOCAL_ENFORCE_USES_LIBRARIES := true
+endif
+ifneq (,$(LOCAL_USES_LIBRARIES))
+LOCAL_ENFORCE_USES_LIBRARIES := true
+endif
+endif
+
+my_uses_libraries := $(LOCAL_USES_LIBRARIES)
+my_optional_uses_libraries := $(LOCAL_OPTIONAL_USES_LIBRARIES)
+my_missing_uses_libraries := $(INTERNAL_PLATFORM_MISSING_USES_LIBRARIES)
+
+# If we have either optional or required uses-libraries, set up the class loader context
+# accordingly.
+my_lib_names :=
+my_optional_lib_names :=
+my_filtered_optional_uses_libraries :=
+my_system_dependencies :=
+my_stored_preopt_class_loader_context_libs :=
+my_conditional_uses_libraries_host :=
+my_conditional_uses_libraries_target :=
+
+ifneq (true,$(LOCAL_ENFORCE_USES_LIBRARIES))
+ # Pass special class loader context to skip the classpath and collision check.
+ # This will get removed once LOCAL_USES_LIBRARIES is enforced.
+ # Right now LOCAL_USES_LIBRARIES is opt in, for the case where it's not specified we still default
+ # to the &.
+ my_dex_preopt_class_loader_context := \&
+else
+ # Compute the filtered optional uses libraries by removing ones that are not supposed to exist.
+ my_filtered_optional_uses_libraries := \
+ $(filter-out $(my_missing_uses_libraries), $(my_optional_uses_libraries))
+ my_filtered_uses_libraries := $(my_uses_libraries) $(my_filtered_optional_uses_libraries)
+
+ # These are the ones we are verifying in the make rule, use the unfiltered libraries.
+ my_lib_names := $(my_uses_libraries)
+ my_optional_lib_names := $(my_optional_uses_libraries)
+
+ # Calculate system build dependencies based on the filtered libraries.
+ my_intermediate_libs := $(foreach lib_name, $(my_lib_names) $(my_filtered_optional_uses_libraries), \
+ $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib_name),,)/javalib.jar)
+ my_dex_preopt_system_dependencies := $(my_intermediate_libs)
+ my_dex_preopt_class_loader_context := $(call normalize-path-list,$(my_intermediate_libs))
+
+ # The class loader context checksums are filled in by dex2oat.
+ my_stored_preopt_class_loader_context_libs := $(call normalize-path-list, \
+ $(foreach lib_name,$(my_filtered_uses_libraries),/system/framework/$(lib_name).jar))
+
+ # Fix up org.apache.http.legacy.boot since it should be org.apache.http.legacy in the manifest.
+ my_lib_names := $(patsubst org.apache.http.legacy.boot,org.apache.http.legacy,$(my_lib_names))
+ my_optional_lib_names := $(patsubst org.apache.http.legacy.boot,org.apache.http.legacy,$(my_optional_lib_names))
+ ifeq (,$(filter org.apache.http.legacy,$(my_lib_names) $(my_optional_lib_names)))
+ my_conditional_uses_libraries_host := $(call intermediates-dir-for,JAVA_LIBRARIES,org.apache.http.legacy.boot,,)/javalib.jar
+ my_conditional_uses_libraries_target := /system/framework/org.apache.http.legacy.boot.jar
+ endif
+endif
+
+# Always depend on org.apache.http.legacy.boot since it may get used by dex2oat-one-file for apps
+# targetting <SDK 28(P).
+my_always_depend_libraries := $(call intermediates-dir-for,JAVA_LIBRARIES,org.apache.http.legacy.boot,,COMMON)/javalib.jar
+
+$(my_built_odex): $(AAPT)
+$(my_built_odex): $(my_always_depend_libraries)
+$(my_built_odex): $(my_dex_preopt_system_dependencies)
+$(my_built_odex): PRIVATE_ENFORCE_USES_LIBRARIES := $(LOCAL_ENFORCE_USES_LIBRARIES)
+$(my_built_odex): PRIVATE_CONDITIONAL_USES_LIBRARIES_HOST := $(my_conditional_uses_libraries_host)
+$(my_built_odex): PRIVATE_CONDITIONAL_USES_LIBRARIES_TARGET := $(my_conditional_uses_libraries_target)
+$(my_built_odex): PRIVATE_USES_LIBRARY_NAMES := $(my_lib_names)
+$(my_built_odex): PRIVATE_OPTIONAL_USES_LIBRARY_NAMES := $(my_optional_lib_names)
$(my_built_odex): PRIVATE_2ND_ARCH_VAR_PREFIX := $(my_2nd_arch_prefix)
$(my_built_odex): PRIVATE_DEX_LOCATION := $(patsubst $(PRODUCT_OUT)%,%,$(LOCAL_INSTALLED_MODULE))
$(my_built_odex): PRIVATE_DEX_PREOPT_IMAGE_LOCATION := $(my_dex_preopt_image_location)
+$(my_built_odex): PRIVATE_DEX2OAT_CLASS_LOADER_CONTEXT := $(my_dex_preopt_class_loader_context)
+$(my_built_odex): PRIVATE_DEX2OAT_STORED_CLASS_LOADER_CONTEXT_LIBS := $(my_stored_preopt_class_loader_context_libs)
$(my_built_odex) : $($(my_2nd_arch_prefix)DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BOOT_PREOPT) \
$(DEXPREOPT_ONE_FILE_DEPENDENCY_TOOLS) \
$(my_dex_preopt_image_filename)
-# Pass special class loader context to skip the classpath and collision check.
-# Should modify build system to pass used libraries properly later.
-$(my_built_odex): PRIVATE_DEX2OAT_CLASS_LOADER_CONTEXT := \&
-
my_installed_odex := $(call get-odex-installed-file-path,$($(my_2nd_arch_prefix)DEX2OAT_TARGET_ARCH),$(LOCAL_INSTALLED_MODULE))
my_built_vdex := $(patsubst %.odex,%.vdex,$(my_built_odex))
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 4d502ec..ea3714a 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -45,6 +45,7 @@
$(call add_json_str, BuildId, $(BUILD_ID))
$(call add_json_str, BuildNumberFromFile, $$$(BUILD_NUMBER_FROM_FILE))
+$(call add_json_str, Platform_version_name, $(PLATFORM_VERSION))
$(call add_json_val, Platform_sdk_version, $(PLATFORM_SDK_VERSION))
$(call add_json_str, Platform_sdk_codename, $(PLATFORM_VERSION_CODENAME))
$(call add_json_bool, Platform_sdk_final, $(filter REL,$(PLATFORM_VERSION_CODENAME)))
@@ -140,6 +141,11 @@
$(call add_json_list, PgoAdditionalProfileDirs, $(PGO_ADDITIONAL_PROFILE_DIRS))
+$(call add_json_list, BoardVendorSepolicyDirs, $(BOARD_SEPOLICY_DIRS))
+$(call add_json_list, BoardOdmSepolicyDirs, $(BOARD_ODM_SEPOLICY_DIRS))
+$(call add_json_str, BoardPlatPublicSepolicyDir, $(BOARD_PLAT_PUBLIC_SEPOLICY_DIR))
+$(call add_json_str, BoardPlatPrivateSepolicyDir, $(BOARD_PLAT_PRIVATE_SEPOLICY_DIR))
+
_contents := $(_contents) "VendorVars": {$(newline)
$(foreach namespace,$(SOONG_CONFIG_NAMESPACES),\
$(eval _contents := $$(_contents) "$(namespace)": {$$(newline)) \
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 8ef28b8..332314f 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -28,6 +28,8 @@
my_res_package :=
+include $(BUILD_SYSTEM)/force_aapt2.mk
+
ifdef LOCAL_AAPT2_ONLY
LOCAL_USE_AAPT2 := true
endif
@@ -44,7 +46,7 @@
need_compile_res := true
LOCAL_RESOURCE_DIR := $(foreach d,$(LOCAL_RESOURCE_DIR),$(call clean-path,$(d)))
endif
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
ifneq ($(LOCAL_STATIC_ANDROID_LIBRARIES),)
need_compile_res := true
endif
@@ -82,7 +84,7 @@
R_file_stamp := $(intermediates.COMMON)/src/R.stamp
LOCAL_INTERMEDIATE_TARGETS += $(R_file_stamp)
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
# For library we treat all the resource equal with no overlay.
my_res_resources := $(all_resources)
my_overlay_resources :=
@@ -117,7 +119,7 @@
endif
endif
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
import_proguard_flag_files := $(strip $(foreach l,$(LOCAL_STATIC_ANDROID_LIBRARIES),\
$(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/export_proguard_flags))
$(intermediates.COMMON)/export_proguard_flags: $(import_proguard_flag_files) $(addprefix $(LOCAL_PATH)/,$(LOCAL_EXPORT_PROGUARD_FLAG_FILES))
@@ -140,7 +142,7 @@
# add --non-constant-id to prevent inlining constants.
# AAR needs text symbol file R.txt.
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) --static-lib --output-text-symbols $(intermediates.COMMON)/R.txt
ifndef LOCAL_AAPT_NAMESPACES
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS += --no-static-lib-packages
@@ -168,7 +170,7 @@
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_PACKAGE_NAME :=
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_INSTRUMENTATION_FOR :=
-ifdef LOCAL_USE_AAPT2
+ifeq ($(LOCAL_USE_AAPT2),true)
# One more level with name res so we can zip up the flat resources that can be linked by apps.
my_compiled_res_base_dir := $(intermediates.COMMON)/flat-res/res
ifneq (,$(renderscript_target_api))
diff --git a/core/tasks/collect_gpl_sources.mk b/core/tasks/collect_gpl_sources.mk
index 70f0afe..fdbf6c9 100644
--- a/core/tasks/collect_gpl_sources.mk
+++ b/core/tasks/collect_gpl_sources.mk
@@ -22,7 +22,7 @@
# FORCE since we can't know whether any of the sources changed
$(gpl_source_tgz): PRIVATE_PATHS := $(sort $(patsubst %/, %, $(dir $(ALL_GPL_MODULE_LICENSE_FILES))))
$(gpl_source_tgz) : $(ALL_GPL_MODULE_LICENSE_FILES)
- @echo Package gpl sources: $@
+ @echo Package GPL sources: $@
$(hide) tar cfz $@ --exclude ".git*" $(PRIVATE_PATHS)
# Dist the tgz only if we are doing a full build
diff --git a/core/verify_uses_libraries.sh b/core/verify_uses_libraries.sh
new file mode 100755
index 0000000..dde0447
--- /dev/null
+++ b/core/verify_uses_libraries.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# apt_binary is $(AAPT) in the build.
+
+# Parse sdk, targetSdk, and uses librares in the APK, then cross reference against build specified ones.
+
+set -e
+local_apk=$1
+badging=$(${aapt_binary} dump badging "${local_apk}")
+export sdk_version=$(echo "${badging}" | grep "sdkVersion" | sed -n "s/sdkVersion:'\(.*\)'/\1/p")
+# Export target_sdk_version to the caller.
+export target_sdk_version=$(echo "${badging}" | grep "targetSdkVersion" | sed -n "s/targetSdkVersion:'\(.*\)'/\1/p")
+uses_libraries=$(echo "${badging}" | grep "uses-library" | sed -n "s/uses-library:'\(.*\)'/\1/p")
+optional_uses_libraries=$(echo "${badging}" | grep "uses-library-not-required" | sed -n "s/uses-library-not-required:'\(.*\)'/\1/p")
+
+# Verify that the uses libraries match exactly.
+# Currently we validate the ordering of the libraries since it matters for resolution.
+single_line_libs=$(echo "${uses_libraries}" | tr '\n' ' ' | awk '{$1=$1}1')
+if [[ "${single_line_libs}" != "${uses_library_names}" ]]; then
+ echo "LOCAL_USES_LIBRARIES (${uses_library_names})" \
+ "do not match (${single_line_libs}) in manifest for ${local_apk}"
+ exit 1
+fi
+
+# Verify that the optional uses libraries match exactly.
+single_line_optional_libs=$(echo "${optional_uses_libraries}" | tr '\n' ' ' | awk '{$1=$1}1')
+if [[ "${single_line_optional_libs}" != "${optional_uses_library_names}" ]]; then
+ echo "LOCAL_OPTIONAL_USES_LIBRARIES (${optional_uses_library_names}) " \
+ "do not match (${single_line_optional_libs}) in manifest for ${local_apk}"
+ exit 1
+fi
+
diff --git a/target/product/base.mk b/target/product/base.mk
index 919c16d..d6507c6 100644
--- a/target/product/base.mk
+++ b/target/product/base.mk
@@ -153,6 +153,7 @@
PRODUCT_PACKAGES_DEBUG := \
iotop \
logpersist.start \
+ micro_bench \
perfprofd \
sqlite3 \
strace
diff --git a/tools/apicheck/Android.bp b/tools/apicheck/Android.bp
new file mode 100644
index 0000000..8fe20e9
--- /dev/null
+++ b/tools/apicheck/Android.bp
@@ -0,0 +1,22 @@
+// Copyright (C) 2008 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+java_binary_host {
+ name: "apicheck",
+ wrapper: "etc/apicheck",
+ static_libs: [
+ "doclava",
+ "jsilver",
+ ],
+}
diff --git a/tools/apicheck/Android.mk b/tools/apicheck/Android.mk
deleted file mode 100644
index ab3493d..0000000
--- a/tools/apicheck/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2007-2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# the hat script
-# ============================================================
-include $(CLEAR_VARS)
-LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE := apicheck
-LOCAL_SRC_FILES := etc/apicheck
-LOCAL_REQUIRED_MODULES := doclava
-include $(BUILD_PREBUILT)
-
-# Apicheck is now part of Doclava -- See external/doclava.
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index e8ec50e..968fd77 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -24,12 +24,12 @@
--downgrade
Intentionally generate an incremental OTA that updates from a newer build
- to an older one (based on timestamp comparison). "post-timestamp" will be
- replaced by "ota-downgrade=yes" in the metadata file. A data wipe will
- always be enforced, so "ota-wipe=yes" will also be included in the
- metadata file. The update-binary in the source build will be used in the
- OTA package, unless --binary flag is specified. Please also check the doc
- for --override_timestamp below.
+ to an older one (e.g. downgrading from P preview back to O MR1).
+ "ota-downgrade=yes" will be set in the package metadata file. A data wipe
+ will always be enforced when using this flag, so "ota-wipe=yes" will also
+ be included in the metadata file. The update-binary in the source build
+ will be used in the OTA package, unless --binary flag is specified. Please
+ also check the comment for --override_timestamp below.
-i (--incremental_from) <file>
Generate an incremental OTA using the given target-files zip as the
@@ -46,14 +46,19 @@
--override_timestamp
Intentionally generate an incremental OTA that updates from a newer build
- to an older one (based on timestamp comparison), by overriding the
- timestamp in package metadata. This differs from --downgrade flag: we know
- for sure this is NOT an actual downgrade case, but two builds are cut in a
- reverse order. A legit use case is that we cut a new build C (after having
- A and B), but want to enfore an update path of A -> C -> B. Specifying
- --downgrade may not help since that would enforce a data wipe for C -> B
- update. The value of "post-timestamp" will be set to the newer timestamp
- plus one, so that the package can be pushed and applied.
+ to an older one (based on timestamp comparison), by setting the downgrade
+ flag in the package metadata. This differs from --downgrade flag, as we
+ don't enforce a data wipe with this flag. Because we know for sure this is
+ NOT an actual downgrade case, but two builds happen to be cut in a reverse
+ order (e.g. from two branches). A legit use case is that we cut a new
+ build C (after having A and B), but want to enfore an update path of A ->
+ C -> B. Specifying --downgrade may not help since that would enforce a
+ data wipe for C -> B update.
+
+ We used to set a fake timestamp in the package metadata for this flow. But
+ now we consolidate the two cases (i.e. an actual downgrade, or a downgrade
+ based on timestamp) with the same "ota-downgrade=yes" flag, with the
+ difference being whether "ota-wipe=yes" is set.
--wipe_user_data
Generate an OTA package that will wipe the user data partition when
@@ -184,7 +189,6 @@
OPTIONS.patch_threshold = 0.95
OPTIONS.wipe_user_data = False
OPTIONS.downgrade = False
-OPTIONS.timestamp = False
OPTIONS.extra_script = None
OPTIONS.worker_threads = multiprocessing.cpu_count() // 2
if OPTIONS.worker_threads == 0:
@@ -902,23 +906,16 @@
if OPTIONS.downgrade:
if not is_downgrade:
- raise RuntimeError("--downgrade specified but no downgrade detected: "
- "pre: %s, post: %s" % (pre_timestamp, post_timestamp))
+ raise RuntimeError(
+ "--downgrade or --override_timestamp specified but no downgrade "
+ "detected: pre: %s, post: %s" % (pre_timestamp, post_timestamp))
metadata["ota-downgrade"] = "yes"
- elif OPTIONS.timestamp:
- if not is_downgrade:
- raise RuntimeError("--override_timestamp specified but no timestamp hack "
- "needed: pre: %s, post: %s" % (pre_timestamp,
- post_timestamp))
- metadata["post-timestamp"] = str(long(pre_timestamp) + 1)
else:
if is_downgrade:
- raise RuntimeError("Downgrade detected based on timestamp check: "
- "pre: %s, post: %s. Need to specify "
- "--override_timestamp OR --downgrade to allow "
- "building the incremental." % (pre_timestamp,
- post_timestamp))
- metadata["post-timestamp"] = post_timestamp
+ raise RuntimeError(
+ "Downgrade detected based on timestamp check: pre: %s, post: %s. "
+ "Need to specify --override_timestamp OR --downgrade to allow "
+ "building the incremental." % (pre_timestamp, post_timestamp))
def GetPackageMetadata(target_info, source_info=None):
@@ -926,7 +923,7 @@
It generates a dict() that contains the info to be written into an OTA
package (META-INF/com/android/metadata). It also handles the detection of
- downgrade / timestamp override / data wipe based on the global options.
+ downgrade / data wipe based on the global options.
Args:
target_info: The BuildInfo instance that holds the target build info.
@@ -967,11 +964,12 @@
else:
metadata['pre-device'] = target_info.device
- # Detect downgrades, or fill in the post-timestamp.
+ # Use the actual post-timestamp, even for a downgrade case.
+ metadata['post-timestamp'] = target_info.GetBuildProp('ro.build.date.utc')
+
+ # Detect downgrades and set up downgrade flags accordingly.
if is_incremental:
HandleDowngradeMetadata(metadata, target_info, source_info)
- else:
- metadata['post-timestamp'] = target_info.GetBuildProp('ro.build.date.utc')
return metadata
@@ -1796,7 +1794,7 @@
OPTIONS.downgrade = True
OPTIONS.wipe_user_data = True
elif o == "--override_timestamp":
- OPTIONS.timestamp = True
+ OPTIONS.downgrade = True
elif o in ("-o", "--oem_settings"):
OPTIONS.oem_source = a.split(',')
elif o == "--oem_no_mount":
@@ -1874,19 +1872,12 @@
sys.exit(1)
if OPTIONS.downgrade:
- # Sanity check to enforce a data wipe.
- if not OPTIONS.wipe_user_data:
- raise ValueError("Cannot downgrade without a data wipe")
-
# We should only allow downgrading incrementals (as opposed to full).
# Otherwise the device may go back from arbitrary build with this full
# OTA package.
if OPTIONS.incremental_source is None:
raise ValueError("Cannot generate downgradable full OTAs")
- assert not (OPTIONS.downgrade and OPTIONS.timestamp), \
- "Cannot have --downgrade AND --override_timestamp both"
-
# Load the build info dicts from the zip directly or the extracted input
# directory. We don't need to unzip the entire target-files zips, because they
# won't be needed for A/B OTAs (brillo_update_payload does that on its own).
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index 213e830..e472363 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -532,31 +532,7 @@
'post-build-incremental' : 'build-version-incremental-target',
'post-sdk-level' : '27',
'post-security-patch-level' : '2017-12-01',
- 'pre-device' : 'product-device',
- 'pre-build' : 'build-fingerprint-source',
- 'pre-build-incremental' : 'build-version-incremental-source',
- },
- metadata)
-
- def test_GetPackageMetadata_overrideTimestamp(self):
- target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
- source_info_dict = copy.deepcopy(self.TEST_SOURCE_INFO_DICT)
- self._test_GetPackageMetadata_swapBuildTimestamps(
- target_info_dict, source_info_dict)
-
- target_info = BuildInfo(target_info_dict, None)
- source_info = BuildInfo(source_info_dict, None)
- common.OPTIONS.incremental_source = ''
- common.OPTIONS.timestamp = True
- metadata = GetPackageMetadata(target_info, source_info)
- self.assertDictEqual(
- {
- 'ota-type' : 'BLOCK',
- 'post-build' : 'build-fingerprint-target',
- 'post-build-incremental' : 'build-version-incremental-target',
- 'post-sdk-level' : '27',
- 'post-security-patch-level' : '2017-12-01',
- 'post-timestamp' : '1500000001',
+ 'post-timestamp' : '1400000000',
'pre-device' : 'product-device',
'pre-build' : 'build-fingerprint-source',
'pre-build-incremental' : 'build-version-incremental-source',
diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py
index e8cea29..acd5b6e 100755
--- a/tools/releasetools/validate_target_files.py
+++ b/tools/releasetools/validate_target_files.py
@@ -66,7 +66,7 @@
file_name, actual_sha1, expected_sha1)
-def ValidateFileConsistency(input_zip, input_tmp):
+def ValidateFileConsistency(input_zip, input_tmp, info_dict):
"""Compare the files from image files and unpacked folders."""
def CheckAllFiles(which):
@@ -103,6 +103,11 @@
logging.info('Validating file consistency.')
+ # TODO(b/79617342): Validate non-sparse images.
+ if info_dict.get('extfs_sparse_flag') != '-s':
+ logging.warning('Skipped due to target using non-sparse images')
+ return
+
# Verify IMAGES/system.img.
CheckAllFiles('system')
@@ -324,10 +329,10 @@
logging.info("Unzipping the input target_files.zip: %s", args.target_files)
input_tmp = common.UnzipTemp(args.target_files)
- with zipfile.ZipFile(args.target_files, 'r') as input_zip:
- ValidateFileConsistency(input_zip, input_tmp)
-
info_dict = common.LoadInfoDict(input_tmp)
+ with zipfile.ZipFile(args.target_files, 'r') as input_zip:
+ ValidateFileConsistency(input_zip, input_tmp, info_dict)
+
ValidateInstallRecoveryScript(input_tmp, info_dict)
ValidateVerifiedBootImages(input_tmp, info_dict, options)
diff --git a/tools/signapk/src/com/android/signapk/CountingOutputStream.java b/tools/signapk/src/com/android/signapk/CountingOutputStream.java
new file mode 100644
index 0000000..893a780
--- /dev/null
+++ b/tools/signapk/src/com/android/signapk/CountingOutputStream.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.signapk;
+import java.io.OutputStream;
+import java.io.IOException;
+
+class CountingOutputStream extends OutputStream {
+ private final OutputStream mBase;
+ private long mWrittenBytes;
+
+ public CountingOutputStream(OutputStream base) {
+ mBase = base;
+ }
+
+ @Override
+ public void close() throws IOException {
+ mBase.close();
+ }
+
+ @Override
+ public void flush() throws IOException {
+ mBase.flush();
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ mBase.write(b);
+ mWrittenBytes += b.length;
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ mBase.write(b, off, len);
+ mWrittenBytes += len;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ mBase.write(b);
+ mWrittenBytes += 1;
+ }
+
+ public long getWrittenBytes() {
+ return mWrittenBytes;
+ }
+}
diff --git a/tools/signapk/src/com/android/signapk/SignApk.java b/tools/signapk/src/com/android/signapk/SignApk.java
index fdf6283..57973ec 100644
--- a/tools/signapk/src/com/android/signapk/SignApk.java
+++ b/tools/signapk/src/com/android/signapk/SignApk.java
@@ -36,6 +36,7 @@
import com.android.apksig.ApkSignerEngine;
import com.android.apksig.DefaultApkSignerEngine;
+import com.android.apksig.Hints;
import com.android.apksig.apk.ApkUtils;
import com.android.apksig.apk.MinSdkVersionException;
import com.android.apksig.util.DataSink;
@@ -73,6 +74,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
@@ -80,6 +82,7 @@
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
import javax.crypto.Cipher;
import javax.crypto.EncryptedPrivateKeyInfo;
@@ -372,11 +375,16 @@
Pattern ignoredFilenamePattern,
ApkSignerEngine apkSigner,
JarOutputStream out,
+ CountingOutputStream outCounter,
long timestamp,
int defaultAlignment) throws IOException {
byte[] buffer = new byte[4096];
int num;
+ List<Pattern> pinPatterns = extractPinPatterns(in);
+ ArrayList<Hints.ByteRange> pinByteRanges = pinPatterns == null ? null : new ArrayList<>();
+ HashSet<String> namesToPin = new HashSet<>();
+
ArrayList<String> names = new ArrayList<String>();
for (Enumeration<JarEntry> e = in.entries(); e.hasMoreElements();) {
JarEntry entry = e.nextElement();
@@ -388,6 +396,16 @@
&& (ignoredFilenamePattern.matcher(entryName).matches())) {
continue;
}
+ if (Hints.PIN_BYTE_RANGE_ZIP_ENTRY_NAME.equals(entryName)) {
+ continue; // We regenerate it below.
+ }
+ if (pinPatterns != null) {
+ for (Pattern pinPattern : pinPatterns) {
+ if (pinPattern.matcher(entryName).matches()) {
+ namesToPin.add(entryName);
+ }
+ }
+ }
names.add(entryName);
}
Collections.sort(names);
@@ -460,6 +478,7 @@
outEntry.setExtra(extra);
offset += extra.length;
+ long entryHeaderStart = outCounter.getWrittenBytes();
out.putNextEntry(outEntry);
ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
(apkSigner != null) ? apkSigner.outputJarEntry(name) : null;
@@ -475,10 +494,18 @@
offset += num;
}
}
+ out.closeEntry();
out.flush();
if (inspectEntryRequest != null) {
inspectEntryRequest.done();
}
+
+ if (namesToPin.contains(name)) {
+ pinByteRanges.add(
+ new Hints.ByteRange(
+ entryHeaderStart,
+ outCounter.getWrittenBytes()));
+ }
}
// Copy all the non-STORED entries. We don't attempt to
@@ -494,6 +521,7 @@
// Create a new entry so that the compressed len is recomputed.
JarEntry outEntry = new JarEntry(name);
outEntry.setTime(timestamp);
+ long entryHeaderStart = outCounter.getWrittenBytes();
out.putNextEntry(outEntry);
ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
(apkSigner != null) ? apkSigner.outputJarEntry(name) : null;
@@ -507,11 +535,47 @@
entryDataSink.consume(buffer, 0, num);
}
}
+ out.closeEntry();
out.flush();
if (inspectEntryRequest != null) {
inspectEntryRequest.done();
}
+
+ if (namesToPin.contains(name)) {
+ pinByteRanges.add(
+ new Hints.ByteRange(
+ entryHeaderStart,
+ outCounter.getWrittenBytes()));
+ }
}
+
+ if (pinByteRanges != null) {
+ // Cover central directory
+ pinByteRanges.add(
+ new Hints.ByteRange(outCounter.getWrittenBytes(),
+ Long.MAX_VALUE));
+ addPinByteRanges(out, pinByteRanges, timestamp);
+ }
+ }
+
+ private static List<Pattern> extractPinPatterns(JarFile in) throws IOException {
+ ZipEntry pinMetaEntry = in.getEntry(Hints.PIN_HINT_ASSET_ZIP_ENTRY_NAME);
+ if (pinMetaEntry == null) {
+ return null;
+ }
+ InputStream pinMetaStream = in.getInputStream(pinMetaEntry);
+ byte[] patternBlob = new byte[(int) pinMetaEntry.getSize()];
+ pinMetaStream.read(patternBlob);
+ return Hints.parsePinPatterns(patternBlob);
+ }
+
+ private static void addPinByteRanges(JarOutputStream outputJar,
+ ArrayList<Hints.ByteRange> pinByteRanges,
+ long timestamp) throws IOException {
+ JarEntry je = new JarEntry(Hints.PIN_BYTE_RANGE_ZIP_ENTRY_NAME);
+ je.setTime(timestamp);
+ outputJar.putNextEntry(je);
+ outputJar.write(Hints.encodeByteRangeList(pinByteRanges));
}
private static boolean shouldOutputApkEntry(
@@ -679,9 +743,11 @@
public void write(OutputStream out) throws IOException {
try {
signer = new WholeFileSignerOutputStream(out, outputStream);
- JarOutputStream outputJar = new JarOutputStream(signer);
+ CountingOutputStream outputJarCounter = new CountingOutputStream(signer);
+ JarOutputStream outputJar = new JarOutputStream(outputJarCounter);
- copyFiles(inputJar, STRIP_PATTERN, null, outputJar, timestamp, 0);
+ copyFiles(inputJar, STRIP_PATTERN, null, outputJar,
+ outputJarCounter, timestamp, 0);
addOtacert(outputJar, publicKeyFile, timestamp);
signer.notifyClosing();
@@ -1065,11 +1131,14 @@
// Build the output APK in memory, by copying input APK's ZIP entries across
// and then signing the output APK.
ByteArrayOutputStream v1SignedApkBuf = new ByteArrayOutputStream();
- JarOutputStream outputJar = new JarOutputStream(v1SignedApkBuf);
+ CountingOutputStream outputJarCounter =
+ new CountingOutputStream(v1SignedApkBuf);
+ JarOutputStream outputJar = new JarOutputStream(outputJarCounter);
// Use maximum compression for compressed entries because the APK lives forever
// on the system partition.
outputJar.setLevel(9);
- copyFiles(inputJar, null, apkSigner, outputJar, timestamp, alignment);
+ copyFiles(inputJar, null, apkSigner, outputJar,
+ outputJarCounter, timestamp, alignment);
ApkSignerEngine.OutputJarSignatureRequest addV1SignatureRequest =
apkSigner.outputJarEntries();
if (addV1SignatureRequest != null) {