Make change and version bump to QP1A.190117.001
Change-Id: I1224ea54d0e6d18aff6d5bc5394de7383fc74319
diff --git a/core/build_id.mk b/core/build_id.mk
index 1f7ee18..d5f4542 100644
--- a/core/build_id.mk
+++ b/core/build_id.mk
@@ -18,4 +18,4 @@
# (like "CRB01"). It must be a single word, and is
# capitalized by convention.
-BUILD_ID=QP1A.190116.001
+BUILD_ID=QP1A.190117.001
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index 69790cb..58c458a 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -122,8 +122,7 @@
ifeq ($(LOCAL_MODULE_CLASS),JAVA_LIBRARIES)
my_module_multilib := $(LOCAL_MULTILIB)
# If the module is not an SDK library and it's a system server jar, only preopt the primary arch.
- my_filtered_lib_name := $(patsubst %.impl,%,$(LOCAL_MODULE))
- ifeq (,$(filter $(JAVA_SDK_LIBRARIES),$(my_filtered_lib_name)))
+ ifeq (,$(filter $(JAVA_SDK_LIBRARIES),$(LOCAL_MODULE)))
# For a Java library, by default we build odex for both 1st arch and 2nd arch.
# But it can be overridden with "LOCAL_MULTILIB := first".
ifneq (,$(filter $(PRODUCT_SYSTEM_SERVER_JARS),$(LOCAL_MODULE)))
@@ -192,7 +191,7 @@
$(call add_json_list, OptionalUsesLibraries, $(LOCAL_OPTIONAL_USES_LIBRARIES))
$(call add_json_list, UsesLibraries, $(LOCAL_USES_LIBRARIES))
$(call add_json_map, LibraryPaths)
- $(foreach lib,$(sort $(LOCAL_USES_LIBRARIES) $(LOCAL_OPTIONAL_USES_LIBRARIES) org.apache.http.legacy.impl android.hidl.base-V1.0-java android.hidl.manager-V1.0-java),\
+ $(foreach lib,$(sort $(LOCAL_USES_LIBRARIES) $(LOCAL_OPTIONAL_USES_LIBRARIES) org.apache.http.legacy android.hidl.base-V1.0-java android.hidl.manager-V1.0-java),\
$(call add_json_str, $(lib), $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar))
$(call end_json_map)
$(call add_json_list, Archs, $(my_dexpreopt_archs))
@@ -234,7 +233,7 @@
my_dexpreopt_deps := $(my_dex_jar)
my_dexpreopt_deps += $(if $(my_process_profile),$(LOCAL_DEX_PREOPT_PROFILE))
my_dexpreopt_deps += \
- $(foreach lib,$(sort $(LOCAL_USES_LIBRARIES) $(LOCAL_OPTIONAL_USES_LIBRARIES) org.apache.http.legacy.impl android.hidl.base-V1.0-java android.hidl.manager-V1.0-java),\
+ $(foreach lib,$(sort $(LOCAL_USES_LIBRARIES) $(LOCAL_OPTIONAL_USES_LIBRARIES) org.apache.http.legacy android.hidl.base-V1.0-java android.hidl.manager-V1.0-java),\
$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar)
my_dexpreopt_deps += $(LOCAL_DEX_PREOPT_IMAGE_LOCATION)
# TODO: default boot images
diff --git a/core/java_common.mk b/core/java_common.mk
index ac26e5e..4e331d0 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -280,7 +280,7 @@
sdk_libs := $(foreach lib_name,$(LOCAL_SDK_LIBRARIES),$(call resolve-prebuilt-sdk-module,system_current,$(lib_name)))
else
# When SDK libraries are referenced from modules built without SDK, provide the all APIs to them
- sdk_libs := $(foreach lib_name,$(LOCAL_SDK_LIBRARIES),$(lib_name).impl)
+ sdk_libs := $(foreach lib_name,$(LOCAL_SDK_LIBRARIES),$(lib_name))
endif
else
ifeq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index c50df07..91865bc 100644
--- a/core/soong_app_prebuilt.mk
+++ b/core/soong_app_prebuilt.mk
@@ -27,22 +27,8 @@
full_classes_pre_proguard_jar := $(intermediates.COMMON)/classes-pre-proguard.jar
full_classes_header_jar := $(intermediates.COMMON)/classes-header.jar
-ifdef LOCAL_SOONG_CLASSES_JAR
- $(eval $(call copy-one-file,$(LOCAL_SOONG_CLASSES_JAR),$(full_classes_jar)))
- $(eval $(call copy-one-file,$(LOCAL_SOONG_CLASSES_JAR),$(full_classes_pre_proguard_jar)))
- $(eval $(call add-dependency,$(LOCAL_BUILT_MODULE),$(full_classes_jar)))
-
- ifneq ($(TURBINE_ENABLED),false)
- ifdef LOCAL_SOONG_HEADER_JAR
- $(eval $(call copy-one-file,$(LOCAL_SOONG_HEADER_JAR),$(full_classes_header_jar)))
- $(eval $(call add-dependency,$(full_classes_jar),$(full_classes_header_jar)))
- else
- $(eval $(call copy-one-file,$(full_classes_jar),$(full_classes_header_jar)))
- endif
- endif # TURBINE_ENABLED != false
-endif
-
-$(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(LOCAL_BUILT_MODULE)))
+$(eval $(call copy-one-file,$(LOCAL_SOONG_CLASSES_JAR),$(full_classes_jar)))
+$(eval $(call copy-one-file,$(LOCAL_SOONG_CLASSES_JAR),$(full_classes_pre_proguard_jar)))
ifdef LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR
$(eval $(call copy-one-file,$(LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR),\
@@ -58,6 +44,15 @@
$(intermediates.COMMON)/proguard_dictionary)
endif
+ifneq ($(TURBINE_ENABLED),false)
+ifdef LOCAL_SOONG_HEADER_JAR
+$(eval $(call copy-one-file,$(LOCAL_SOONG_HEADER_JAR),$(full_classes_header_jar)))
+else
+$(eval $(call copy-one-file,$(full_classes_jar),$(full_classes_header_jar)))
+endif
+endif # TURBINE_ENABLED != false
+
+
ifdef LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE
resource_export_package := $(intermediates.COMMON)/package-export.apk
resource_export_stamp := $(intermediates.COMMON)/src/R.stamp
@@ -79,6 +74,29 @@
$(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(dir $(LOCAL_BUILT_MODULE))package.dex.apk))
endif
+# Run veridex on product, product_services and vendor modules.
+# We skip it for unbundled app builds where we cannot build veridex.
+module_run_appcompat :=
+ifeq (true,$(filter true, \
+ $(LOCAL_PRODUCT_MODULE) $(LOCAL_PRODUCT_SERVICES_MODULE) \
+ $(LOCAL_VENDOR_MODULE) $(LOCAL_PROPRIETARY_MODULE)))
+ifeq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK))) # ! unbundled app build
+ module_run_appcompat := true
+endif
+endif
+
+ifeq ($(module_run_appcompat),true)
+ $(LOCAL_BUILT_MODULE): $(appcompat-files)
+ $(LOCAL_BUILT_MODULE): PRIVATE_INSTALLED_MODULE := $(LOCAL_INSTALLED_MODULE)
+ $(LOCAL_BUILT_MODULE): $(LOCAL_PREBUILT_MODULE_FILE)
+ @echo "Copy: $@"
+ $(copy-file-to-target)
+ $(call appcompat-header, aapt2)
+ $(run-appcompat)
+else
+ $(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(LOCAL_BUILT_MODULE)))
+endif
+
my_built_installed := $(foreach f,$(LOCAL_SOONG_BUILT_INSTALLED),\
$(call word-colon,1,$(f)):$(PRODUCT_OUT)$(call word-colon,2,$(f)))
my_installed := $(call copy-many-files, $(my_built_installed))
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index 81a65d0..cfda44e 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -24,22 +24,8 @@
hiddenapi_flags_csv := $(intermediates.COMMON)/hiddenapi/flags.csv
hiddenapi_metadata_csv := $(intermediates.COMMON)/hiddenapi/greylist.csv
-ifdef LOCAL_SOONG_CLASSES_JAR
- $(eval $(call copy-one-file,$(LOCAL_SOONG_CLASSES_JAR),$(full_classes_jar)))
- $(eval $(call copy-one-file,$(LOCAL_SOONG_CLASSES_JAR),$(full_classes_pre_proguard_jar)))
- $(eval $(call add-dependency,$(LOCAL_BUILT_MODULE),$(full_classes_jar)))
-
- ifneq ($(TURBINE_ENABLED),false)
- ifdef LOCAL_SOONG_HEADER_JAR
- $(eval $(call copy-one-file,$(LOCAL_SOONG_HEADER_JAR),$(full_classes_header_jar)))
- $(eval $(call add-dependency,$(full_classes_jar),$(full_classes_header_jar)))
- else
- $(eval $(call copy-one-file,$(full_classes_jar),$(full_classes_header_jar)))
- endif
- endif # TURBINE_ENABLED != false
-endif
-
-$(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(LOCAL_BUILT_MODULE)))
+$(eval $(call copy-one-file,$(LOCAL_SOONG_CLASSES_JAR),$(full_classes_jar)))
+$(eval $(call copy-one-file,$(LOCAL_SOONG_CLASSES_JAR),$(full_classes_pre_proguard_jar)))
ifdef LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR
$(eval $(call copy-one-file,$(LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR),\
@@ -78,33 +64,49 @@
$(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_static_library_android_manifest))
endif # LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE
+ifneq ($(TURBINE_ENABLED),false)
+ifdef LOCAL_SOONG_HEADER_JAR
+$(eval $(call copy-one-file,$(LOCAL_SOONG_HEADER_JAR),$(full_classes_header_jar)))
+else
+$(eval $(call copy-one-file,$(full_classes_jar),$(full_classes_header_jar)))
+endif
+endif # TURBINE_ENABLED != false
ifdef LOCAL_SOONG_DEX_JAR
- ifndef LOCAL_IS_HOST_MODULE
- ifneq ($(filter $(LOCAL_MODULE),$(PRODUCT_BOOT_JARS)),) # is_boot_jar
- # Derive greylist from classes.jar.
- # We use full_classes_jar here, which is the post-proguard jar (on the basis that we also
- # have a full_classes_pre_proguard_jar). This is consistent with the equivalent code in
- # java.mk.
- $(eval $(call hiddenapi-generate-csv,$(full_classes_jar),$(hiddenapi_flags_csv),$(hiddenapi_metadata_csv)))
- $(eval $(call hiddenapi-copy-soong-jar,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
+ ifneq ($(LOCAL_UNINSTALLABLE_MODULE),true)
+ ifndef LOCAL_IS_HOST_MODULE
+ ifneq ($(filter $(LOCAL_MODULE),$(PRODUCT_BOOT_JARS)),) # is_boot_jar
+ # Derive greylist from classes.jar.
+ # We use full_classes_jar here, which is the post-proguard jar (on the basis that we also
+ # have a full_classes_pre_proguard_jar). This is consistent with the equivalent code in
+ # java.mk.
+ $(eval $(call hiddenapi-generate-csv,$(full_classes_jar),$(hiddenapi_flags_csv),$(hiddenapi_metadata_csv)))
+ $(eval $(call hiddenapi-copy-soong-jar,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
- ifeq (true,$(WITH_DEXPREOPT))
- # For libart, the boot jars' odex files are replaced by $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE).
- # We use this installed_odex trick to get boot.art installed.
- installed_odex := $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE)
- # Append the odex for the 2nd arch if we have one.
- installed_odex += $($(TARGET_2ND_ARCH_VAR_PREFIX)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE)
- ALL_MODULES.$(my_register_name).INSTALLED += $(installed_odex)
- # Make sure to install the .odex and .vdex when you run "make <module_name>"
- $(my_all_targets): $(installed_odex)
- endif
- else # !is_boot_jar
- $(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
- endif # is_boot_jar
+ ifeq (true,$(WITH_DEXPREOPT))
+ # For libart, the boot jars' odex files are replaced by $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE).
+ # We use this installed_odex trick to get boot.art installed.
+ installed_odex := $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE)
+ # Append the odex for the 2nd arch if we have one.
+ installed_odex += $($(TARGET_2ND_ARCH_VAR_PREFIX)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE)
+ ALL_MODULES.$(my_register_name).INSTALLED += $(installed_odex)
+ # Make sure to install the .odex and .vdex when you run "make <module_name>"
+ $(my_all_targets): $(installed_odex)
+ endif
+ else # !is_boot_jar
+ $(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
+ endif # is_boot_jar
+ $(eval $(call add-dependency,$(common_javalib.jar),$(full_classes_jar) $(full_classes_header_jar)))
- $(eval $(call add-dependency,$(LOCAL_BUILT_MODULE),$(common_javalib.jar)))
- $(eval $(call add-dependency,$(common_javalib.jar),$(full_classes_jar) $(full_classes_header_jar)))
+ $(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(LOCAL_BUILT_MODULE)))
+ $(eval $(call add-dependency,$(LOCAL_BUILT_MODULE),$(common_javalib.jar)))
+ else # LOCAL_IS_HOST_MODULE
+ $(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(LOCAL_BUILT_MODULE)))
+ $(eval $(call add-dependency,$(LOCAL_BUILT_MODULE),$(full_classes_jar) $(full_classes_header_jar)))
+ endif
+
+ java-dex : $(LOCAL_BUILT_MODULE)
+ else # LOCAL_UNINSTALLABLE_MODULE
ifneq ($(filter $(LOCAL_MODULE),$(HIDDENAPI_EXTRA_APP_USAGE_JARS)),)
# Derive greylist from classes.jar.
@@ -113,15 +115,18 @@
# java.mk.
$(eval $(call hiddenapi-generate-csv,$(full_classes_jar),$(hiddenapi_flags_csv),$(hiddenapi_metadata_csv)))
endif
- endif
- java-dex : $(LOCAL_BUILT_MODULE)
+ $(eval $(call copy-one-file,$(full_classes_jar),$(LOCAL_BUILT_MODULE)))
+ $(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
+ java-dex : $(common_javalib.jar)
+ endif # LOCAL_UNINSTALLABLE_MODULE
else # LOCAL_SOONG_DEX_JAR
ifndef LOCAL_UNINSTALLABLE_MODULE
ifndef LOCAL_IS_HOST_MODULE
$(call pretty-error,Installable device module must have LOCAL_SOONG_DEX_JAR set)
endif
endif
+ $(eval $(call copy-one-file,$(full_classes_jar),$(LOCAL_BUILT_MODULE)))
endif # LOCAL_SOONG_DEX_JAR
my_built_installed := $(foreach f,$(LOCAL_SOONG_BUILT_INSTALLED),\
diff --git a/target/board/BoardConfigGsiCommon.mk b/target/board/BoardConfigGsiCommon.mk
index f9e9ee1..05ce35f 100644
--- a/target/board/BoardConfigGsiCommon.mk
+++ b/target/board/BoardConfigGsiCommon.mk
@@ -25,8 +25,8 @@
# Enable dynamic system image size and reserved 64MB in it.
BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE := 67108864
-# GSI always requires separate vendor packages to vendor.img
-TARGET_COPY_OUT_VENDOR := vendor
+# GSI forces product packages to /system for now.
+TARGET_COPY_OUT_PRODUCT := system/product
# Creates metadata partition mount point under root for
# the devices with metadata parition
diff --git a/target/board/BoardConfigMainlineCommon.mk b/target/board/BoardConfigMainlineCommon.mk
index ec3c74f..46e5d93 100644
--- a/target/board/BoardConfigMainlineCommon.mk
+++ b/target/board/BoardConfigMainlineCommon.mk
@@ -8,6 +8,10 @@
TARGET_USERIMAGES_USE_EXT4 := true
+# Mainline devices must have /vendor and /product partitions.
+TARGET_COPY_OUT_VENDOR := vendor
+TARGET_COPY_OUT_PRODUCT := product
+
# system-as-root is mandatory from Android P
TARGET_NO_RECOVERY := true
BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index f5defcf..8c20a42 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -296,7 +296,7 @@
PRODUCT_PACKAGES += framework-oahl-backward-compatibility
PRODUCT_BOOT_JARS += framework-oahl-backward-compatibility
else
-PRODUCT_BOOT_JARS += org.apache.http.legacy.impl
+PRODUCT_BOOT_JARS += org.apache.http.legacy
endif
PRODUCT_COPY_FILES += \
@@ -311,7 +311,7 @@
PRODUCT_PACKAGES += framework-atb-backward-compatibility
PRODUCT_BOOT_JARS += framework-atb-backward-compatibility
else
-PRODUCT_BOOT_JARS += android.test.base.impl
+PRODUCT_BOOT_JARS += android.test.base
endif
PRODUCT_COPY_FILES += system/core/rootdir/init.zygote32.rc:root/init.zygote32.rc
diff --git a/target/product/gsi/current.txt b/target/product/gsi/current.txt
index bd5d97e..fa0cecd 100644
--- a/target/product/gsi/current.txt
+++ b/target/product/gsi/current.txt
@@ -106,6 +106,7 @@
VNDK-core: android.hardware.fastboot@1.0.so
VNDK-core: android.hardware.gatekeeper@1.0.so
VNDK-core: android.hardware.gnss.measurement_corrections@1.0.so
+VNDK-core: android.hardware.gnss.visibility_control@1.0.so
VNDK-core: android.hardware.gnss@1.0.so
VNDK-core: android.hardware.gnss@1.1.so
VNDK-core: android.hardware.gnss@2.0.so
diff --git a/target/product/mainline_arm64.mk b/target/product/mainline_arm64.mk
index d6ccd34..e15c876 100644
--- a/target/product/mainline_arm64.mk
+++ b/target/product/mainline_arm64.mk
@@ -45,6 +45,7 @@
system/app/Music/Music.apk \
system/app/PrintRecommendationService/PrintRecommendationService.apk \
system/app/QuickSearchBox/QuickSearchBox.apk \
+ system/app/webview/webview.apk \
system/bin/healthd \
system/etc/init/healthd.rc \
system/etc/vintf/manifest/manifest_healthd.xml \
diff --git a/target/product/mainline_system.mk b/target/product/mainline_system.mk
index d91fa12..e494880 100644
--- a/target/product/mainline_system.mk
+++ b/target/product/mainline_system.mk
@@ -65,7 +65,7 @@
# - These libraries are used by the new media code path that relies on new
# plugins and HAL implementations that may not exist on older devices.
PRODUCT_PACKAGES += \
- libmedia_codecserviceregistrant \
+ com.android.media.swcodec \
libsfplugin_ccodec \
# For ringtones that rely on forward lock encryption
diff --git a/target/product/media_system.mk b/target/product/media_system.mk
index 38488ec..b59bbd3 100644
--- a/target/product/media_system.mk
+++ b/target/product/media_system.mk
@@ -58,7 +58,6 @@
requestsync \
StatementService \
vndk_snapshot_package \
- webview \
PRODUCT_COPY_FILES += \
@@ -74,7 +73,7 @@
services \
ethernet-service \
wifi-service \
- com.android.location.provider.impl \
+ com.android.location.provider \
PRODUCT_COPY_FILES += \
system/core/rootdir/etc/public.libraries.android.txt:system/etc/public.libraries.txt
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 6aaff6b..ad0432d 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -76,7 +76,12 @@
cmd = ["find", path, "-print"]
output = common.RunAndCheckOutput(cmd, verbose=False)
# increase by > 4% as number of files and directories is not whole picture.
- return output.count('\n') * 25 // 24
+ inodes = output.count('\n')
+ spare_inodes = inodes * 4 // 100
+ min_spare_inodes = 8
+ if spare_inodes < min_spare_inodes:
+ spare_inodes = min_spare_inodes
+ return inodes + spare_inodes
def GetFilesystemCharacteristics(image_path, sparse_image=True):
@@ -436,8 +441,8 @@
size -= free_size
size += reserved_size
if reserved_size == 0:
- # add .2% margin
- size = size * 1002 // 1000
+ # add .3% margin
+ size = size * 1003 // 1000
# Use a minimum size, otherwise we will fail to calculate an AVB footer
# or fail to construct an ext4 image.
size = max(size, 256 * 1024)
@@ -448,8 +453,12 @@
extfs_inode_count = prop_dict["extfs_inode_count"]
inodes = int(fs_dict.get("Inode count", extfs_inode_count))
inodes -= int(fs_dict.get("Free inodes", "0"))
- # add .2% margin
- inodes = inodes * 1002 // 1000
+ # add .2% margin or 1 inode, whichever is greater
+ spare_inodes = inodes * 2 // 1000
+ min_spare_inodes = 1
+ if spare_inodes < min_spare_inodes:
+ spare_inodes = min_spare_inodes
+ inodes += spare_inodes
prop_dict["extfs_inode_count"] = str(inodes)
prop_dict["partition_size"] = str(size)
logger.info(
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index dcc083c..be2c108 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -14,6 +14,7 @@
from __future__ import print_function
+import collections
import copy
import errno
import getopt
@@ -1523,6 +1524,13 @@
"""Called at the start of full OTA installation."""
return self._DoCall("FullOTA_InstallBegin")
+ def FullOTA_GetBlockDifferences(self):
+ """Called during full OTA installation and verification.
+ Implementation should return a list of BlockDifference objects describing
+ the update on each additional partitions.
+ """
+ return self._DoCall("FullOTA_GetBlockDifferences")
+
def FullOTA_InstallEnd(self):
"""Called at the end of full OTA installation; typically this is
used to install the image for the device's baseband processor."""
@@ -1551,6 +1559,13 @@
verification is complete)."""
return self._DoCall("IncrementalOTA_InstallBegin")
+ def IncrementalOTA_GetBlockDifferences(self):
+ """Called during incremental OTA installation and verification.
+ Implementation should return a list of BlockDifference objects describing
+ the update on each additional partitions.
+ """
+ return self._DoCall("IncrementalOTA_GetBlockDifferences")
+
def IncrementalOTA_InstallEnd(self):
"""Called at the end of incremental OTA installation; typically
this is used to install the image for the device's baseband
@@ -1745,11 +1760,29 @@
self.touched_src_ranges = b.touched_src_ranges
self.touched_src_sha1 = b.touched_src_sha1
- if src is None:
- _, self.device = GetTypeAndDevice("/" + partition, OPTIONS.info_dict)
+ # On devices with dynamic partitions, for new partitions,
+ # src is None but OPTIONS.source_info_dict is not.
+ if OPTIONS.source_info_dict is None:
+ is_dynamic_build = OPTIONS.info_dict.get(
+ "use_dynamic_partitions") == "true"
else:
- _, self.device = GetTypeAndDevice("/" + partition,
- OPTIONS.source_info_dict)
+ is_dynamic_build = OPTIONS.source_info_dict.get(
+ "use_dynamic_partitions") == "true"
+
+ # For dynamic partitions builds, always check partition list in target build
+ # because new partitions may be added.
+ is_dynamic = is_dynamic_build and partition in shlex.split(
+ OPTIONS.info_dict.get("dynamic_partition_list", "").strip())
+
+ if is_dynamic:
+ self.device = 'map_partition("%s")' % partition
+ else:
+ if OPTIONS.source_info_dict is None:
+ _, device_path = GetTypeAndDevice("/" + partition, OPTIONS.info_dict)
+ else:
+ _, device_path = GetTypeAndDevice("/" + partition,
+ OPTIONS.source_info_dict)
+ self.device = '"%s"' % device_path
@property
def required_cache(self):
@@ -1768,7 +1801,7 @@
self._WriteUpdate(script, output_zip)
if write_verify_script:
- self._WritePostInstallVerifyScript(script)
+ self.WritePostInstallVerifyScript(script)
def WriteStrictVerifyScript(self, script):
"""Verify all the blocks in the care_map, including clobbered blocks.
@@ -1782,11 +1815,11 @@
ranges = self.tgt.care_map
ranges_str = ranges.to_string_raw()
script.AppendExtra(
- 'range_sha1("%s", "%s") == "%s" && ui_print(" Verified.") || '
- 'ui_print("\\"%s\\" has unexpected contents.");' % (
+ 'range_sha1(%s, "%s") == "%s" && ui_print(" Verified.") || '
+ 'ui_print("%s has unexpected contents.");' % (
self.device, ranges_str,
self.tgt.TotalSha1(include_clobbered_blocks=True),
- self.device))
+ self.partition))
script.AppendExtra("")
def WriteVerifyScript(self, script, touched_blocks_only=False):
@@ -1811,7 +1844,7 @@
ranges_str = ranges.to_string_raw()
script.AppendExtra(
- 'if (range_sha1("%s", "%s") == "%s" || block_image_verify("%s", '
+ 'if (range_sha1(%s, "%s") == "%s" || block_image_verify(%s, '
'package_extract_file("%s.transfer.list"), "%s.new.dat", '
'"%s.patch.dat")) then' % (
self.device, ranges_str, expected_sha1,
@@ -1828,7 +1861,7 @@
# this check fails, give an explicit log message about the partition
# having been remounted R/W (the most likely explanation).
if self.check_first_block:
- script.AppendExtra('check_first_block("%s");' % (self.device,))
+ script.AppendExtra('check_first_block(%s);' % (self.device,))
# If version >= 4, try block recovery before abort update
if partition == "system":
@@ -1836,8 +1869,8 @@
else:
code = ErrorCode.VENDOR_RECOVER_FAILURE
script.AppendExtra((
- 'ifelse (block_image_recover("{device}", "{ranges}") && '
- 'block_image_verify("{device}", '
+ 'ifelse (block_image_recover({device}, "{ranges}") && '
+ 'block_image_verify({device}, '
'package_extract_file("{partition}.transfer.list"), '
'"{partition}.new.dat", "{partition}.patch.dat"), '
'ui_print("{partition} recovered successfully."), '
@@ -1859,14 +1892,14 @@
'abort("E%d: %s partition has unexpected contents");\n'
'endif;') % (code, partition))
- def _WritePostInstallVerifyScript(self, script):
+ def WritePostInstallVerifyScript(self, script):
partition = self.partition
script.Print('Verifying the updated %s image...' % (partition,))
# Unlike pre-install verification, clobbered_blocks should not be ignored.
ranges = self.tgt.care_map
ranges_str = ranges.to_string_raw()
script.AppendExtra(
- 'if range_sha1("%s", "%s") == "%s" then' % (
+ 'if range_sha1(%s, "%s") == "%s" then' % (
self.device, ranges_str,
self.tgt.TotalSha1(include_clobbered_blocks=True)))
@@ -1875,7 +1908,7 @@
if self.tgt.extended:
ranges_str = self.tgt.extended.to_string_raw()
script.AppendExtra(
- 'if range_sha1("%s", "%s") == "%s" then' % (
+ 'if range_sha1(%s, "%s") == "%s" then' % (
self.device, ranges_str,
self._HashZeroBlocks(self.tgt.extended.size())))
script.Print('Verified the updated %s image.' % (partition,))
@@ -1941,7 +1974,7 @@
else:
code = ErrorCode.VENDOR_UPDATE_FAILURE
- call = ('block_image_update("{device}", '
+ call = ('block_image_update({device}, '
'package_extract_file("{partition}.transfer.list"), '
'"{new_data_name}", "{partition}.patch.dat") ||\n'
' abort("E{code}: Failed to update {partition} image.");'.format(
@@ -2134,3 +2167,209 @@
logger.info("putting script in %s", sh_location)
output_sink(sh_location, sh)
+
+
+class DynamicPartitionUpdate(object):
+ def __init__(self, src_group=None, tgt_group=None, progress=None,
+ block_difference=None):
+ self.src_group = src_group
+ self.tgt_group = tgt_group
+ self.progress = progress
+ self.block_difference = block_difference
+
+ @property
+ def src_size(self):
+ if not self.block_difference:
+ return 0
+ return DynamicPartitionUpdate._GetSparseImageSize(self.block_difference.src)
+
+ @property
+ def tgt_size(self):
+ if not self.block_difference:
+ return 0
+ return DynamicPartitionUpdate._GetSparseImageSize(self.block_difference.tgt)
+
+ @staticmethod
+ def _GetSparseImageSize(img):
+ if not img:
+ return 0
+ return img.blocksize * img.total_blocks
+
+
+class DynamicGroupUpdate(object):
+ def __init__(self, src_size=None, tgt_size=None):
+ # None: group does not exist. 0: no size limits.
+ self.src_size = src_size
+ self.tgt_size = tgt_size
+
+
+class DynamicPartitionsDifference(object):
+ def __init__(self, info_dict, block_diffs, progress_dict=None,
+ source_info_dict=None):
+ if progress_dict is None:
+ progress_dict = dict()
+
+ self._remove_all_before_apply = False
+ if source_info_dict is None:
+ self._remove_all_before_apply = True
+ source_info_dict = dict()
+
+ block_diff_dict = {e.partition:e for e in block_diffs}
+ assert len(block_diff_dict) == len(block_diffs), \
+ "Duplicated BlockDifference object for {}".format(
+ [partition for partition, count in
+ collections.Counter(e.partition for e in block_diffs).items()
+ if count > 1])
+
+ dynamic_partitions = set(shlex.split(info_dict.get(
+ "dynamic_partition_list", "").strip()))
+ assert set(block_diff_dict.keys()) == dynamic_partitions, \
+ "Dynamic partitions: {}, BlockDifference objects: {}".format(
+ list(dynamic_partitions), list(block_diff_dict.keys()))
+
+ self._partition_updates = dict()
+
+ for p, block_diff in block_diff_dict.items():
+ self._partition_updates[p] = DynamicPartitionUpdate()
+ self._partition_updates[p].block_difference = block_diff
+
+ for p, progress in progress_dict.items():
+ if p in self._partition_updates:
+ self._partition_updates[p].progress = progress
+
+ tgt_groups = shlex.split(info_dict.get(
+ "super_partition_groups", "").strip())
+ src_groups = shlex.split(source_info_dict.get(
+ "super_partition_groups", "").strip())
+
+ for g in tgt_groups:
+ for p in shlex.split(info_dict.get(
+ "super_%s_partition_list" % g, "").strip()):
+ assert p in self._partition_updates, \
+ "{} is in target super_{}_partition_list but no BlockDifference " \
+ "object is provided.".format(p, g)
+ self._partition_updates[p].tgt_group = g
+
+ for g in src_groups:
+ for p in shlex.split(source_info_dict.get(
+ "super_%s_partition_list" % g, "").strip()):
+ assert p in self._partition_updates, \
+ "{} is in source super_{}_partition_list but no BlockDifference " \
+ "object is provided.".format(p, g)
+ self._partition_updates[p].src_group = g
+
+ if self._partition_updates:
+ logger.info("Updating dynamic partitions %s",
+ self._partition_updates.keys())
+
+ self._group_updates = dict()
+
+ for g in tgt_groups:
+ self._group_updates[g] = DynamicGroupUpdate()
+ self._group_updates[g].tgt_size = int(info_dict.get(
+ "super_%s_group_size" % g, "0").strip())
+
+ for g in src_groups:
+ if g not in self._group_updates:
+ self._group_updates[g] = DynamicGroupUpdate()
+ self._group_updates[g].src_size = int(source_info_dict.get(
+ "super_%s_group_size" % g, "0").strip())
+
+ self._Compute()
+
+ def WriteScript(self, script, output_zip, write_verify_script=False):
+ script.Comment('--- Start patching dynamic partitions ---')
+ for p, u in self._partition_updates.items():
+ if u.src_size and u.tgt_size and u.src_size > u.tgt_size:
+ script.Comment('Patch partition %s' % p)
+ u.block_difference.WriteScript(script, output_zip, progress=u.progress,
+ write_verify_script=False)
+
+ op_list_path = MakeTempFile()
+ with open(op_list_path, 'w') as f:
+ for line in self._op_list:
+ f.write('{}\n'.format(line))
+
+ ZipWrite(output_zip, op_list_path, "dynamic_partitions_op_list")
+
+ script.Comment('Update dynamic partition metadata')
+ script.AppendExtra('assert(update_dynamic_partitions('
+ 'package_extract_file("dynamic_partitions_op_list")));')
+
+ if write_verify_script:
+ for p, u in self._partition_updates.items():
+ if u.src_size and u.tgt_size and u.src_size > u.tgt_size:
+ u.block_difference.WritePostInstallVerifyScript(script)
+ script.AppendExtra('unmap_partition("%s");' % p) # ignore errors
+
+ for p, u in self._partition_updates.items():
+ if u.tgt_size and u.src_size <= u.tgt_size:
+ script.Comment('Patch partition %s' % p)
+ u.block_difference.WriteScript(script, output_zip, progress=u.progress,
+ write_verify_script=write_verify_script)
+ if write_verify_script:
+ script.AppendExtra('unmap_partition("%s");' % p) # ignore errors
+
+ script.Comment('--- End patching dynamic partitions ---')
+
+ def _Compute(self):
+ self._op_list = list()
+
+ def append(line):
+ self._op_list.append(line)
+
+ def comment(line):
+ self._op_list.append("# %s" % line)
+
+ if self._remove_all_before_apply:
+ comment('Remove all existing dynamic partitions and groups before '
+ 'applying full OTA')
+ append('remove_all_groups')
+
+ for p, u in self._partition_updates.items():
+ if u.src_group and not u.tgt_group:
+ append('remove %s' % p)
+
+ for p, u in self._partition_updates.items():
+ if u.src_group and u.tgt_group and u.src_group != u.tgt_group:
+ comment('Move partition %s from %s to default' % (p, u.src_group))
+ append('move %s default' % p)
+
+ for p, u in self._partition_updates.items():
+ if u.src_size and u.tgt_size and u.src_size > u.tgt_size:
+ comment('Shrink partition %s from %d to %d' %
+ (p, u.src_size, u.tgt_size))
+ append('resize %s %s' % (p, u.tgt_size))
+
+ for g, u in self._group_updates.items():
+ if u.src_size is not None and u.tgt_size is None:
+ append('remove_group %s' % g)
+ if (u.src_size is not None and u.tgt_size is not None and
+ u.src_size > u.tgt_size):
+ comment('Shrink group %s from %d to %d' % (g, u.src_size, u.tgt_size))
+ append('resize_group %s %d' % (g, u.tgt_size))
+
+ for g, u in self._group_updates.items():
+ if u.src_size is None and u.tgt_size is not None:
+ comment('Add group %s with maximum size %d' % (g, u.tgt_size))
+ append('add_group %s %d' % (g, u.tgt_size))
+ if (u.src_size is not None and u.tgt_size is not None and
+ u.src_size < u.tgt_size):
+ comment('Grow group %s from %d to %d' % (g, u.src_size, u.tgt_size))
+ append('resize_group %s %d' % (g, u.tgt_size))
+
+ for p, u in self._partition_updates.items():
+ if u.tgt_group and not u.src_group:
+ comment('Add partition %s to group %s' % (p, u.tgt_group))
+ append('add %s %s' % (p, u.tgt_group))
+
+ for p, u in self._partition_updates.items():
+ if u.tgt_size and u.src_size < u.tgt_size:
+ comment('Grow partition %s from %d to %d' % (p, u.src_size, u.tgt_size))
+ append('resize %s %d' % (p, u.tgt_size))
+
+ for p, u in self._partition_updates.items():
+ if u.src_group and u.tgt_group and u.src_group != u.tgt_group:
+ comment('Move partition %s from default to %s' %
+ (p, u.tgt_group))
+ append('move %s %s' % (p, u.tgt_group))
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 7ec8ad8..3fbcbcf 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -826,32 +826,51 @@
# See the notes in WriteBlockIncrementalOTAPackage().
allow_shared_blocks = target_info.get('ext4_share_dup_blocks') == "true"
- # Full OTA is done as an "incremental" against an empty source image. This
- # has the effect of writing new data from the package to the entire
- # partition, but lets us reuse the updater code that writes incrementals to
- # do it.
- system_tgt = common.GetSparseImage("system", OPTIONS.input_tmp, input_zip,
- allow_shared_blocks)
- system_tgt.ResetFileMap()
- system_diff = common.BlockDifference("system", system_tgt, src=None)
- system_diff.WriteScript(script, output_zip,
- write_verify_script=OPTIONS.verify)
+ def GetBlockDifference(partition):
+ # Full OTA is done as an "incremental" against an empty source image. This
+ # has the effect of writing new data from the package to the entire
+ # partition, but lets us reuse the updater code that writes incrementals to
+ # do it.
+ tgt = common.GetSparseImage(partition, OPTIONS.input_tmp, input_zip,
+ allow_shared_blocks)
+ tgt.ResetFileMap()
+ diff = common.BlockDifference(partition, tgt, src=None)
+ return diff
- boot_img = common.GetBootableImage(
- "boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
+ device_specific_diffs = device_specific.FullOTA_GetBlockDifferences()
+ if device_specific_diffs:
+ assert all(isinstance(diff, common.BlockDifference)
+ for diff in device_specific_diffs), \
+ "FullOTA_GetBlockDifferences is not returning a list of " \
+ "BlockDifference objects"
+ progress_dict = dict()
+ block_diffs = [GetBlockDifference("system")]
if HasVendorPartition(input_zip):
- script.ShowProgress(0.1, 0)
+ block_diffs.append(GetBlockDifference("vendor"))
+ progress_dict["vendor"] = 0.1
+ if device_specific_diffs:
+ block_diffs += device_specific_diffs
- vendor_tgt = common.GetSparseImage("vendor", OPTIONS.input_tmp, input_zip,
- allow_shared_blocks)
- vendor_tgt.ResetFileMap()
- vendor_diff = common.BlockDifference("vendor", vendor_tgt)
- vendor_diff.WriteScript(script, output_zip,
- write_verify_script=OPTIONS.verify)
+ if target_info.get('use_dynamic_partitions') == "true":
+ # Use empty source_info_dict to indicate that all partitions / groups must
+ # be re-added.
+ dynamic_partitions_diff = common.DynamicPartitionsDifference(
+ info_dict=OPTIONS.info_dict,
+ block_diffs=block_diffs,
+ progress_dict=progress_dict)
+ dynamic_partitions_diff.WriteScript(script, output_zip,
+ write_verify_script=OPTIONS.verify)
+ else:
+ for block_diff in block_diffs:
+ block_diff.WriteScript(script, output_zip,
+ progress=progress_dict.get(block_diff.partition),
+ write_verify_script=OPTIONS.verify)
AddCompatibilityArchiveIfTrebleEnabled(input_zip, output_zip, target_info)
+ boot_img = common.GetBootableImage(
+ "boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
common.CheckSize(boot_img.data, "boot.img", target_info)
common.ZipWriteStr(output_zip, "boot.img", boot_img.data)
@@ -1571,18 +1590,43 @@
system_diff.WriteVerifyScript(script, touched_blocks_only=True)
if vendor_diff:
vendor_diff.WriteVerifyScript(script, touched_blocks_only=True)
+ device_specific_diffs = device_specific.IncrementalOTA_GetBlockDifferences()
+ if device_specific_diffs:
+ assert all(isinstance(diff, common.BlockDifference)
+ for diff in device_specific_diffs), \
+ "IncrementalOTA_GetBlockDifferences is not returning a list of " \
+ "BlockDifference objects"
+ for diff in device_specific_diffs:
+ diff.WriteVerifyScript(script, touched_blocks_only=True)
script.Comment("---- start making changes here ----")
device_specific.IncrementalOTA_InstallBegin()
- system_diff.WriteScript(script, output_zip,
- progress=0.8 if vendor_diff else 0.9,
- write_verify_script=OPTIONS.verify)
-
+ block_diffs = [system_diff]
+ progress_dict = {"system": 0.8 if vendor_diff else 0.9}
if vendor_diff:
- vendor_diff.WriteScript(script, output_zip, progress=0.1,
- write_verify_script=OPTIONS.verify)
+ block_diffs.append(vendor_diff)
+ progress_dict["vendor"] = 0.1
+ if device_specific_diffs:
+ block_diffs += device_specific_diffs
+
+ if OPTIONS.source_info_dict.get("use_dynamic_partitions") == "true":
+ if OPTIONS.target_info_dict.get("use_dynamic_partitions") != "true":
+ raise RuntimeError(
+ "can't generate incremental that disables dynamic partitions")
+ dynamic_partitions_diff = common.DynamicPartitionsDifference(
+ info_dict=OPTIONS.target_info_dict,
+ source_info_dict=OPTIONS.source_info_dict,
+ block_diffs=block_diffs,
+ progress_dict=progress_dict)
+ dynamic_partitions_diff.WriteScript(
+ script, output_zip, write_verify_script=OPTIONS.verify)
+ else:
+ for block_diff in block_diffs:
+ block_diff.WriteScript(script, output_zip,
+ progress=progress_dict.get(block_diff.partition),
+ write_verify_script=OPTIONS.verify)
if OPTIONS.two_step:
common.ZipWriteStr(output_zip, "boot.img", target_boot.data)