Merge "Disable Jack's NNode cache"
diff --git a/core/Makefile b/core/Makefile
index 547db71..8f63f4a 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -835,6 +835,7 @@
 # $(1): the path of the output dictionary file
 # $(2): additional "key=value" pairs to append to the dictionary file.
 define generate-userimage-prop-dictionary
+$(hide) echo "ext_mkuserimg=$(MKEXTUSERIMG)" >> $(1)
 $(if $(INTERNAL_USERIMAGES_EXT_VARIANT),$(hide) echo "fs_type=$(INTERNAL_USERIMAGES_EXT_VARIANT)" >> $(1))
 $(if $(BOARD_SYSTEMIMAGE_PARTITION_SIZE),$(hide) echo "system_size=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)" >> $(1))
 $(if $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "system_fs_type=$(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
@@ -1655,8 +1656,8 @@
   $(HOST_OUT_JAVA_LIBRARIES)/dumpkey.jar \
   $(HOST_OUT_JAVA_LIBRARIES)/signapk.jar \
   $(HOST_OUT_JAVA_LIBRARIES)/BootSignature.jar \
-  $(HOST_OUT_EXECUTABLES)/mkuserimg.sh \
-  $(HOST_OUT_EXECUTABLES)/make_ext4fs \
+  $(MAKE_EXT4FS) \
+  $(MKEXTUSERIMG) \
   $(HOST_OUT_EXECUTABLES)/mksquashfsimage.sh \
   $(HOST_OUT_EXECUTABLES)/mksquashfs \
   $(HOST_OUT_EXECUTABLES)/mkf2fsuserimg.sh \
diff --git a/core/binary.mk b/core/binary.mk
index 17b1bf2..848bba9 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -835,7 +835,6 @@
 ###########################################################
 proto_sources := $(filter %.proto,$(my_src_files))
 ifneq ($(proto_sources),)
-my_soong_problems += proto
 proto_gen_dir := $(generated_sources_dir)/proto
 proto_sources_fullpath := $(addprefix $(LOCAL_PATH)/, $(proto_sources))
 
@@ -974,7 +973,6 @@
 aidl_src := $(strip $(filter %.aidl,$(my_src_files)))
 aidl_gen_cpp :=
 ifneq ($(aidl_src),)
-my_soong_problems += aidl
 
 # Use the intermediates directory to avoid writing our own .cpp -> .o rules.
 aidl_gen_cpp_root := $(intermediates)/aidl-generated/src
@@ -1286,7 +1284,6 @@
 $(call track-src-file-obj,$(objcpp_sources),$(objcpp_objects))
 
 ifneq ($(strip $(objcpp_objects)),)
-my_soong_problems += objc
 $(objcpp_objects): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.mm \
     $(my_additional_dependencies)
 	$(transform-$(PRIVATE_HOST)mm-to-o)
diff --git a/core/config.mk b/core/config.mk
index f9d6e7e..6111afe 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -550,7 +550,6 @@
 YASM := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/yasm/yasm
 
 DOXYGEN:= doxygen
-AIDL_CPP := $(HOST_OUT_EXECUTABLES)/aidl-cpp$(HOST_EXECUTABLE_SUFFIX)
 ifeq ($(HOST_OS),linux)
 BREAKPAD_DUMP_SYMS := $(HOST_OUT_EXECUTABLES)/dump_syms
 else
@@ -583,9 +582,14 @@
 endif
 APICHECK := $(HOST_OUT_EXECUTABLES)/apicheck$(HOST_EXECUTABLE_SUFFIX)
 FS_GET_STATS := $(HOST_OUT_EXECUTABLES)/fs_get_stats$(HOST_EXECUTABLE_SUFFIX)
+ifeq ($(TARGET_USES_MKE2FS),true)
+MAKE_EXT4FS := $(HOST_OUT_EXECUTABLES)/mke2fs$(HOST_EXECUTABLE_SUFFIX)
+MKEXTUSERIMG := $(HOST_OUT_EXECUTABLES)/mkuserimg_mke2fs.sh
+else
 MAKE_EXT4FS := $(HOST_OUT_EXECUTABLES)/make_ext4fs$(HOST_EXECUTABLE_SUFFIX)
-BLK_ALLOC_TO_BASE_FS := $(HOST_OUT_EXECUTABLES)/blk_alloc_to_base_fs$(HOST_EXECUTABLE_SUFFIX)
 MKEXTUSERIMG := $(HOST_OUT_EXECUTABLES)/mkuserimg.sh
+endif
+BLK_ALLOC_TO_BASE_FS := $(HOST_OUT_EXECUTABLES)/blk_alloc_to_base_fs$(HOST_EXECUTABLE_SUFFIX)
 MAKE_SQUASHFS := $(HOST_OUT_EXECUTABLES)/mksquashfs$(HOST_EXECUTABLE_SUFFIX)
 MKSQUASHFSUSERIMG := $(HOST_OUT_EXECUTABLES)/mksquashfsimage.sh
 MAKE_F2FS := $(HOST_OUT_EXECUTABLES)/make_f2fs$(HOST_EXECUTABLE_SUFFIX)
diff --git a/core/definitions.mk b/core/definitions.mk
index 1a9276c..698f52c 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -417,7 +417,7 @@
 define find-subdir-assets
 $(sort $(if $(1),$(patsubst ./%,%, \
 	$(shell if [ -d $(1) ] ; then cd $(1) ; find -L ./ -not -name '.*' -and -type f ; fi)), \
-	$(warning Empty argument supplied to find-subdir-assets) \
+	$(warning Empty argument supplied to find-subdir-assets in $(LOCAL_PATH)) \
 ))
 endef
 
diff --git a/core/package_internal.mk b/core/package_internal.mk
index af1d2a5..5dd021c 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -140,9 +140,9 @@
     $(addprefix $(d)/, \
         $(call find-subdir-assets,$(d)))))
 
-my_res_resources := $(strip \
+my_res_resources := $(if $(my_res_dir),$(strip \
     $(addprefix $(my_res_dir)/, \
-        $(call find-subdir-assets,$(my_res_dir))))
+        $(call find-subdir-assets,$(my_res_dir)))))
 
 all_resources := $(strip $(my_res_resources) $(my_overlay_resources))
 
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 1782ce5..6440d82 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -37,6 +37,7 @@
 	echo '    "DevicePrefer32BitExecutables": $(if $(filter true,$(TARGET_PREFER_32_BIT_EXECUTABLES)),true,false),'; \
 	echo '    "UseGoma": $(if $(filter-out false,$(USE_GOMA)),true,false),'; \
 	echo '    "Debuggable": $(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),true,false),'; \
+	echo '    "VendorPath": "$(TARGET_COPY_OUT_VENDOR)",'; \
 	echo ''; \
 	echo '    "ClangTidy": $(if $(filter 1 true,$(WITH_TIDY)),true,false),'; \
 	echo '    "TidyChecks": "$(WITH_TIDY_CHECKS)",'; \
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 5dffcac..7365baa 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -64,7 +64,7 @@
   # PLATFORM_SDK_VERSION. During development, this number may be incremented
   # before PLATFORM_SDK_VERSION if the plateform starts to add new java
   # language supports.
-  PLATFORM_JACK_MIN_SDK_VERSION := 24
+  PLATFORM_JACK_MIN_SDK_VERSION := o-b1
 endif
 
 ifeq "" "$(PLATFORM_VERSION_CODENAME)"
diff --git a/target/product/core_minimal.mk b/target/product/core_minimal.mk
index 63c516a..fe1a382 100644
--- a/target/product/core_minimal.mk
+++ b/target/product/core_minimal.mk
@@ -59,7 +59,6 @@
     keystore \
     keystore.default \
     ld.mc \
-    libbcc \
     libOpenMAXAL \
     libOpenSLES \
     libdownmix \
diff --git a/target/product/embedded.mk b/target/product/embedded.mk
index 5faf24f..78b61a6 100644
--- a/target/product/embedded.mk
+++ b/target/product/embedded.mk
@@ -79,12 +79,12 @@
 
 # SELinux packages
 PRODUCT_PACKAGES += \
-    sepolicy \
     file_contexts.bin \
-    seapp_contexts \
-    property_contexts \
     mac_permissions.xml \
+    property_contexts \
+    seapp_contexts \
     selinux_version \
+    sepolicy \
     service_contexts
 
 # Ensure that this property is always defined so that bionic_systrace.cpp
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 3884f49..6852d02 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -383,6 +383,14 @@
       if recovery_image:
         recovery_image.AddToZip(output_zip)
 
+      banner("recovery (two-step image)")
+      # The special recovery.img for two-step package use.
+      recovery_two_step_image = common.GetBootableImage(
+          "IMAGES/recovery-two-step.img", "recovery-two-step.img",
+          OPTIONS.input_tmp, "RECOVERY", two_step_image=True)
+      if recovery_two_step_image:
+        recovery_two_step_image.AddToZip(output_zip)
+
   banner("system")
   system_img_path = AddSystem(
     output_zip, recovery_img=recovery_image, boot_img=boot_image)
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 6bf42d1..c5be3df 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -437,7 +437,7 @@
     prop_dict["original_partition_size"] = str(partition_size)
 
   if fs_type.startswith("ext"):
-    build_command = ["mkuserimg.sh"]
+    build_command = [prop_dict["ext_mkuserimg"]]
     if "extfs_sparse_flag" in prop_dict:
       build_command.append(prop_dict["extfs_sparse_flag"])
       run_fsck = True
@@ -606,6 +606,7 @@
       "squashfs_sparse_flag",
       "selinux_fc",
       "skip_fsck",
+      "ext_mkuserimg",
       "verity",
       "verity_key",
       "verity_signer_cmd",
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 813b2c6..8ed12dc 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -395,13 +395,17 @@
 
 
 def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None,
-                        has_ramdisk=False):
+                        has_ramdisk=False, two_step_image=False):
   """Build a bootable image from the specified sourcedir.
 
   Take a kernel, cmdline, and optionally a ramdisk directory from the input (in
-  'sourcedir'), and turn them into a boot image.  Return the image data, or
-  None if sourcedir does not appear to contains files for building the
-  requested image."""
+  'sourcedir'), and turn them into a boot image. 'two_step_image' indicates if
+  we are building a two-step special image (i.e. building a recovery image to
+  be loaded into /boot in two-step OTAs).
+
+  Return the image data, or None if sourcedir does not appear to contains files
+  for building the requested image.
+  """
 
   def make_ramdisk():
     ramdisk_img = tempfile.NamedTemporaryFile()
@@ -485,7 +489,12 @@
 
   if (info_dict.get("boot_signer", None) == "true" and
       info_dict.get("verity_key", None)):
-    path = "/" + os.path.basename(sourcedir).lower()
+    # Hard-code the path as "/boot" for two-step special recovery image (which
+    # will be loaded into /boot during the two-step OTA).
+    if two_step_image:
+      path = "/boot"
+    else:
+      path = "/" + os.path.basename(sourcedir).lower()
     cmd = [OPTIONS.boot_signer_path]
     cmd.extend(OPTIONS.boot_signer_args)
     cmd.extend([path, img.name,
@@ -539,7 +548,7 @@
 
 
 def GetBootableImage(name, prebuilt_name, unpack_dir, tree_subdir,
-                     info_dict=None, system_img_path=None):
+                     info_dict=None, two_step_image=False):
   """Return a File object with the desired bootable image.
 
   Look for it in 'unpack_dir'/BOOTABLE_IMAGES under the name 'prebuilt_name',
@@ -571,7 +580,7 @@
   fs_config = "META/" + tree_subdir.lower() + "_filesystem_config.txt"
   data = _BuildBootableImage(os.path.join(unpack_dir, tree_subdir),
                              os.path.join(unpack_dir, fs_config),
-                             info_dict, has_ramdisk)
+                             info_dict, has_ramdisk, two_step_image)
   if data:
     return File(name, data)
   return None
diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py
index aa21d7e..84e0e63 100755
--- a/tools/releasetools/img_from_target_files.py
+++ b/tools/releasetools/img_from_target_files.py
@@ -86,6 +86,8 @@
             continue
           if not image.endswith(".img"):
             continue
+          if image == "recovery-two-step.img":
+            continue
           common.ZipWrite(
               output_zip, os.path.join(images_path, image), image)
         done = True
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 403a3a4..b11e85d 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -461,6 +461,39 @@
       script.AssertOemProperty(prop, oem_dict.get(prop))
 
 
+def _WriteRecoveryImageToBoot(script, output_zip):
+  """Find and write recovery image to /boot in two-step OTA.
+
+  In two-step OTAs, we write recovery image to /boot as the first step so that
+  we can reboot to there and install a new recovery image to /recovery.
+  A special "recovery-two-step.img" will be preferred, which encodes the correct
+  path of "/boot". Otherwise the device may show "device is corrupt" message
+  when booting into /boot.
+
+  Fall back to using the regular recovery.img if the two-step recovery image
+  doesn't exist. Note that rebuilding the special image at this point may be
+  infeasible, because we don't have the desired boot signer and keys when
+  calling ota_from_target_files.py.
+  """
+
+  recovery_two_step_img_name = "recovery-two-step.img"
+  recovery_two_step_img_path = os.path.join(
+      OPTIONS.input_tmp, "IMAGES", recovery_two_step_img_name)
+  if os.path.exists(recovery_two_step_img_path):
+    recovery_two_step_img = common.GetBootableImage(
+        recovery_two_step_img_name, recovery_two_step_img_name,
+        OPTIONS.input_tmp, "RECOVERY")
+    common.ZipWriteStr(
+        output_zip, recovery_two_step_img_name, recovery_two_step_img.data)
+    print "two-step package: using %s in stage 1/3" % (
+        recovery_two_step_img_name,)
+    script.WriteRawImage("/boot", recovery_two_step_img_name)
+  else:
+    print "two-step package: using recovery.img in stage 1/3"
+    # The "recovery.img" entry has been written into package earlier.
+    script.WriteRawImage("/boot", "recovery.img")
+
+
 def HasRecoveryPatch(target_files_zip):
   namelist = [name for name in target_files_zip.namelist()]
   return ("SYSTEM/recovery-from-boot.p" in namelist or
@@ -609,6 +642,9 @@
     script.AppendExtra("""
 if get_stage("%(bcb_dev)s") == "2/3" then
 """ % bcb_dev)
+
+    # Stage 2/3: Write recovery image to /recovery (currently running /boot).
+    script.Comment("Stage 2/3")
     script.WriteRawImage("/recovery", "recovery.img")
     script.AppendExtra("""
 set_stage("%(bcb_dev)s", "3/3");
@@ -616,6 +652,9 @@
 else if get_stage("%(bcb_dev)s") == "3/3" then
 """ % bcb_dev)
 
+    # Stage 3/3: Make changes.
+    script.Comment("Stage 3/3")
+
   # Dump fingerprints
   script.Print("Target: %s" % target_fp)
 
@@ -714,7 +753,11 @@
 set_stage("%(bcb_dev)s", "");
 """ % bcb_dev)
     script.AppendExtra("else\n")
-    script.WriteRawImage("/boot", "recovery.img")
+
+    # Stage 1/3: Nothing to verify for full OTA. Write recovery image to /boot.
+    script.Comment("Stage 1/3")
+    _WriteRecoveryImageToBoot(script, output_zip)
+
     script.AppendExtra("""
 set_stage("%(bcb_dev)s", "2/3");
 reboot_now("%(bcb_dev)s", "");
@@ -938,6 +981,9 @@
     script.AppendExtra("""
 if get_stage("%(bcb_dev)s") == "2/3" then
 """ % bcb_dev)
+
+    # Stage 2/3: Write recovery image to /recovery (currently running /boot).
+    script.Comment("Stage 2/3")
     script.AppendExtra("sleep(20);\n")
     script.WriteRawImage("/recovery", "recovery.img")
     script.AppendExtra("""
@@ -946,6 +992,9 @@
 else if get_stage("%(bcb_dev)s") != "3/3" then
 """ % bcb_dev)
 
+    # Stage 1/3: (a) Verify the current system.
+    script.Comment("Stage 1/3")
+
   # Dump fingerprints
   script.Print(source_fp)
   script.Print(target_fp)
@@ -1016,13 +1065,18 @@
   device_specific.IncrementalOTA_VerifyEnd()
 
   if OPTIONS.two_step:
-    script.WriteRawImage("/boot", "recovery.img")
+    # Stage 1/3: (b) Write recovery image to /boot.
+    _WriteRecoveryImageToBoot(script, output_zip)
+
     script.AppendExtra("""
 set_stage("%(bcb_dev)s", "2/3");
 reboot_now("%(bcb_dev)s", "");
 else
 """ % bcb_dev)
 
+    # Stage 3/3: Make changes.
+    script.Comment("Stage 3/3")
+
   # Verify the existing partitions.
   system_diff.WriteVerifyScript(script, touched_blocks_only=True)
   if vendor_diff:
@@ -1615,6 +1669,9 @@
     script.AppendExtra("""
 if get_stage("%(bcb_dev)s") == "2/3" then
 """ % bcb_dev)
+
+    # Stage 2/3: Write recovery image to /recovery (currently running /boot).
+    script.Comment("Stage 2/3")
     script.AppendExtra("sleep(20);\n")
     script.WriteRawImage("/recovery", "recovery.img")
     script.AppendExtra("""
@@ -1623,6 +1680,9 @@
 else if get_stage("%(bcb_dev)s") != "3/3" then
 """ % bcb_dev)
 
+    # Stage 1/3: (a) Verify the current system.
+    script.Comment("Stage 1/3")
+
   # Dump fingerprints
   script.Print("Source: %s" % (source_fp,))
   script.Print("Target: %s" % (target_fp,))
@@ -1667,13 +1727,18 @@
   device_specific.IncrementalOTA_VerifyEnd()
 
   if OPTIONS.two_step:
-    script.WriteRawImage("/boot", "recovery.img")
+    # Stage 1/3: (b) Write recovery image to /boot.
+    _WriteRecoveryImageToBoot(script, output_zip)
+
     script.AppendExtra("""
 set_stage("%(bcb_dev)s", "2/3");
 reboot_now("%(bcb_dev)s", "");
 else
 """ % bcb_dev)
 
+    # Stage 3/3: Make changes.
+    script.Comment("Stage 3/3")
+
   script.Comment("---- start making changes here ----")
 
   device_specific.IncrementalOTA_InstallBegin()