Merge "Use soong_zip and zip2zip to make dist faster" am: 6dcdb45485 am: 96963dfd4d
am: 592cfc1859

Change-Id: Id9a60ebbd282026ab7a0ff5bc85757a5c545ffb7
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 3c8d6ce..a97c71a 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -374,6 +374,10 @@
 # $(PRODUCT_OUT)/recovery/root/sdcard goes from symlink to folder.
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/sdcard)
 
+# Add BOARD_USES_SYSTEM_OTHER_ODEX
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/*)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/Makefile b/core/Makefile
index 8a61b90..11be472 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -543,10 +543,17 @@
 endif
 endif
 
+ifeq ($(BOARD_BVB_ENABLE),true)
+BOARD_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE))
+ifdef BOARD_KERNEL_CMDLINE
+  INTERNAL_BVBTOOL_MAKE_BOOT_IMAGE_ARGS += --kernel_cmdline "$(BOARD_KERNEL_CMDLINE)"
+endif
+else
 BOARD_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE) buildvariant=$(TARGET_BUILD_VARIANT) $(VERITY_KEYID))
 ifdef BOARD_KERNEL_CMDLINE
 INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)"
 endif
+endif
 
 INTERNAL_MKBOOTIMG_VERSION_ARGS := \
     --os_version $(PLATFORM_VERSION) \
@@ -841,6 +848,7 @@
 $(if $(BOARD_HAS_EXT4_RESERVED_BLOCKS),$(hide) echo "has_ext4_reserved_blocks=$(BOARD_HAS_EXT4_RESERVED_BLOCKS)" >> $(1))
 $(if $(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "system_squashfs_compressor=$(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
 $(if $(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "system_squashfs_compressor_opt=$(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
+$(if $(BOARD_SYSTEMIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "system_squashfs_block_size=$(BOARD_SYSTEMIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
 $(if $(BOARD_SYSTEMIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "system_squashfs_disable_4k_align=$(BOARD_SYSTEMIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH),$(hide) echo "system_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH)" >> $(1))
 $(if $(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "userdata_fs_type=$(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
@@ -852,6 +860,7 @@
 $(if $(BOARD_VENDORIMAGE_JOURNAL_SIZE),$(hide) echo "vendor_journal_size=$(BOARD_VENDORIMAGE_JOURNAL_SIZE)" >> $(1))
 $(if $(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "vendor_squashfs_compressor=$(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR)" >> $(1))
 $(if $(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR_OPT),$(hide) echo "vendor_squashfs_compressor_opt=$(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR_OPT)" >> $(1))
+$(if $(BOARD_VENDORIMAGE_SQUASHFS_BLOCK_SIZE),$(hide) echo "vendor_squashfs_block_size=$(BOARD_VENDORIMAGE_SQUASHFS_BLOCK_SIZE)" >> $(1))
 $(if $(BOARD_VENDORIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "vendor_squashfs_disable_4k_align=$(BOARD_VENDORIMAGE_SQUASHFS_DISABLE_4K_ALIGN)" >> $(1))
 $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH),$(hide) echo "vendor_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH)" >> $(1))
 $(if $(BOARD_OEMIMAGE_PARTITION_SIZE),$(hide) echo "oem_size=$(BOARD_OEMIMAGE_PARTITION_SIZE)" >> $(1))
@@ -932,10 +941,10 @@
 else
 recovery_fstab := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery.fstab))
 endif
-ifdef TARGET_RECOVERY_BRICK
-recovery_brick := $(TARGET_RECOVERY_BRICK)
+ifdef TARGET_RECOVERY_WIPE
+recovery_wipe := $(TARGET_RECOVERY_WIPE)
 else
-recovery_brick :=
+recovery_wipe :=
 endif
 
 # Prior to A/B update, we used to have:
@@ -1007,7 +1016,7 @@
   $(hide) mkdir -p $(TARGET_RECOVERY_OUT)
   $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc $(TARGET_RECOVERY_ROOT_OUT)/sdcard $(TARGET_RECOVERY_ROOT_OUT)/tmp
   @echo Copying baseline ramdisk...
-  $(hide) rsync -a --exclude=etc --exclude=sdcard $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT) # "cp -Rf" fails to overwrite broken symlinks on Mac.
+  $(hide) rsync -a --exclude=etc --exclude=sdcard $(IGNORE_CACHE_LINK) $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT) # "cp -Rf" fails to overwrite broken symlinks on Mac.
   @echo Modifying ramdisk contents...
   $(hide) rm -f $(TARGET_RECOVERY_ROOT_OUT)/init*.rc
   $(hide) cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/
@@ -1022,8 +1031,8 @@
     cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/$(newline))
   $(hide) $(foreach item,$(recovery_fstab), \
     cp -f $(item) $(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.fstab)
-  $(if $(strip $(recovery_brick)), \
-    $(hide) cp -f $(recovery_brick) $(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.brick)
+  $(if $(strip $(recovery_wipe)), \
+    $(hide) cp -f $(recovery_wipe) $(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.wipe)
   $(hide) cp $(RECOVERY_INSTALL_OTA_KEYS) $(TARGET_RECOVERY_ROOT_OUT)/res/keys
   $(hide) cat $(INSTALLED_DEFAULT_PROP_TARGET) $(recovery_build_prop) \
           > $(TARGET_RECOVERY_ROOT_OUT)/default.prop
@@ -1036,10 +1045,14 @@
     $(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1).unsigned, \
     $(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1) --id > $(RECOVERYIMAGE_ID_FILE))
   $(if $(filter true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER)),\
-    $(BOOT_SIGNER) /recovery $(1) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $(1))
+    $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
+      $(BOOT_SIGNER) /boot $(1) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $(1),\
+      $(BOOT_SIGNER) /recovery $(1) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $(1)\
+    )\
+  )
   $(if $(filter true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)), \
     $(VBOOT_SIGNER) $(FUTILITY) $(1).unsigned $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbpubk $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbprivk $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_SUBKEY).vbprivk $(1).keyblock $(1))
-  $(if $(filter true,BOARD_USES_RECOVERY_AS_BOOT), \
+  $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)), \
     $(hide) $(call assert-max-image-size,$(1),$(BOARD_BOOTIMAGE_PARTITION_SIZE)), \
     $(hide) $(call assert-max-image-size,$(1),$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)))
   @echo ----- Made recovery image: $(1) --------
@@ -1491,10 +1504,66 @@
 cacheimage-nodeps: | $(INTERNAL_USERIMAGES_DEPS)
 	$(build-cacheimage-target)
 
+else # BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
+# we need to ignore the broken cache link when doing the rsync
+IGNORE_CACHE_LINK := --exclude=cache
 endif # BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
 
 
 # -----------------------------------------------------------------
+# system_other partition image
+ifeq ($(BOARD_USES_SYSTEM_OTHER_ODEX),true)
+BOARD_USES_SYSTEM_OTHER := true
+
+# Marker file to identify that odex files are installed
+INSTALLED_SYSTEM_OTHER_ODEX_MARKER := $(TARGET_OUT_SYSTEM_OTHER)/system-other-odex-marker
+ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_SYSTEM_OTHER_ODEX_MARKER)
+$(INSTALLED_SYSTEM_OTHER_ODEX_MARKER):
+	$(hide) touch $@
+endif
+
+ifdef BOARD_USES_SYSTEM_OTHER
+INTERNAL_SYSTEMOTHERIMAGE_FILES := \
+    $(filter $(TARGET_OUT_SYSTEM_OTHER)/%,\
+      $(ALL_DEFAULT_INSTALLED_MODULES)\
+      $(ALL_PDK_FUSION_FILES))
+
+INSTALLED_FILES_FILE_SYSTEMOTHER := $(PRODUCT_OUT)/installed-files-system-other.txt
+$(INSTALLED_FILES_FILE_SYSTEMOTHER) : $(INTERNAL_SYSTEMOTHERIMAGE_FILES)
+	@echo Installed file list: $@
+	@mkdir -p $(dir $@)
+	@rm -f $@
+	$(hide) build/tools/fileslist.py $(TARGET_OUT_SYSTEM_OTHER) > $@
+
+systemotherimage_intermediates := \
+    $(call intermediates-dir-for,PACKAGING,system_other)
+BUILT_SYSTEMOTHERIMAGE_TARGET := $(PRODUCT_OUT)/system_other.img
+
+# Note that we assert the size is SYSTEMIMAGE_PARTITION_SIZE since this is the 'b' system image.
+define build-systemotherimage-target
+  $(call pretty,"Target system_other fs image: $(INSTALLED_SYSTEMOTHERIMAGE_TARGET)")
+  @mkdir -p $(TARGET_OUT_SYSTEM_OTHER)
+  @mkdir -p $(systemotherimage_intermediates) && rm -rf $(systemotherimage_intermediates)/system_other_image_info.txt
+  $(call generate-userimage-prop-dictionary, $(systemotherimage_intermediates)/system_other_image_info.txt, skip_fsck=true)
+  $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
+      ./build/tools/releasetools/build_image.py \
+      $(TARGET_OUT_SYSTEM_OTHER) $(systemotherimage_intermediates)/system_other_image_info.txt $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) $(TARGET_OUT)
+  $(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
+endef
+
+# We just build this directly to the install location.
+INSTALLED_SYSTEMOTHERIMAGE_TARGET := $(BUILT_SYSTEMOTHERIMAGE_TARGET)
+$(INSTALLED_SYSTEMOTHERIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_SYSTEMOTHERIMAGE_FILES) $(INSTALLED_FILES_FILE_SYSTEMOTHER)
+	$(build-systemotherimage-target)
+
+.PHONY: systemotherimage-nodeps
+systemotherimage-nodeps: | $(INTERNAL_USERIMAGES_DEPS)
+	$(build-systemotherimage-target)
+
+endif # BOARD_USES_SYSTEM_OTHER
+
+
+# -----------------------------------------------------------------
 # vendor partition image
 ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
 INTERNAL_VENDORIMAGE_FILES := \
@@ -1729,6 +1798,7 @@
 		$(INSTALLED_USERDATAIMAGE_TARGET) \
 		$(INSTALLED_CACHEIMAGE_TARGET) \
 		$(INSTALLED_VENDORIMAGE_TARGET) \
+		$(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
 		$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
 		$(SELINUX_FC) \
 		$(APKCERTS_FILE) \
@@ -1804,6 +1874,11 @@
 	$(hide) $(call package_files-copy-root, \
 		$(TARGET_OUT_VENDOR),$(zip_root)/VENDOR)
 endif
+ifdef INSTALLED_SYSTEMOTHERIMAGE_TARGET
+	@# Contents of the system_other image
+	$(hide) $(call package_files-copy-root, \
+		$(TARGET_OUT_SYSTEM_OTHER),$(zip_root)/SYSTEM_OTHER)
+endif
 	@# Extra contents of the OTA package
 	$(hide) mkdir -p $(zip_root)/OTA
 	$(hide) $(ACP) $(INSTALLED_ANDROID_INFO_TXT_TARGET) $(zip_root)/OTA/
@@ -1951,6 +2026,9 @@
 ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
 	$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="RECOVERY/RAMDISK/" } /^RECOVERY\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/recovery_filesystem_config.txt
 endif
+ifdef INSTALLED_SYSTEMOTHERIMAGE_TARGET
+	$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="SYSTEM_OTHER/" } /^SYSTEM_OTHER\// { print "system/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/system_other_filesystem_config.txt
+endif
 	$(hide) (cd $(zip_root) && zip -qX ../$(notdir $@) META/*filesystem_config.txt)
 	$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
 	    ./build/tools/releasetools/add_img_to_target_files -a -v -p $(HOST_OUT) $@
diff --git a/core/cleanbuild.mk b/core/cleanbuild.mk
index de6a5eb..633790c 100644
--- a/core/cleanbuild.mk
+++ b/core/cleanbuild.mk
@@ -237,6 +237,7 @@
 	$(PRODUCT_OUT)/recovery \
 	$(PRODUCT_OUT)/root \
 	$(PRODUCT_OUT)/system \
+	$(PRODUCT_OUT)/system_other \
 	$(PRODUCT_OUT)/vendor \
 	$(PRODUCT_OUT)/oem \
 	$(PRODUCT_OUT)/obj/FAKE
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 635dd55..09032b2 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -213,6 +213,8 @@
 LOCAL_NDK_VERSION:=current
 LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES:=
 LOCAL_LOGTAGS_FILES:=
+LOCAL_EXTRACT_APK:=
+LOCAL_EXTRACT_DPI_APK:=
 LOCAL_RECORDED_MODULE_TYPE:=
 
 # arch specific variables
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index fa8bb19..ff0dfd5 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -19,6 +19,10 @@
 # The default value for LOCAL_DEX_PREOPT
 DEX_PREOPT_DEFAULT ?= true
 
+# The default filter for which files go into the system_other image (if it is
+# being used). To bundle everything one should set this to '%'
+SYSTEM_OTHER_ODEX_FILTER ?= app/% priv-app/%
+
 # The default values for pre-opting: always preopt PIC.
 # Conditional to building on linux, as dex2oat currently does not work on darwin.
 ifeq ($(HOST_OS),linux)
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index d01eb1d..ba21497 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -59,6 +59,21 @@
 $(dir $(2))oat/$(1)/$(basename $(notdir $(2))).odex
 endef
 
+# Returns the full path to the installed .odex file.
+# This handles BOARD_USES_SYSTEM_OTHER_ODEX to install odex files into another
+# partition.
+# $(1): the arch name.
+# $(2): the full install path (including file name) of the corresponding .apk.
+ifeq ($(BOARD_USES_SYSTEM_OTHER_ODEX),true)
+define get-odex-installed-file-path
+$(if $(filter $(foreach f,$(SYSTEM_OTHER_ODEX_FILTER),$(TARGET_OUT)/$(f)),$(2)),
+  $(call get-odex-file-path,$(1),$(patsubst $(TARGET_OUT)/%,$(TARGET_OUT_SYSTEM_OTHER)/%,$(2))),
+  $(call get-odex-file-path,$(1),$(2)))
+endef
+else
+get-odex-installed-file-path = $(get-odex-file-path)
+endif
+
 # Returns the path to the image file (such as "/system/framework/<arch>/boot.art"
 # $(1): the arch name (such as "arm")
 # $(2): the image location (such as "/system/framework/boot.art")
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index b7ecf2e..75178ad 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -39,6 +39,14 @@
 LOCAL_DEX_PREOPT :=
 endif
 endif
+# if installing into system, and odex are being installed into system_other, don't strip
+ifeq ($(BOARD_USES_SYSTEM_OTHER_ODEX),true)
+ifeq ($(LOCAL_DEX_PREOPT),true)
+ifneq ($(filter $(foreach f,$(SYSTEM_OTHER_ODEX_FILTER),$(TARGET_OUT)/$(f)),$(my_module_path)),)
+LOCAL_DEX_PREOPT := nostripping
+endif
+endif
+endif
 
 built_odex :=
 installed_odex :=
@@ -102,13 +110,6 @@
 endif
 
 $(built_odex): PRIVATE_DEX_PREOPT_FLAGS := $(LOCAL_DEX_PREOPT_FLAGS)
-
-# Use pattern rule - we may have multiple installed odex files.
-# Ugly syntax - See the definition get-odex-file-path.
-$(installed_odex) : $(dir $(LOCAL_INSTALLED_MODULE))%$(notdir $(word 1,$(installed_odex))) \
-                  : $(dir $(LOCAL_BUILT_MODULE))%$(notdir $(word 1,$(built_odex)))
-	@echo "Install: $@"
-	$(copy-file-to-target)
 endif
 
 # Add the installed_odex to the list of installed files for this module.
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 52e985a..8643c70 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -110,6 +110,7 @@
 # TARGET_COPY_OUT_* are all relative to the staging directory, ie PRODUCT_OUT.
 # Define them here so they can be used in product config files.
 TARGET_COPY_OUT_SYSTEM := system
+TARGET_COPY_OUT_SYSTEM_OTHER := system_other
 TARGET_COPY_OUT_DATA := data
 TARGET_COPY_OUT_OEM := oem
 TARGET_COPY_OUT_ODM := odm
@@ -347,6 +348,8 @@
 TARGET_OUT_NOTICE_FILES := $(TARGET_OUT_INTERMEDIATES)/NOTICE_FILES
 TARGET_OUT_FAKE := $(PRODUCT_OUT)/fake_packages
 
+TARGET_OUT_SYSTEM_OTHER := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_SYSTEM_OTHER)
+
 # Out for TARGET_2ND_ARCH
 TARGET_2ND_ARCH_VAR_PREFIX := $(HOST_2ND_ARCH_VAR_PREFIX)
 ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
diff --git a/core/main.mk b/core/main.mk
index bf6b017..47280af 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -79,6 +79,7 @@
     cacheimage-nodeps \
     bptimage-nodeps \
     vendorimage-nodeps \
+    systemotherimage-nodeps \
     ramdisk-nodeps \
     bootimage-nodeps \
     recoveryimage-nodeps \
@@ -915,6 +916,9 @@
 .PHONY: vendorimage
 vendorimage: $(INSTALLED_VENDORIMAGE_TARGET)
 
+.PHONY: systemotherimage
+systemotherimage: $(INSTALLED_SYSTEMOTHERIMAGE_TARGET)
+
 .PHONY: bootimage
 bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
 
@@ -945,8 +949,10 @@
 	$(INSTALLED_CACHEIMAGE_TARGET) \
 	$(INSTALLED_BPTIMAGE_TARGET) \
 	$(INSTALLED_VENDORIMAGE_TARGET) \
+	$(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
 	$(INSTALLED_FILES_FILE) \
-	$(INSTALLED_FILES_FILE_VENDOR)
+	$(INSTALLED_FILES_FILE_VENDOR) \
+	$(INSTALLED_FILES_FILE_SYSTEMOTHER)
 
 # dist_files only for putting your library into the dist directory with a full build.
 .PHONY: dist_files
@@ -1007,6 +1013,7 @@
     $(SYMBOLS_ZIP) \
     $(INSTALLED_FILES_FILE) \
     $(INSTALLED_FILES_FILE_VENDOR) \
+    $(INSTALLED_FILES_FILE_SYSTEMOTHER) \
     $(INSTALLED_BUILD_PROP_TARGET) \
     $(BUILT_TARGET_FILES_PACKAGE) \
     $(INSTALLED_ANDROID_INFO_TXT_TARGET) \
diff --git a/core/pathmap.mk b/core/pathmap.mk
index 9b5a7db..edc584b 100644
--- a/core/pathmap.mk
+++ b/core/pathmap.mk
@@ -106,7 +106,11 @@
 #
 FRAMEWORKS_SUPPORT_SUBDIRS := \
         annotations \
-        v4 \
+        compat \
+        media-compat \
+        fragment \
+        core-ui \
+        core-utils \
         v7/gridlayout \
         v7/cardview \
         v7/mediarouter \
@@ -147,6 +151,7 @@
 #
 FRAMEWORKS_SUPPORT_JAVA_LIBRARIES := \
     $(foreach dir,$(FRAMEWORKS_SUPPORT_SUBDIRS),android-support-$(subst /,-,$(dir))) \
+    android-support-v4 \
     android-support-vectordrawable \
     android-support-animatedvectordrawable \
     android-support-v7-appcompat \
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 18277f9..03f110e 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -94,8 +94,10 @@
 
 ifeq ($(LOCAL_MODULE_CLASS),APPS)
 LOCAL_BUILT_MODULE_STEM := package.apk
+ifndef LOCAL_INSTALLED_MODULE_STEM
 LOCAL_INSTALLED_MODULE_STEM := $(LOCAL_MODULE).apk
 endif
+endif
 
 ifneq ($(filter true keep_symbols no_debuglink mini-debug-info,$(my_strip_module) $(my_pack_module_relocations)),)
   ifdef LOCAL_IS_HOST_MODULE
@@ -168,6 +170,8 @@
 ifeq ($(LOCAL_MODULE_CLASS),APPS)
 PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
 
+my_extract_apk := $(strip $(LOCAL_EXTRACT_APK))
+
 # Select dpi-specific source
 ifdef LOCAL_DPI_VARIANTS
 my_dpi := $(firstword $(filter $(LOCAL_DPI_VARIANTS),$(PRODUCT_AAPT_PREF_CONFIG) $(PRODUCT_AAPT_PREBUILT_DPI)))
@@ -178,9 +182,27 @@
 my_prebuilt_dpi_file_stem := $(LOCAL_MODULE)_%.apk
 endif
 my_prebuilt_src_file := $(dir $(my_prebuilt_src_file))$(subst %,$(my_dpi),$(my_prebuilt_dpi_file_stem))
+
+ifneq ($(strip $(LOCAL_EXTRACT_DPI_APK)),)
+my_extract_apk := $(subst %,$(my_dpi),$(LOCAL_EXTRACT_DPI_APK))
+endif  # LOCAL_EXTRACT_DPI_APK
 endif  # my_dpi
 endif  # LOCAL_DPI_VARIANTS
 
+ifdef my_extract_apk
+my_extracted_apk := $(intermediates)/extracted.apk
+
+$(my_extracted_apk): PRIVATE_EXTRACT := $(my_extract_apk)
+$(my_extracted_apk): $(my_prebuilt_src_file)
+	@echo Extract APK: $@
+	$(hide) mkdir -p $(dir $@) && rm -f $@
+	$(hide) unzip -p $< $(PRIVATE_EXTRACT) >$@
+
+my_prebuilt_src_file := $(my_extracted_apk)
+my_extracted_apk :=
+my_extract_apk :=
+endif
+
 rs_compatibility_jni_libs :=
 include $(BUILD_SYSTEM)/install_jni_libs.mk
 
diff --git a/core/product_config.mk b/core/product_config.mk
index 0d4ced3..6438d51 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -74,7 +74,7 @@
 ###########################################################
 
 define find-copy-subdir-files
-$(shell find $(2) -name "$(1)" | $(SED_EXTENDED) "s:($(2)/?(.*)):\\1\\:$(3)/\\2:" | sed "s://:/:g")
+$(sort $(shell find $(2) -name "$(1)" -type f | $(SED_EXTENDED) "s:($(2)/?(.*)):\\1\\:$(3)/\\2:" | sed "s://:/:g"))
 endef
 
 # ---------------------------------------------------------------
diff --git a/core/setup_one_odex.mk b/core/setup_one_odex.mk
index ec8a28a..36b6817 100644
--- a/core/setup_one_odex.mk
+++ b/core/setup_one_odex.mk
@@ -32,7 +32,9 @@
     $(DEXPREOPT_ONE_FILE_DEPENDENCY_TOOLS) \
     $(my_dex_preopt_image_filename)
 
-my_installed_odex := $(call get-odex-file-path,$($(my_2nd_arch_prefix)DEX2OAT_TARGET_ARCH),$(LOCAL_INSTALLED_MODULE))
+my_installed_odex := $(call get-odex-installed-file-path,$($(my_2nd_arch_prefix)DEX2OAT_TARGET_ARCH),$(LOCAL_INSTALLED_MODULE))
+
+$(eval $(call copy-one-file,$(my_built_odex),$(my_installed_odex)))
 
 built_odex += $(my_built_odex)
 installed_odex += $(my_installed_odex)
diff --git a/core/tasks/vendor_module_check.mk b/core/tasks/vendor_module_check.mk
index 2a9c3d8..ae967c6 100644
--- a/core/tasks/vendor_module_check.mk
+++ b/core/tasks/vendor_module_check.mk
@@ -43,6 +43,7 @@
         synaptics \
         ti \
         trusted_logic \
+        verizon \
         widevine
 
 
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 57a6f8a..f207185 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -25,7 +25,7 @@
 #     BUILD_ID
 #     BUILD_NUMBER
 #     BUILD_DATETIME
-#     SECURITY_PATCH
+#     PLATFORM_SECURITY_PATCH
 #
 
 # Look for an optional file containing overrides of the defaults,
@@ -43,7 +43,7 @@
   # which is the version that we reveal to the end user.
   # Update this value when the platform version changes (rather
   # than overriding it somewhere else).  Can be an arbitrary string.
-  PLATFORM_VERSION := 7.0
+  PLATFORM_VERSION := NMR1
 endif
 
 ifeq "" "$(PLATFORM_SDK_VERSION)"
@@ -55,7 +55,7 @@
   # intermediate builds).  During development, this number remains at the
   # SDK version the branch is based on and PLATFORM_VERSION_CODENAME holds
   # the code-name of the new development work.
-  PLATFORM_SDK_VERSION := 24
+  PLATFORM_SDK_VERSION := 25
 endif
 
 ifeq "" "$(PLATFORM_JACK_MIN_SDK_VERSION)"
@@ -64,13 +64,13 @@
   # 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 := 25
 endif
 
 ifeq "" "$(PLATFORM_VERSION_CODENAME)"
   # This is the current development code-name, if the build is not a final
   # release build.  If this is a final release build, it is simply "REL".
-  PLATFORM_VERSION_CODENAME := REL
+  PLATFORM_VERSION_CODENAME := NMR1
 
   # This is all of the development codenames that are active.  Should be either
   # the same as PLATFORM_VERSION_CODENAME or a comma-separated list of additional
@@ -91,7 +91,7 @@
     # assuming the device can only support APIs as of the previous official
     # public release.
     # This value will always be 0 for release builds.
-    PLATFORM_PREVIEW_SDK_VERSION := 0
+    PLATFORM_PREVIEW_SDK_VERSION := 1
   endif
 endif
 
diff --git a/target/product/core.mk b/target/product/core.mk
index 75cf649..0a4e0fd 100644
--- a/target/product/core.mk
+++ b/target/product/core.mk
@@ -53,6 +53,7 @@
     QuickSearchBox \
     Settings \
     SharedStorageBackup \
+    StorageManager \
     Telecom \
     TeleService \
     VpnDialogs \
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 5730019..aeb73d4 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -39,6 +39,7 @@
 
 import build_image
 import common
+import sparse_img
 
 OPTIONS = common.OPTIONS
 
@@ -48,6 +49,19 @@
 OPTIONS.replace_verity_private_key = False
 OPTIONS.verity_signer_path = None
 
+def GetCareMap(which, imgname):
+  """Generate care_map of system (or vendor) partition"""
+
+  assert which in ("system", "vendor")
+  _, blk_device = common.GetTypeAndDevice("/" + which, OPTIONS.info_dict)
+
+  simg = sparse_img.SparseImage(imgname)
+  care_map_list = []
+  care_map_list.append(blk_device)
+  care_map_list.append(simg.care_map.to_string_raw())
+  return care_map_list
+
+
 def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None):
   """Turn the contents of SYSTEM into a system image and store it in
   output_zip. Returns the name of the system image file."""
@@ -95,6 +109,24 @@
   return CreateImage(input_dir, info_dict, "system", block_list=block_list)
 
 
+def AddSystemOther(output_zip, prefix="IMAGES/"):
+  """Turn the contents of SYSTEM_OTHER into a system_other image
+  and store it in output_zip."""
+
+  prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "system_other.img")
+  if os.path.exists(prebuilt_path):
+    print "system_other.img already exists in %s, no need to rebuild..." % (prefix,)
+    return
+
+  imgname = BuildSystemOther(OPTIONS.input_tmp, OPTIONS.info_dict)
+  common.ZipWrite(output_zip, imgname, prefix + "system_other.img")
+
+def BuildSystemOther(input_dir, info_dict):
+  """Build the (sparse) system_other image and return the name of a temp
+  file containing it."""
+  return CreateImage(input_dir, info_dict, "system_other", block_list=None)
+
+
 def AddVendor(output_zip, prefix="IMAGES/"):
   """Turn the contents of VENDOR into a vendor image and store in it
   output_zip."""
@@ -102,13 +134,14 @@
   prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "vendor.img")
   if os.path.exists(prebuilt_path):
     print "vendor.img already exists in %s, no need to rebuild..." % (prefix,)
-    return
+    return prebuilt_path
 
   block_list = common.MakeTempFile(prefix="vendor-blocklist-", suffix=".map")
   imgname = BuildVendor(OPTIONS.input_tmp, OPTIONS.info_dict,
                         block_list=block_list)
   common.ZipWrite(output_zip, imgname, prefix + "vendor.img")
   common.ZipWrite(output_zip, block_list, prefix + "vendor.map")
+  return imgname
 
 
 def BuildVendor(input_dir, info_dict, block_list=None):
@@ -138,8 +171,9 @@
 
   image_props = build_image.ImagePropFromGlobalDict(info_dict, what)
   fstab = info_dict["fstab"]
-  if fstab:
-    image_props["fs_type"] = fstab["/" + what].fs_type
+  mount_point = "/" + what
+  if fstab and mount_point in fstab:
+    image_props["fs_type"] = fstab[mount_point].fs_type
 
   # Use a fixed timestamp (01/01/2009) when packaging the image.
   # Bug: 24377993
@@ -312,6 +346,8 @@
   except KeyError:
     has_vendor = False
 
+  has_system_other = "SYSTEM_OTHER/" in input_zip.namelist()
+
   OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)
 
   common.ZipClose(input_zip)
@@ -382,9 +418,13 @@
       system_img_path=system_img_path)
     if boot_image:
       boot_image.AddToZip(output_zip)
+  vendor_img_path = None
   if has_vendor:
     banner("vendor")
-    AddVendor(output_zip)
+    vendor_img_path = AddVendor(output_zip)
+  if has_system_other:
+    banner("system_other")
+    AddSystemOther(output_zip)
   banner("userdata")
   AddUserdata(output_zip)
   banner("cache")
@@ -401,7 +441,19 @@
   if os.path.exists(ab_partitions):
     with open(ab_partitions, 'r') as f:
       lines = f.readlines()
+    # For devices using A/B update, generate care_map for system and vendor
+    # partitions (if present), then write this file to target_files package.
+    care_map_list = []
     for line in lines:
+      if line.strip() == "system" and OPTIONS.info_dict.get(
+          "system_verity_block_device", None) is not None:
+        assert os.path.exists(system_img_path)
+        care_map_list += GetCareMap("system", system_img_path)
+      if line.strip() == "vendor" and OPTIONS.info_dict.get(
+          "vendor_verity_block_device", None) is not None:
+        assert os.path.exists(vendor_img_path)
+        care_map_list += GetCareMap("vendor", vendor_img_path)
+
       img_name = line.strip() + ".img"
       prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
       if os.path.exists(prebuilt_path):
@@ -425,6 +477,10 @@
       img_path = 'IMAGES/' + img_name
       assert img_path in output_zip.namelist(), "cannot find " + img_name
 
+    if care_map_list:
+      file_path = "META/care_map.txt"
+      common.ZipWriteStr(output_zip, file_path, '\n'.join(care_map_list))
+
   common.ZipClose(output_zip)
 
 def main(argv):
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index 66d5907..0d9aabd 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -342,19 +342,20 @@
     return ctx.hexdigest()
 
   def WriteTransfers(self, prefix):
-    def WriteTransfersZero(out, to_zero):
-      """Limit the number of blocks in command zero to 1024 blocks.
+    def WriteSplitTransfers(out, style, target_blocks):
+      """Limit the size of operand in command 'new' and 'zero' to 1024 blocks.
 
       This prevents the target size of one command from being too large; and
       might help to avoid fsync errors on some devices."""
 
-      zero_blocks_limit = 1024
+      assert (style == "new" or style == "zero")
+      blocks_limit = 1024
       total = 0
-      while to_zero:
-        zero_blocks = to_zero.first(zero_blocks_limit)
-        out.append("zero %s\n" % (zero_blocks.to_string_raw(),))
-        total += zero_blocks.size()
-        to_zero = to_zero.subtract(zero_blocks)
+      while target_blocks:
+        blocks_to_write = target_blocks.first(blocks_limit)
+        out.append("%s %s\n" % (style, blocks_to_write.to_string_raw()))
+        total += blocks_to_write.size()
+        target_blocks = target_blocks.subtract(blocks_to_write)
       return total
 
     out = []
@@ -478,7 +479,7 @@
 
       if xf.style == "new":
         assert xf.tgt_ranges
-        out.append("%s %s\n" % (xf.style, xf.tgt_ranges.to_string_raw()))
+        assert tgt_size == WriteSplitTransfers(out, xf.style, xf.tgt_ranges)
         total += tgt_size
       elif xf.style == "move":
         assert xf.tgt_ranges
@@ -538,7 +539,7 @@
       elif xf.style == "zero":
         assert xf.tgt_ranges
         to_zero = xf.tgt_ranges.subtract(xf.src_ranges)
-        assert WriteTransfersZero(out, to_zero) == to_zero.size()
+        assert WriteSplitTransfers(out, xf.style, to_zero) == to_zero.size()
         total += to_zero.size()
       else:
         raise ValueError("unknown transfer style '%s'\n" % xf.style)
@@ -568,7 +569,7 @@
 
     # Zero out extended blocks as a workaround for bug 20881595.
     if self.tgt.extended:
-      assert (WriteTransfersZero(out, self.tgt.extended) ==
+      assert (WriteSplitTransfers(out, "zero", self.tgt.extended) ==
               self.tgt.extended.size())
       total += self.tgt.extended.size()
 
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 9ee472b..b105265 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -406,6 +406,8 @@
       build_command.extend(["-z", prop_dict["squashfs_compressor"]])
     if "squashfs_compressor_opt" in prop_dict:
       build_command.extend(["-zo", prop_dict["squashfs_compressor_opt"]])
+    if "squashfs_block_size" in prop_dict:
+      build_command.extend(["-b", prop_dict["squashfs_block_size"]])
     if "squashfs_disable_4k_align" in prop_dict and prop_dict.get("squashfs_disable_4k_align") == "true":
       build_command.extend(["-a"])
   elif fs_type.startswith("f2fs"):
@@ -544,8 +546,22 @@
     copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
     copy_prop("system_squashfs_compressor", "squashfs_compressor")
     copy_prop("system_squashfs_compressor_opt", "squashfs_compressor_opt")
+    copy_prop("system_squashfs_block_size", "squashfs_block_size")
     copy_prop("system_squashfs_disable_4k_align", "squashfs_disable_4k_align")
     copy_prop("system_base_fs_file", "base_fs_file")
+  elif mount_point == "system_other":
+    # We inherit the selinux policies of /system since we contain some of its files.
+    d["mount_point"] = "system"
+    copy_prop("fs_type", "fs_type")
+    copy_prop("system_fs_type", "fs_type")
+    copy_prop("system_size", "partition_size")
+    copy_prop("system_journal_size", "journal_size")
+    copy_prop("system_verity_block_device", "verity_block_device")
+    copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
+    copy_prop("system_squashfs_compressor", "squashfs_compressor")
+    copy_prop("system_squashfs_compressor_opt", "squashfs_compressor_opt")
+    copy_prop("system_squashfs_block_size", "squashfs_block_size")
+    copy_prop("system_base_fs_file", "base_fs_file")
   elif mount_point == "data":
     # Copy the generic fs type first, override with specific one if available.
     copy_prop("fs_type", "fs_type")
@@ -562,6 +578,7 @@
     copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
     copy_prop("vendor_squashfs_compressor", "squashfs_compressor")
     copy_prop("vendor_squashfs_compressor_opt", "squashfs_compressor_opt")
+    copy_prop("vendor_squashfs_block_size", "squashfs_block_size")
     copy_prop("vendor_squashfs_disable_4k_align", "squashfs_disable_4k_align")
     copy_prop("vendor_base_fs_file", "base_fs_file")
   elif mount_point == "oem":
@@ -607,6 +624,8 @@
     mount_point = ""
     if image_filename == "system.img":
       mount_point = "system"
+    elif image_filename == "system_other.img":
+      mount_point = "system_other"
     elif image_filename == "userdata.img":
       mount_point = "data"
     elif image_filename == "cache.img":
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 3f3b011..e035302 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -251,11 +251,18 @@
   makeint("boot_size")
   makeint("fstab_version")
 
-  if d.get("no_recovery", False) == "true":
-    d["fstab"] = None
-  else:
+  system_root_image = d.get("system_root_image", None) == "true"
+  if d.get("no_recovery", None) != "true":
+    recovery_fstab_path = "RECOVERY/RAMDISK/etc/recovery.fstab"
     d["fstab"] = LoadRecoveryFSTab(read_helper, d["fstab_version"],
-                                   d.get("system_root_image", False))
+        recovery_fstab_path, system_root_image)
+  elif d.get("recovery_as_boot", None) == "true":
+    recovery_fstab_path = "BOOT/RAMDISK/etc/recovery.fstab"
+    d["fstab"] = LoadRecoveryFSTab(read_helper, d["fstab_version"],
+        recovery_fstab_path, system_root_image)
+  else:
+    d["fstab"] = None
+
   d["build.prop"] = LoadBuildProp(read_helper)
   return d
 
@@ -278,7 +285,8 @@
       d[name] = value
   return d
 
-def LoadRecoveryFSTab(read_helper, fstab_version, system_root_image=False):
+def LoadRecoveryFSTab(read_helper, fstab_version, recovery_fstab_path,
+                      system_root_image=False):
   class Partition(object):
     def __init__(self, mount_point, fs_type, device, length, device2, context):
       self.mount_point = mount_point
@@ -289,9 +297,9 @@
       self.context = context
 
   try:
-    data = read_helper("RECOVERY/RAMDISK/etc/recovery.fstab")
+    data = read_helper(recovery_fstab_path)
   except KeyError:
-    print "Warning: could not find RECOVERY/RAMDISK/etc/recovery.fstab"
+    print "Warning: could not find {}".format(recovery_fstab_path)
     data = ""
 
   if fstab_version == 1:
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index f32d9d8..dc93a9d 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -1317,6 +1317,19 @@
                   compress_type=zipfile.ZIP_STORED)
   WriteMetadata(metadata, output_zip)
 
+  # If dm-verity is supported for the device, copy contents of care_map
+  # into A/B OTA package.
+  if OPTIONS.info_dict.get("verity") == "true":
+    target_zip = zipfile.ZipFile(target_file, "r")
+    care_map_path = "META/care_map.txt"
+    namelist = target_zip.namelist()
+    if care_map_path in namelist:
+      care_map_data = target_zip.read(care_map_path)
+      common.ZipWriteStr(output_zip, "care_map.txt", care_map_data)
+    else:
+      print "Warning: cannot find care map file in target_file package"
+    common.ZipClose(target_zip)
+
   # Sign the whole package to comply with the Android OTA package format.
   common.ZipClose(output_zip)
   SignOutput(temp_zip_file.name, output_file)