Merge changes from topic "vendor_property_enforce"

* changes:
  Set BUILD_BROKEN_VENDOR_PROPERTY_NAMESPACE for goldfish
  Add BUILD_BROKEN_VENDOR_PROPERTY_NAMESPACE to BoardConfig
  Add PRODUCT_SHIPPING_API_LEVEL to productVariables
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..ab2564e
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,49 @@
+//
+// Copyright (C) 2021 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 {
+    default_applicable_licenses: ["build_make_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+    name: "build_make_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+        "SPDX-license-identifier-BSD",
+        "SPDX-license-identifier-CC-BY",
+        "SPDX-license-identifier-GPL",
+        "SPDX-license-identifier-GPL-2.0",
+        "SPDX-license-identifier-LGPL",
+        "SPDX-license-identifier-MIT",
+        "legacy_not_a_contribution",
+        "legacy_restricted",
+    ],
+    // large-scale-change unable to identify any license_text files
+}
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..814cb00
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,8 @@
+third_party {
+  # would be NOTICE save for GPL in:
+  #   core/LINUX_KERNEL_COPYING
+  #   tools/droiddoc/templates-pdk/assets/jquery-1.6.2.min.js
+  #   tools/droiddoc/templates-pdk/assets/jquery-history.js
+  #   tools/droiddoc/templates-pdk/assets/jquery-resizable.min.js
+  license_type: RESTRICTED
+}
diff --git a/common/json.mk b/common/json.mk
index ba8ffa7..e376aab 100644
--- a/common/json.mk
+++ b/common/json.mk
@@ -24,7 +24,10 @@
 add_json_csv =$= $(call add_json_val,$(1),$(call csv_to_json_list,$(strip $(2))))
 add_json_bool =$= $(call add_json_val,$(1),$(if $(strip $(2)),true,false))
 add_json_map =$= $(eval _json_contents := $$(_json_contents)$$(_json_indent)"$$(strip $$(1))": {$$(newline))$(json_increase_indent)
+add_json_map_anon =$= $(eval _json_contents := $$(_json_contents)$$(_json_indent){$$(newline))$(json_increase_indent)
 end_json_map =$= $(json_decrease_indent)$(eval _json_contents := $$(_json_contents)$$(if $$(filter %$$(comma),$$(lastword $$(_json_contents))),__SV_END)$$(_json_indent)},$$(newline))
+add_json_array =$= $(eval _json_contents := $$(_json_contents)$$(_json_indent)"$$(strip $$(1))": [$$(newline))$(json_increase_indent)
+end_json_array =$= $(json_decrease_indent)$(eval _json_contents := $$(_json_contents)$$(if $$(filter %$$(comma),$$(lastword $$(_json_contents))),__SV_END)$$(_json_indent)],$$(newline))
 
 # Clears _json_contents to start a new json file
 json_start =$= $(eval _json_contents := {$$(newline))$(eval _json_indent := $$(4space))
diff --git a/core/Makefile b/core/Makefile
index 95bac40..a7553f0 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -230,7 +230,7 @@
 # $(7): module archive
 # $(8): staging dir for stripped modules
 # $(9): module directory name
-# Returns the a list of src:dest pairs to install the modules using copy-many-files.
+# Returns a list of src:dest pairs to install the modules using copy-many-files.
 define build-image-kernel-modules
   $(if $(9), \
     $(eval _dir := $(9)/), \
@@ -315,6 +315,26 @@
 	@echo '$$(strip $$(notdir $$(PRIVATE_LOAD_MODULES)))' | tr ' ' '\n' > $$(@)
 endef
 
+# $(1): source blocklist file
+# $(2): destination pathname
+# Returns a build rule that checks the syntax of and installs a kernel modules
+# blocklist file. Strip and squeeze any extra space in the blocklist.
+# For use via $(eval).
+define build-image-kernel-modules-blocklist-file
+$(2): $(1)
+	@echo "modprobe blocklist $$(@)"
+	$(hide) mkdir -p "$$(dir $$@)"
+	$(hide) rm -f "$$@"
+	$(hide) awk <"$$<" >"$$@" \
+	  '/^#/ { print; next } \
+	   NF == 0 { next } \
+	   NF != 2 || $$$$1 != "blocklist" \
+	     { print "Invalid blocklist line " FNR ": " $$$$0 >"/dev/stderr"; \
+	       exit_status = 1; next } \
+	   { $$$$1 = $$$$1; print } \
+	   END { exit exit_status }'
+endef
+
 # $(1): image name
 # $(2): build output directory (TARGET_OUT_VENDOR, TARGET_RECOVERY_ROOT_OUT, etc)
 # $(3): mount point
@@ -331,7 +351,12 @@
 $(if $(strip $(BOARD_$(1)_KERNEL_MODULES$(_sep)$(_kver))$(BOARD_$(1)_KERNEL_MODULES_ARCHIVE$(_sep)$(_kver))),\
   $(if $(BOARD_$(1)_KERNEL_MODULES_LOAD$(_sep)$(_kver)),,\
     $(eval BOARD_$(1)_KERNEL_MODULES_LOAD$(_sep)$(_kver) := $(BOARD_$(1)_KERNEL_MODULES$(_sep)$(_kver)))) \
-  $(call copy-many-files,$(call build-image-kernel-modules,$(BOARD_$(1)_KERNEL_MODULES$(_sep)$(_kver)),$(2),$(3),$(call intermediates-dir-for,PACKAGING,depmod_$(1)$(_sep)$(_kver)),$(BOARD_$(1)_KERNEL_MODULES_LOAD$(_sep)$(_kver)),$(4),$(BOARD_$(1)_KERNEL_MODULES_ARCHIVE$(_sep)$(_kver)),$(_stripped_staging_dir),$(_kver))))
+  $(call copy-many-files,$(call build-image-kernel-modules,$(BOARD_$(1)_KERNEL_MODULES$(_sep)$(_kver)),$(2),$(3),$(call intermediates-dir-for,PACKAGING,depmod_$(1)$(_sep)$(_kver)),$(BOARD_$(1)_KERNEL_MODULES_LOAD$(_sep)$(_kver)),$(4),$(BOARD_$(1)_KERNEL_MODULES_ARCHIVE$(_sep)$(_kver)),$(_stripped_staging_dir),$(_kver)))) \
+$(if $(BOARD_$(1)_KERNEL_MODULES_BLOCKLIST_FILE$(_sep)$(_kver)), \
+  $(eval $(call build-image-kernel-modules-blocklist-file, \
+    $(BOARD_$(1)_KERNEL_MODULES_BLOCKLIST_FILE$(_sep)$(_kver)), \
+    $(2)/lib/modules/modules.blocklist)) \
+  $(2)/lib/modules/modules.blocklist)
 endef
 
 # $(1): kernel module directory name (top is an out of band value for no directory)
@@ -4110,6 +4135,7 @@
   mksquashfsimage.sh \
   mkuserimg_mke2fs \
   ota_from_target_files \
+  repack_bootimg \
   sefcontext_compile \
   sgdisk \
   shflags \
@@ -5028,7 +5054,7 @@
 	@# help early validation of the .zip file while uploading it.
 	$(hide) find $(zip_root)/META | sort >$@.list
 	$(hide) find $(zip_root) -path $(zip_root)/META -prune -o -print | sort >>$@.list
-	$(hide) $(SOONG_ZIP) -d -o $@ -C $(zip_root) -l $@.list
+	$(hide) $(SOONG_ZIP) -d -o $@ -C $(zip_root) -r $@.list
 
 .PHONY: target-files-package
 target-files-package: $(BUILT_TARGET_FILES_PACKAGE)
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index 3a0c0f1..cc369a3 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -33,7 +33,23 @@
   $(call add_soong_config_namespace,art_module)
   SOONG_CONFIG_art_module += source_build
 endif
-SOONG_CONFIG_art_module_source_build ?= true
+ifneq (,$(findstring .android.art,$(TARGET_BUILD_APPS)))
+  # Build ART modules from source if they are listed in TARGET_BUILD_APPS.
+  SOONG_CONFIG_art_module_source_build := true
+else ifneq (,$(filter true,$(NATIVE_COVERAGE) $(CLANG_COVERAGE)))
+  # Always build ART APEXes from source in coverage builds since the prebuilts
+  # aren't built with instrumentation.
+  # TODO(b/172480617): Find another solution for this.
+  SOONG_CONFIG_art_module_source_build := true
+else ifneq (,$(SANITIZE_TARGET)$(SANITIZE_HOST))
+  # Prebuilts aren't built with sanitizers either.
+  SOONG_CONFIG_art_module_source_build := true
+else
+  # This sets the default for building ART APEXes from source rather than
+  # prebuilts (in packages/modules/ArtPrebuilt and prebuilt/module_sdk/art) in
+  # all other platform builds.
+  SOONG_CONFIG_art_module_source_build ?= true
+endif
 
 # Apex build mode variables
 ifdef APEX_BUILD_FOR_PRE_S_DEVICES
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 4fd8baa..68f880f 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -508,6 +508,7 @@
 ###########################################################
 
 my_init_rc_installed :=
+my_init_rc_path :=
 my_init_rc_pairs :=
 my_installed_symlinks :=
 my_default_test_module :=
@@ -534,7 +535,11 @@
 # Rule to install the module's companion init.rc.
 my_init_rc := $(LOCAL_INIT_RC_$(my_32_64_bit_suffix)) $(LOCAL_INIT_RC)
 ifneq ($(strip $(my_init_rc)),)
-my_init_rc_pairs := $(foreach rc,$(my_init_rc),$(LOCAL_PATH)/$(rc):$(TARGET_OUT$(partition_tag)_ETC)/init/$(notdir $(rc)))
+# Make doesn't support recovery as an output partition, but some Soong modules installed in recovery
+# have init.rc files that need to be installed alongside them. Manually handle the case where the
+# output file is in the recovery partition.
+my_init_rc_path := $(if $(filter $(TARGET_RECOVERY_ROOT_OUT)/%,$(my_module_path)),$(TARGET_RECOVERY_ROOT_OUT)/system/etc,$(TARGET_OUT$(partition_tag)_ETC))
+my_init_rc_pairs := $(foreach rc,$(my_init_rc),$(LOCAL_PATH)/$(rc):$(my_init_rc_path)/init/$(notdir $(rc)))
 my_init_rc_installed := $(foreach rc,$(my_init_rc_pairs),$(call word-colon,2,$(rc)))
 
 # Make sure we only set up the copy rules once, even if another arch variant
diff --git a/core/definitions.mk b/core/definitions.mk
index 033ab30..5f0bf55 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2138,6 +2138,17 @@
 $(hide) $(call commit-change-for-toc,$@)
 endef
 
+# Runs jarjar on an input file.  Jarjar doesn't exit with a nonzero return code
+# when there is a syntax error in a rules file and doesn't write the output
+# file, so removes the output file before running jarjar and check if it exists
+# after running jarjar.
+define transform-jarjar
+echo $($(PRIVATE_PREFIX)DISPLAY) JarJar: $@
+rm -f $@
+$(JAVA) -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+[ -e $@ ] || (echo "Missing output file"; exit 1)
+endef
+
 # Moves $1.tmp to $1 if necessary. This is designed to be used with
 # .KATI_RESTAT. For kati, this function doesn't update the timestamp
 # of $1 when $1.tmp is identical to $1 so that ninja won't rebuild
diff --git a/core/dex_preopt_config_merger.py b/core/dex_preopt_config_merger.py
index ebb99e1..4efcc17 100755
--- a/core/dex_preopt_config_merger.py
+++ b/core/dex_preopt_config_merger.py
@@ -67,26 +67,25 @@
   # the loop in case this changes in the future.
   for sdk_ver in clc_map:
     clcs = clc_map[sdk_ver]
-    clcs2 = OrderedDict()
-    for lib in clcs:
-      clc = clcs[lib]
+    clcs2 = []
+    for clc in clcs:
+      lib = clc['Name']
       if lib in uses_libs:
         ulib = uses_libs[lib]
-        # On-host (build) path to the dependency DEX jar file.
-        clc['Host'] = ulib['BuildPath']
+        # The real <uses-library> name (may be different from the module name).
+        clc['Name'] = ulib['ProvidesUsesLibrary']
         # On-device (install) path to the dependency DEX jar file.
         clc['Device'] = ulib['DexLocation']
         # CLC of the dependency becomes a subcontext. We only need sub-CLC for
         # 'any' version because all other versions are for compatibility
         # libraries, which exist only for apps and not for libraries.
         clc['Subcontexts'] = ulib['ClassLoaderContexts'].get('any')
-        # Patch the library name in the CLC as well.
-        clcs2[ulib['ProvidesUsesLibrary']] = clc
       else:
         # dexpreopt.config for this <uses-library> is not among the script
         # arguments, which may be the case with compatibility libraries that
         # don't need patching anyway. Just use the original CLC.
-        clcs2[lib] = clc
+        pass
+      clcs2.append(clc)
     clc_map2[sdk_ver] = clcs2
 
   # Overwrite the original class loader context with the patched one.
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index 084b302..f9a9ba7 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -189,6 +189,16 @@
   my_filtered_optional_uses_libraries := $(filter-out $(INTERNAL_PLATFORM_MISSING_USES_LIBRARIES), \
     $(LOCAL_OPTIONAL_USES_LIBRARIES))
 
+  # TODO(b/132357300): This may filter out too much, as PRODUCT_PACKAGES doesn't
+  # include all packages (the full list is unknown until reading all Android.mk
+  # makefiles). As a consequence, a library may be present but not included in
+  # dexpreopt, which will result in class loader context mismatch and a failure
+  # to load dexpreopt code on device. We should fix this, either by deferring
+  # dependency computation until the full list of product packages is known, or
+  # by adding product-specific lists of missing libraries.
+  my_filtered_optional_uses_libraries := $(filter $(PRODUCT_PACKAGES), \
+    $(my_filtered_optional_uses_libraries))
+
   ifeq ($(LOCAL_MODULE_CLASS),APPS)
     # compatibility libraries are added to class loader context of an app only if
     # targetSdkVersion in the app's manifest is lower than the given SDK version
@@ -212,10 +222,9 @@
     my_dexpreopt_libs_compat :=
   endif
 
-  my_dexpreopt_libs := $(sort \
+  my_dexpreopt_libs := \
     $(LOCAL_USES_LIBRARIES) \
-    $(my_filtered_optional_uses_libraries) \
-  )
+    $(my_filtered_optional_uses_libraries)
 
   # 1: SDK version
   # 2: list of libraries
@@ -233,14 +242,15 @@
   # which are special and not handled by dex_preopt_config_merger.py.
   #
   add_json_class_loader_context = \
-    $(call add_json_map, $(1)) \
+    $(call add_json_array, $(1)) \
     $(foreach lib, $(2),\
-      $(call add_json_map, $(lib)) \
+      $(call add_json_map_anon) \
+      $(call add_json_str, Name, $(lib)) \
       $(call add_json_str, Host, $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar) \
       $(call add_json_str, Device, /system/framework/$(lib).jar) \
-      $(call add_json_map, Subcontexts, ${$}) $(call end_json_map) \
+      $(call add_json_val, Subcontexts, null) \
       $(call end_json_map)) \
-    $(call end_json_map)
+    $(call end_json_array)
 
   # Record dex-preopt config.
   DEXPREOPT.$(LOCAL_MODULE).DEX_PREOPT := $(LOCAL_DEX_PREOPT)
diff --git a/core/host_dalvik_java_library.mk b/core/host_dalvik_java_library.mk
index da32978..5eeb8ac 100644
--- a/core/host_dalvik_java_library.mk
+++ b/core/host_dalvik_java_library.mk
@@ -125,8 +125,7 @@
 ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
 $(full_classes_header_jarjar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
 $(full_classes_header_jarjar): $(full_classes_turbine_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
-	@echo Header JarJar: $@
-	$(hide) $(JAVA) -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+	$(call transform-jarjar)
 else
 full_classes_header_jarjar := $(full_classes_turbine_jar)
 endif
@@ -149,8 +148,7 @@
 ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
 $(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
 $(full_classes_jarjar_jar): $(full_classes_combined_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
-	@echo JarJar: $@
-	$(hide) $(JAVA) -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+	$(call transform-jarjar)
 else
 full_classes_jarjar_jar := $(full_classes_combined_jar)
 endif
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index f9abe9b..0f95202 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -113,8 +113,7 @@
 ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
 $(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
 $(full_classes_jarjar_jar): $(full_classes_combined_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
-	@echo JarJar: $@
-	$(hide) $(JAVA) -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+	$(call transform-jarjar)
 else
 full_classes_jarjar_jar := $(full_classes_combined_jar)
 endif
diff --git a/core/java.mk b/core/java.mk
index 5fe8da5..d28c0c4 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -253,8 +253,7 @@
 ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
 $(full_classes_header_jarjar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
 $(full_classes_header_jarjar): $(full_classes_turbine_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
-	@echo Header JarJar: $@
-	$(hide) $(JAVA) -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+	$(call transform-jarjar)
 else
 full_classes_header_jarjar := $(full_classes_turbine_jar)
 endif
@@ -334,8 +333,7 @@
 ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
 $(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
 $(full_classes_jarjar_jar): $(full_classes_processed_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
-	@echo JarJar: $@
-	$(hide) $(JAVA) -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+	$(call transform-jarjar)
 else
 full_classes_jarjar_jar := $(full_classes_processed_jar)
 endif
diff --git a/core/main.mk b/core/main.mk
index 5ea95c8..2c78815 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -83,6 +83,8 @@
 -include test/vts/tools/vts-core-tradefed/build/config.mk
 # CSUITE-specific config.
 -include test/app_compat/csuite/tools/build/config.mk
+# CTS-Root-specific config.
+-include test/cts-root/tools/build/config.mk
 
 # Clean rules
 .PHONY: clean-dex-files
diff --git a/core/soong_config.mk b/core/soong_config.mk
index a4b87ea..1569300 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -153,13 +153,18 @@
   $(call add_json_bool,$(module),true))
 $(call end_json_map)
 
+$(call add_json_bool, DirectedRecoverySnapshot,          $(DIRECTED_RECOVERY_SNAPSHOT))
+$(call add_json_map,  RecoverySnapshotModules)
+$(foreach module,$(RECOVERY_SNAPSHOT_MODULES),\
+  $(call add_json_bool,$(module),true))
+$(call end_json_map)
+
 $(call add_json_bool, Treble_linker_namespaces,          $(filter true,$(PRODUCT_TREBLE_LINKER_NAMESPACES)))
 $(call add_json_bool, Enforce_vintf_manifest,            $(filter true,$(PRODUCT_ENFORCE_VINTF_MANIFEST)))
 
 $(call add_json_bool, Check_elf_files,                   $(filter true,$(PRODUCT_CHECK_ELF_FILES)))
 
 $(call add_json_bool, Uml,                               $(filter true,$(TARGET_USER_MODE_LINUX)))
-$(call add_json_bool, Use_lmkd_stats_log,                $(filter true,$(TARGET_LMKD_STATS_LOG)))
 $(call add_json_str,  VendorPath,                        $(TARGET_COPY_OUT_VENDOR))
 $(call add_json_str,  OdmPath,                           $(TARGET_COPY_OUT_ODM))
 $(call add_json_str,  VendorDlkmPath,                    $(TARGET_COPY_OUT_VENDOR_DLKM))
diff --git a/core/tasks/cts_root.mk b/core/tasks/cts_root.mk
new file mode 100644
index 0000000..b618121
--- /dev/null
+++ b/core/tasks/cts_root.mk
@@ -0,0 +1,25 @@
+# Copyright (C) 2021 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.
+
+ifneq ($(wildcard test/cts-root/README.md),)
+test_suite_name := cts_root
+test_suite_tradefed := cts-root-tradefed
+test_suite_readme := test/cts-root/README.md
+
+include $(BUILD_SYSTEM)/tasks/tools/compatibility.mk
+
+.PHONY: cts_root
+cts_root: $(compatibility_zip)
+$(call dist-for-goals, cts_root, $(compatibility_zip))
+endif
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index fe90165..0c91a14 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -240,7 +240,7 @@
     #  It must be of the form "YYYY-MM-DD" on production devices.
     #  It must match one of the Android Security Patch Level strings of the Public Security Bulletins.
     #  If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
-      PLATFORM_SECURITY_PATCH := 2021-01-05
+      PLATFORM_SECURITY_PATCH := 2021-02-05
 endif
 .KATI_READONLY := PLATFORM_SECURITY_PATCH
 
diff --git a/target/board/Android.mk b/target/board/Android.mk
index 9edc85c..4dd6b17 100644
--- a/target/board/Android.mk
+++ b/target/board/Android.mk
@@ -35,6 +35,8 @@
 # $(DEVICE_MANIFEST_FILE) can be a list of files
 include $(CLEAR_VARS)
 LOCAL_MODULE        := vendor_manifest.xml
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
 LOCAL_MODULE_STEM   := manifest.xml
 LOCAL_MODULE_CLASS  := ETC
 LOCAL_MODULE_PATH   := $(TARGET_OUT_VENDOR)/etc/vintf
@@ -65,6 +67,8 @@
 my_fragment_files := $$($$(my_fragment_files_var))
 include $$(CLEAR_VARS)
 LOCAL_MODULE := vendor_manifest_$(1).xml
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
 LOCAL_MODULE_STEM := manifest_$(1).xml
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_PATH   := $(TARGET_OUT_VENDOR)/etc/vintf
@@ -94,6 +98,8 @@
 # ODM_MANIFEST_FILES is a list of files that is combined and installed as the default ODM manifest.
 include $(CLEAR_VARS)
 LOCAL_MODULE := odm_manifest.xml
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
 LOCAL_MODULE_STEM := manifest.xml
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_RELATIVE_PATH := vintf
@@ -124,6 +130,8 @@
 my_fragment_files := $$($$(my_fragment_files_var))
 include $$(CLEAR_VARS)
 LOCAL_MODULE := odm_manifest_$(1).xml
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
 LOCAL_MODULE_STEM := manifest_$(1).xml
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_RELATIVE_PATH := vintf
diff --git a/target/board/module_arm64/device.mk b/target/board/module_arm64/device.mk
deleted file mode 100644
index 0d4c543..0000000
--- a/target/board/module_arm64/device.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (C) 2020 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.
-#
-
-$(call inherit-product, build/make/target/product/default_art_config.mk)
-$(call inherit-product, build/make/target/product/core_64_bit.mk)
-$(call inherit-product, build/make/target/product/languages_default.mk)
diff --git a/target/board/module_x86/device.mk b/target/board/module_x86/device.mk
deleted file mode 100644
index cceb987..0000000
--- a/target/board/module_x86/device.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (C) 2020 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.
-#
-
-$(call inherit-product, build/make/target/product/default_art_config.mk)
-$(call inherit-product, build/make/target/product/languages_default.mk)
diff --git a/target/board/module_x86_64/device.mk b/target/board/module_x86_64/device.mk
deleted file mode 100644
index 0d4c543..0000000
--- a/target/board/module_x86_64/device.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (C) 2020 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.
-#
-
-$(call inherit-product, build/make/target/product/default_art_config.mk)
-$(call inherit-product, build/make/target/product/core_64_bit.mk)
-$(call inherit-product, build/make/target/product/languages_default.mk)
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index c7ae1f0..5238d40 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -400,4 +400,8 @@
 PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
     frameworks/base/config/dirty-image-objects:system/etc/dirty-image-objects)
 
+# This property allows enabling Keystore 2.0 selectively for testing.
+# TODO Remove when Keystore 2.0 migration is complete. b/171563717
+PRODUCT_SYSTEM_PROPERTIES += persist.android.security.keystore2.enable=false
+
 $(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk)
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index 131ba31..1545780 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -36,7 +36,8 @@
     com.android.permission:framework-permission \
     com.android.sdkext:framework-sdkextensions \
     com.android.wifi:framework-wifi \
-    com.android.tethering:framework-tethering
+    com.android.tethering:framework-tethering \
+    com.android.ipsec:android.net.ipsec.ike
 
 # Add the compatibility library that is needed when android.test.base
 # is removed from the bootclasspath.
diff --git a/target/product/gsi/Android.bp b/target/product/gsi/Android.bp
index b7ce86e..88472eb 100644
--- a/target/product/gsi/Android.bp
+++ b/target/product/gsi/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "build_make_license"
+    // to get the below license kinds:
+    //   legacy_restricted
+    default_applicable_licenses: ["build_make_license"],
+}
+
 filegroup {
     name: "vndk_lib_lists",
     srcs: [
diff --git a/target/product/gsi/Android.mk b/target/product/gsi/Android.mk
index f21fe16..ecce01a 100644
--- a/target/product/gsi/Android.mk
+++ b/target/product/gsi/Android.mk
@@ -63,6 +63,8 @@
 # Script to update the latest VNDK lib list
 include $(CLEAR_VARS)
 LOCAL_MODULE := update-vndk-list.sh
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := EXECUTABLES
 LOCAL_MODULE_STEM := $(LOCAL_MODULE)
 LOCAL_IS_HOST_MODULE := true
@@ -146,6 +148,8 @@
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := vndk_package
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 # Filter LLNDK libs moved to APEX to avoid pulling them into /system/LIB
 LOCAL_REQUIRED_MODULES := \
     $(filter-out $(LLNDK_MOVED_TO_APEX_LIBRARIES),$(LLNDK_LIBRARIES))
@@ -169,6 +173,8 @@
 	_vndk_versions += $(BOARD_VNDK_VERSION)
 endif
 LOCAL_MODULE := vndk_apex_snapshot_package
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_REQUIRED_MODULES := $(foreach vndk_ver,$(_vndk_versions),com.android.vndk.v$(vndk_ver))
 include $(BUILD_PHONY_PACKAGE)
 
@@ -181,6 +187,8 @@
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := gsi_skip_mount.cfg
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_STEM := skip_mount.cfg
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
 LOCAL_MODULE_CLASS := ETC
@@ -204,6 +212,8 @@
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := init.gsi.rc
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
 LOCAL_MODULE_CLASS := ETC
 LOCAL_SYSTEM_EXT_MODULE := true
@@ -214,6 +224,8 @@
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := init.vndk-nodef.rc
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
 LOCAL_MODULE_CLASS := ETC
 LOCAL_SYSTEM_EXT_MODULE := true
diff --git a/target/product/gsi/current.txt b/target/product/gsi/current.txt
index 2ca6687..717d990 100644
--- a/target/product/gsi/current.txt
+++ b/target/product/gsi/current.txt
@@ -96,6 +96,9 @@
 VNDK-core: android.hardware.oemlock-unstable-ndk_platform.so
 VNDK-core: android.hardware.power-V1-ndk_platform.so
 VNDK-core: android.hardware.power-ndk_platform.so
+VNDK-core: android.hardware.power.stats-V1-ndk_platform.so
+VNDK-core: android.hardware.power.stats-ndk_platform.so
+VNDK-core: android.hardware.power.stats-unstable-ndk_platform.so
 VNDK-core: android.hardware.rebootescrow-V1-ndk_platform.so
 VNDK-core: android.hardware.rebootescrow-ndk_platform.so
 VNDK-core: android.hardware.security.keymint-V1-ndk_platform.so
diff --git a/target/product/gsi_release.mk b/target/product/gsi_release.mk
index 2c74ce0..25716ce 100644
--- a/target/product/gsi_release.mk
+++ b/target/product/gsi_release.mk
@@ -34,6 +34,9 @@
 # Split selinux policy
 PRODUCT_FULL_TREBLE_OVERRIDE := true
 
+# Enable dynamic partitions to facilitate mixing onto Cuttlefish
+PRODUCT_USE_DYNAMIC_PARTITIONS := true
+
 # Enable dynamic partition size
 PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
 
diff --git a/target/product/media_system.mk b/target/product/media_system.mk
index 4ebec51..143131e 100644
--- a/target/product/media_system.mk
+++ b/target/product/media_system.mk
@@ -58,7 +58,6 @@
 # The values should be of the format <apex name>:<jar name>
 PRODUCT_UPDATABLE_SYSTEM_SERVER_JARS := \
     com.android.permission:service-permission \
-    com.android.ipsec:android.net.ipsec.ike \
 
 PRODUCT_COPY_FILES += \
     system/core/rootdir/etc/public.libraries.android.txt:system/etc/public.libraries.txt
diff --git a/target/product/module_arm.mk b/target/product/module_arm.mk
index 09ccf5f..d99dce8 100644
--- a/target/product/module_arm.mk
+++ b/target/product/module_arm.mk
@@ -14,7 +14,7 @@
 # limitations under the License.
 #
 
-$(call inherit-product, $(SRC_TARGET_DIR)/board/module_arm/device.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/module_common.mk)
 
 PRODUCT_NAME := module_arm
 PRODUCT_BRAND := Android
diff --git a/target/product/module_arm64.mk b/target/product/module_arm64.mk
index 468c9db..fc9529c 100644
--- a/target/product/module_arm64.mk
+++ b/target/product/module_arm64.mk
@@ -14,7 +14,8 @@
 # limitations under the License.
 #
 
-$(call inherit-product, $(SRC_TARGET_DIR)/board/module_arm64/device.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/module_common.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
 
 PRODUCT_NAME := module_arm64
 PRODUCT_BRAND := Android
diff --git a/target/board/module_arm/device.mk b/target/product/module_common.mk
similarity index 75%
rename from target/board/module_arm/device.mk
rename to target/product/module_common.mk
index cceb987..eedd479 100644
--- a/target/board/module_arm/device.mk
+++ b/target/product/module_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2020 The Android Open Source Project
+# Copyright (C) 2021 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.
@@ -14,5 +14,5 @@
 # limitations under the License.
 #
 
-$(call inherit-product, build/make/target/product/default_art_config.mk)
-$(call inherit-product, build/make/target/product/languages_default.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/default_art_config.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/languages_default.mk)
diff --git a/target/product/module_x86.mk b/target/product/module_x86.mk
index dec4aed..b852e7a 100644
--- a/target/product/module_x86.mk
+++ b/target/product/module_x86.mk
@@ -14,7 +14,7 @@
 # limitations under the License.
 #
 
-$(call inherit-product, $(SRC_TARGET_DIR)/board/module_x86/device.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/module_common.mk)
 
 PRODUCT_NAME := module_x86
 PRODUCT_BRAND := Android
diff --git a/target/product/module_x86_64.mk b/target/product/module_x86_64.mk
index 5fabade..f6bc1fc 100644
--- a/target/product/module_x86_64.mk
+++ b/target/product/module_x86_64.mk
@@ -14,7 +14,8 @@
 # limitations under the License.
 #
 
-$(call inherit-product, $(SRC_TARGET_DIR)/board/module_x86_64/device.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/module_common.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
 
 PRODUCT_NAME := module_x86_64
 PRODUCT_BRAND := Android
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index e655d51..d3da8fe 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -56,17 +56,18 @@
 ifeq (eng,$(TARGET_BUILD_VARIANT))
     PRODUCT_SYSTEM_PROPERTIES += \
         pm.dexopt.first-boot?=extract \
-        pm.dexopt.boot?=extract
+        pm.dexopt.boot-after-ota?=extract
 else
     PRODUCT_SYSTEM_PROPERTIES += \
-        pm.dexopt.first-boot?=quicken \
-        pm.dexopt.boot?=verify
+        pm.dexopt.first-boot?=verify \
+        pm.dexopt.boot-after-ota?=verify
 endif
 
 # The install filter is speed-profile in order to enable the use of
 # profiles from the dex metadata files. Note that if a profile is not provided
 # or if it is empty speed-profile is equivalent to (quicken + empty app image).
 PRODUCT_SYSTEM_PROPERTIES += \
+    pm.dexopt.post-boot?=extract \
     pm.dexopt.install?=speed-profile \
     pm.dexopt.install-fast?=skip \
     pm.dexopt.install-bulk?=speed-profile \
diff --git a/target/product/security/Android.bp b/target/product/security/Android.bp
index 5f4f82b..98698c5 100644
--- a/target/product/security/Android.bp
+++ b/target/product/security/Android.bp
@@ -1,4 +1,13 @@
 // AOSP test certificate
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "build_make_license"
+    // to get the below license kinds:
+    //   legacy_restricted
+    default_applicable_licenses: ["build_make_license"],
+}
+
 android_app_certificate {
     name: "aosp-testkey",
     certificate: "testkey",
diff --git a/target/product/security/Android.mk b/target/product/security/Android.mk
index d6a8b53..83f0a4b 100644
--- a/target/product/security/Android.mk
+++ b/target/product/security/Android.mk
@@ -5,6 +5,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := verity_key
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
@@ -24,6 +26,8 @@
 ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
   include $(CLEAR_VARS)
   LOCAL_MODULE := verity_key_ramdisk
+  LOCAL_LICENSE_KINDS := legacy_restricted
+  LOCAL_LICENSE_CONDITIONS := restricted
   LOCAL_MODULE_CLASS := ETC
   LOCAL_SRC_FILES := verity_key
   LOCAL_MODULE_STEM := verity_key
@@ -37,6 +41,8 @@
   ifneq ($(filter eng userdebug,$(TARGET_BUILD_VARIANT)),)
     include $(CLEAR_VARS)
     LOCAL_MODULE := adb_keys
+    LOCAL_LICENSE_KINDS := legacy_restricted
+    LOCAL_LICENSE_CONDITIONS := restricted
     LOCAL_MODULE_CLASS := ETC
     LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
     LOCAL_PREBUILT_MODULE_FILE := $(PRODUCT_ADB_KEYS)
@@ -51,6 +57,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := otacerts
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_STEM := otacerts.zip
 LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/security
@@ -65,6 +73,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := otacerts.recovery
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_STEM := otacerts.zip
 LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/etc/security
diff --git a/target/product/sysconfig/Android.bp b/target/product/sysconfig/Android.bp
index 5632d17..29122e4 100644
--- a/target/product/sysconfig/Android.bp
+++ b/target/product/sysconfig/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 prebuilt_etc {
     name: "preinstalled-packages-platform-aosp-product.xml",
     product_specific: true,
@@ -30,4 +34,4 @@
     product_specific: true,
     sub_dir: "sysconfig",
     src: "preinstalled-packages-platform-handheld-product.xml",
-}
\ No newline at end of file
+}
diff --git a/tools/Android.bp b/tools/Android.bp
index e0f3739..269e610 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -12,6 +12,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "build_make_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-BSD
+    //   SPDX-license-identifier-CC-BY
+    //   SPDX-license-identifier-GPL
+    //   SPDX-license-identifier-MIT
+    default_applicable_licenses: ["build_make_license"],
+}
+
 python_binary_host {
   name: "generate-self-extracting-archive",
   srcs: ["generate-self-extracting-archive.py"],
@@ -62,10 +75,10 @@
   srcs: ["extract_kernel.py"],
   version: {
     py2: {
-      enabled: true,
+      enabled: false,
     },
     py3: {
-      enabled: false,
+      enabled: true,
     },
   },
 }
diff --git a/tools/acp/Android.bp b/tools/acp/Android.bp
index 64f5a10..78738b0 100644
--- a/tools/acp/Android.bp
+++ b/tools/acp/Android.bp
@@ -2,6 +2,15 @@
 //
 // Custom version of cp.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "build_make_license"
+    // to get the below license kinds:
+    //   legacy_restricted
+    default_applicable_licenses: ["build_make_license"],
+}
+
 cc_binary_host {
 
     srcs: ["acp.c"],
diff --git a/tools/apicheck/Android.bp b/tools/apicheck/Android.bp
index 8fe20e9..f58042f 100644
--- a/tools/apicheck/Android.bp
+++ b/tools/apicheck/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 java_binary_host {
     name: "apicheck",
     wrapper: "etc/apicheck",
diff --git a/tools/atree/Android.bp b/tools/atree/Android.bp
index 5fbe042..7906d8b 100644
--- a/tools/atree/Android.bp
+++ b/tools/atree/Android.bp
@@ -2,6 +2,15 @@
 //
 // Copies files into the directory structure described by a manifest
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "build_make_license"
+    // to get the below license kinds:
+    //   legacy_restricted
+    default_applicable_licenses: ["build_make_license"],
+}
+
 cc_binary_host {
     name: "atree",
     srcs: [
diff --git a/tools/droiddoc/Android.bp b/tools/droiddoc/Android.bp
index 0428068..efd30c1 100644
--- a/tools/droiddoc/Android.bp
+++ b/tools/droiddoc/Android.bp
@@ -12,6 +12,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "build_make_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-BSD
+    //   SPDX-license-identifier-CC-BY
+    //   SPDX-license-identifier-GPL
+    //   SPDX-license-identifier-MIT
+    default_applicable_licenses: ["build_make_license"],
+}
+
 droiddoc_exported_dir {
     name: "droiddoc-templates-pdk",
     path: "templates-pdk",
diff --git a/tools/extract_kernel.py b/tools/extract_kernel.py
index 0046b38..44fbcdf 100755
--- a/tools/extract_kernel.py
+++ b/tools/extract_kernel.py
@@ -39,12 +39,12 @@
 # "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
 # LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
 LINUX_BANNER_PREFIX = b'Linux version '
-LINUX_BANNER_REGEX = LINUX_BANNER_PREFIX + \
+LINUX_BANNER_REGEX = LINUX_BANNER_PREFIX.decode() + \
     r'(?P<release>(?P<version>[0-9]+[.][0-9]+[.][0-9]+).*) \(.*@.*\) \((?P<compiler>.*)\) .*\n'
 
 
 def get_from_release(input_bytes, start_idx, key):
-  null_idx = input_bytes.find('\x00', start_idx)
+  null_idx = input_bytes.find(b'\x00', start_idx)
   if null_idx < 0:
     return None
   try:
@@ -69,7 +69,7 @@
 
     value = get_from_release(input_bytes, idx, key)
     if value:
-      return value
+      return value.encode()
 
     idx += len(LINUX_BANNER_PREFIX)
 
@@ -140,7 +140,7 @@
   while True:
     idx = input_bytes.find(search_bytes, idx)
     if idx < 0:
-      raise StopIteration()
+      return
 
     yield try_decompress_bytes(cmd, input_bytes[idx:])
     idx += 1
@@ -183,6 +183,11 @@
       return False
   return True
 
+def to_bytes_io(b):
+  """
+  Make b, which is either sys.stdout or sys.stdin, receive bytes as arguments.
+  """
+  return b.buffer if sys.version_info.major == 3 else b
 
 def main():
   parser = argparse.ArgumentParser(
@@ -194,35 +199,35 @@
                       help='Input kernel image. If not specified, use stdin',
                       metavar='FILE',
                       type=argparse.FileType('rb'),
-                      default=sys.stdin)
+                      default=to_bytes_io(sys.stdin))
   parser.add_argument('--output-configs',
                       help='If specified, write configs. Use stdout if no file '
                            'is specified.',
                       metavar='FILE',
                       nargs='?',
                       type=argparse.FileType('wb'),
-                      const=sys.stdout)
+                      const=to_bytes_io(sys.stdout))
   parser.add_argument('--output-version',
                       help='If specified, write version. Use stdout if no file '
                            'is specified.',
                       metavar='FILE',
                       nargs='?',
                       type=argparse.FileType('wb'),
-                      const=sys.stdout)
+                      const=to_bytes_io(sys.stdout))
   parser.add_argument('--output-release',
                       help='If specified, write kernel release. Use stdout if '
                            'no file is specified.',
                       metavar='FILE',
                       nargs='?',
                       type=argparse.FileType('wb'),
-                      const=sys.stdout)
+                      const=to_bytes_io(sys.stdout))
   parser.add_argument('--output-compiler',
                       help='If specified, write the compiler information. Use stdout if no file '
                            'is specified.',
                       metavar='FILE',
                       nargs='?',
                       type=argparse.FileType('wb'),
-                      const=sys.stdout)
+                      const=to_bytes_io(sys.stdout))
   parser.add_argument('--tools',
                       help='Decompression tools to use. If not specified, PATH '
                            'is searched.',
diff --git a/tools/fs_config/Android.bp b/tools/fs_config/Android.bp
index 1dd5e4a..4544e07 100644
--- a/tools/fs_config/Android.bp
+++ b/tools/fs_config/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "build_make_license"
+    // to get the below license kinds:
+    //   legacy_restricted
+    default_applicable_licenses: ["build_make_license"],
+}
+
 bootstrap_go_package {
     name: "soong-fs_config",
     pkgPath: "android/soong/fs_config",
diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk
index c338462..10d25e0 100644
--- a/tools/fs_config/Android.mk
+++ b/tools/fs_config/Android.mk
@@ -42,6 +42,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := fs_config_dirs
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_REQUIRED_MODULES := \
   fs_config_dirs_system \
   fs_config_dirs_system_ext \
@@ -55,6 +57,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := fs_config_files
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_REQUIRED_MODULES := \
   fs_config_files_system \
   fs_config_files_system_ext \
@@ -69,6 +73,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := fs_config_dirs_system_ext
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_SYSTEM_EXTIMAGE)$(BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE),_fs_config_dirs_system_ext)
 include $(BUILD_PHONY_PACKAGE)
 
@@ -79,6 +85,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := fs_config_files_system_ext
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_SYSTEM_EXTIMAGE)$(BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE),_fs_config_files_system_ext)
 include $(BUILD_PHONY_PACKAGE)
 
@@ -89,6 +97,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := fs_config_dirs_product
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_PRODUCTIMAGE)$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),_fs_config_dirs_product)
 include $(BUILD_PHONY_PACKAGE)
 
@@ -99,6 +109,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := fs_config_files_product
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_PRODUCTIMAGE)$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),_fs_config_files_product)
 include $(BUILD_PHONY_PACKAGE)
 
@@ -109,6 +121,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := fs_config_dirs_nonsystem
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),_fs_config_dirs_$(t))
 include $(BUILD_PHONY_PACKAGE)
 
@@ -119,6 +133,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := fs_config_files_nonsystem
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),_fs_config_files_$(t))
 include $(BUILD_PHONY_PACKAGE)
 
@@ -129,6 +145,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := fs_config_dirs_system
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
 include $(BUILD_SYSTEM)/base_rules.mk
@@ -154,6 +172,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := fs_config_files_system
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_files
 include $(BUILD_SYSTEM)/base_rules.mk
@@ -180,6 +200,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_dirs_vendor
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
 LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc
@@ -204,6 +226,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_files_vendor
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_files
 LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc
@@ -231,6 +255,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_dirs_oem
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
 LOCAL_MODULE_PATH := $(TARGET_OUT_OEM)/etc
@@ -255,6 +281,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_files_oem
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_files
 LOCAL_MODULE_PATH := $(TARGET_OUT_OEM)/etc
@@ -282,6 +310,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_dirs_odm
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
 LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc
@@ -306,6 +336,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_files_odm
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_files
 LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc
@@ -333,6 +365,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_dirs_vendor_dlkm
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
 LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_DLKM)/etc
@@ -357,6 +391,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_files_vendor_dlkm
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_files
 LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_DLKM)/etc
@@ -384,6 +420,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_dirs_odm_dlkm
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
 LOCAL_MODULE_PATH := $(TARGET_OUT_ODM_DLKM)/etc
@@ -408,6 +446,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_files_odm_dlkm
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_files
 LOCAL_MODULE_PATH := $(TARGET_OUT_ODM_DLKM)/etc
@@ -435,6 +475,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_dirs_product
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
 LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/etc
@@ -459,6 +501,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_files_product
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_files
 LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/etc
@@ -485,6 +529,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_dirs_system_ext
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
 LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_EXT)/etc
@@ -509,6 +555,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := _fs_config_files_system_ext
+LOCAL_LICENSE_KINDS := legacy_restricted
+LOCAL_LICENSE_CONDITIONS := restricted
 LOCAL_MODULE_CLASS := ETC
 LOCAL_INSTALLED_MODULE_STEM := fs_config_files
 LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_EXT)/etc
diff --git a/tools/fs_get_stats/Android.bp b/tools/fs_get_stats/Android.bp
index 67742b8..9457de4 100644
--- a/tools/fs_get_stats/Android.bp
+++ b/tools/fs_get_stats/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "build_make_license"
+    // to get the below license kinds:
+    //   legacy_restricted
+    default_applicable_licenses: ["build_make_license"],
+}
+
 cc_binary_host {
     name: "fs_get_stats",
     srcs: ["fs_get_stats.c"],
diff --git a/tools/libhost/Android.bp b/tools/libhost/Android.bp
index 4c9100f..a83f2e7 100644
--- a/tools/libhost/Android.bp
+++ b/tools/libhost/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "build_make_license"
+    // to get the below license kinds:
+    //   legacy_restricted
+    default_applicable_licenses: ["build_make_license"],
+}
+
 cc_library_host_static {
 
     srcs: ["CopyFile.c"],
diff --git a/tools/product_config/Android.bp b/tools/product_config/Android.bp
index 287ed5a..5fdbcf0 100644
--- a/tools/product_config/Android.bp
+++ b/tools/product_config/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 java_defaults {
     name: "product-config-defaults",
     srcs: ["src/**/*.java"],
@@ -18,6 +22,6 @@
     static_libs: [
         "junit"
     ],
+    manifest: "TEST_MANIFEST.MF",
     test_suites: ["general-tests"]
 }
-
diff --git a/tools/product_config/TEST_MANIFEST.MF b/tools/product_config/TEST_MANIFEST.MF
new file mode 100644
index 0000000..287a77f
--- /dev/null
+++ b/tools/product_config/TEST_MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Main-Class: com.android.build.config.TestRunner
diff --git a/tools/product_config/src/com/android/build/config/CommandException.java b/tools/product_config/src/com/android/build/config/CommandException.java
new file mode 100644
index 0000000..f1a2c39
--- /dev/null
+++ b/tools/product_config/src/com/android/build/config/CommandException.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 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.build.config;
+
+/**
+ * Exception to indicate that a fatal error has occurred.  Throwing this
+ * will cause errors to be printed, cleanup to occur, and the command to
+ * exit with a failure code.
+ *
+ * These are user errors. Throwing other exceptions will result in
+ * the stack trace being shown.
+ */
+public class CommandException extends RuntimeException {
+    public CommandException() {
+        super();
+    }
+
+    public CommandException(String message) {
+        super(message);
+    }
+
+    public CommandException(String message, Throwable chain) {
+        super(message, chain);
+    }
+}
diff --git a/tools/product_config/src/com/android/build/config/ErrorReporter.java b/tools/product_config/src/com/android/build/config/ErrorReporter.java
index f382b4e..5d87636 100644
--- a/tools/product_config/src/com/android/build/config/ErrorReporter.java
+++ b/tools/product_config/src/com/android/build/config/ErrorReporter.java
@@ -49,6 +49,16 @@
      */
     private boolean mHadError;
 
+    public static class FatalException extends RuntimeException {
+        FatalException(String message) {
+            super(message);
+        }
+
+        FatalException(String message, Throwable chain) {
+            super(message, chain);
+        }
+    }
+
     /**
      * Whether errors are errors, warnings or hidden.
      */
@@ -127,6 +137,35 @@
         public String getHelp() {
             return mHelp;
         }
+
+        /**
+         * Add an error with no source position.
+         */
+        public void add(String message) {
+            ErrorReporter.this.add(this, false, new Position(), message);
+        }
+
+        /**
+         * Add an error.
+         */
+        public void add(Position pos, String message) {
+            ErrorReporter.this.add(this, false, pos, message);
+        }
+
+        /**
+         * Add an error with no source position, and throw a FatalException, stopping processing
+         * immediately.
+         */
+        public void fatal(String message) {
+            ErrorReporter.this.add(this, true, new Position(), message);
+        }
+
+        /**
+         * Add an error, and throw a FatalException, stopping processing immediately.
+         */
+        public void fatal(Position pos, String message) {
+            ErrorReporter.this.add(this, true, pos, message);
+        }
     }
 
     /**
@@ -154,6 +193,13 @@
         public String getMessage() {
             return mMessage;
         }
+
+        @Override
+        public String toString() {
+            return mPosition
+                    + "[" + mCategory.getLevel().getLabel() + " " + mCategory.getCode() + "] "
+                    + mMessage;
+        }
     }
 
     private void initLocked() {
@@ -191,22 +237,16 @@
     }
 
     /**
-     * Add an error with no source position.
-     */
-    public void add(Category category, String message) {
-        add(category, new Position(), message);
-    }
-
-    /**
      * Add an error.
      */
-    public void add(Category category, Position pos, String message) {
+    private void add(Category category, boolean fatal, Position pos, String message) {
         synchronized (mEntries) {
             initLocked();
             if (mCategories.get(category.getCode()) != category) {
                 throw new RuntimeException("Errors.Category used from the wrong Errors object.");
             }
-            mEntries.add(new Entry(category, pos, message));
+            final Entry entry = new Entry(category, pos, message);
+            mEntries.add(entry);
             final Level level = category.getLevel();
             if (level == Level.WARNING || level == Level.ERROR) {
                 mHadWarningOrError = true;
@@ -214,6 +254,9 @@
             if (level == Level.ERROR) {
                 mHadError = true;
             }
+            if (fatal) {
+                throw new FatalException(entry.toString());
+            }
         }
     }
 
@@ -250,13 +293,10 @@
     public void printErrors(PrintStream out) {
         synchronized (mEntries) {
             for (Entry entry: mEntries) {
-                final Category category = entry.getCategory();
-                final Level level = category.getLevel();
-                if (level == Level.HIDDEN) {
+                if (entry.getCategory().getLevel() == Level.HIDDEN) {
                     continue;
                 }
-                out.println(entry.getPosition() + "[" + level.getLabel() + " "
-                        + category.getCode() + "] " + entry.getMessage());
+                out.println(entry.toString());
             }
         }
     }
diff --git a/tools/product_config/src/com/android/build/config/Main.java b/tools/product_config/src/com/android/build/config/Main.java
index 7669742..b792193 100644
--- a/tools/product_config/src/com/android/build/config/Main.java
+++ b/tools/product_config/src/com/android/build/config/Main.java
@@ -38,27 +38,45 @@
 
         // TODO: Get the variables that were defined in starlark and use that to write
         // out the make, soong and bazel input files.
+        mErrors.ERROR_COMMAND_LINE.add("asdf");
+        throw new RuntimeException("poop");
     }
 
     public static void main(String[] args) {
         Errors errors = new Errors();
+        int exitCode = 0;
 
-        Options options = Options.parse(errors, args);
-        if (errors.hadError()) {
-            Options.printHelp(System.err);
+        try {
+            Options options = Options.parse(errors, args);
+            if (errors.hadError()) {
+                Options.printHelp(System.err);
+                System.err.println();
+                throw new CommandException();
+            }
+
+            switch (options.getAction()) {
+                case DEFAULT:
+                    (new Main(errors, options)).run();
+                    return;
+                case HELP:
+                    Options.printHelp(System.out);
+                    return;
+            }
+        } catch (CommandException ex) {
+            // These are user errors, so don't show a stack trace
+            exitCode = 1;
+        } catch (Throwable ex) {
+            // These are programming errors in the code of this tool, so print the exception.
+            // We'll try to print this.  If it's something unrecoverable, then we'll hope
+            // for the best. We will still print the errors below, because they can be useful
+            // for debugging.
+            ex.printStackTrace(System.err);
             System.err.println();
+            exitCode = 1;
+        } finally {
+            // Print errors and warnings
             errors.printErrors(System.err);
-            System.exit(1);
         }
-
-        switch (options.getAction()) {
-            case DEFAULT:
-                (new Main(errors, options)).run();
-                errors.printErrors(System.err);
-                return;
-            case HELP:
-                Options.printHelp(System.out);
-                return;
-        }
+        System.exit(exitCode);
     }
 }
diff --git a/tools/product_config/src/com/android/build/config/Options.java b/tools/product_config/src/com/android/build/config/Options.java
index 494b947..48146cb 100644
--- a/tools/product_config/src/com/android/build/config/Options.java
+++ b/tools/product_config/src/com/android/build/config/Options.java
@@ -96,14 +96,14 @@
                     mIndex++;
                 }
             } catch (ParseException ex) {
-                mErrors.add(mErrors.ERROR_COMMAND_LINE, ex.getMessage());
+                mErrors.ERROR_COMMAND_LINE.add(ex.getMessage());
             }
 
             return mResult;
         }
 
         private void addWarning(Errors.Category category, String message) {
-            mErrors.add(category, message);
+            category.add(message);
         }
 
         private String getNextNonFlagArg() {
@@ -133,12 +133,11 @@
             final int code = requireNextNumberArg(arg);
             final Errors.Category category = mErrors.getCategories().get(code);
             if (category == null) {
-                mErrors.add(mErrors.WARNING_UNKNOWN_COMMAND_LINE_ERROR,
-                        "Unknown error code: " + code);
+                mErrors.WARNING_UNKNOWN_COMMAND_LINE_ERROR.add("Unknown error code: " + code);
                 return;
             }
             if (!category.isLevelSettable()) {
-                mErrors.add(mErrors.ERROR_COMMAND_LINE, "Can't set level for error " + code);
+                mErrors.ERROR_COMMAND_LINE.add("Can't set level for error " + code);
                 return;
             }
             category.setLevel(level);
diff --git a/tools/product_config/test/com/android/build/config/ErrorReporterTest.java b/tools/product_config/test/com/android/build/config/ErrorReporterTest.java
index 2cde476..b9b25b4 100644
--- a/tools/product_config/test/com/android/build/config/ErrorReporterTest.java
+++ b/tools/product_config/test/com/android/build/config/ErrorReporterTest.java
@@ -30,7 +30,7 @@
     public void testAdding() {
         TestErrors errors = new TestErrors();
 
-        errors.add(errors.ERROR, new Position("a", 12), "Errrororrrr");
+        errors.ERROR.add(new Position("a", 12), "Errrororrrr");
 
         Assert.assertTrue(errors.hadWarningOrError());
         Assert.assertTrue(errors.hadError());
@@ -66,7 +66,7 @@
     public void testWarning() {
         TestErrors errors = new TestErrors();
 
-        errors.add(errors.WARNING, "Waaaaarninggggg");
+        errors.WARNING.add("Waaaaarninggggg");
 
         Assert.assertTrue(errors.hadWarningOrError());
         Assert.assertFalse(errors.hadError());
@@ -80,7 +80,7 @@
     public void testHidden() {
         TestErrors errors = new TestErrors();
 
-        errors.add(errors.HIDDEN, "Hidddeennn");
+        errors.HIDDEN.add("Hidddeennn");
 
         Assert.assertFalse(errors.hadWarningOrError());
         Assert.assertFalse(errors.hadError());
diff --git a/tools/product_config/test/com/android/build/config/TestRunner.java b/tools/product_config/test/com/android/build/config/TestRunner.java
new file mode 100644
index 0000000..9a5ee69
--- /dev/null
+++ b/tools/product_config/test/com/android/build/config/TestRunner.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2020 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.build.config;
+
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+public class TestRunner {
+    public static void main(String[] args) {
+        JUnitCore junit = new JUnitCore();
+
+        junit.addListener(new RunListener() {
+                    @Override
+                    public void testStarted(Description description) {
+                        System.out.println("\nSTARTING: " + description.getDisplayName());
+                    }
+
+                    @Override
+                    public void testFailure(Failure failure) {
+                        System.out.println("FAILED: "
+                                + failure.getDescription().getDisplayName());
+                        System.out.println(failure.getTrace());
+                    }
+                });
+        Result result = junit.run(ErrorReporterTest.class,
+                                  OptionsTest.class);
+        if (!result.wasSuccessful()) {
+            System.out.println("\n*** FAILED ***");
+        }
+    }
+}
+
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 0c84d4f..81528ae 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -22,6 +22,10 @@
 //    `releasetools_X_defaults` in their defaults.
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 python_defaults {
     name: "releasetools_add_img_to_target_files_defaults",
     srcs: [
@@ -569,7 +573,6 @@
     name: "releasetools_test",
     defaults: ["releasetools_test_defaults"],
     main: "test_utils.py",
-    test_suites: ["general-tests"],
     version: {
         py2: {
             enabled: true,
diff --git a/tools/releasetools/TEST_MAPPING b/tools/releasetools/TEST_MAPPING
deleted file mode 100644
index 3d57960..0000000
--- a/tools/releasetools/TEST_MAPPING
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-    "presubmit": [
-        {
-            "name": "releasetools_test",
-            "host" : true
-        }
-    ]
-}
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 26c4ae8..da189f3 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -276,29 +276,6 @@
   return subprocess.Popen(args, **kwargs)
 
 
-def RunAndWait(args, verbose=None, **kwargs):
-  """Runs the given command waiting for it to complete.
-
-  Args:
-    args: The command represented as a list of strings.
-    verbose: Whether the commands should be shown. Default to the global
-        verbosity if unspecified.
-    kwargs: Any additional args to be passed to subprocess.Popen(), such as env,
-        stdin, etc. stdout and stderr will default to subprocess.PIPE and
-        subprocess.STDOUT respectively unless caller specifies any of them.
-
-  Raises:
-    ExternalError: On non-zero exit from the command.
-  """
-  proc = Run(args, verbose=verbose, **kwargs)
-  proc.wait()
-
-  if proc.returncode != 0:
-    raise ExternalError(
-        "Failed to run command '{}' (exit code {})".format(
-            args, proc.returncode))
-
-
 def RunAndCheckOutput(args, verbose=None, **kwargs):
   """Runs the given command and returns the output.
 
@@ -663,7 +640,7 @@
   """Extracts the contents of fn from input zipfile or directory into a file."""
   if isinstance(input_file, zipfile.ZipFile):
     tmp_file = MakeTempFile(os.path.basename(fn))
-    with open(tmp_file, 'w') as f:
+    with open(tmp_file, 'wb') as f:
       f.write(input_file.read(fn))
     return tmp_file
   else:
@@ -887,8 +864,8 @@
     prop_file = GetBootImageBuildProp(boot_img)
     if prop_file is None:
       return ''
-    with open(prop_file) as f:
-      return f.read().decode()
+    with open(prop_file, "r") as f:
+      return f.read()
 
   @staticmethod
   def _ReadPartitionPropFile(input_file, name):
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index 9360d7b..3d9c717 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -887,12 +887,12 @@
       output_zip,
       '-C',
       source_dir,
-      '-l',
+      '-r',
       output_target_files_list,
   ]
 
   logger.info('creating %s', output_file)
-  common.RunAndWait(command, verbose=True)
+  common.RunAndCheckOutput(command, verbose=True)
   logger.info('finished creating %s', output_file)
 
   return output_zip
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 41644d8..2cbaf37 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -272,6 +272,8 @@
 OPTIONS.disable_verity_computation = False
 OPTIONS.partial = None
 OPTIONS.custom_images = {}
+OPTIONS.disable_vabc = False
+OPTIONS.spl_downgrade = False
 
 POSTINSTALL_CONFIG = 'META/postinstall_config.txt'
 DYNAMIC_PARTITION_INFO = 'META/dynamic_partitions_info.txt'
@@ -290,6 +292,8 @@
     'system_ext', 'vbmeta', 'vbmeta_system', 'vbmeta_vendor', 'vendor',
     'vendor_boot']
 
+SECURITY_PATCH_LEVEL_PROP_NAME = "ro.build.version.security_patch"
+
 
 class PayloadSigner(object):
   """A class that wraps the payload signing works.
@@ -1090,6 +1094,8 @@
     partition_timestamps_flags = GeneratePartitionTimestampFlags(
         metadata.postcondition.partition_state)
 
+  if OPTIONS.disable_vabc:
+    additional_args += ["--disable_vabc", "true"]
   additional_args += ["--max_timestamp", max_timestamp]
 
   if SupportsMainlineGkiUpdates(source_file):
@@ -1257,6 +1263,10 @@
     elif o == "--custom_image":
       custom_partition, custom_image = a.split("=")
       OPTIONS.custom_images[custom_partition] = custom_image
+    elif o == "--disable_vabc":
+      OPTIONS.disable_vabc = True
+    elif o == "--spl_downgrade":
+      OPTIONS.spl_downgrade = True
     else:
       return False
     return True
@@ -1298,6 +1308,8 @@
                                  "boot_variable_file=",
                                  "partial=",
                                  "custom_image=",
+                                 "disable_vabc",
+                                 "spl_downgrade"
                              ], extra_option_handler=option_handler)
 
   if len(args) != 2:
@@ -1393,7 +1405,27 @@
           "build/make/target/product/security/testkey")
     # Get signing keys
     OPTIONS.key_passwords = common.GetKeyPasswords([OPTIONS.package_key])
+    private_key_path = OPTIONS.package_key + OPTIONS.private_key_suffix
+    if not os.path.exists(private_key_path):
+      raise common.ExternalError(
+                        "Private key {} doesn't exist. Make sure you passed the"
+                        " correct key path through -k option".format(
+                          private_key_path)
+                          )
 
+  if OPTIONS.source_info_dict:
+    source_build_prop = OPTIONS.source_info_dict["build.prop"]
+    target_build_prop = OPTIONS.target_info_dict["build.prop"]
+    source_spl = source_build_prop.GetProp(SECURITY_PATCH_LEVEL_PROP_NAME)
+    target_spl = target_build_prop.GetProp(SECURITY_PATCH_LEVEL_PROP_NAME)
+    if target_spl < source_spl and not OPTIONS.spl_downgrade:
+      raise common.ExternalError(
+        "Target security patch level {} is older than source SPL {} applying "
+        "such OTA will likely cause device fail to boot. Pass --spl-downgrade "
+        "to override this check. This script expects security patch level to "
+        "be in format yyyy-mm-dd (e.x. 2021-02-05). It's possible to use "
+        "separators other than -, so as long as it's used consistenly across "
+        "all SPL dates".format(target_spl, source_spl))
   if generate_ab:
     GenerateAbOtaPackage(
         target_file=args[0],
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 176e258..890cb51 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -444,6 +444,23 @@
 
   return data
 
+def IsBuildPropFile(filename):
+  return filename in (
+        "SYSTEM/etc/prop.default",
+        "BOOT/RAMDISK/prop.default",
+        "RECOVERY/RAMDISK/prop.default",
+
+        "VENDOR_BOOT/RAMDISK/default.prop",
+        "VENDOR_BOOT/RAMDISK/prop.default",
+
+        # ROOT/default.prop is a legacy path, but may still exist for upgrading
+        # devices that don't support `property_overrides_split_enabled`.
+        "ROOT/default.prop",
+
+        # RECOVERY/RAMDISK/default.prop is a legacy path, but will always exist
+        # as a symlink in the current code. So it's a no-op here. Keeping the
+        # path here for clarity.
+        "RECOVERY/RAMDISK/default.prop") or filename.endswith("build.prop")
 
 def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
                        apk_keys, apex_keys, key_passwords,
@@ -534,33 +551,7 @@
       continue
 
     # System properties.
-    elif filename in (
-        "SYSTEM/build.prop",
-
-        "VENDOR/build.prop",
-        "SYSTEM/vendor/build.prop",
-
-        "ODM/etc/build.prop",
-        "VENDOR/odm/etc/build.prop",
-
-        "PRODUCT/build.prop",
-        "SYSTEM/product/build.prop",
-
-        "SYSTEM_EXT/build.prop",
-        "SYSTEM/system_ext/build.prop",
-
-        "SYSTEM/etc/prop.default",
-        "BOOT/RAMDISK/prop.default",
-        "RECOVERY/RAMDISK/prop.default",
-
-        # ROOT/default.prop is a legacy path, but may still exist for upgrading
-        # devices that don't support `property_overrides_split_enabled`.
-        "ROOT/default.prop",
-
-        # RECOVERY/RAMDISK/default.prop is a legacy path, but will always exist
-        # as a symlink in the current code. So it's a no-op here. Keeping the
-        # path here for clarity.
-        "RECOVERY/RAMDISK/default.prop"):
+    elif IsBuildPropFile(filename):
       print("Rewriting %s:" % (filename,))
       if stat.S_ISLNK(info.external_attr >> 16):
         new_data = data
@@ -588,12 +579,7 @@
 
     # Don't copy OTA certs if we're replacing them.
     # Replacement of update-payload-key.pub.pem was removed in b/116660991.
-    elif (
-        OPTIONS.replace_ota_keys and
-        filename in (
-            "BOOT/RAMDISK/system/etc/security/otacerts.zip",
-            "RECOVERY/RAMDISK/system/etc/security/otacerts.zip",
-            "SYSTEM/etc/security/otacerts.zip")):
+    elif OPTIONS.replace_ota_keys and filename.endswith("/otacerts.zip"):
       pass
 
     # Skip META/misc_info.txt since we will write back the new values later.
@@ -861,21 +847,12 @@
     print("META/otakeys.txt has no keys; using %s for OTA package"
           " verification." % (mapped_keys[0],))
 
-  # recovery now uses the same x509.pem version of the keys.
-  # extra_recovery_keys are used only in recovery.
-  if misc_info.get("recovery_as_boot") == "true":
-    recovery_keys_location = "BOOT/RAMDISK/system/etc/security/otacerts.zip"
-  else:
-    recovery_keys_location = "RECOVERY/RAMDISK/system/etc/security/otacerts.zip"
-
-  WriteOtacerts(output_tf_zip, recovery_keys_location,
-                mapped_keys + extra_recovery_keys)
-
-  # SystemUpdateActivity uses the x509.pem version of the keys, but
-  # put into a zipfile system/etc/security/otacerts.zip.
-  # We DO NOT include the extra_recovery_keys (if any) here.
-  WriteOtacerts(output_tf_zip, "SYSTEM/etc/security/otacerts.zip", mapped_keys)
-
+  otacerts = [info
+              for info in input_tf_zip.infolist()
+              if info.filename.endswith("/otacerts.zip")]
+  for info in otacerts:
+    print("Rewriting OTA key:", info.filename, mapped_keys)
+    WriteOtacerts(output_tf_zip, info.filename, mapped_keys)
 
 
 def ReplaceVerityPublicKey(output_zip, filename, key_path):
diff --git a/tools/signapk/Android.bp b/tools/signapk/Android.bp
index b90f010..bee6a6f 100644
--- a/tools/signapk/Android.bp
+++ b/tools/signapk/Android.bp
@@ -16,6 +16,10 @@
 
 // the signapk tool (a .jar application used to sign packages)
 // ============================================================
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 java_binary_host {
     name: "signapk",
     srcs: ["src/**/*.java"],
diff --git a/tools/signtos/Android.bp b/tools/signtos/Android.bp
index 688e7b8..cd41acc 100644
--- a/tools/signtos/Android.bp
+++ b/tools/signtos/Android.bp
@@ -16,6 +16,10 @@
 
 // the signtos tool - signs Trusty images
 // ============================================================
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 java_library_host {
     name: "signtos",
     srcs: ["SignTos.java"],
diff --git a/tools/test_extract_kernel.py b/tools/test_extract_kernel.py
index 1a1cfcb..002e387 100644
--- a/tools/test_extract_kernel.py
+++ b/tools/test_extract_kernel.py
@@ -15,16 +15,16 @@
 # limitations under the License.
 
 import unittest
-from extract_kernel import get_version, dump_version
+from extract_kernel import dump_version
 
 class ExtractKernelTest(unittest.TestCase):
   def test_extract_version(self):
-    self.assertEqual("4.9.100", get_version(
-        b'Linux version 4.9.100-a123 (a@a) (a) a\n\x00', 0))
-    self.assertEqual("4.9.123", get_version(
-        b'Linux version 4.9.123 (@) () \n\x00', 0))
+    self.assertEqual("4.9.100", dump_version(
+        b'Linux version 4.9.100-a123 (a@a) (a) a\n\x00'))
+    self.assertEqual("4.9.123", dump_version(
+        b'Linux version 4.9.123 (@) () \n\x00'))
 
   def test_dump_self(self):
     self.assertEqual("4.9.1", dump_version(
         b"trash\x00Linux version 4.8.8\x00trash\x00"
-        "other trash Linux version 4.9.1-g3 (2@s) (2) a\n\x00"))
+        b"other trash Linux version 4.9.1-g3 (2@s) (2) a\n\x00"))
diff --git a/tools/zipalign/Android.bp b/tools/zipalign/Android.bp
index 1ebf4eb..8cab04c 100644
--- a/tools/zipalign/Android.bp
+++ b/tools/zipalign/Android.bp
@@ -4,6 +4,10 @@
 // Zip alignment tool
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 cc_defaults {
     name: "zipalign_defaults",
     target: {
diff --git a/tools/ziptime/Android.bp b/tools/ziptime/Android.bp
index 5ef45ed..fa46b30 100644
--- a/tools/ziptime/Android.bp
+++ b/tools/ziptime/Android.bp
@@ -18,6 +18,10 @@
 // Zip timestamp removal tool
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 cc_binary_host {
 
     srcs: [