Merge "Install product shared libraries in /product/lib"
diff --git a/Changes.md b/Changes.md
index 37bbad0..7519096 100644
--- a/Changes.md
+++ b/Changes.md
@@ -1,5 +1,32 @@
 # Build System Changes for Android.mk Writers
 
+## PATH Tools {#PATH_Tools}
+
+The build has started restricting the external host tools usable inside the
+build. This will help ensure that build results are reproducible across
+different machines, and catch mistakes before they become larger issues.
+
+To start with, this includes replacing the $PATH with our own directory of
+tools, mirroring that of the host PATH.  The only difference so far is the
+removal of the host GCC tools. Anything that is not explicitly in the
+configuration as allowed will continue functioning, but will generate a log
+message. This is expected to become more restrictive over time.
+
+The configuration is located in build/soong/ui/build/paths/config.go, and
+contains all the common tools in use in many builds. Anything not in that list
+will currently print a warning in the `$OUT_DIR/soong.log` file, including the
+command and arguments used, and the process tree in order to help locate the
+usage.
+
+In order to fix any issues brought up by these checks, the best way to fix them
+is to use tools checked into the tree -- either as prebuilts, or building them
+as host tools during the build.
+
+As a temporary measure, you can set `TEMPORARY_DISABLE_PATH_RESTRICTIONS=true`
+in your environment to temporarily turn off the error checks and allow any tool
+to be used (with logging). Beware that GCC didn't work well with the interposer
+used for logging, so this may not help in all cases.
+
 ## Deprecating / obsoleting envsetup.sh variables in Makefiles
 
 It is not required to source envsetup.sh before running a build. Many scripts,
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 043aa60..beca20b 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -476,6 +476,9 @@
 $(call add-clean-step, rm -rf $(TARGET_COMMON_OUT_ROOT)/obj_asan/APPS/*_intermediates/java-source-list)
 $(call add-clean-step, rm -rf $(TARGET_COMMON_OUT_ROOT)/obj_asan/JAVA_LIBRARIES/*_intermediates/java-source-list)
 
+# Remove stale init.noenforce.rc
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/init/gsi/init.noenforce.rc)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/Makefile b/core/Makefile
index 002e955..882dc9f 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -125,8 +125,12 @@
   else
     FINAL_VENDOR_DEFAULT_PROPERTIES := ro.vndk.version=$(BOARD_VNDK_VERSION)
   endif
+  ifdef BOARD_VNDK_RUNTIME_DISABLE
+    FINAL_VENDOR_DEFAULT_PROPERTIES += ro.vndk.lite=true
+  endif
 else
-  FINAL_VENDOR_DEFAULT_PROPERTIES :=
+  FINAL_VENDOR_DEFAULT_PROPERTIES := ro.vndk.version=$(PLATFORM_VNDK_VERSION)
+  FINAL_VENDOR_DEFAULT_PROPERTIES += ro.vndk.lite=true
 endif
 FINAL_VENDOR_DEFAULT_PROPERTIES += \
     $(call collapse-pairs, $(PRODUCT_DEFAULT_PROPERTY_OVERRIDES))
diff --git a/core/aapt2.mk b/core/aapt2.mk
index 4385b4d..fbbf3dd 100644
--- a/core/aapt2.mk
+++ b/core/aapt2.mk
@@ -52,7 +52,7 @@
 ifneq ($(my_generated_res_zips),)
 my_zipped_resources_flata := $(my_compiled_res_base_dir)/zip_res.flata
 $(my_zipped_resources_flata): PRIVATE_SOURCE_RES_ZIPS := $(my_generated_res_zips)
-$(my_zipped_resources_flata) : $(my_generated_res_deps) $(AAPT2) $(ZIPSYNC)
+$(my_zipped_resources_flata) : $(my_generated_res_zips) $(AAPT2) $(ZIPSYNC)
 	@echo "AAPT2 compile $@ <- $(PRIVATE_SOURCE_RES_ZIPS)"
 	$(call aapt2-compile-resource-zips)
 
@@ -64,9 +64,11 @@
 $(my_res_resources_flat) $(my_overlay_resources_flat) $(my_resources_flata): \
   PRIVATE_AAPT2_CFLAGS := --pseudo-localize
 
-my_static_library_resources := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES)),\
+# TODO(b/78447299): Forbid LOCAL_STATIC_JAVA_AAR_LIBRARIES in aapt2 and remove
+# support for it.
+my_static_library_resources := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),\
   $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/package-res.apk)
-my_static_library_extra_packages := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES)),\
+my_static_library_extra_packages := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),\
   $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/extra_packages)
 my_shared_library_resources := $(foreach l, $(LOCAL_SHARED_ANDROID_LIBRARIES),\
   $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/package-res.apk)
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/autogen_test_config.mk b/core/autogen_test_config.mk
index d2eb7c3..20c582a 100644
--- a/core/autogen_test_config.mk
+++ b/core/autogen_test_config.mk
@@ -17,8 +17,7 @@
 # This build rule allows TradeFed test config file to be created based on
 # following inputs:
 #   is_native: If the test is a native test.
-#   LOCAL_MANIFEST_FILE: Name of the AndroidManifest file for the test. If it's
-#       not set, default value `AndroidManifest.xml` will be used.
+#   full_android_manifest: Name of the AndroidManifest file for the test.
 # Output:
 #   autogen_test_config_file: Path to the test config file generated.
 
@@ -36,25 +35,17 @@
 my_auto_generate_config := true
 else
 # Auto generating test config file for instrumentation test
-ifeq ($(strip $(LOCAL_MANIFEST_FILE)),)
-  LOCAL_MANIFEST_FILE := AndroidManifest.xml
-endif
-ifdef LOCAL_FULL_MANIFEST_FILE
-  my_android_manifest := $(LOCAL_FULL_MANIFEST_FILE)
-else
-  my_android_manifest := $(LOCAL_PATH)/$(LOCAL_MANIFEST_FILE)
-endif
-ifneq (,$(wildcard $(my_android_manifest)))
+ifneq (,$(full_android_manifest))
 $(autogen_test_config_file): PRIVATE_AUTOGEN_TEST_CONFIG_SCRIPT := $(AUTOGEN_TEST_CONFIG_SCRIPT)
-$(autogen_test_config_file): PRIVATE_TEST_CONFIG_ANDROID_MANIFEST := $(my_android_manifest)
+$(autogen_test_config_file): PRIVATE_TEST_CONFIG_ANDROID_MANIFEST := $(full_android_manifest)
 $(autogen_test_config_file): PRIVATE_EMPTY_TEST_CONFIG := $(EMPTY_TEST_CONFIG)
 $(autogen_test_config_file): PRIVATE_TEMPLATE := $(INSTRUMENTATION_TEST_CONFIG_TEMPLATE)
-$(autogen_test_config_file) : $(my_android_manifest) $(EMPTY_TEST_CONFIG) $(INSTRUMENTATION_TEST_CONFIG_TEMPLATE) $(AUTOGEN_TEST_CONFIG_SCRIPT)
+$(autogen_test_config_file) : $(full_android_manifest) $(EMPTY_TEST_CONFIG) $(INSTRUMENTATION_TEST_CONFIG_TEMPLATE) $(AUTOGEN_TEST_CONFIG_SCRIPT)
 	@echo "Auto generating test config $(notdir $@)"
 	@rm -f $@
 	$(hide) $(PRIVATE_AUTOGEN_TEST_CONFIG_SCRIPT) $@ $(PRIVATE_TEST_CONFIG_ANDROID_MANIFEST) $(PRIVATE_EMPTY_TEST_CONFIG) $(PRIVATE_TEMPLATE)
 my_auto_generate_config := true
-endif # ifeq (,$(wildcard $(my_android_manifest)))
+endif # ifneq (,$(full_android_manifest))
 endif # ifneq (true,$(is_native))
 
 ifeq (true,$(my_auto_generate_config))
@@ -65,5 +56,4 @@
   autogen_test_config_file :=
 endif
 
-my_android_manifest :=
 my_auto_generate_config :=
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 63c6c52..075465e 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -557,7 +557,8 @@
 # The module itself.
 $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
   $(eval my_compat_dist_$(suite) := $(foreach dir, $(call compatibility_suite_dirs,$(suite),$(arch_dir)), \
-    $(LOCAL_BUILT_MODULE):$(dir)/$(my_installed_module_stem))))
+    $(LOCAL_BUILT_MODULE):$(dir)/$(my_installed_module_stem))) \
+  $(eval my_compat_dist_config_$(suite) := ))
 
 # Make sure we only add the files once for multilib modules.
 ifndef $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
@@ -604,7 +605,7 @@
 
 ifneq (,$(test_config))
 $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
-  $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+  $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
     $(test_config):$(dir)/$(LOCAL_MODULE).config)))
 endif
 
@@ -612,14 +613,14 @@
 
 ifneq (,$(wildcard $(LOCAL_PATH)/DynamicConfig.xml))
 $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
-  $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+  $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
     $(LOCAL_PATH)/DynamicConfig.xml:$(dir)/$(LOCAL_MODULE).dynamic)))
 endif
 
 ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config))
 $(foreach extra_config, $(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config), \
   $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
-    $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+    $(eval my_compat_dist_config_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
       $(extra_config):$(dir)/$(notdir $(extra_config))))))
 endif
 endif # $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
@@ -638,6 +639,8 @@
 is_native :=
 
 $(call create-suite-dependencies)
+$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+  $(eval my_compat_dist_config_$(suite) := ))
 
 endif  # LOCAL_COMPATIBILITY_SUITE
 
diff --git a/core/binary.mk b/core/binary.mk
index 39f1161..e3adaf3 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -804,7 +804,7 @@
 $(RenderScript_file_stamp): PRIVATE_RS_FLAGS := $(renderscript_flags)
 $(RenderScript_file_stamp): PRIVATE_RS_SOURCE_FILES := $(renderscript_sources_fullpath)
 $(RenderScript_file_stamp): PRIVATE_RS_OUTPUT_DIR := $(renderscript_intermediate)
-$(RenderScript_file_stamp): PRIVATE_RS_TARGET_API := $(renderscript_target_api)
+$(RenderScript_file_stamp): PRIVATE_RS_TARGET_API := $(patsubst current,0,$(renderscript_target_api))
 $(RenderScript_file_stamp): PRIVATE_DEP_FILES := $(bc_dep_files)
 $(RenderScript_file_stamp): $(renderscript_sources_fullpath) $(LOCAL_RENDERSCRIPT_CC)
 	$(transform-renderscripts-to-cpp-and-bc)
@@ -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 3325752..1a33153 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -57,6 +57,7 @@
 LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING:=
 LOCAL_DEX_PREOPT:= # '',true,false,nostripping
 LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG:=
+LOCAL_DISABLE_RESOLVE_SUPPORT_LIBRARIES:=
 LOCAL_DONT_CHECK_MODULE:=
 # Don't delete the META_INF dir when merging static Java libraries.
 LOCAL_DONT_DELETE_JAR_META_INF:=
@@ -74,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:=
@@ -179,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:=
@@ -271,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:=
@@ -465,6 +469,8 @@
 LOCAL_CUSTOM_BUILD_STEP_OUTPUT:=
 LOCAL_IS_AUX_MODULE :=
 
+full_android_manifest :=
+
 # Trim MAKEFILE_LIST so that $(call my-dir) doesn't need to
 # iterate over thousands of entries every time.
 # Leave the current makefile to make sure we don't break anything
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 39dbf55..075af49 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
@@ -110,6 +108,9 @@
 # Various mappings to avoid hard-coding paths all over the place
 include $(BUILD_SYSTEM)/pathmap.mk
 
+# Allow projects to define their own globally-available variables
+include $(BUILD_SYSTEM)/project_definitions.mk
+
 # ###############################################################
 # Build system internal files
 # ###############################################################
@@ -711,9 +712,12 @@
 
 # Tool to merge AndroidManifest.xmls
 ANDROID_MANIFEST_MERGER_CLASSPATH := \
-    prebuilts/gradle-plugin/com/android/tools/build/manifest-merger/26.0.0-beta2/manifest-merger-26.0.0-beta2.jar \
-    prebuilts/gradle-plugin/com/android/tools/sdk-common/26.0.0-beta2/sdk-common-26.0.0-beta2.jar \
-    prebuilts/gradle-plugin/com/android/tools/common/26.0.0-beta2/common-26.0.0-beta2.jar \
+    prebuilts/gradle-plugin/com/android/tools/build/manifest-merger/26.1.0/manifest-merger-26.1.0.jar \
+    prebuilts/gradle-plugin/com/android/tools/common/26.1.0/common-26.1.0.jar \
+    prebuilts/gradle-plugin/com/android/tools/sdk-common/26.1.0/sdk-common-26.1.0.jar \
+    prebuilts/gradle-plugin/com/android/tools/sdklib/26.1.0/sdklib-26.1.0.jar \
+    prebuilts/gradle-plugin/org/jetbrains/kotlin/kotlin-runtime/1.0.5/kotlin-runtime-1.0.5.jar \
+    prebuilts/gradle-plugin/org/jetbrains/kotlin/kotlin-stdlib/1.1.3/kotlin-stdlib-1.1.3.jar \
     prebuilts/misc/common/guava/guava-21.0.jar
 ANDROID_MANIFEST_MERGER := $(JAVA) \
     -classpath $(subst $(space),:,$(strip $(ANDROID_MANIFEST_MERGER_CLASSPATH))) \
@@ -750,8 +754,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)))
@@ -913,6 +916,15 @@
     PLATFORM_SEPOLICY_VERSION \
     TOT_SEPOLICY_VERSION \
 
+ifndef USE_LOGICAL_PARTITIONS
+  USE_LOGICAL_PARTITIONS := $(PRODUCT_USE_LOGICAL_PARTITIONS)
+endif
+.KATI_READONLY := USE_LOGICAL_PARTITIONS
+
+ifeq ($(USE_LOGICAL_PARTITIONS),true)
+  BOARD_KERNEL_CMDLINE += androidboot.lrap=1
+endif
+
 # ###############################################################
 # Set up final options.
 # ###############################################################
@@ -1021,6 +1033,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..e18f9a4 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,19 @@
 $(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">' && \
+	 echo '    <uses-sdk android:minSdkVersion="$(2)" />' && \
+	 echo '</manifest>' ) > $1
+endef
+
+define create-default-manifest-file
+  $(eval $(call _create-default-manifest-file,$(1),$(2)))
+endef
+
+
 ###########################################################
 xlint_unchecked := -Xlint:unchecked
 
@@ -2671,6 +2684,18 @@
 	$$(copy-file-to-target)
 endef
 
+# Copies many xml files and check they are well-formed.
+# $(1): The xml files to copy.  Each entry is a ':' separated src:dst pair.
+# Evaluates to the list of the dst files. (ie suitable for a dependency list.)
+define copy-many-xml-files-checked
+$(foreach f, $(1), $(strip \
+    $(eval _cmf_tuple := $(subst :, ,$(f))) \
+    $(eval _cmf_src := $(word 1,$(_cmf_tuple))) \
+    $(eval _cmf_dest := $(word 2,$(_cmf_tuple))) \
+    $(eval $(call copy-xml-file-checked,$(_cmf_src),$(_cmf_dest))) \
+    $(_cmf_dest)))
+endef
+
 # Copy the file only if it is a well-formed manifest file. For use viea $(eval)
 # $(1): source file
 # $(2): destination file
@@ -3116,15 +3141,20 @@
 
 # For each suite:
 # 1. Copy the files to the many suite output directories.
+#    And for test config files, we'll check the .xml is well-formed before copy.
 # 2. Add all the files to each suite's dependent files list.
 # 3. Do the dependency addition to my_all_targets
-# Requires for each suite: my_compat_dist_$(suite) to be defined.
+# Requires for each suite: use my_compat_dist_config_$(suite) to define the test config.
+#    and use my_compat_dist_$(suite) to define the others.
 define create-suite-dependencies
 $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
   $(eval COMPATIBILITY.$(suite).FILES := \
-    $$(COMPATIBILITY.$(suite).FILES) $$(foreach f,$$(my_compat_dist_$(suite)),$$(call word-colon,2,$$(f))))) \
+    $$(COMPATIBILITY.$(suite).FILES) $$(foreach f,$$(my_compat_dist_$(suite)),$$(call word-colon,2,$$(f))) \
+      $$(foreach f,$$(my_compat_dist_config_$(suite)),$$(call word-colon,2,$$(f))))) \
 $(eval $(my_all_targets) : $(call copy-many-files, \
-  $(sort $(foreach suite,$(LOCAL_COMPATIBILITY_SUITE),$(my_compat_dist_$(suite))))))
+  $(sort $(foreach suite,$(LOCAL_COMPATIBILITY_SUITE),$(my_compat_dist_$(suite))))) \
+  $(call copy-many-xml-files-checked, \
+    $(sort $(foreach suite,$(LOCAL_COMPATIBILITY_SUITE),$(my_compat_dist_config_$(suite))))))
 endef
 
 ###########################################################
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index 10522ac..64ad200 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.impl 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/dex_preopt_libart_boot.mk b/core/dex_preopt_libart_boot.mk
index 29584b1..977f852 100644
--- a/core/dex_preopt_libart_boot.mk
+++ b/core/dex_preopt_libart_boot.mk
@@ -54,11 +54,11 @@
 
 ifeq (,$(my_out_boot_image_profile_location))
 my_boot_image_flags := --image-classes=$(PRELOADED_CLASSES)
-my_boot_image_flags += $(DIRTY_IMAGE_OBJECTS_FLAGS)
 else
 my_boot_image_flags := --compiler-filter=speed-profile
 my_boot_image_flags += --profile-file=$(my_out_boot_image_profile_location)
 endif
+my_boot_image_flags += $(DIRTY_IMAGE_OBJECTS_FLAGS)
 
 ifneq (addresstrue,$(SANITIZE_TARGET)$(SANITIZE_LITE))
 # Skip recompiling the boot image for the second sanitization phase. We'll get separate paths
diff --git a/core/force_aapt2.mk b/core/force_aapt2.mk
new file mode 100644
index 0000000..a097bd2
--- /dev/null
+++ b/core/force_aapt2.mk
@@ -0,0 +1,72 @@
+#
+# 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)
+  ifeq ($(LOCAL_USE_AAPT2),)
+    # Force AAPT2 on
+    LOCAL_USE_AAPT2 := true
+    # Filter out support library resources
+    LOCAL_RESOURCE_DIR := $(filter-out \
+      prebuilts/sdk/current/% \
+      frameworks/support/%,\
+        $(LOCAL_RESOURCE_DIR))
+    # Filter out unnecessary aapt flags
+    ifneq (,$(filter --extra-packages,$(LOCAL_AAPT_FLAGS)))
+      LOCAL_AAPT_FLAGS := $(subst --extra-packages=,--extra-packages$(space), \
+        $(filter-out \
+          --extra-packages=android.support.% \
+          --extra-packages=androidx.%, \
+            $(subst --extra-packages$(space),--extra-packages=,$(LOCAL_AAPT_FLAGS))))
+        ifeq (,$(filter --extra-packages,$(LOCAL_AAPT_FLAGS)))
+          LOCAL_AAPT_FLAGS := $(filter-out --auto-add-overlay,$(LOCAL_AAPT_FLAGS))
+        endif
+    endif
+
+    # 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
+        ifdef LOCAL_MIN_SDK_VERSION
+          my_manifest_min_sdk_version := $(LOCAL_MIN_SDK_VERSION)
+        else ifneq (,$(filter-out current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
+          my_manifest_min_sdk_version := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
+        else
+          my_manifest_min_sdk_version := $(DEFAULT_APP_TARGET_SDK)
+        endif
+        $(call create-default-manifest-file,$(LOCAL_FULL_MANIFEST_FILE),$(my_manifest_min_sdk_version))
+        my_manifest_min_sdk_version :=
+      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..b75949a 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -259,9 +259,14 @@
       LOCAL_JAVA_LIBRARIES := $(filter-out $(TARGET_DEFAULT_BOOTCLASSPATH_LIBRARIES) $(TARGET_DEFAULT_JAVA_LIBRARIES),$(LOCAL_JAVA_LIBRARIES))
       my_system_modules := $(DEFAULT_SYSTEM_MODULES)
     endif  # LOCAL_NO_STANDARD_LIBRARIES
-    # When SDK libraries are referenced from modules built without SDK, provide the system stub to them
-    # because it has the largest API surface.
-    sdk_libs := $(foreach lib_name,$(LOCAL_SDK_LIBRARIES),$(lib_name).stubs.system)
+
+    ifneq (,$(TARGET_BUILD_APPS))
+      sdk_libs := $(foreach lib_name,$(LOCAL_SDK_LIBRARIES),$(call resolve-prebuilt-sdk-module,system_current,$(lib_name)))
+    else
+      # When SDK libraries are referenced from modules built without SDK, provide the system stub to them
+      # because it has the largest API surface.
+      sdk_libs := $(foreach lib_name,$(LOCAL_SDK_LIBRARIES),$(lib_name).stubs.system)
+    endif
   else
     ifeq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
       $(call pretty-error,Must not define both LOCAL_NO_STANDARD_LIBRARIES and LOCAL_SDK_VERSION)
@@ -477,7 +482,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/java_renderscript.mk b/core/java_renderscript.mk
index 191b3be..d7dd4ed 100644
--- a/core/java_renderscript.mk
+++ b/core/java_renderscript.mk
@@ -75,7 +75,7 @@
 $(rs_generated_src_jar): PRIVATE_RS_FLAGS := $(renderscript_flags)
 $(rs_generated_src_jar): PRIVATE_RS_SOURCE_FILES := $(renderscript_sources_fullpath)
 $(rs_generated_src_jar): PRIVATE_RS_OUTPUT_DIR := $(renderscript_intermediate.COMMON)
-$(rs_generated_src_jar): PRIVATE_RS_TARGET_API := $(renderscript_target_api)
+$(rs_generated_src_jar): PRIVATE_RS_TARGET_API := $(patsubst current,0,$(renderscript_target_api))
 $(rs_generated_src_jar): PRIVATE_DEP_FILES := $(bc_dep_files)
 $(rs_generated_src_jar): PRIVATE_RS_OUTPUT_RES_ZIP := $(rs_generated_res_zip)
 $(rs_generated_src_jar): .KATI_IMPLICIT_OUTPUTS := $(rs_generated_res_zip)
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 ac4b53c..637a135 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -87,6 +87,11 @@
   LOCAL_RESOURCE_DIR := $(foreach d,$(LOCAL_RESOURCE_DIR),$(call clean-path,$(d)))
 endif
 
+include $(BUILD_SYSTEM)/force_aapt2.mk
+
+# Process Support Library dependencies.
+include $(BUILD_SYSTEM)/support_libraries.mk
+
 package_resource_overlays := $(strip \
     $(wildcard $(foreach dir, $(PRODUCT_PACKAGE_OVERLAYS), \
       $(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))) \
@@ -153,13 +158,13 @@
 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 :=
 my_overlay_res_dirs :=
 
-ifneq ($(LOCAL_STATIC_ANDROID_LIBRARIES),)
+ifneq ($(strip $(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),)
 # If we are using static android libraries, every source file becomes an overlay.
 # This is to emulate old AAPT behavior which simulated library support.
 my_res_dir :=
@@ -354,9 +359,9 @@
 ###############################
 ## 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 (,$(filter-out current,$(renderscript_target_api)))
     ifneq ($(call math_gt_or_eq,$(renderscript_target_api),21),true)
       my_generated_res_zips := $(rs_generated_res_zip)
     endif  # renderscript_target_api < 21
@@ -411,7 +416,7 @@
     $(resource_export_package): PRIVATE_PRODUCT_AAPT_CONFIG :=
     $(resource_export_package): PRIVATE_PRODUCT_AAPT_PREF_CONFIG :=
     $(resource_export_package): PRIVATE_RESOURCE_LIST := $(all_res_assets)
-    $(resource_export_package): $(all_res_assets) $(full_android_manifest) $(RenderScript_file_stamp) $(AAPT)
+    $(resource_export_package): $(all_res_assets) $(full_android_manifest) $(rs_generated_res_zip) $(AAPT)
 	@echo "target Export Resources: $(PRIVATE_MODULE) ($@)"
 	$(create-empty-package)
 	$(add-assets-to-package)
@@ -506,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
 
@@ -590,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
@@ -601,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),\
@@ -617,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/product.mk b/core/product.mk
index 976c939..95d169c 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -197,6 +197,7 @@
     PRODUCT_CFI_EXCLUDE_PATHS \
     PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE \
     PRODUCT_ACTIONABLE_COMPATIBLE_PROPERTY_DISABLE \
+    PRODUCT_USE_LOGICAL_PARTITIONS \
 
 define dump-product
 $(info ==== $(1) ====)\
diff --git a/core/product_config.mk b/core/product_config.mk
index 6449b9f..3a77d0b 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -500,3 +500,8 @@
 # Whether the whitelist of actionable compatible properties should be disabled or not
 PRODUCT_ACTIONABLE_COMPATIBLE_PROPERTY_DISABLE := \
     $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ACTIONABLE_COMPATIBLE_PROPERTY_DISABLE))
+
+# Logical and Resizable Partitions feature flag.
+PRODUCT_USE_LOGICAL_PARTITIONS := \
+    $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_USE_LOGICAL_PARTITIONS))
+.KATI_READONLY := PRODUCT_USE_LOGICAL_PARTITIONS
diff --git a/core/project_definitions.mk b/core/project_definitions.mk
new file mode 100644
index 0000000..5728b67
--- /dev/null
+++ b/core/project_definitions.mk
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+
+#
+# Allow projects to define their own globally-available variables.
+#
+
+#
+# Include definitions for prebuilt SDK, if present.
+#
+-include prebuilts/sdk/current/definitions.mk
diff --git a/core/setup_one_odex.mk b/core/setup_one_odex.mk
index e0d9926..92f58b2 100644
--- a/core/setup_one_odex.mk
+++ b/core/setup_one_odex.mk
@@ -25,17 +25,85 @@
 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),,COMMON)/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.impl since it should be org.apache.http.legacy in the manifest.
+  my_lib_names := $(patsubst org.apache.http.legacy.impl,org.apache.http.legacy,$(my_lib_names))
+  my_optional_lib_names := $(patsubst org.apache.http.legacy.impl,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.impl,,COMMON)/javalib.jar
+    my_conditional_uses_libraries_target := /system/framework/org.apache.http.legacy.impl.jar
+  endif
+endif
+
+$(my_built_odex): $(AAPT)
+$(my_built_odex): $(my_conditional_uses_libraries_host)
+$(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..3f1fb66 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_list, BoardPlatPublicSepolicyDirs,       $(BOARD_PLAT_PUBLIC_SEPOLICY_DIR))
+$(call add_json_list, BoardPlatPrivateSepolicyDirs,      $(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 a3f560c..2a87705 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -28,6 +28,11 @@
 
 my_res_package :=
 
+# Process Support Library dependencies.
+include $(BUILD_SYSTEM)/support_libraries.mk
+
+include $(BUILD_SYSTEM)/force_aapt2.mk
+
 ifdef LOCAL_AAPT2_ONLY
 LOCAL_USE_AAPT2 := true
 endif
@@ -41,8 +46,8 @@
 need_compile_res := true
 LOCAL_RESOURCE_DIR := $(foreach d,$(LOCAL_RESOURCE_DIR),$(call clean-path,$(d)))
 endif
-ifdef LOCAL_USE_AAPT2
-ifneq ($(LOCAL_STATIC_ANDROID_LIBRARIES),)
+ifeq ($(LOCAL_USE_AAPT2),true)
+ifneq ($(strip $(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES)),)
 need_compile_res := true
 endif
 endif
@@ -79,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 :=
@@ -114,8 +119,8 @@
 endif
 endif
 
-ifdef LOCAL_USE_AAPT2
-import_proguard_flag_files := $(strip $(foreach l,$(LOCAL_STATIC_ANDROID_LIBRARIES),\
+ifeq ($(LOCAL_USE_AAPT2),true)
+import_proguard_flag_files := $(strip $(foreach l,$(LOCAL_STATIC_ANDROID_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_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))
 	@echo "Export proguard flags: $@"
@@ -137,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
@@ -165,10 +170,10 @@
 $(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))
+  ifneq (,$(filter-out current,$(renderscript_target_api)))
     ifneq ($(call math_gt_or_eq,$(renderscript_target_api),21),true)
       my_generated_res_zips := $(rs_generated_res_zip)
     endif  # renderscript_target_api < 21
diff --git a/core/support_libraries.mk b/core/support_libraries.mk
new file mode 100644
index 0000000..7538ce0
--- /dev/null
+++ b/core/support_libraries.mk
@@ -0,0 +1,53 @@
+#
+# 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.
+#
+
+###########################################################
+## Rules for resolving Support Library dependencies.
+##
+## The following variables may be modified:
+## - LOCAL_JAVA_LIBRARIES
+## - LOCAL_STATIC_JAVA_LIBRARIES
+## - LOCAL_SHARED_ANDROID_LIBRARIES
+## - LOCAL_STATIC_ANDROID_LIBRARIES
+###########################################################
+
+# Some projects don't work correctly yet. Allow them to skip resolution.
+ifndef LOCAL_DISABLE_RESOLVE_SUPPORT_LIBRARIES
+
+# Aggregate all requested Support Library modules.
+requested_support_libs := $(filter $(SUPPORT_LIBRARIES_JARS) $(SUPPORT_LIBRARIES_AARS), \
+    $(LOCAL_JAVA_LIBRARIES) $(LOCAL_STATIC_JAVA_LIBRARIES) \
+    $(LOCAL_SHARED_ANDROID_LIBRARIES) $(LOCAL_STATIC_ANDROID_LIBRARIES))
+
+# Filter the Support Library modules out of the library variables. We don't
+# trust developers to get these right, so they will be added back by the
+# build system based on the output of this file and the type of build.
+LOCAL_JAVA_LIBRARIES := $(filter-out $(requested_support_libs), \
+    $(LOCAL_JAVA_LIBRARIES))
+LOCAL_STATIC_JAVA_LIBRARIES := $(filter-out $(requested_support_libs), \
+    $(LOCAL_STATIC_JAVA_LIBRARIES))
+LOCAL_SHARED_ANDROID_LIBRARIES := $(filter-out $(requested_support_libs), \
+    $(LOCAL_SHARED_ANDROID_LIBRARIES))
+LOCAL_STATIC_ANDROID_LIBRARIES := $(filter-out $(requested_support_libs), \
+    $(LOCAL_STATIC_ANDROID_LIBRARIES))
+
+LOCAL_STATIC_ANDROID_LIBRARIES := $(strip $(LOCAL_STATIC_ANDROID_LIBRARIES) \
+    $(filter $(SUPPORT_LIBRARIES_AARS),$(requested_support_libs)))
+LOCAL_STATIC_JAVA_LIBRARIES := $(strip $(LOCAL_STATIC_JAVA_LIBRARIES) \
+    $(filter $(SUPPORT_LIBRARIES_JARS),$(requested_support_libs)))
+
+endif #LOCAL_DISABLE_RESOLVE_SUPPORT_LIBRARIES
+LOCAL_DISABLE_RESOLVE_SUPPORT_LIBRARIES :=
diff --git a/core/tasks/apicheck.mk b/core/tasks/apicheck.mk
deleted file mode 100644
index 1a1a12c..0000000
--- a/core/tasks/apicheck.mk
+++ /dev/null
@@ -1,168 +0,0 @@
-# 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.
-
-#
-# Rules for running apicheck to confirm that you haven't broken
-# api compatibility or added apis illegally.
-#
-
-# skip api check for PDK buid
-ifeq (,$(filter true, $(WITHOUT_CHECK_API) $(TARGET_BUILD_PDK)))
-
-.PHONY: checkapi
-
-# Run the checkapi rules by default.
-droidcore: checkapi
-
-last_released_sdk_version := \
-    $(lastword $(call numerically_sort, \
-        $(patsubst \
-            $(HISTORICAL_SDK_VERSIONS_ROOT)/%/public/api/android.txt,\
-            %,\
-            $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/public/api/android.txt)\
-        ) \
-    ))
-
-.PHONY: check-public-api
-checkapi : check-public-api
-
-.PHONY: update-api
-
-# INTERNAL_PLATFORM_API_FILE is the one build by droiddoc.
-# Note that since INTERNAL_PLATFORM_API_FILE is the byproduct of api-stubs module,
-# (See frameworks/base/Android.mk)
-# we need to add api-stubs as additional dependency of the api check.
-
-# Check that the API we're building hasn't broken the last-released
-# SDK version.
-$(eval $(call check-api, \
-    checkpublicapi-last, \
-    $(HISTORICAL_SDK_VERSIONS_ROOT)/$(last_released_sdk_version)/public/api/android.txt, \
-    $(INTERNAL_PLATFORM_API_FILE), \
-    frameworks/base/api/removed.txt, \
-    $(INTERNAL_PLATFORM_REMOVED_API_FILE), \
-    -hide 2 -hide 3 -hide 4 -hide 5 -hide 6 -hide 24 -hide 25 -hide 26 -hide 27 \
-    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-    -error 16 -error 17 -error 18 , \
-    cat $(BUILD_SYSTEM)/apicheck_msg_last.txt, \
-    check-public-api, \
-    $(OUT_DOCS)/api-stubs-docs-stubs.srcjar \
-    ))
-
-# Check that the API we're building hasn't changed from the not-yet-released
-# SDK version.
-$(eval $(call check-api, \
-    checkpublicapi-current, \
-    frameworks/base/api/current.txt, \
-    $(INTERNAL_PLATFORM_API_FILE), \
-    frameworks/base/api/removed.txt, \
-    $(INTERNAL_PLATFORM_REMOVED_API_FILE), \
-    -error 2 -error 3 -error 4 -error 5 -error 6 \
-    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-    -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
-    -error 25 -error 26 -error 27, \
-    cat $(BUILD_SYSTEM)/apicheck_msg_current.txt, \
-    check-public-api, \
-    $(OUT_DOCS)/api-stubs-docs-stubs.srcjar \
-    ))
-
-.PHONY: update-public-api
-update-public-api: $(INTERNAL_PLATFORM_API_FILE) | $(ACP)
-	@echo Copying current.txt
-	$(hide) $(ACP) $(INTERNAL_PLATFORM_API_FILE) frameworks/base/api/current.txt
-	@echo Copying removed.txt
-	$(hide) $(ACP) $(INTERNAL_PLATFORM_REMOVED_API_FILE) frameworks/base/api/removed.txt
-
-update-api : update-public-api
-
-#####################Check System API#####################
-.PHONY: check-system-api
-checkapi : check-system-api
-
-# Check that the System API we're building hasn't broken the last-released
-# SDK version.
-$(eval $(call check-api, \
-    checksystemapi-last, \
-    $(HISTORICAL_SDK_VERSIONS_ROOT)/$(last_released_sdk_version)/system/api/android.txt, \
-    $(INTERNAL_PLATFORM_SYSTEM_API_FILE), \
-    frameworks/base/api/system-removed.txt, \
-    $(INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE), \
-    -hide 2 -hide 3 -hide 4 -hide 5 -hide 6 -hide 24 -hide 25 -hide 26 -hide 27 \
-    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-    -error 16 -error 17 -error 18 , \
-    cat $(BUILD_SYSTEM)/apicheck_msg_last.txt, \
-    check-system-api, \
-    $(OUT_DOCS)/system-api-stubs-docs-stubs.srcjar \
-    ))
-
-# Check that the System API we're building hasn't changed from the not-yet-released
-# SDK version.
-$(eval $(call check-api, \
-    checksystemapi-current, \
-    frameworks/base/api/system-current.txt, \
-    $(INTERNAL_PLATFORM_SYSTEM_API_FILE), \
-    frameworks/base/api/system-removed.txt, \
-    $(INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE), \
-    -error 2 -error 3 -error 4 -error 5 -error 6 \
-    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-    -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
-    -error 25 -error 26 -error 27, \
-    cat $(BUILD_SYSTEM)/apicheck_msg_current.txt, \
-    check-system-api, \
-    $(OUT_DOCS)/system-api-stubs-docs-stubs.srcjar \
-    ))
-
-.PHONY: update-system-api
-update-api : update-system-api
-
-update-system-api: $(INTERNAL_PLATFORM_SYSTEM_API_FILE) | $(ACP)
-	@echo Copying system-current.txt
-	$(hide) $(ACP) $(INTERNAL_PLATFORM_SYSTEM_API_FILE) frameworks/base/api/system-current.txt
-	@echo Copying system-removed.txt
-	$(hide) $(ACP) $(INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE) frameworks/base/api/system-removed.txt
-
-#####################Check Test API#####################
-.PHONY: check-test-api
-checkapi : check-test-api
-
-# Check that the Test API we're building hasn't changed from the not-yet-released
-# SDK version. Note that we don't check that we haven't broken the previous
-# SDK's API because the test API is meant only for CTS which is always
-# associated with the current release.
-$(eval $(call check-api, \
-    checktestapi-current, \
-    frameworks/base/api/test-current.txt, \
-    $(INTERNAL_PLATFORM_TEST_API_FILE), \
-    frameworks/base/api/test-removed.txt, \
-    $(INTERNAL_PLATFORM_TEST_REMOVED_API_FILE), \
-    -error 2 -error 3 -error 4 -error 5 -error 6 \
-    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-    -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
-    -error 25 -error 26 -error 27, \
-    cat $(BUILD_SYSTEM)/apicheck_msg_current.txt, \
-    check-test-api, \
-    $(OUT_DOCS)/test-api-stubs-docs-stubs.srcjar \
-    ))
-
-.PHONY: update-test-api
-update-api : update-test-api
-
-update-test-api: $(INTERNAL_PLATFORM_TEST_API_FILE) | $(ACP)
-	@echo Copying test-current.txt
-	$(hide) $(ACP) $(INTERNAL_PLATFORM_TEST_API_FILE) frameworks/base/api/test-current.txt
-	@echo Copying test-removed.txt
-	$(hide) $(ACP) $(INTERNAL_PLATFORM_TEST_REMOVED_API_FILE) frameworks/base/api/test-removed.txt
-
-
-endif
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/envsetup.sh b/envsetup.sh
index 5182253..bad16e2 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -301,7 +301,6 @@
 
 function set_stuff_for_environment()
 {
-    settitle
     setpaths
     set_sequence_number
 
@@ -316,26 +315,6 @@
     export BUILD_ENV_SEQUENCE_NUMBER=13
 }
 
-function settitle()
-{
-    # This used to be opt-out with STAY_OFF_MY_LAWN, but this breaks folks
-    # actually using PROMPT_COMMAND (https://issuetracker.google.com/38402256),
-    # and the attempt to set the title doesn't do anything for the default
-    # window manager in debian right now, so switch it to opt-in for anyone
-    # who actually wants this.
-    if [ "$ANDROID_BUILD_SET_WINDOW_TITLE" = "true" ]; then
-        local arch=$(gettargetarch)
-        local product=$TARGET_PRODUCT
-        local variant=$TARGET_BUILD_VARIANT
-        local apps=$TARGET_BUILD_APPS
-        if [ -z "$apps" ]; then
-            export PROMPT_COMMAND="echo -ne \"\033]0;[${arch}-${product}-${variant}] ${USER}@${HOSTNAME}: ${PWD}\007\""
-        else
-            export PROMPT_COMMAND="echo -ne \"\033]0;[$arch $apps $variant] ${USER}@${HOSTNAME}: ${PWD}\007\""
-        fi
-    fi
-}
-
 function addcompletions()
 {
     local T dir f
@@ -352,7 +331,6 @@
 
     for f in system/core/adb/adb.bash system/core/fastboot/fastboot.bash; do
         if [ -f $f ]; then
-            echo "including $f"
             . $f
         fi
     done
diff --git a/target/product/base.mk b/target/product/base.mk
index e778e76..74514af 100644
--- a/target/product/base.mk
+++ b/target/product/base.mk
@@ -18,7 +18,7 @@
 PRODUCT_PACKAGES += \
     20-dns.conf \
     95-configured \
-    org.apache.http.legacy.boot \
+    org.apache.http.legacy \
     appwidget \
     appops \
     am \
@@ -151,7 +151,9 @@
 
 # Packages included only for eng or userdebug builds, previously debug tagged
 PRODUCT_PACKAGES_DEBUG := \
+    iotop \
     logpersist.start \
+    micro_bench \
     perfprofd \
     sqlite3 \
     strace
diff --git a/target/product/core.mk b/target/product/core.mk
index bbc2b75..90e15db 100644
--- a/target/product/core.mk
+++ b/target/product/core.mk
@@ -46,7 +46,6 @@
     ManagedProvisioning \
     MtpDocumentsProvider \
     PacProcessor \
-    libpac \
     PrintSpooler \
     PrintRecommendationService \
     ProxyHandler \
diff --git a/target/product/core_minimal.mk b/target/product/core_minimal.mk
index 16599cb..8797248 100644
--- a/target/product/core_minimal.mk
+++ b/target/product/core_minimal.mk
@@ -116,7 +116,7 @@
     telephony-common \
     voip-common \
     ims-common \
-    org.apache.http.legacy.boot \
+    org.apache.http.legacy.impl \
     android.hidl.base-V1.0-java \
     android.hidl.manager-V1.0-java
 
diff --git a/target/product/core_tiny.mk b/target/product/core_tiny.mk
index 122f5c7..c6bc72c 100644
--- a/target/product/core_tiny.mk
+++ b/target/product/core_tiny.mk
@@ -103,7 +103,7 @@
     voip-common \
     ims-common \
     nullwebview \
-    org.apache.http.legacy.boot \
+    org.apache.http.legacy.impl \
     android.hidl.base-V1.0-java \
     android.hidl.manager-V1.0-java
 
diff --git a/target/product/treble_common.mk b/target/product/treble_common.mk
index 5352e77..7e0e2ae 100644
--- a/target/product/treble_common.mk
+++ b/target/product/treble_common.mk
@@ -76,15 +76,11 @@
 PRODUCT_COPY_FILES += \
     device/generic/common/nfc/libnfc-nci.conf:system/etc/libnfc-nci.conf
 
-# Support for the devices with no VNDK enforcing
+# Support for the O-MR1 devices
 PRODUCT_COPY_FILES += \
     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
+    build/make/target/product/vndk/init.vndk-27.rc:system/etc/init/gsi/init.vndk-27.rc
 
 # 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)
+    ld.config.vndk_lite.txt
diff --git a/target/product/vndk/init.gsi.rc b/target/product/vndk/init.gsi.rc
index 3e6b1fb..0150b1a 100644
--- a/target/product/vndk/init.gsi.rc
+++ b/target/product/vndk/init.gsi.rc
@@ -1,2 +1,2 @@
-# If ro.vndk.version is not defined, import init.noenforce.rc
-import /system/etc/init/gsi/init.${ro.vndk.version:-noenforce}.rc
+# If ro.vndk.version is not defined, import init.vndk-27.rc.
+import /system/etc/init/gsi/init.vndk-${ro.vndk.version:-27}.rc
diff --git a/target/product/vndk/init.noenforce.rc b/target/product/vndk/init.noenforce.rc
deleted file mode 100644
index 6cf1df7..0000000
--- a/target/product/vndk/init.noenforce.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-on early-init
-    # If ro.vndk.version is not set, use ld.config.nonenforce.txt
-    export LD_CONFIG_FILE /system/etc/ld.config.noenforce.txt
-    # To use current VNDK libs, set ro.vndk.version to system vndk version
-    setprop ro.vndk.version ${ro.gsi.vndk.version}
diff --git a/target/product/vndk/init.vndk-27.rc b/target/product/vndk/init.vndk-27.rc
new file mode 100644
index 0000000..d464a2f
--- /dev/null
+++ b/target/product/vndk/init.vndk-27.rc
@@ -0,0 +1,3 @@
+on early-init
+    # Set ro.vndk.version to 27 so that O-MR1-VENDOR can run latest GSI.
+    setprop ro.vndk.version 27
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/checkowners.py b/tools/checkowners.py
index 1190d30..54198a7 100755
--- a/tools/checkowners.py
+++ b/tools/checkowners.py
@@ -30,12 +30,11 @@
 
 def find_address(address):
   if address not in checked_addresses:
-    request = (gerrit_server + '/accounts/?n=1&o=ALL_EMAILS&q=email:'
+    request = (gerrit_server + '/accounts/?n=1&q=email:'
                + urllib.quote(address))
     echo('Checking email address: ' + address)
     result = urllib2.urlopen(request).read()
-    checked_addresses[address] = (
-        result.find('"email":') >= 0 and result.find('"_account_id":') >= 0)
+    checked_addresses[address] = result.find('"_account_id":') >= 0
   return checked_addresses[address]
 
 
diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk
index f946303..a01e702 100644
--- a/tools/fs_config/Android.mk
+++ b/tools/fs_config/Android.mk
@@ -254,7 +254,7 @@
 include $(BUILD_HEADER_LIBRARY)
 
 ##################################
-# Generate the system/etc/passwd text file for the target
+# Generate the vendor/etc/passwd text file for the target
 # This file may be empty if no AIDs are defined in
 # TARGET_FS_CONFIG_GEN files.
 include $(CLEAR_VARS)
@@ -270,10 +270,10 @@
 $(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
 $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config)
 	@mkdir -p $(dir $@)
-	$(hide) $< passwd --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(PRIVATE_TARGET_FS_CONFIG_GEN) > $@
+	$(hide) $< passwd --required-prefix=vendor_ --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(PRIVATE_TARGET_FS_CONFIG_GEN) > $@
 
 ##################################
-# Generate the system/etc/group text file for the target
+# Generate the vendor/etc/group text file for the target
 # This file may be empty if no AIDs are defined in
 # TARGET_FS_CONFIG_GEN files.
 include $(CLEAR_VARS)
@@ -289,7 +289,7 @@
 $(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
 $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config)
 	@mkdir -p $(dir $@)
-	$(hide) $< group --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(PRIVATE_TARGET_FS_CONFIG_GEN) > $@
+	$(hide) $< group --required-prefix=vendor_ --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(PRIVATE_TARGET_FS_CONFIG_GEN) > $@
 
 system_android_filesystem_config :=
 endif
diff --git a/tools/fs_config/fs_config_generator.py b/tools/fs_config/fs_config_generator.py
index d51d075..ed63c0e 100755
--- a/tools/fs_config/fs_config_generator.py
+++ b/tools/fs_config/fs_config_generator.py
@@ -1235,12 +1235,19 @@
             help='An android_filesystem_config.h file'
             'to parse AIDs and OEM Ranges from')
 
+        opt_group.add_argument(
+            '--required-prefix',
+            required=False,
+            help='A prefix that the names are required to contain.')
+
     def __call__(self, args):
 
         hdr_parser = AIDHeaderParser(args['aid_header'])
 
         parser = FSConfigFileParser(args['fsconfig'], hdr_parser.oem_ranges)
 
+        required_prefix = args['required_prefix']
+
         aids = parser.aids
 
         # nothing to do if no aids defined
@@ -1250,7 +1257,11 @@
         print PasswdGen._GENERATED
 
         for aid in aids:
-            self._print_formatted_line(aid)
+            if required_prefix is None or aid.friendly.startswith(required_prefix):
+                self._print_formatted_line(aid)
+            else:
+                sys.exit("%s: AID '%s' must start with '%s'" %
+                         (args['fsconfig'], aid.friendly, required_prefix))
 
     def _print_formatted_line(self, aid):
         """Prints the aid to stdout in the passwd format. Internal use only.
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index b6c26bf..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
 
@@ -1026,7 +1024,7 @@
       A string with placeholders for the metadata offset/size info, e.g.
       "payload.bin:679:343,payload_properties.txt:378:45,metadata:        ".
     """
-    return self._GetPropertyFilesString(input_zip, reserve_space=True)
+    return self.GetPropertyFilesString(input_zip, reserve_space=True)
 
   class InsufficientSpaceException(Exception):
     pass
@@ -1055,7 +1053,7 @@
       InsufficientSpaceException: If the reserved length is insufficient to hold
           the final string.
     """
-    result = self._GetPropertyFilesString(input_zip, reserve_space=False)
+    result = self.GetPropertyFilesString(input_zip, reserve_space=False)
     if len(result) > reserved_length:
       raise self.InsufficientSpaceException(
           'Insufficient reserved space: reserved={}, actual={}'.format(
@@ -1074,12 +1072,22 @@
     Raises:
       AssertionError: On finding a mismatch.
     """
-    actual = self._GetPropertyFilesString(input_zip)
+    actual = self.GetPropertyFilesString(input_zip)
     assert actual == expected, \
         "Mismatching streaming metadata: {} vs {}.".format(actual, expected)
 
-  def _GetPropertyFilesString(self, zip_file, reserve_space=False):
-    """Constructs the property-files string per request."""
+  def GetPropertyFilesString(self, zip_file, reserve_space=False):
+    """
+    Constructs the property-files string per request.
+
+    Args:
+      zip_file: The input ZIP file.
+      reserved_length: The reserved length of the property-files string.
+
+    Returns:
+      A property-files string including the metadata offset/size info, e.g.
+      "payload.bin:679:343,payload_properties.txt:378:45,metadata:     ".
+    """
 
     def ComputeEntryOffsetSize(name):
       """Computes the zip entry offset and size."""
@@ -1786,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":
@@ -1864,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 0eb24b5..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',
@@ -774,8 +750,7 @@
     zip_file = self.construct_zip_package(entries)
     property_files = TestPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
       streaming_metadata = property_files.Finalize(zip_fp, len(raw_metadata))
     tokens = self._parse_property_files_string(streaming_metadata)
@@ -798,8 +773,7 @@
     property_files = TestPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       # First get the raw metadata string (i.e. without padding space).
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
       raw_length = len(raw_metadata)
 
@@ -833,8 +807,7 @@
     property_files = TestPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       # First get the raw metadata string (i.e. without padding space).
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
 
       # Should pass the test if verification passes.
@@ -891,8 +864,7 @@
     zip_file = self.construct_zip_package(entries)
     property_files = StreamingPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
       streaming_metadata = property_files.Finalize(zip_fp, len(raw_metadata))
     tokens = self._parse_property_files_string(streaming_metadata)
@@ -915,8 +887,7 @@
     property_files = StreamingPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       # First get the raw metadata string (i.e. without padding space).
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
 
       # Should pass the test if verification passes.
@@ -1051,8 +1022,7 @@
     zip_file = self.construct_zip_package_withValidPayload(with_metadata=True)
     property_files = AbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
       property_files_string = property_files.Finalize(zip_fp, len(raw_metadata))
 
@@ -1067,8 +1037,7 @@
     zip_file = self.construct_zip_package_withValidPayload(with_metadata=True)
     property_files = AbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
 
       property_files.Verify(zip_fp, raw_metadata)
@@ -1101,8 +1070,7 @@
     zip_file = self.construct_zip_package(entries)
     property_files = NonAbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file) as zip_fp:
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
       property_files_string = property_files.Finalize(zip_fp, len(raw_metadata))
     tokens = self._parse_property_files_string(property_files_string)
@@ -1119,8 +1087,7 @@
     zip_file = self.construct_zip_package(entries)
     property_files = NonAbOtaPropertyFiles()
     with zipfile.ZipFile(zip_file) as zip_fp:
-      # pylint: disable=protected-access
-      raw_metadata = property_files._GetPropertyFilesString(
+      raw_metadata = property_files.GetPropertyFilesString(
           zip_fp, reserve_space=False)
 
       property_files.Verify(zip_fp, raw_metadata)
diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py
index e8cea29..886de26 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):
@@ -90,6 +90,12 @@
         logging.warning('Skipping %s that has incomplete block list', entry)
         continue
 
+      # TODO(b/79951650): Handle files with non-monotonic ranges.
+      if not ranges.monotonic:
+        logging.warning(
+            'Skipping %s that has non-monotonic ranges: %s', entry, ranges)
+        continue
+
       blocks_sha1 = image.RangeSha1(ranges)
 
       # The filename under unpacked directory, such as SYSTEM/bin/sh.
@@ -103,6 +109,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 +335,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) {