Merge "Build "secdiscard" for securely discarding data from flash devices." into mnc-dr-dev
diff --git a/CleanSpec.mk b/CleanSpec.mk
index bfb27d9..c95ae05 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -359,6 +359,11 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
+# 23 is becoming alive!!!
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
+
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/core/Makefile b/core/Makefile
index c96f04f..c98df0c 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -460,12 +460,12 @@
INSTALLED_RAMDISK_TARGET := $(BUILT_RAMDISK_TARGET)
$(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_RAMDISK_FILES) | $(MINIGZIP)
$(call pretty,"Target ram disk: $@")
- $(hide) $(MKBOOTFS) $(TARGET_ROOT_OUT) | $(MINIGZIP) > $@
+ $(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_ROOT_OUT) | $(MINIGZIP) > $@
.PHONY: ramdisk-nodeps
ramdisk-nodeps: $(MKBOOTFS) | $(MINIGZIP)
@echo "make $@: ignoring dependencies"
- $(hide) $(MKBOOTFS) $(TARGET_ROOT_OUT) | $(MINIGZIP) > $(INSTALLED_RAMDISK_TARGET)
+ $(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_ROOT_OUT) | $(MINIGZIP) > $(INSTALLED_RAMDISK_TARGET)
ifneq ($(strip $(TARGET_NO_KERNEL)),true)
@@ -710,7 +710,11 @@
endif
ifeq ($(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),squashfs)
-INTERNAL_USERIMAGES_DEPS += $(MAKE_SQUASHFS) $(MKSQUASHFSUSERIMG)
+INTERNAL_USERIMAGES_DEPS += $(MAKE_SQUASHFS) $(MKSQUASHFSUSERIMG) $(IMG2SIMG)
+endif
+
+ifeq ($(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),squashfs)
+INTERNAL_USERIMAGES_DEPS += $(MAKE_SQUASHFS) $(MKSQUASHFSUSERIMG) $(IMG2SIMG)
endif
INTERNAL_USERIMAGES_BINARY_PATHS := $(sort $(dir $(INTERNAL_USERIMAGES_DEPS)))
@@ -729,6 +733,9 @@
$(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))
$(if $(BOARD_SYSTEMIMAGE_JOURNAL_SIZE),$(hide) echo "system_journal_size=$(BOARD_SYSTEMIMAGE_JOURNAL_SIZE)" >> $(1))
+$(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_USERDATAIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "userdata_fs_type=$(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
$(if $(BOARD_USERDATAIMAGE_PARTITION_SIZE),$(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(1))
$(if $(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "cache_fs_type=$(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
@@ -877,7 +884,7 @@
$(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
- $(hide) $(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)
+ $(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)
$(if $(filter true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)), \
$(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1).unsigned, \
$(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1) --id > $(RECOVERYIMAGE_ID_FILE))
@@ -988,10 +995,18 @@
skip_fsck=true)
$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
./build/tools/releasetools/build_image.py \
- $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) \
+ $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) $(TARGET_OUT) \
|| ( echo "Out of space? the tree size of $(TARGET_OUT) is (MB): " 1>&2 ;\
du -sm $(TARGET_OUT) 1>&2;\
- echo "The max is $$(( $(BOARD_SYSTEMIMAGE_PARTITION_SIZE) / 1048576 )) MB." 1>&2 ;\
+ if [ "$(INTERNAL_USERIMAGES_EXT_VARIANT)" == "ext4" ]; then \
+ maxsize=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE); \
+ if [ "$(BOARD_HAS_EXT4_RESERVED_BLOCKS)" == "true" ]; then \
+ maxsize=$$((maxsize - 4096 * 4096)); \
+ fi; \
+ echo "The max is $$(( maxsize / 1048576 )) MB." 1>&2 ;\
+ else \
+ echo "The max is $$(( $(BOARD_SYSTEMIMAGE_PARTITION_SIZE) / 1048576 )) MB." 1>&2 ;\
+ fi; \
mkdir -p $(DIST_DIR); cp $(INSTALLED_FILES_FILE) $(DIST_DIR)/installed-files-rescued.txt; \
exit 1 )
endef
@@ -1047,7 +1062,7 @@
$(call create-system-vendor-symlink)
$(MKTARBALL) $(FS_GET_STATS) \
$(PRODUCT_OUT) system $(PRIVATE_SYSTEM_TAR) \
- $(INSTALLED_SYSTEMTARBALL_TARGET)
+ $(INSTALLED_SYSTEMTARBALL_TARGET) $(TARGET_OUT)
endef
ifndef SYSTEM_TARBALL_FORMAT
@@ -1115,7 +1130,7 @@
$(hide) echo $(BOARD_KERNEL_CMDLINE) > $(PRODUCT_OUT)/boot/cmdline
$(hide) $(MKTARBALL) $(FS_GET_STATS) \
$(PRODUCT_OUT) boot $(PRIVATE_BOOT_TAR) \
- $(INSTALLED_BOOTTARBALL_TARGET)
+ $(INSTALLED_BOOTTARBALL_TARGET) $(TARGET_OUT)
endef
ifndef BOOT_TARBALL_FORMAT
@@ -1159,7 +1174,7 @@
$(call generate-userimage-prop-dictionary, $(userdataimage_intermediates)/userdata_image_info.txt, skip_fsck=true)
$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
./build/tools/releasetools/build_image.py \
- $(TARGET_OUT_DATA) $(userdataimage_intermediates)/userdata_image_info.txt $(INSTALLED_USERDATAIMAGE_TARGET)
+ $(TARGET_OUT_DATA) $(userdataimage_intermediates)/userdata_image_info.txt $(INSTALLED_USERDATAIMAGE_TARGET) $(TARGET_OUT)
$(hide) $(call assert-max-image-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_PARTITION_SIZE))
endef
@@ -1183,7 +1198,7 @@
"$(INSTALLED_USERDATATARBALL_TARGET)")
$(MKTARBALL) $(FS_GET_STATS) \
$(PRODUCT_OUT) data $(PRIVATE_USERDATA_TAR) \
- $(INSTALLED_USERDATATARBALL_TARGET)
+ $(INSTALLED_USERDATATARBALL_TARGET) $(TARGET_OUT)
endef
userdata_tar := $(PRODUCT_OUT)/userdata.tar
@@ -1214,7 +1229,7 @@
$(call generate-userimage-prop-dictionary, $(cacheimage_intermediates)/cache_image_info.txt, skip_fsck=true)
$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
./build/tools/releasetools/build_image.py \
- $(TARGET_OUT_CACHE) $(cacheimage_intermediates)/cache_image_info.txt $(INSTALLED_CACHEIMAGE_TARGET)
+ $(TARGET_OUT_CACHE) $(cacheimage_intermediates)/cache_image_info.txt $(INSTALLED_CACHEIMAGE_TARGET) $(TARGET_OUT)
$(hide) $(call assert-max-image-size,$(INSTALLED_CACHEIMAGE_TARGET),$(BOARD_CACHEIMAGE_PARTITION_SIZE))
endef
@@ -1252,7 +1267,7 @@
$(call generate-userimage-prop-dictionary, $(vendorimage_intermediates)/vendor_image_info.txt, skip_fsck=true)
$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
./build/tools/releasetools/build_image.py \
- $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt $(INSTALLED_VENDORIMAGE_TARGET)
+ $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt $(INSTALLED_VENDORIMAGE_TARGET) $(TARGET_OUT)
$(hide) $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET),$(BOARD_VENDORIMAGE_PARTITION_SIZE))
endef
@@ -1293,6 +1308,7 @@
$(HOST_OUT_EXECUTABLES)/build_verity_tree \
$(HOST_OUT_EXECUTABLES)/verity_signer \
$(HOST_OUT_EXECUTABLES)/append2simg \
+ $(HOST_OUT_EXECUTABLES)/img2simg \
$(HOST_OUT_EXECUTABLES)/boot_signer
# Shared libraries.
@@ -1473,6 +1489,9 @@
ifdef BOARD_RECOVERYIMAGE_PARTITION_SIZE
$(hide) echo "recovery_size=$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
endif
+ifdef BOARD_HAS_EXT4_RESERVED_BLOCKS
+ $(hide) echo "has_ext4_reserved_blocks=$(BOARD_HAS_EXT4_RESERVED_BLOCKS)" >> $(zip_root)/META/misc_info.txt
+endif
ifdef TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS
@# TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS can be empty to indicate that nothing but defaults should be used.
$(hide) echo "recovery_mount_options=$(TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS)" >> $(zip_root)/META/misc_info.txt
@@ -1488,7 +1507,7 @@
$(hide) echo "use_set_metadata=1" >> $(zip_root)/META/misc_info.txt
$(hide) echo "multistage_support=1" >> $(zip_root)/META/misc_info.txt
$(hide) echo "update_rename_support=1" >> $(zip_root)/META/misc_info.txt
- $(hide) echo "blockimgdiff_versions=1,2,3" >> $(zip_root)/META/misc_info.txt
+ $(hide) echo "blockimgdiff_versions=1,2" >> $(zip_root)/META/misc_info.txt
ifneq ($(OEM_THUMBPRINT_PROPERTIES),)
# OTA scripts are only interested in fingerprint related properties
$(hide) echo "oem_fingerprint_properties=$(OEM_THUMBPRINT_PROPERTIES)" >> $(zip_root)/META/misc_info.txt
@@ -1500,10 +1519,10 @@
$(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)
@# Run fs_config on all the system, vendor, boot ramdisk,
@# and recovery ramdisk files in the zip, and save the output
- $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="SYSTEM/" } /^SYSTEM\// {print "system/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/filesystem_config.txt
- $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="VENDOR/" } /^VENDOR\// {print "vendor/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/vendor_filesystem_config.txt
- $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="BOOT/RAMDISK/" } /^BOOT\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/boot_filesystem_config.txt
- $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="RECOVERY/RAMDISK/" } /^RECOVERY\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/recovery_filesystem_config.txt
+ $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="SYSTEM/" } /^SYSTEM\// {print "system/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/filesystem_config.txt
+ $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="VENDOR/" } /^VENDOR\// {print "vendor/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/vendor_filesystem_config.txt
+ $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="BOOT/RAMDISK/" } /^BOOT\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/boot_filesystem_config.txt
+ $(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
$(hide) (cd $(zip_root) && zip -q ../$(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 -p $(HOST_OUT) $@
diff --git a/core/config.mk b/core/config.mk
index 87cd1cf..ba8f310 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -419,6 +419,7 @@
MAKE_F2FS := $(HOST_OUT_EXECUTABLES)/make_f2fs$(HOST_EXECUTABLE_SUFFIX)
MKF2FSUSERIMG := $(HOST_OUT_EXECUTABLES)/mkf2fsuserimg.sh
SIMG2IMG := $(HOST_OUT_EXECUTABLES)/simg2img$(HOST_EXECUTABLE_SUFFIX)
+IMG2SIMG := $(HOST_OUT_EXECUTABLES)/img2simg$(HOST_EXECUTABLE_SUFFIX)
E2FSCK := $(HOST_OUT_EXECUTABLES)/e2fsck$(HOST_EXECUTABLE_SUFFIX)
MKTARBALL := build/tools/mktarball.sh
TUNE2FS := $(HOST_OUT_EXECUTABLES)/tune2fs$(HOST_EXECUTABLE_SUFFIX)
diff --git a/core/java.mk b/core/java.mk
index ae4a602..b371289 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -441,9 +441,10 @@
my_support_library_sdk_raise :=
ifneq (,$(filter android-support-%,$(LOCAL_STATIC_JAVA_LIBRARIES)))
ifdef LOCAL_SDK_VERSION
-ifeq (,$(filter current system_current, $(LOCAL_SDK_VERSION)))
ifdef TARGET_BUILD_APPS
+ifeq (,$(filter current system_current, $(LOCAL_SDK_VERSION)))
my_support_library_sdk_raise := $(call java-lib-files, sdk_vcurrent)
+endif
else
# For platform build, we can't just raise to the "current" SDK,
# that would break apps that use APIs removed from the current SDK.
@@ -451,7 +452,6 @@
endif
endif
endif
-endif
# jack already has the libraries in its classpath and doesn't support jars
legacy_proguard_flags := $(addprefix -libraryjars ,$(my_support_library_sdk_raise) $(full_shared_java_libs))
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 6cbe81c..e384526 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -53,7 +53,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 := 22
+ PLATFORM_SDK_VERSION := 23
endif
ifeq "" "$(PLATFORM_VERSION_CODENAME)"
@@ -80,7 +80,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 := 1
+ PLATFORM_PREVIEW_SDK_VERSION := 2
endif
endif
diff --git a/target/board/generic/sepolicy/init.te b/target/board/generic/sepolicy/init.te
new file mode 100644
index 0000000..3aa81d1
--- /dev/null
+++ b/target/board/generic/sepolicy/init.te
@@ -0,0 +1 @@
+allow init tmpfs:lnk_file create_file_perms;
diff --git a/target/board/generic_x86/sepolicy/init.te b/target/board/generic_x86/sepolicy/init.te
new file mode 100644
index 0000000..3aa81d1
--- /dev/null
+++ b/target/board/generic_x86/sepolicy/init.te
@@ -0,0 +1 @@
+allow init tmpfs:lnk_file create_file_perms;
diff --git a/target/product/base.mk b/target/product/base.mk
index 6a74c00..4c49e86 100644
--- a/target/product/base.mk
+++ b/target/product/base.mk
@@ -36,6 +36,7 @@
dpm \
framework \
fsck_msdos \
+ hid \
ime \
input \
javax.obex \
diff --git a/tools/droiddoc/templates-sdk/assets/js/docs.js b/tools/droiddoc/templates-sdk/assets/js/docs.js
index feaf06b..d88c0e6 100644
--- a/tools/droiddoc/templates-sdk/assets/js/docs.js
+++ b/tools/droiddoc/templates-sdk/assets/js/docs.js
@@ -2101,9 +2101,8 @@
// Search for matching JD docs
if (text.length >= 2) {
- // Regex to match only the beginning of a word
- var textRegex = new RegExp("\\b" + text.toLowerCase(), "g");
-
+ // match only the beginning of a word
+ var queryStr = text.toLowerCase();
// Search for Training classes
for (var i=0; i<TRAINING_RESOURCES.length; i++) {
@@ -2117,7 +2116,7 @@
// Check if query matches any tags; work backwards toward 1 to assist ranking
for (var j = s.keywords.length - 1; j >= 0; j--) {
// it matches a tag
- if (s.keywords[j].toLowerCase().match(textRegex)) {
+ if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_tag = j + 1; // add 1 to index position
}
@@ -2127,7 +2126,7 @@
if ((s.lang == currentLang) &&
(!(s.type == "training" && s.url.indexOf("index.html") == -1) || matched)) {
// it matches the doc title
- if (s.title.toLowerCase().match(textRegex)) {
+ if (s.title.toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_title = 1;
}
@@ -2151,7 +2150,8 @@
// Check if query matches any tags; work backwards toward 1 to assist ranking
for (var j = s.keywords.length - 1; j >= 0; j--) {
// it matches a tag
- if (s.keywords[j].toLowerCase().match(textRegex)) {
+ if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
+
matched = true;
s.matched_tag = j + 1; // add 1 to index position
}
@@ -2159,7 +2159,7 @@
// Check if query matches the doc title, but only for current language
if (s.lang == currentLang) {
// if query matches the doc title
- if (s.title.toLowerCase().match(textRegex)) {
+ if (s.title.toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_title = 1;
}
@@ -2183,7 +2183,7 @@
// Check if query matches any tags; work backwards toward 1 to assist ranking
for (var j = s.keywords.length - 1; j >= 0; j--) {
// it matches a tag
- if (s.keywords[j].toLowerCase().match(textRegex)) {
+ if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_tag = j + 1; // add 1 to index position
}
@@ -2191,7 +2191,7 @@
// Check if query matches the doc title, but only for current language
if (s.lang == currentLang) {
// if query matches the doc title
- if (s.title.toLowerCase().match(textRegex)) {
+ if (s.title.toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_title = 1;
}
@@ -2215,7 +2215,7 @@
// Check if query matches any tags; work backwards toward 1 to assist ranking
for (var j = s.keywords.length - 1; j >= 0; j--) {
// it matches a tag
- if (s.keywords[j].toLowerCase().match(textRegex)) {
+ if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_tag = j + 1; // add 1 to index position
}
@@ -2223,7 +2223,7 @@
// Check if query matches the doc title, but only for current language
if (s.lang == currentLang) {
// if query matches the doc title
- if (s.title.toLowerCase().match(textRegex)) {
+ if (s.title.toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_title = 1;
}
@@ -2247,7 +2247,7 @@
// Check if query matches any tags; work backwards toward 1 to assist ranking
for (var j = s.keywords.length - 1; j >= 0; j--) {
// it matches a tag
- if (s.keywords[j].toLowerCase().match(textRegex)) {
+ if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_tag = j + 1; // add 1 to index position
}
@@ -2255,7 +2255,7 @@
// Check if query matches the doc title, but only for current language
if (s.lang == currentLang) {
// if query matches the doc title
- if (s.title.toLowerCase().match(textRegex)) {
+ if (s.title.toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_title = 1;
}
@@ -2279,7 +2279,7 @@
// Check if query matches any tags; work backwards toward 1 to assist ranking
for (var j = s.keywords.length - 1; j >= 0; j--) {
// it matches a tag
- if (s.keywords[j].toLowerCase().match(textRegex)) {
+ if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_tag = j + 1; // add 1 to index position
}
@@ -2287,7 +2287,7 @@
// Check if query matches the doc title, but only for current language
if (s.lang == currentLang) {
// if query matches the doc title
- if (s.title.toLowerCase().match(textRegex)) {
+ if (s.title.toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_title = 1;
}
@@ -2311,7 +2311,7 @@
// Check if query matches any tags; work backwards toward 1 to assist ranking
for (var j = s.keywords.length - 1; j >= 0; j--) {
// it matches a tag
- if (s.keywords[j].toLowerCase().match(textRegex)) {
+ if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_tag = j + 1; // add 1 to index position
}
@@ -2319,7 +2319,7 @@
// Check if query matches the doc title, but only for current language
if (s.lang == currentLang) {
// if query matches the doc title
- if (s.title.toLowerCase().match(textRegex)) {
+ if (s.title.toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_title = 1;
}
@@ -2342,7 +2342,7 @@
// Check if query matches any tags; work backwards toward 1 to assist ranking
for (var j = s.keywords.length - 1; j >= 0; j--) {
// it matches a tag
- if (s.keywords[j].toLowerCase().match(textRegex)) {
+ if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_tag = j + 1; // add 1 to index position
}
@@ -2350,7 +2350,7 @@
// Check if query matches the doc title, but only for current language
if (s.lang == currentLang) {
// if query matches the doc title.t
- if (s.title.toLowerCase().match(textRegex)) {
+ if (s.title.toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_title = 1;
}
@@ -2373,7 +2373,7 @@
// Check if query matches any tags; work backwards toward 1 to assist ranking
for (var j = s.keywords.length - 1; j >= 0; j--) {
// it matches a tag
- if (s.keywords[j].toLowerCase().match(textRegex)) {
+ if (s.keywords[j].toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_tag = j + 1; // add 1 to index position
}
@@ -2381,7 +2381,7 @@
// Check if query matches the doc title, but only for current language
if (s.lang == currentLang) {
// if query matches the doc title
- if (s.title.toLowerCase().match(textRegex)) {
+ if (s.title.toLowerCase().indexOf(queryStr) == 0) {
matched = true;
s.matched_title = 1;
}
diff --git a/tools/droiddoc/templates-sdk/docpage.cs b/tools/droiddoc/templates-sdk/docpage.cs
index 204e06c..668105b 100644
--- a/tools/droiddoc/templates-sdk/docpage.cs
+++ b/tools/droiddoc/templates-sdk/docpage.cs
@@ -194,10 +194,10 @@
<?cs include:"trailer.cs" ?>
<script src="https://developer.android.com/ytblogger_lists_unified.js" type="text/javascript"></script>
- <script src="<?cs var:toroot ?>jd_lists_unified.js?v=14" type="text/javascript"></script>
- <script src="<?cs var:toroot ?>jd_extras.js?v=14" type="text/javascript"></script>
- <script src="<?cs var:toroot ?>jd_collections.js?v=14" type="text/javascript"></script>
- <script src="<?cs var:toroot ?>jd_tag_helpers.js?v=14" type="text/javascript"></script>
+ <script src="<?cs var:toroot ?>jd_lists_unified.js?v=15" type="text/javascript"></script>
+ <script src="<?cs var:toroot ?>jd_extras.js?v=15" type="text/javascript"></script>
+ <script src="<?cs var:toroot ?>jd_collections.js?v=15" type="text/javascript"></script>
+ <script src="<?cs var:toroot ?>jd_tag_helpers.js?v=15" type="text/javascript"></script>
</body>
</html>
diff --git a/tools/droiddoc/templates-sdk/footer.cs b/tools/droiddoc/templates-sdk/footer.cs
index c960953..1ffee63 100644
--- a/tools/droiddoc/templates-sdk/footer.cs
+++ b/tools/droiddoc/templates-sdk/footer.cs
@@ -46,6 +46,7 @@
<option value="es">Español</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
+ <option value="pt-br">Português Brasileiro</option>
<option value="ru">Русский</option>
<option value="zh-cn">中文(简体)</option>
<option value="zh-tw">中文(繁體)</option>
diff --git a/tools/droiddoc/templates-sdk/head_tag.cs b/tools/droiddoc/templates-sdk/head_tag.cs
index dfbff5a..babb3c7 100644
--- a/tools/droiddoc/templates-sdk/head_tag.cs
+++ b/tools/droiddoc/templates-sdk/head_tag.cs
@@ -65,7 +65,7 @@
var metaTags = [<?cs var:meta.tags ?>];
var devsite = <?cs if:devsite ?>true<?cs else ?>false<?cs /if ?>;
</script>
-<script src="<?cs var:toroot ?>assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="<?cs var:toroot ?>assets/js/docs.js?v=6" type="text/javascript"></script>
<?cs if:helpoutsWidget ?>
<script type="text/javascript" src="https://helpouts.google.com/ps/res/embed.js" defer async
diff --git a/tools/fs_config/fs_config.c b/tools/fs_config/fs_config.c
index f594c1e..b9a14e1 100644
--- a/tools/fs_config/fs_config.c
+++ b/tools/fs_config/fs_config.c
@@ -68,16 +68,17 @@
}
static void usage() {
- fprintf(stderr, "Usage: fs_config [-S context_file] [-C]\n");
+ fprintf(stderr, "Usage: fs_config [-D product_out_path] [-S context_file] [-C]\n");
}
int main(int argc, char** argv) {
char buffer[1024];
const char* context_file = NULL;
+ const char* product_out_path = NULL;
struct selabel_handle* sehnd = NULL;
int print_capabilities = 0;
int opt;
- while((opt = getopt(argc, argv, "CS:")) != -1) {
+ while((opt = getopt(argc, argv, "CS:D:")) != -1) {
switch(opt) {
case 'C':
print_capabilities = 1;
@@ -85,6 +86,9 @@
case 'S':
context_file = optarg;
break;
+ case 'D':
+ product_out_path = optarg;
+ break;
default:
usage();
exit(EXIT_FAILURE);
@@ -115,7 +119,7 @@
unsigned uid = 0, gid = 0, mode = 0;
uint64_t capabilities;
- fs_config(buffer, is_dir, &uid, &gid, &mode, &capabilities);
+ fs_config(buffer, is_dir, product_out_path, &uid, &gid, &mode, &capabilities);
printf("%s %d %d %o", buffer, uid, gid, mode);
if (sehnd != NULL) {
diff --git a/tools/fs_get_stats/fs_get_stats.c b/tools/fs_get_stats/fs_get_stats.c
index a9814b9..159e2aa 100644
--- a/tools/fs_get_stats/fs_get_stats.c
+++ b/tools/fs_get_stats/fs_get_stats.c
@@ -25,11 +25,12 @@
{
fprintf(stderr, "fs_get_stats: retrieve the target file stats "
"for the specified file\n");
- fprintf(stderr, "usage: fs_get_stats cur_perms is_dir filename\n");
+ fprintf(stderr, "usage: fs_get_stats cur_perms is_dir filename targetout\n");
fprintf(stderr, "\tcur_perms - The current permissions of "
"the file\n");
fprintf(stderr, "\tis_dir - Is filename is a dir, 1. Otherwise, 0.\n");
fprintf(stderr, "\tfilename - The filename to lookup\n");
+ fprintf(stderr, "\ttargetout - The target out path to query device specific FS configs\n");
fprintf(stderr, "\n");
}
@@ -42,7 +43,7 @@
unsigned uid = (unsigned)-1;
unsigned gid = (unsigned)-1;
- if (argc < 4) {
+ if (argc < 5) {
ERROR("Invalid arguments\n");
print_help();
exit(-1);
@@ -58,7 +59,7 @@
is_dir = 1;
uint64_t capabilities;
- fs_config(argv[3], is_dir, &uid, &gid, &perms, &capabilities);
+ fs_config(argv[3], is_dir, argv[4], &uid, &gid, &perms, &capabilities);
fprintf(stdout, "%d %d 0%o\n", uid, gid, perms);
return 0;
diff --git a/tools/mktarball.sh b/tools/mktarball.sh
index 3e32006..ef0fe86 100755
--- a/tools/mktarball.sh
+++ b/tools/mktarball.sh
@@ -5,8 +5,9 @@
# $3: subdir to tar up (from $2)
# $4: target tar name
# $5: target tarball name (usually $(3).bz2)
+# $6: TARGET_OUT path to query device specific FS configs
-if [ $# -ne 5 ]; then
+if [ $# -ne 6 ]; then
echo "Error: wrong number of arguments in cmd: $0 $* "
exit 1
fi
@@ -16,6 +17,7 @@
dir_to_tar=$3
target_tar=`readlink -f $4`
target_tarball=`readlink -f $5`
+target_out=`readlink -f $6`
cd $2
@@ -28,7 +30,7 @@
for f in ${subdirs} ${files} ; do
curr_perms=`stat -c 0%a $f`
[ -d "$f" ] && is_dir=1 || is_dir=0
- new_info=`${fs_get_stats} ${curr_perms} ${is_dir} ${f}`
+ new_info=`${fs_get_stats} ${curr_perms} ${is_dir} ${f} ${target_out}`
new_uid=`echo ${new_info} | awk '{print $1;}'`
new_gid=`echo ${new_info} | awk '{print $2;}'`
new_perms=`echo ${new_info} | awk '{print $3;}'`
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index 3402572..6ed9ca2 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -83,6 +83,7 @@
blocksize = 4096
care_map = RangeSet()
clobbered_blocks = RangeSet()
+ extended = RangeSet()
total_blocks = 0
file_map = {}
def ReadRangeSet(self, ranges):
@@ -119,6 +120,7 @@
self.total_blocks = len(self.data) / self.blocksize
self.care_map = RangeSet(data=(0, self.total_blocks))
self.clobbered_blocks = RangeSet()
+ self.extended = RangeSet()
zero_blocks = []
nonzero_blocks = []
@@ -411,7 +413,7 @@
elif self.version >= 3:
# take into account automatic stashing of overlapping blocks
if xf.src_ranges.overlaps(xf.tgt_ranges):
- temp_stash_usage = stashed_blocks + xf.src_ranges.size();
+ temp_stash_usage = stashed_blocks + xf.src_ranges.size()
if temp_stash_usage > max_stashed_blocks:
max_stashed_blocks = temp_stash_usage
@@ -435,7 +437,7 @@
elif self.version >= 3:
# take into account automatic stashing of overlapping blocks
if xf.src_ranges.overlaps(xf.tgt_ranges):
- temp_stash_usage = stashed_blocks + xf.src_ranges.size();
+ temp_stash_usage = stashed_blocks + xf.src_ranges.size()
if temp_stash_usage > max_stashed_blocks:
max_stashed_blocks = temp_stash_usage
@@ -462,18 +464,17 @@
# stash space
assert max_stashed_blocks * self.tgt.blocksize < (512 << 20)
+ # Zero out extended blocks as a workaround for bug 20881595.
+ if self.tgt.extended:
+ out.append("zero %s\n" % (self.tgt.extended.to_string_raw(),))
+
+ # We erase all the blocks on the partition that a) don't contain useful
+ # data in the new image and b) will not be touched by dm-verity.
all_tgt = RangeSet(data=(0, self.tgt.total_blocks))
- if performs_read:
- # if some of the original data is used, then at the end we'll
- # erase all the blocks on the partition that don't contain data
- # in the new image.
- new_dontcare = all_tgt.subtract(self.tgt.care_map)
- if new_dontcare:
- out.append("erase %s\n" % (new_dontcare.to_string_raw(),))
- else:
- # if nothing is read (ie, this is a full OTA), then we can start
- # by erasing the entire partition.
- out.insert(0, "erase %s\n" % (all_tgt.to_string_raw(),))
+ all_tgt_minus_extended = all_tgt.subtract(self.tgt.extended)
+ new_dontcare = all_tgt_minus_extended.subtract(self.tgt.care_map)
+ if new_dontcare:
+ out.append("erase %s\n" % (new_dontcare.to_string_raw(),))
out.insert(0, "%d\n" % (self.version,)) # format version number
out.insert(1, str(total) + "\n")
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 6c526c8..4b43c0c 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -22,6 +22,7 @@
"""
import os
import os.path
+import re
import subprocess
import sys
import commands
@@ -34,17 +35,18 @@
FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
def RunCommand(cmd):
- """ Echo and run the given command
+ """Echo and run the given command.
Args:
cmd: the command represented as a list of strings.
Returns:
- The exit code.
+ A tuple of the output and the exit code.
"""
print "Running: ", " ".join(cmd)
- p = subprocess.Popen(cmd)
- p.communicate()
- return p.returncode
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ output, _ = p.communicate()
+ print "%s" % (output.rstrip(),)
+ return (output, p.returncode)
def GetVerityTreeSize(partition_size):
cmd = "build_verity_tree -s %d"
@@ -146,7 +148,7 @@
else:
return True, unsparse_image_path
inflate_command = ["simg2img", sparse_image_path, unsparse_image_path]
- exit_code = RunCommand(inflate_command)
+ (_, exit_code) = RunCommand(inflate_command)
if exit_code != 0:
os.remove(unsparse_image_path)
return False, None
@@ -202,13 +204,14 @@
shutil.rmtree(tempdir_name, ignore_errors=True)
return True
-def BuildImage(in_dir, prop_dict, out_file):
+def BuildImage(in_dir, prop_dict, out_file, target_out=None):
"""Build an image to out_file from in_dir with property prop_dict.
Args:
in_dir: path of input directory.
prop_dict: property dictionary.
out_file: path of the output image file.
+ target_out: path of the product out directory to read device specific FS config files.
Returns:
True iff the image is built successfully.
@@ -241,11 +244,12 @@
fs_spans_partition = True
if fs_type.startswith("squash"):
- fs_spans_partition = False
+ fs_spans_partition = False
is_verity_partition = "verity_block_device" in prop_dict
verity_supported = prop_dict.get("verity") == "true"
- # adjust the partition size to make room for the hashes if this is to be verified
+ # Adjust the partition size to make room for the hashes if this is to be
+ # verified.
if verity_supported and is_verity_partition and fs_spans_partition:
partition_size = int(prop_dict.get("partition_size"))
@@ -269,6 +273,8 @@
build_command.extend(["-T", str(prop_dict["timestamp"])])
if fs_config:
build_command.extend(["-C", fs_config])
+ if target_out:
+ build_command.extend(["-D", target_out])
if "block_list" in prop_dict:
build_command.extend(["-B", prop_dict["block_list"]])
build_command.extend(["-L", prop_dict["mount_point"]])
@@ -277,9 +283,16 @@
elif fs_type.startswith("squash"):
build_command = ["mksquashfsimage.sh"]
build_command.extend([in_dir, out_file])
+ build_command.extend(["-s"])
build_command.extend(["-m", prop_dict["mount_point"]])
+ if target_out:
+ build_command.extend(["-d", target_out])
if "selinux_fc" in prop_dict:
build_command.extend(["-c", prop_dict["selinux_fc"]])
+ if "squashfs_compressor" in prop_dict:
+ build_command.extend(["-z", prop_dict["squashfs_compressor"]])
+ if "squashfs_compressor_opt" in prop_dict:
+ build_command.extend(["-zo", prop_dict["squashfs_compressor_opt"]])
elif fs_type.startswith("f2fs"):
build_command = ["mkf2fsuserimg.sh"]
build_command.extend([out_file, prop_dict["partition_size"]])
@@ -302,8 +315,15 @@
staging_system = os.path.join(in_dir, "system")
shutil.rmtree(staging_system, ignore_errors=True)
shutil.copytree(origin_in, staging_system, symlinks=True)
+
+ reserved_blocks = prop_dict.get("has_ext4_reserved_blocks") == "true"
+ ext4fs_output = None
+
try:
- exit_code = RunCommand(build_command)
+ if reserved_blocks and fs_type.startswith("ext4"):
+ (ext4fs_output, exit_code) = RunCommand(build_command)
+ else:
+ (_, exit_code) = RunCommand(build_command)
finally:
if in_dir != origin_in:
# Clean up temporary directories and files.
@@ -313,17 +333,42 @@
if exit_code != 0:
return False
+ # Bug: 21522719, 22023465
+ # There are some reserved blocks on ext4 FS (lesser of 4096 blocks and 2%).
+ # We need to deduct those blocks from the available space, since they are
+ # not writable even with root privilege. It only affects devices using
+ # file-based OTA and a kernel version of 3.10 or greater (currently just
+ # sprout).
+ if reserved_blocks and fs_type.startswith("ext4"):
+ assert ext4fs_output is not None
+ ext4fs_stats = re.compile(
+ r'Created filesystem with .* (?P<used_blocks>[0-9]+)/'
+ r'(?P<total_blocks>[0-9]+) blocks')
+ m = ext4fs_stats.match(ext4fs_output.strip().split('\n')[-1])
+ used_blocks = int(m.groupdict().get('used_blocks'))
+ total_blocks = int(m.groupdict().get('total_blocks'))
+ reserved_blocks = min(4096, int(total_blocks * 0.02))
+ adjusted_blocks = total_blocks - reserved_blocks
+ if used_blocks > adjusted_blocks:
+ mount_point = prop_dict.get("mount_point")
+ print("Error: Not enough room on %s (total: %d blocks, used: %d blocks, "
+ "reserved: %d blocks, available: %d blocks)" % (
+ mount_point, total_blocks, used_blocks, reserved_blocks,
+ adjusted_blocks))
+ return False
+
if not fs_spans_partition:
mount_point = prop_dict.get("mount_point")
partition_size = int(prop_dict.get("partition_size"))
image_size = os.stat(out_file).st_size
if image_size > partition_size:
- print "Error: %s image size of %d is larger than partition size of %d" % (mount_point, image_size, partition_size)
- return False
+ print("Error: %s image size of %d is larger than partition size of "
+ "%d" % (mount_point, image_size, partition_size))
+ return False
if verity_supported and is_verity_partition:
- if 2 * image_size - AdjustPartitionSizeForVerity(image_size) > partition_size:
- print "Error: No more room on %s to fit verity data" % mount_point
- return False
+ if 2 * image_size - AdjustPartitionSizeForVerity(image_size) > partition_size:
+ print "Error: No more room on %s to fit verity data" % mount_point
+ return False
prop_dict["original_partition_size"] = prop_dict["partition_size"]
prop_dict["partition_size"] = str(image_size)
@@ -339,7 +384,7 @@
# Run e2fsck on the inflated image file
e2fsck_command = ["e2fsck", "-f", "-n", unsparse_image]
- exit_code = RunCommand(e2fsck_command)
+ (_, exit_code) = RunCommand(e2fsck_command)
os.remove(unsparse_image)
@@ -386,6 +431,9 @@
copy_prop("system_verity_block_device", "verity_block_device")
copy_prop("system_root_image", "system_root_image")
copy_prop("ramdisk_dir", "ramdisk_dir")
+ 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")
elif mount_point == "data":
# Copy the generic fs type first, override with specific one if available.
copy_prop("fs_type", "fs_type")
@@ -399,10 +447,12 @@
copy_prop("vendor_size", "partition_size")
copy_prop("vendor_journal_size", "journal_size")
copy_prop("vendor_verity_block_device", "verity_block_device")
+ copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
elif mount_point == "oem":
copy_prop("fs_type", "fs_type")
copy_prop("oem_size", "partition_size")
copy_prop("oem_journal_size", "journal_size")
+ copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
return d
@@ -422,17 +472,19 @@
def main(argv):
- if len(argv) != 3:
+ if len(argv) != 4:
print __doc__
sys.exit(1)
in_dir = argv[0]
glob_dict_file = argv[1]
out_file = argv[2]
+ target_out = argv[3]
glob_dict = LoadGlobalDict(glob_dict_file)
if "mount_point" in glob_dict:
- # The caller knows the mount point and provides a dictionay needed by BuildImage().
+ # The caller knows the mount point and provides a dictionay needed by
+ # BuildImage().
image_properties = glob_dict
else:
image_filename = os.path.basename(out_file)
@@ -453,7 +505,7 @@
image_properties = ImagePropFromGlobalDict(glob_dict, mount_point)
- if not BuildImage(in_dir, image_properties, out_file):
+ if not BuildImage(in_dir, image_properties, out_file, target_out):
print >> sys.stderr, "error: failed to build %s from %s" % (out_file,
in_dir)
exit(1)
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 6f921e0..99b319d 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1253,7 +1253,23 @@
script.AppendExtra('if range_sha1("%s", "%s") == "%s" then' % (
self.device, ranges_str,
self.tgt.TotalSha1(include_clobbered_blocks=True)))
- script.Print('Verified the updated %s image.' % (partition,))
+
+ # Bug: 20881595
+ # Verify that extended blocks are really zeroed out.
+ if self.tgt.extended:
+ ranges_str = self.tgt.extended.to_string_raw()
+ script.AppendExtra('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,))
+ script.AppendExtra(
+ 'else\n'
+ ' abort("%s partition has unexpected non-zero contents after OTA '
+ 'update");\n'
+ 'endif;' % (partition,))
+ else:
+ script.Print('Verified the updated %s image.' % (partition,))
+
script.AppendExtra(
'else\n'
' abort("%s partition has unexpected contents after OTA update");\n'
@@ -1286,6 +1302,15 @@
return ctx.hexdigest()
+ def _HashZeroBlocks(self, num_blocks): # pylint: disable=no-self-use
+ """Return the hash value for all zero blocks."""
+ zero_block = '\x00' * 4096
+ ctx = sha1()
+ for _ in range(num_blocks):
+ ctx.update(zero_block)
+
+ return ctx.hexdigest()
+
# TODO(tbao): Due to http://b/20939131, block 0 may be changed without
# remounting R/W. Will change the checking to a finer-grained way to
# mask off those bits.
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index 281ed59..566e687 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -20,11 +20,15 @@
"""Class to generate scripts in the 'edify' recovery script language
used from donut onwards."""
- def __init__(self, version, info):
+ def __init__(self, version, info, fstab=None):
self.script = []
self.mounts = set()
self.version = version
self.info = info
+ if fstab is None:
+ self.fstab = self.info.get("fstab", None)
+ else:
+ self.fstab = fstab
def MakeTemporary(self):
"""Make a temporary script object whose commands can latter be
@@ -168,7 +172,7 @@
where option is optname[=optvalue]
E.g. ext4=barrier=1,nodelalloc,errors=panic|f2fs=errors=recover
"""
- fstab = self.info.get("fstab", None)
+ fstab = self.fstab
if fstab:
p = fstab[mount_point]
mount_dict = {}
@@ -202,7 +206,7 @@
self.script.append('ui_print("%s");' % (message,))
def TunePartition(self, partition, *options):
- fstab = self.info.get("fstab", None)
+ fstab = self.fstab
if fstab:
p = fstab[partition]
if p.fs_type not in ("ext2", "ext3", "ext4"):
@@ -216,7 +220,7 @@
"""Format the given partition, specified by its mount point (eg,
"/system")."""
- fstab = self.info.get("fstab", None)
+ fstab = self.fstab
if fstab:
p = fstab[partition]
self.script.append('format("%s", "%s", "%s", "%s", "%s");' %
@@ -226,7 +230,7 @@
def WipeBlockDevice(self, partition):
if partition not in ("/system", "/vendor"):
raise ValueError(("WipeBlockDevice doesn't work on %s\n") % (partition,))
- fstab = self.info.get("fstab", None)
+ fstab = self.fstab
size = self.info.get(partition.lstrip("/") + "_size", None)
device = fstab[partition].device
@@ -271,7 +275,7 @@
"""Write the given package file into the partition for the given
mount point."""
- fstab = self.info["fstab"]
+ fstab = self.fstab
if fstab:
p = fstab[mount_point]
partition_type = common.PARTITION_TYPES[p.fs_type]
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index c4d0c1b..82d6313 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -486,8 +486,9 @@
def WriteFullOTAPackage(input_zip, output_zip):
# TODO: how to determine this? We don't know what version it will
- # be installed on top of. For now, we expect the API just won't
- # change very often.
+ # be installed on top of. For now, we expect the API just won't
+ # change very often. Similarly for fstab, it might have changed
+ # in the target build.
script = edify_generator.EdifyGenerator(3, OPTIONS.info_dict)
oem_props = OPTIONS.info_dict.get("oem_fingerprint_properties")
@@ -727,8 +728,9 @@
if source_version == 0:
print ("WARNING: generating edify script for a source that "
"can't install it.")
- script = edify_generator.EdifyGenerator(source_version,
- OPTIONS.target_info_dict)
+ script = edify_generator.EdifyGenerator(
+ source_version, OPTIONS.target_info_dict,
+ fstab=OPTIONS.source_info_dict["fstab"])
metadata = {
"pre-device": GetBuildProp("ro.product.device",
@@ -794,7 +796,7 @@
vendor_diff = None
oem_props = OPTIONS.target_info_dict.get("oem_fingerprint_properties")
- recovery_mount_options = OPTIONS.target_info_dict.get(
+ recovery_mount_options = OPTIONS.source_info_dict.get(
"recovery_mount_options")
oem_dict = None
if oem_props is not None and len(oem_props) > 0:
@@ -1114,11 +1116,13 @@
if source_version == 0:
print ("WARNING: generating edify script for a source that "
"can't install it.")
- script = edify_generator.EdifyGenerator(source_version,
- OPTIONS.target_info_dict)
+ script = edify_generator.EdifyGenerator(
+ source_version, OPTIONS.target_info_dict,
+ fstab=OPTIONS.source_info_dict["fstab"])
oem_props = OPTIONS.info_dict.get("oem_fingerprint_properties")
- recovery_mount_options = OPTIONS.info_dict.get("recovery_mount_options")
+ recovery_mount_options = OPTIONS.source_info_dict.get(
+ "recovery_mount_options")
oem_dict = None
if oem_props is not None and len(oem_props) > 0:
if OPTIONS.oem_source is None:
diff --git a/tools/releasetools/rangelib.py b/tools/releasetools/rangelib.py
index 8b327fe..1506658 100644
--- a/tools/releasetools/rangelib.py
+++ b/tools/releasetools/rangelib.py
@@ -238,6 +238,28 @@
out.append(offset + p - start)
return RangeSet(data=out)
+ def extend(self, n):
+ """Extend the RangeSet by 'n' blocks.
+
+ The lower bound is guaranteed to be non-negative.
+
+ >>> RangeSet("0-9").extend(1)
+ <RangeSet("0-10")>
+ >>> RangeSet("10-19").extend(15)
+ <RangeSet("0-34")>
+ >>> RangeSet("10-19 30-39").extend(4)
+ <RangeSet("6-23 26-43")>
+ >>> RangeSet("10-19 30-39").extend(10)
+ <RangeSet("0-49")>
+ """
+ out = self
+ for i in range(0, len(self.data), 2):
+ s, e = self.data[i:i+2]
+ s1 = max(0, s - n)
+ e1 = e + n
+ out = out.union(RangeSet(str(s1) + "-" + str(e1-1)))
+ return out
+
if __name__ == "__main__":
import doctest
diff --git a/tools/releasetools/sparse_img.py b/tools/releasetools/sparse_img.py
index 51a1643..07f3c1c 100644
--- a/tools/releasetools/sparse_img.py
+++ b/tools/releasetools/sparse_img.py
@@ -110,6 +110,17 @@
self.care_map = rangelib.RangeSet(care_data)
self.offset_index = [i[0] for i in offset_map]
+ # Bug: 20881595
+ # Introduce extended blocks as a workaround for the bug. dm-verity may
+ # touch blocks that are not in the care_map due to block device
+ # read-ahead. It will fail if such blocks contain non-zeroes. We zero out
+ # the extended blocks explicitly to avoid dm-verity failures. 512 blocks
+ # are the maximum read-ahead we configure for dm-verity block devices.
+ extended = self.care_map.extend(512)
+ all_blocks = rangelib.RangeSet(data=(0, self.total_blocks))
+ extended = extended.intersect(all_blocks).subtract(self.care_map)
+ self.extended = extended
+
if file_map_fn:
self.LoadFileBlockMap(file_map_fn, self.clobbered_blocks)
else:
@@ -125,7 +136,7 @@
clobbered_blocks."""
ranges = self.care_map
if not include_clobbered_blocks:
- ranges.subtract(self.clobbered_blocks)
+ ranges = ranges.subtract(self.clobbered_blocks)
h = sha1()
for d in self._GetRangeData(ranges):
h.update(d)
@@ -221,9 +232,14 @@
nonzero_blocks.append(b)
nonzero_blocks.append(b+1)
- out["__ZERO"] = rangelib.RangeSet(data=zero_blocks)
- out["__NONZERO"] = rangelib.RangeSet(data=nonzero_blocks)
- out["__COPY"] = clobbered_blocks
+ assert zero_blocks or nonzero_blocks or clobbered_blocks
+
+ if zero_blocks:
+ out["__ZERO"] = rangelib.RangeSet(data=zero_blocks)
+ if nonzero_blocks:
+ out["__NONZERO"] = rangelib.RangeSet(data=nonzero_blocks)
+ if clobbered_blocks:
+ out["__COPY"] = clobbered_blocks
def ResetFileMap(self):
"""Throw away the file map and treat the entire image as