doc: Changed go/ category etc. to topic/ am: 36af4d4d08
am: dae70906a5
* commit 'dae70906a53c692daee4d3ae92efe2166a01fec2':
doc: Changed go/ category etc. to topic/
Change-Id: I5356efde244ffdb17b65199689a8e9255724bd7e
diff --git a/core/Makefile b/core/Makefile
index 22dcee1..07d1c94 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -523,14 +523,14 @@
$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(VBOOT_SIGNER)
$(call pretty,"Target boot image: $@")
$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@.unsigned
- $(VBOOT_SIGNER) $(FUTILITY) $@.unsigned $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbpubk $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbprivk $@.keyblock $@
+ $(VBOOT_SIGNER) $(FUTILITY) $@.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 $@.keyblock $@
$(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE))
.PHONY: bootimage-nodeps
bootimage-nodeps: $(MKBOOTIMG) $(VBOOT_SIGNER)
@echo "make $@: ignoring dependencies"
$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET).unsigned
- $(VBOOT_SIGNER) $(FUTILITY) $(INSTALLED_BOOTIMAGE_TARGET).unsigned $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbpubk $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbprivk $(INSTALLED_BOOTIMAGE_TARGET).keyblock $(INSTALLED_BOOTIMAGE_TARGET)
+ $(VBOOT_SIGNER) $(FUTILITY) $(INSTALLED_BOOTIMAGE_TARGET).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 $(INSTALLED_BOOTIMAGE_TARGET).keyblock $(INSTALLED_BOOTIMAGE_TARGET)
$(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE))
else # PRODUCT_SUPPORTS_VBOOT != true
@@ -757,6 +757,7 @@
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION),$(hide) echo "vendor_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_key=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY)" >> $(1))
+$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_subkey=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_SUBKEY)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "futility=$(FUTILITY)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_signer_cmd=$(VBOOT_SIGNER)" >> $(1))
$(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),\
@@ -893,7 +894,7 @@
$(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,$(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 $(1).keyblock $(1))
+ $(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))
$(hide) $(call assert-max-image-size,$(1),$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))
@echo ----- Made recovery image: $(1) --------
endef
diff --git a/core/definitions.mk b/core/definitions.mk
index 78b0a39..9dea18c 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -175,16 +175,53 @@
endef
###########################################################
+## Find all of the directories under the named directories with
+## the specified name.
+## Meant to be used like:
+## INC_DIRS := $(call all-named-dirs-under,inc,.)
+###########################################################
+
+define all-named-dirs-under
+$(call find-subdir-files,$(2) -type d -name "$(1)")
+endef
+
+###########################################################
+## Find all the directories under the current directory that
+## haves name that match $(1)
+###########################################################
+
+define all-subdir-named-dirs
+$(call all-named-dirs-under,$(1),.)
+endef
+
+###########################################################
+## Find all of the files under the named directories with
+## the specified name.
+## Meant to be used like:
+## SRC_FILES := $(call all-named-files-under,*.h,src tests)
+###########################################################
+
+define all-named-files-under
+$(call find-files-in-subdirs,$(LOCAL_PATH),"$(1)",$(2))
+endef
+
+###########################################################
+## Find all of the files under the current directory with
+## the specified name.
+###########################################################
+
+define all-subdir-named-files
+$(call all-named-files-under,$(1),.)
+endef
+
+###########################################################
## Find all of the java files under the named directories.
## Meant to be used like:
## SRC_FILES := $(call all-java-files-under,src tests)
###########################################################
define all-java-files-under
-$(patsubst ./%,%, \
- $(shell cd $(LOCAL_PATH) ; \
- find -L $(1) -name "*.java" -and -not -name ".*") \
- )
+$(call all-named-files-under,*.java,$(1))
endef
###########################################################
@@ -203,10 +240,7 @@
###########################################################
define all-c-files-under
-$(patsubst ./%,%, \
- $(shell cd $(LOCAL_PATH) ; \
- find -L $(1) -name "*.c" -and -not -name ".*") \
- )
+$(call all-named-files-under,*.c,$(1))
endef
###########################################################
@@ -219,16 +253,36 @@
endef
###########################################################
+## Find all of the cpp files under the named directories.
+## LOCAL_CPP_EXTENSION is respected if set.
+## Meant to be used like:
+## SRC_FILES := $(call all-cpp-files-under,src tests)
+###########################################################
+
+define all-cpp-files-under
+$(sort $(patsubst ./%,%, \
+ $(shell cd $(LOCAL_PATH) ; \
+ find -L $(1) -name "*$(or $(LOCAL_CPP_EXTENSION),.cpp)" -and -not -name ".*") \
+ ))
+endef
+
+###########################################################
+## Find all of the cpp files from here. Meant to be used like:
+## SRC_FILES := $(call all-subdir-cpp-files)
+###########################################################
+
+define all-subdir-cpp-files
+$(call all-cpp-files-under,.)
+endef
+
+###########################################################
## Find all files named "I*.aidl" under the named directories,
## which must be relative to $(LOCAL_PATH). The returned list
## is relative to $(LOCAL_PATH).
###########################################################
define all-Iaidl-files-under
-$(patsubst ./%,%, \
- $(shell cd $(LOCAL_PATH) ; \
- find -L $(1) -name "I*.aidl" -and -not -name ".*") \
- )
+$(call all-named-files-under,I*.aidl,$(1))
endef
###########################################################
@@ -246,10 +300,7 @@
###########################################################
define all-logtags-files-under
-$(patsubst ./%,%, \
- $(shell cd $(LOCAL_PATH) ; \
- find -L $(1) -name "*.logtags" -and -not -name ".*") \
- )
+$(call all-named-files-under,*.logtags,$(1))
endef
###########################################################
@@ -259,10 +310,7 @@
###########################################################
define all-proto-files-under
-$(patsubst ./%,%, \
- $(shell cd $(LOCAL_PATH) ; \
- find -L $(1) -name "*.proto" -and -not -name ".*") \
- )
+$(call all-named-files-under,*.proto,$(1))
endef
###########################################################
@@ -272,10 +320,7 @@
###########################################################
define all-renderscript-files-under
-$(patsubst ./%,%, \
- $(shell cd $(LOCAL_PATH) ; \
- find -L $(1) \( -name "*.rs" -or -name "*.fs" \) -and -not -name ".*") \
- )
+$(call find-subdir-files,$(1) \( -name "*.rs" -or -name "*.fs" \) -and -not -name ".*")
endef
###########################################################
@@ -285,10 +330,7 @@
###########################################################
define all-S-files-under
-$(patsubst ./%,%, \
- $(shell cd $(LOCAL_PATH) ; \
- find -L $(1) -name "*.S" -and -not -name ".*") \
- )
+$(call all-named-files-under,*.S,$(1))
endef
###########################################################
@@ -298,10 +340,7 @@
###########################################################
define all-html-files-under
-$(patsubst ./%,%, \
- $(shell cd $(LOCAL_PATH) ; \
- find -L $(1) -name "*.html" -and -not -name ".*") \
- )
+$(call all-named-files-under,*.html,$(1))
endef
###########################################################
@@ -319,7 +358,7 @@
###########################################################
define find-subdir-files
-$(patsubst ./%,%,$(shell cd $(LOCAL_PATH) ; find -L $(1)))
+$(sort $(patsubst ./%,%,$(shell cd $(LOCAL_PATH) ; find -L $(1))))
endef
###########################################################
@@ -331,8 +370,8 @@
###########################################################
define find-subdir-subdir-files
-$(filter-out $(patsubst %,$(1)/%,$(3)),$(patsubst ./%,%,$(shell cd \
- $(LOCAL_PATH) ; find -L $(1) -maxdepth 1 -name $(2))))
+$(sort $(filter-out $(patsubst %,$(1)/%,$(3)),$(patsubst ./%,%,$(shell cd \
+ $(LOCAL_PATH) ; find -L $(1) -maxdepth 1 -name $(2)))))
endef
###########################################################
@@ -341,10 +380,10 @@
###########################################################
define find-subdir-assets
-$(if $(1),$(patsubst ./%,%, \
+$(sort $(if $(1),$(patsubst ./%,%, \
$(shell if [ -d $(1) ] ; then cd $(1) ; find ./ -not -name '.*' -and -type f -and -not -type l ; fi)), \
$(warning Empty argument supplied to find-subdir-assets) \
-)
+))
endef
###########################################################
@@ -352,11 +391,11 @@
###########################################################
define find-other-java-files
- $(call find-subdir-files,$(1) -name "*.java" -and -not -name ".*")
+$(call all-java-files-under,$(1))
endef
define find-other-html-files
- $(call find-subdir-files,$(1) -name "*.html" -and -not -name ".*")
+$(call all-html-files-under,$(1))
endef
###########################################################
@@ -369,10 +408,10 @@
###########################################################
define find-files-in-subdirs
-$(patsubst ./%,%, \
+$(sort $(patsubst ./%,%, \
$(shell cd $(1) ; \
find -L $(3) -name $(2) -and -not -name ".*") \
- )
+ ))
endef
###########################################################
@@ -1633,8 +1672,12 @@
## Commands for running javac to make .class files
###########################################################
-#@echo "Source intermediates dir: $(PRIVATE_SOURCE_INTERMEDIATES_DIR)"
-#@echo "Source intermediates: $$(find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java')"
+# Add BUILD_NUMBER to apps default version name if it's unbundled build.
+ifdef TARGET_BUILD_APPS
+APPS_DEFAULT_VERSION_NAME := $(PLATFORM_VERSION)-$(BUILD_NUMBER)
+else
+APPS_DEFAULT_VERSION_NAME := $(PLATFORM_VERSION)
+endif
# TODO: Right now we generate the asset resources twice, first as part
# of generating the Java classes, then at the end when packaging the final
@@ -1661,8 +1704,8 @@
$(addprefix -G , $(PRIVATE_PROGUARD_OPTIONS_FILE)) \
$(addprefix --min-sdk-version , $(PRIVATE_DEFAULT_APP_TARGET_SDK)) \
$(addprefix --target-sdk-version , $(PRIVATE_DEFAULT_APP_TARGET_SDK)) \
- $(if $(filter --version-code,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-code , $(PLATFORM_SDK_VERSION))) \
- $(if $(filter --version-name,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-name , $(PLATFORM_VERSION)-$(BUILD_NUMBER))) \
+ $(if $(filter --version-code,$(PRIVATE_AAPT_FLAGS)),,--version-code $(PLATFORM_SDK_VERSION)) \
+ $(if $(filter --version-name,$(PRIVATE_AAPT_FLAGS)),,--version-name $(APPS_DEFAULT_VERSION_NAME)) \
$(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
$(addprefix --rename-instrumentation-target-package , $(PRIVATE_MANIFEST_INSTRUMENTATION_FOR)) \
--skip-symbols-without-default-localization
@@ -2010,8 +2053,8 @@
$(addprefix --min-sdk-version , $(PRIVATE_DEFAULT_APP_TARGET_SDK)) \
$(addprefix --target-sdk-version , $(PRIVATE_DEFAULT_APP_TARGET_SDK)) \
$(if $(filter --product,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --product , $(TARGET_AAPT_CHARACTERISTICS))) \
- $(if $(filter --version-code,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-code , $(PLATFORM_SDK_VERSION))) \
- $(if $(filter --version-name,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --version-name , $(PLATFORM_VERSION)-$(BUILD_NUMBER))) \
+ $(if $(filter --version-code,$(PRIVATE_AAPT_FLAGS)),,--version-code $(PLATFORM_SDK_VERSION)) \
+ $(if $(filter --version-name,$(PRIVATE_AAPT_FLAGS)),,--version-name $(APPS_DEFAULT_VERSION_NAME)) \
$(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
$(addprefix --rename-instrumentation-target-package , $(PRIVATE_MANIFEST_INSTRUMENTATION_FOR)) \
--skip-symbols-without-default-localization \
diff --git a/core/main.mk b/core/main.mk
index 4f22b93..5b6e1e9 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -939,6 +939,7 @@
$(call dist-for-goals, droidcore, \
$(INTERNAL_UPDATE_PACKAGE_TARGET) \
$(INTERNAL_OTA_PACKAGE_TARGET) \
+ $(BUILT_OTATOOLS_PACKAGE) \
$(SYMBOLS_ZIP) \
$(INSTALLED_FILES_FILE) \
$(INSTALLED_BUILD_PROP_TARGET) \
diff --git a/core/product.mk b/core/product.mk
index 4e8bff1..e97cba4 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -104,6 +104,7 @@
PRODUCT_SYSTEM_PROPERTY_BLACKLIST \
PRODUCT_SYSTEM_SERVER_JARS \
PRODUCT_VBOOT_SIGNING_KEY \
+ PRODUCT_VBOOT_SIGNING_SUBKEY \
PRODUCT_VERITY_SIGNING_KEY \
PRODUCT_SYSTEM_VERITY_PARTITION \
PRODUCT_VENDOR_VERITY_PARTITION \
diff --git a/core/product_config.mk b/core/product_config.mk
index 5240ae7..94449c2 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -117,7 +117,7 @@
# which really means TARGET_PRODUCT=dream make installclean.
ifneq ($(filter-out $(INTERNAL_VALID_VARIANTS),$(TARGET_BUILD_VARIANT)),)
MAKECMDGOALS := $(MAKECMDGOALS) $(TARGET_BUILD_VARIANT)
- TARGET_BUILD_VARIANT := eng
+ TARGET_BUILD_VARIANT := userdebug
default_goal_substitution :=
else
default_goal_substitution := $(DEFAULT_GOAL)
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 483c8f2..a67a82e 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -42,7 +42,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 := 6.0
+ PLATFORM_VERSION := 6.0.1
endif
ifeq "" "$(PLATFORM_SDK_VERSION)"
@@ -103,7 +103,7 @@
# Can be an arbitrary string, but must be a single word.
#
# If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
- PLATFORM_SECURITY_PATCH :=
+ PLATFORM_SECURITY_PATCH := 2015-12-01
endif
ifeq "" "$(PLATFORM_BASE_OS)"
diff --git a/envsetup.sh b/envsetup.sh
index dba64ee..6ad3a9e 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -1355,14 +1355,20 @@
return
fi
T=$(gettop)
- if [[ ! -f $T/filelist ]]; then
+ if [ ! "$OUT_DIR" = "" ]; then
+ mkdir -p $OUT_DIR
+ FILELIST=$OUT_DIR/filelist
+ else
+ FILELIST=$T/filelist
+ fi
+ if [[ ! -f $FILELIST ]]; then
echo -n "Creating index..."
- (\cd $T; find . -wholename ./out -prune -o -wholename ./.repo -prune -o -type f > filelist)
+ (\cd $T; find . -wholename ./out -prune -o -wholename ./.repo -prune -o -type f > $FILELIST)
echo " Done"
echo ""
fi
local lines
- lines=($(\grep "$1" $T/filelist | sed -e 's/\/[^/]*$//' | sort | uniq))
+ lines=($(\grep "$1" $FILELIST | sed -e 's/\/[^/]*$//' | sort | uniq))
if [[ ${#lines[@]} = 0 ]]; then
echo "Not found"
return
diff --git a/target/board/generic/sepolicy/property_contexts b/target/board/generic/sepolicy/property_contexts
index 09b9b06..a0a4020 100644
--- a/target/board/generic/sepolicy/property_contexts
+++ b/target/board/generic/sepolicy/property_contexts
@@ -1,2 +1,4 @@
qemu. u:object_r:qemu_prop:s0
+emu. u:object_r:qemu_prop:s0
+emulator. u:object_r:qemu_prop:s0
radio.noril u:object_r:radio_noril_prop:s0
diff --git a/target/product/base.mk b/target/product/base.mk
index 1699156..4c49e86 100644
--- a/target/product/base.mk
+++ b/target/product/base.mk
@@ -111,6 +111,7 @@
run-as \
schedtest \
sdcard \
+ secdiscard \
services \
settings \
sgdisk \
diff --git a/target/product/core.mk b/target/product/core.mk
index 519dbb8..d453303 100644
--- a/target/product/core.mk
+++ b/target/product/core.mk
@@ -23,7 +23,6 @@
PRODUCT_PACKAGES += \
BasicDreams \
Browser \
- Calculator \
Calendar \
CalendarProvider \
CaptivePortalLogin \
@@ -33,6 +32,7 @@
DocumentsUI \
DownloadProviderUi \
Email \
+ ExactCalculator \
Exchange2 \
ExternalStorageProvider \
FusedLocation \
diff --git a/target/product/core_tiny.mk b/target/product/core_tiny.mk
index 0a92275..2be0507 100644
--- a/target/product/core_tiny.mk
+++ b/target/product/core_tiny.mk
@@ -57,6 +57,7 @@
gatekeeperd \
keystore \
keystore.default \
+ ld.mc \
libOpenMAXAL \
libOpenSLES \
libdownmix \
diff --git a/target/product/embedded.mk b/target/product/embedded.mk
index c40de4f..25a8975 100644
--- a/target/product/embedded.mk
+++ b/target/product/embedded.mk
@@ -89,6 +89,7 @@
PRODUCT_COPY_FILES += \
system/core/rootdir/init.usb.rc:root/init.usb.rc \
+ system/core/rootdir/init.usb.configfs.rc:root/init.usb.configfs.rc \
system/core/rootdir/init.trace.rc:root/init.trace.rc \
system/core/rootdir/ueventd.rc:root/ueventd.rc \
system/core/rootdir/etc/hosts:system/etc/hosts
diff --git a/target/product/emulator.mk b/target/product/emulator.mk
index 982f7da..7394d4f 100644
--- a/target/product/emulator.mk
+++ b/target/product/emulator.mk
@@ -50,6 +50,7 @@
sensors.ranchu
PRODUCT_COPY_FILES += \
+ frameworks/native/data/etc/android.hardware.ethernet.xml:system/etc/permissions/android.hardware.ethernet.xml \
device/generic/goldfish/fstab.goldfish:root/fstab.goldfish \
device/generic/goldfish/init.goldfish.rc:root/init.goldfish.rc \
device/generic/goldfish/init.goldfish.sh:system/etc/init.goldfish.sh \
diff --git a/target/product/full_base.mk b/target/product/full_base.mk
index 3b547c8..65bdf0f 100644
--- a/target/product/full_base.mk
+++ b/target/product/full_base.mk
@@ -45,9 +45,6 @@
# Put en_US first in the list, so make it default.
PRODUCT_LOCALES := en_US
-# Include drawables for all densities
-PRODUCT_AAPT_CONFIG := normal
-
# Get some sounds
$(call inherit-product-if-exists, frameworks/base/data/sounds/AllAudio.mk)
diff --git a/target/product/vboot.mk b/target/product/vboot.mk
index e4b1144..48a4883 100644
--- a/target/product/vboot.mk
+++ b/target/product/vboot.mk
@@ -22,3 +22,4 @@
# We expect this file to exist with the suffixes ".vbprivk" and ".vbpupk".
# TODO: find a proper location for this
PRODUCT_VBOOT_SIGNING_KEY := external/vboot_reference/tests/devkeys/kernel_data_key
+PRODUCT_VBOOT_SIGNING_SUBKEY := external/vboot_reference/tests/devkeys/kernel_subkey
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index eab8113..f2bf1e1 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -28,6 +28,7 @@
print >> sys.stderr, "Python 2.7 or newer is required."
sys.exit(1)
+import datetime
import errno
import os
import tempfile
@@ -40,6 +41,9 @@
OPTIONS.add_missing = False
OPTIONS.rebuild_recovery = False
+OPTIONS.replace_verity_public_key = False
+OPTIONS.replace_verity_private_key = False
+OPTIONS.verity_signer_path = None
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
@@ -119,6 +123,12 @@
if fstab:
image_props["fs_type"] = fstab["/" + what].fs_type
+ # Use a fixed timestamp (01/01/2009) when packaging the image.
+ # Bug: 24377993
+ epoch = datetime.datetime.fromtimestamp(0)
+ timestamp = (datetime.datetime(2009, 1, 1) - epoch).total_seconds()
+ image_props["timestamp"] = int(timestamp)
+
if what == "system":
fs_config_prefix = ""
else:
@@ -170,6 +180,12 @@
print "creating userdata.img..."
+ # Use a fixed timestamp (01/01/2009) when packaging the image.
+ # Bug: 24377993
+ epoch = datetime.datetime.fromtimestamp(0)
+ timestamp = (datetime.datetime(2009, 1, 1) - epoch).total_seconds()
+ image_props["timestamp"] = int(timestamp)
+
# The name of the directory it is making an image out of matters to
# mkyaffs2image. So we create a temp dir, and within it we create an
# empty dir named "data", and build the image from that.
@@ -207,6 +223,12 @@
print "creating cache.img..."
+ # Use a fixed timestamp (01/01/2009) when packaging the image.
+ # Bug: 24377993
+ epoch = datetime.datetime.fromtimestamp(0)
+ timestamp = (datetime.datetime(2009, 1, 1) - epoch).total_seconds()
+ image_props["timestamp"] = int(timestamp)
+
# The name of the directory it is making an image out of matters to
# mkyaffs2image. So we create a temp dir, and within it we create an
# empty dir named "cache", and build the image from that.
@@ -296,18 +318,27 @@
common.ZipClose(output_zip)
def main(argv):
- def option_handler(o, _):
+ def option_handler(o, a):
if o in ("-a", "--add_missing"):
OPTIONS.add_missing = True
elif o in ("-r", "--rebuild_recovery",):
OPTIONS.rebuild_recovery = True
+ elif o == "--replace_verity_private_key":
+ OPTIONS.replace_verity_private_key = (True, a)
+ elif o == "--replace_verity_public_key":
+ OPTIONS.replace_verity_public_key = (True, a)
+ elif o == "--verity_signer_path":
+ OPTIONS.verity_signer_path = a
else:
return False
return True
args = common.ParseOptions(
argv, __doc__, extra_opts="ar",
- extra_long_opts=["add_missing", "rebuild_recovery"],
+ extra_long_opts=["add_missing", "rebuild_recovery",
+ "replace_verity_public_key=",
+ "replace_verity_private_key=",
+ "verity_signer_path="],
extra_option_handler=option_handler)
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index 6ed9ca2..cb6fc85 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -16,6 +16,7 @@
from collections import deque, OrderedDict
from hashlib import sha1
+import common
import heapq
import itertools
import multiprocessing
@@ -105,11 +106,13 @@
assert not (trim and pad)
partial = len(self.data) % self.blocksize
+ padded = False
if partial > 0:
if trim:
self.data = self.data[:-partial]
elif pad:
self.data += '\0' * (self.blocksize - partial)
+ padded = True
else:
raise ValueError(("data for DataImage must be multiple of %d bytes "
"unless trim or pad is specified") %
@@ -119,14 +122,23 @@
self.total_blocks = len(self.data) / self.blocksize
self.care_map = RangeSet(data=(0, self.total_blocks))
- self.clobbered_blocks = RangeSet()
+ # When the last block is padded, we always write the whole block even for
+ # incremental OTAs. Because otherwise the last block may get skipped if
+ # unchanged for an incremental, but would fail the post-install
+ # verification if it has non-zero contents in the padding bytes.
+ # Bug: 23828506
+ if padded:
+ self.clobbered_blocks = RangeSet(
+ data=(self.total_blocks-1, self.total_blocks))
+ else:
+ self.clobbered_blocks = RangeSet()
self.extended = RangeSet()
zero_blocks = []
nonzero_blocks = []
reference = '\0' * self.blocksize
- for i in range(self.total_blocks):
+ for i in range(self.total_blocks-1 if padded else self.total_blocks):
d = self.data[i*self.blocksize : (i+1)*self.blocksize]
if d == reference:
zero_blocks.append(i)
@@ -138,14 +150,18 @@
self.file_map = {"__ZERO": RangeSet(zero_blocks),
"__NONZERO": RangeSet(nonzero_blocks)}
+ if self.clobbered_blocks:
+ self.file_map["__COPY"] = self.clobbered_blocks
+
def ReadRangeSet(self, ranges):
return [self.data[s*self.blocksize:e*self.blocksize] for (s, e) in ranges]
def TotalSha1(self, include_clobbered_blocks=False):
- # DataImage always carries empty clobbered_blocks, so
- # include_clobbered_blocks can be ignored.
- assert self.clobbered_blocks.size() == 0
- return sha1(self.data).hexdigest()
+ if not include_clobbered_blocks:
+ ranges = self.care_map.subtract(self.clobbered_blocks)
+ return sha1(self.ReadRangeSet(ranges)).hexdigest()
+ else:
+ return sha1(self.data).hexdigest()
class Transfer(object):
@@ -173,6 +189,12 @@
return (sum(sr.size() for (_, sr) in self.stash_before) -
sum(sr.size() for (_, sr) in self.use_stash))
+ def ConvertToNew(self):
+ assert self.style != "new"
+ self.use_stash = []
+ self.style = "new"
+ self.src_ranges = RangeSet()
+
def __str__(self):
return (str(self.id) + ": <" + str(self.src_ranges) + " " + self.style +
" to " + str(self.tgt_ranges) + ">")
@@ -267,6 +289,10 @@
self.ReverseBackwardEdges()
self.ImproveVertexSequence()
+ # Ensure the runtime stash size is under the limit.
+ if self.version >= 2 and common.OPTIONS.cache_size is not None:
+ self.ReviseStashSize()
+
# Double-check our work.
self.AssertSequenceGood()
@@ -286,7 +312,6 @@
out = []
total = 0
- performs_read = False
stashes = {}
stashed_blocks = 0
@@ -398,7 +423,6 @@
out.append("%s %s\n" % (xf.style, xf.tgt_ranges.to_string_raw()))
total += tgt_size
elif xf.style == "move":
- performs_read = True
assert xf.tgt_ranges
assert xf.src_ranges.size() == tgt_size
if xf.src_ranges != xf.tgt_ranges:
@@ -423,7 +447,6 @@
xf.tgt_ranges.to_string_raw(), src_str))
total += tgt_size
elif xf.style in ("bsdiff", "imgdiff"):
- performs_read = True
assert xf.tgt_ranges
assert xf.src_ranges
if self.version == 1:
@@ -460,9 +483,20 @@
if free_string:
out.append("".join(free_string))
- # sanity check: abort if we're going to need more than 512 MB if
- # stash space
- assert max_stashed_blocks * self.tgt.blocksize < (512 << 20)
+ if self.version >= 2:
+ # Sanity check: abort if we're going to need more stash space than
+ # the allowed size (cache_size * threshold). There are two purposes
+ # of having a threshold here. a) Part of the cache may have been
+ # occupied by some recovery logs. b) It will buy us some time to deal
+ # with the oversize issue.
+ cache_size = common.OPTIONS.cache_size
+ stash_threshold = common.OPTIONS.stash_threshold
+ max_allowed = cache_size * stash_threshold
+ assert max_stashed_blocks * self.tgt.blocksize < max_allowed, \
+ 'Stash size %d (%d * %d) exceeds the limit %d (%d * %.2f)' % (
+ max_stashed_blocks * self.tgt.blocksize, max_stashed_blocks,
+ self.tgt.blocksize, max_allowed, cache_size,
+ stash_threshold)
# Zero out extended blocks as a workaround for bug 20881595.
if self.tgt.extended:
@@ -489,8 +523,81 @@
f.write(i)
if self.version >= 2:
- print("max stashed blocks: %d (%d bytes)\n" % (
- max_stashed_blocks, max_stashed_blocks * self.tgt.blocksize))
+ max_stashed_size = max_stashed_blocks * self.tgt.blocksize
+ max_allowed = common.OPTIONS.cache_size * common.OPTIONS.stash_threshold
+ print("max stashed blocks: %d (%d bytes), limit: %d bytes (%.2f%%)\n" % (
+ max_stashed_blocks, max_stashed_size, max_allowed,
+ max_stashed_size * 100.0 / max_allowed))
+
+ def ReviseStashSize(self):
+ print("Revising stash size...")
+ stashes = {}
+
+ # Create the map between a stash and its def/use points. For example, for a
+ # given stash of (idx, sr), stashes[idx] = (sr, def_cmd, use_cmd).
+ for xf in self.transfers:
+ # Command xf defines (stores) all the stashes in stash_before.
+ for idx, sr in xf.stash_before:
+ stashes[idx] = (sr, xf)
+
+ # Record all the stashes command xf uses.
+ for idx, _ in xf.use_stash:
+ stashes[idx] += (xf,)
+
+ # Compute the maximum blocks available for stash based on /cache size and
+ # the threshold.
+ cache_size = common.OPTIONS.cache_size
+ stash_threshold = common.OPTIONS.stash_threshold
+ max_allowed = cache_size * stash_threshold / self.tgt.blocksize
+
+ stashed_blocks = 0
+ new_blocks = 0
+
+ # Now go through all the commands. Compute the required stash size on the
+ # fly. If a command requires excess stash than available, it deletes the
+ # stash by replacing the command that uses the stash with a "new" command
+ # instead.
+ for xf in self.transfers:
+ replaced_cmds = []
+
+ # xf.stash_before generates explicit stash commands.
+ for idx, sr in xf.stash_before:
+ if stashed_blocks + sr.size() > max_allowed:
+ # We cannot stash this one for a later command. Find out the command
+ # that will use this stash and replace the command with "new".
+ use_cmd = stashes[idx][2]
+ replaced_cmds.append(use_cmd)
+ print("%10d %9s %s" % (sr.size(), "explicit", use_cmd))
+ else:
+ stashed_blocks += sr.size()
+
+ # xf.use_stash generates free commands.
+ for _, sr in xf.use_stash:
+ stashed_blocks -= sr.size()
+
+ # "move" and "diff" may introduce implicit stashes in BBOTA v3. Prior to
+ # ComputePatches(), they both have the style of "diff".
+ if xf.style == "diff" and self.version >= 3:
+ assert xf.tgt_ranges and xf.src_ranges
+ if xf.src_ranges.overlaps(xf.tgt_ranges):
+ if stashed_blocks + xf.src_ranges.size() > max_allowed:
+ replaced_cmds.append(xf)
+ print("%10d %9s %s" % (xf.src_ranges.size(), "implicit", xf))
+
+ # Replace the commands in replaced_cmds with "new"s.
+ for cmd in replaced_cmds:
+ # It no longer uses any commands in "use_stash". Remove the def points
+ # for all those stashes.
+ for idx, sr in cmd.use_stash:
+ def_cmd = stashes[idx][1]
+ assert (idx, sr) in def_cmd.stash_before
+ def_cmd.stash_before.remove((idx, sr))
+ new_blocks += sr.size()
+
+ cmd.ConvertToNew()
+
+ print(" Total %d blocks are packed as new blocks due to insufficient "
+ "cache size." % (new_blocks,))
def ComputePatches(self, prefix):
print("Reticulating splines...")
@@ -847,6 +954,57 @@
a.goes_after[b] = size
def FindTransfers(self):
+ """Parse the file_map to generate all the transfers."""
+
+ def AddTransfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id,
+ split=False):
+ """Wrapper function for adding a Transfer().
+
+ For BBOTA v3, we need to stash source blocks for resumable feature.
+ However, with the growth of file size and the shrink of the cache
+ partition source blocks are too large to be stashed. If a file occupies
+ too many blocks (greater than MAX_BLOCKS_PER_DIFF_TRANSFER), we split it
+ into smaller pieces by getting multiple Transfer()s.
+
+ The downside is that after splitting, we can no longer use imgdiff but
+ only bsdiff."""
+
+ MAX_BLOCKS_PER_DIFF_TRANSFER = 1024
+
+ # We care about diff transfers only.
+ if style != "diff" or not split:
+ Transfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id)
+ return
+
+ # Change nothing for small files.
+ if (tgt_ranges.size() <= MAX_BLOCKS_PER_DIFF_TRANSFER and
+ src_ranges.size() <= MAX_BLOCKS_PER_DIFF_TRANSFER):
+ Transfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id)
+ return
+
+ pieces = 0
+ while (tgt_ranges.size() > MAX_BLOCKS_PER_DIFF_TRANSFER and
+ src_ranges.size() > MAX_BLOCKS_PER_DIFF_TRANSFER):
+ tgt_split_name = "%s-%d" % (tgt_name, pieces)
+ src_split_name = "%s-%d" % (src_name, pieces)
+ tgt_first = tgt_ranges.first(MAX_BLOCKS_PER_DIFF_TRANSFER)
+ src_first = src_ranges.first(MAX_BLOCKS_PER_DIFF_TRANSFER)
+ Transfer(tgt_split_name, src_split_name, tgt_first, src_first, style,
+ by_id)
+
+ tgt_ranges = tgt_ranges.subtract(tgt_first)
+ src_ranges = src_ranges.subtract(src_first)
+ pieces += 1
+
+ # Handle remaining blocks.
+ if tgt_ranges.size() or src_ranges.size():
+ # Must be both non-empty.
+ assert tgt_ranges.size() and src_ranges.size()
+ tgt_split_name = "%s-%d" % (tgt_name, pieces)
+ src_split_name = "%s-%d" % (src_name, pieces)
+ Transfer(tgt_split_name, src_split_name, tgt_ranges, src_ranges, style,
+ by_id)
+
empty = RangeSet()
for tgt_fn, tgt_ranges in self.tgt.file_map.items():
if tgt_fn == "__ZERO":
@@ -854,28 +1012,28 @@
# in any file and that are filled with zeros. We have a
# special transfer style for zero blocks.
src_ranges = self.src.file_map.get("__ZERO", empty)
- Transfer(tgt_fn, "__ZERO", tgt_ranges, src_ranges,
- "zero", self.transfers)
+ AddTransfer(tgt_fn, "__ZERO", tgt_ranges, src_ranges,
+ "zero", self.transfers)
continue
elif tgt_fn == "__COPY":
# "__COPY" domain includes all the blocks not contained in any
# file and that need to be copied unconditionally to the target.
- Transfer(tgt_fn, None, tgt_ranges, empty, "new", self.transfers)
+ AddTransfer(tgt_fn, None, tgt_ranges, empty, "new", self.transfers)
continue
elif tgt_fn in self.src.file_map:
# Look for an exact pathname match in the source.
- Transfer(tgt_fn, tgt_fn, tgt_ranges, self.src.file_map[tgt_fn],
- "diff", self.transfers)
+ AddTransfer(tgt_fn, tgt_fn, tgt_ranges, self.src.file_map[tgt_fn],
+ "diff", self.transfers, self.version >= 3)
continue
b = os.path.basename(tgt_fn)
if b in self.src_basenames:
# Look for an exact basename match in the source.
src_fn = self.src_basenames[b]
- Transfer(tgt_fn, src_fn, tgt_ranges, self.src.file_map[src_fn],
- "diff", self.transfers)
+ AddTransfer(tgt_fn, src_fn, tgt_ranges, self.src.file_map[src_fn],
+ "diff", self.transfers, self.version >= 3)
continue
b = re.sub("[0-9]+", "#", b)
@@ -885,11 +1043,11 @@
# for .so files that contain version numbers in the filename
# that get bumped.)
src_fn = self.src_numpatterns[b]
- Transfer(tgt_fn, src_fn, tgt_ranges, self.src.file_map[src_fn],
- "diff", self.transfers)
+ AddTransfer(tgt_fn, src_fn, tgt_ranges, self.src.file_map[src_fn],
+ "diff", self.transfers, self.version >= 3)
continue
- Transfer(tgt_fn, None, tgt_ranges, empty, "new", self.transfers)
+ AddTransfer(tgt_fn, None, tgt_ranges, empty, "new", self.transfers)
def AbbreviateSourceNames(self):
for k in self.src.file_map.keys():
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 4b43c0c..357a666 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -399,6 +399,7 @@
mount_point: such as "system", "data" etc.
"""
d = {}
+
if "build.prop" in glob_dict:
bp = glob_dict["build.prop"]
if "ro.build.date.utc" in bp:
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 99b319d..2965fa8 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -59,6 +59,8 @@
self.device_specific = None
self.extras = {}
self.info_dict = None
+ self.source_info_dict = None
+ self.target_info_dict = None
self.worker_threads = None
@@ -390,7 +392,9 @@
img_keyblock = tempfile.NamedTemporaryFile()
cmd = [info_dict["vboot_signer_cmd"], info_dict["futility"],
img_unsigned.name, info_dict["vboot_key"] + ".vbpubk",
- info_dict["vboot_key"] + ".vbprivk", img_keyblock.name,
+ info_dict["vboot_key"] + ".vbprivk",
+ info_dict["vboot_subkey"] + ".vbprivk",
+ img_keyblock.name,
img.name]
p = Run(cmd, stdout=subprocess.PIPE)
p.communicate()
@@ -1193,7 +1197,11 @@
self.path = os.path.join(tmpdir, partition)
b.Compute(self.path)
- _, self.device = GetTypeAndDevice("/" + partition, OPTIONS.info_dict)
+ if src is None:
+ _, self.device = GetTypeAndDevice("/" + partition, OPTIONS.info_dict)
+ else:
+ _, self.device = GetTypeAndDevice("/" + partition,
+ OPTIONS.source_info_dict)
def WriteScript(self, script, output_zip, progress=None):
if not self.src:
@@ -1391,6 +1399,8 @@
output_sink("recovery-from-boot.p", patch)
try:
+ # The following GetTypeAndDevice()s need to use the path in the target
+ # info_dict instead of source_info_dict.
boot_type, boot_device = GetTypeAndDevice("/boot", info_dict)
recovery_type, recovery_device = GetTypeAndDevice("/recovery", info_dict)
except KeyError:
@@ -1413,18 +1423,28 @@
'bonus_args': bonus_args}
# The install script location moved from /system/etc to /system/bin
- # in the L release. Parse the init.rc file to find out where the
+ # in the L release. Parse init.*.rc files to find out where the
# target-files expects it to be, and put it there.
sh_location = "etc/install-recovery.sh"
- try:
- with open(os.path.join(input_dir, "BOOT", "RAMDISK", "init.rc")) as f:
+ found = False
+ init_rc_dir = os.path.join(input_dir, "BOOT", "RAMDISK")
+ init_rc_files = os.listdir(init_rc_dir)
+ for init_rc_file in init_rc_files:
+ if (not init_rc_file.startswith('init.') or
+ not init_rc_file.endswith('.rc')):
+ continue
+
+ with open(os.path.join(init_rc_dir, init_rc_file)) as f:
for line in f:
m = re.match(r"^service flash_recovery /system/(\S+)\s*$", line)
if m:
sh_location = m.group(1)
- print "putting script in", sh_location
+ found = True
break
- except (OSError, IOError) as e:
- print "failed to read init.rc: %s" % (e,)
+
+ if found:
+ break
+
+ print "putting script in", sh_location
output_sink(sh_location, sh)
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index 566e687..a52e328 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -243,6 +243,15 @@
cmd = "delete(" + ",\0".join(['"%s"' % (i,) for i in file_list]) + ");"
self.script.append(self.WordWrap(cmd))
+ def DeleteFilesIfNotMatching(self, file_list):
+ """Delete the file in file_list if not matching the checksum."""
+ if not file_list:
+ return
+ for name, sha1 in file_list:
+ cmd = ('sha1_check(read_file("{name}"), "{sha1}") || '
+ 'delete("{name}");'.format(name=name, sha1=sha1))
+ self.script.append(self.WordWrap(cmd))
+
def RenameFile(self, srcfile, tgtfile):
"""Moves a file from one location to another."""
if self.info.get("update_rename_support", False):
@@ -254,7 +263,7 @@
"""Prepend an action with an apply_patch_check in order to
skip the action if the file exists. Used when a patch
is later renamed."""
- cmd = ('sha1_check(read_file("%s"), %s) || ' % (tgtfile, tgtsha1))
+ cmd = ('sha1_check(read_file("%s"), %s) ||' % (tgtfile, tgtsha1))
self.script.append(self.WordWrap(cmd))
def ApplyPatch(self, srcfile, tgtfile, tgtsize, tgtsha1, *patchpairs):
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 531a728..c5c16b4 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -42,6 +42,11 @@
radio image. This option is only meaningful when -i is specified,
because a full radio is always included in a full OTA if applicable.
+ --full_bootloader
+ When generating an incremental OTA, always include a full copy of
+ bootloader image. This option is only meaningful when -i is specified,
+ because a full bootloader is always included in a full OTA if applicable.
+
-v (--verify)
Remount and verify the checksums of the files written to the
system and vendor (if used) partitions. Incremental builds only.
@@ -84,6 +89,9 @@
Specifies the number of worker-threads that will be used when
generating patches for incremental updates (defaults to 3).
+ --stash_threshold <float>
+ Specifies the threshold that will be used to compute the maximum
+ allowed stash size (defaults to 0.8).
"""
import sys
@@ -122,6 +130,10 @@
OPTIONS.oem_source = None
OPTIONS.fallback_to_full = True
OPTIONS.full_radio = False
+OPTIONS.full_bootloader = False
+# Stash size cannot exceed cache_size * threshold.
+OPTIONS.cache_size = None
+OPTIONS.stash_threshold = 0.8
def MostPopularKey(d, default):
"""Given a dict, return the key corresponding to the largest
@@ -747,7 +759,7 @@
output_zip=output_zip,
script=script,
metadata=metadata,
- info_dict=OPTIONS.info_dict)
+ info_dict=OPTIONS.source_info_dict)
# TODO: Currently this works differently from WriteIncrementalOTAPackage().
# This function doesn't consider thumbprints when writing
@@ -1147,7 +1159,7 @@
output_zip=output_zip,
script=script,
metadata=metadata,
- info_dict=OPTIONS.info_dict)
+ info_dict=OPTIONS.source_info_dict)
system_diff = FileDifference("system", source_zip, target_zip, output_zip)
script.Mount("/system", recovery_mount_options)
@@ -1384,11 +1396,36 @@
# Delete all the symlinks in source that aren't in target. This
# needs to happen before verbatim files are unpacked, in case a
# symlink in the source is replaced by a real file in the target.
- to_delete = []
+
+ # If a symlink in the source will be replaced by a regular file, we cannot
+ # delete the symlink/file in case the package gets applied again. For such
+ # a symlink, we prepend a sha1_check() to detect if it has been updated.
+ # (Bug: 23646151)
+ replaced_symlinks = dict()
+ if system_diff:
+ for i in system_diff.verbatim_targets:
+ replaced_symlinks["/%s" % (i[0],)] = i[2]
+ if vendor_diff:
+ for i in vendor_diff.verbatim_targets:
+ replaced_symlinks["/%s" % (i[0],)] = i[2]
+
+ if system_diff:
+ for tf in system_diff.renames.values():
+ replaced_symlinks["/%s" % (tf.name,)] = tf.sha1
+ if vendor_diff:
+ for tf in vendor_diff.renames.values():
+ replaced_symlinks["/%s" % (tf.name,)] = tf.sha1
+
+ always_delete = []
+ may_delete = []
for dest, link in source_symlinks:
if link not in target_symlinks_d:
- to_delete.append(link)
- script.DeleteFiles(to_delete)
+ if link in replaced_symlinks:
+ may_delete.append((link, replaced_symlinks[link]))
+ else:
+ always_delete.append(link)
+ script.DeleteFiles(always_delete)
+ script.DeleteFilesIfNotMatching(may_delete)
if system_diff.verbatim_targets:
script.Print("Unpacking new system files...")
@@ -1474,6 +1511,8 @@
OPTIONS.incremental_source = a
elif o == "--full_radio":
OPTIONS.full_radio = True
+ elif o == "--full_bootloader":
+ OPTIONS.full_bootloader = True
elif o in ("-w", "--wipe_user_data"):
OPTIONS.wipe_user_data = True
elif o in ("-n", "--no_prereq"):
@@ -1505,6 +1544,12 @@
OPTIONS.updater_binary = a
elif o in ("--no_fallback_to_full",):
OPTIONS.fallback_to_full = False
+ elif o == "--stash_threshold":
+ try:
+ OPTIONS.stash_threshold = float(a)
+ except ValueError:
+ raise ValueError("Cannot parse value %r for option %r - expecting "
+ "a float" % (a, o))
else:
return False
return True
@@ -1516,6 +1561,7 @@
"package_key=",
"incremental_from=",
"full_radio",
+ "full_bootloader",
"wipe_user_data",
"no_prereq",
"extra_script=",
@@ -1528,6 +1574,7 @@
"oem_settings=",
"verify",
"no_fallback_to_full",
+ "stash_threshold=",
], extra_option_handler=option_handler)
if len(args) != 2:
@@ -1585,6 +1632,11 @@
output_zip = zipfile.ZipFile(temp_zip_file, "w",
compression=zipfile.ZIP_DEFLATED)
+ cache_size = OPTIONS.info_dict.get("cache_size", None)
+ if cache_size is None:
+ raise RuntimeError("can't determine the cache partition size")
+ OPTIONS.cache_size = cache_size
+
if OPTIONS.incremental_source is None:
WriteFullOTAPackage(input_zip, output_zip)
if OPTIONS.package_key is None:
diff --git a/tools/releasetools/rangelib.py b/tools/releasetools/rangelib.py
index 1506658..373bbed 100644
--- a/tools/releasetools/rangelib.py
+++ b/tools/releasetools/rangelib.py
@@ -24,6 +24,7 @@
lots of runs."""
def __init__(self, data=None):
+ # TODO(tbao): monotonic is broken when passing in a tuple.
self.monotonic = False
if isinstance(data, str):
self._parse_internal(data)
@@ -260,6 +261,38 @@
out = out.union(RangeSet(str(s1) + "-" + str(e1-1)))
return out
+ def first(self, n):
+ """Return the RangeSet that contains at most the first 'n' integers.
+
+ >>> RangeSet("0-9").first(1)
+ <RangeSet("0")>
+ >>> RangeSet("10-19").first(5)
+ <RangeSet("10-14")>
+ >>> RangeSet("10-19").first(15)
+ <RangeSet("10-19")>
+ >>> RangeSet("10-19 30-39").first(3)
+ <RangeSet("10-12")>
+ >>> RangeSet("10-19 30-39").first(15)
+ <RangeSet("10-19 30-34")>
+ >>> RangeSet("10-19 30-39").first(30)
+ <RangeSet("10-19 30-39")>
+ >>> RangeSet("0-9").first(0)
+ <RangeSet("")>
+ """
+
+ if self.size() <= n:
+ return self
+
+ out = []
+ for s, e in self:
+ if e - s >= n:
+ out += (s, s+n)
+ break
+ else:
+ out += (s, e)
+ n -= e - s
+ return RangeSet(data=out)
+
if __name__ == "__main__":
import doctest
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index ec49112..60d62c2 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -203,11 +203,13 @@
common.ZipWriteStr(output_tf_zip, out_info, data)
elif info.filename in ("SYSTEM/build.prop",
"VENDOR/build.prop",
+ "BOOT/RAMDISK/default.prop",
"RECOVERY/RAMDISK/default.prop"):
print "rewriting %s:" % (info.filename,)
new_data = RewriteProps(data, misc_info)
common.ZipWriteStr(output_tf_zip, out_info, new_data)
- if info.filename == "RECOVERY/RAMDISK/default.prop":
+ if info.filename in ("BOOT/RAMDISK/default.prop",
+ "RECOVERY/RAMDISK/default.prop"):
write_to_temp(info.filename, info.external_attr, new_data)
elif info.filename.endswith("mac_permissions.xml"):
print "rewriting %s with new keys." % (info.filename,)
@@ -310,6 +312,10 @@
pieces = value.split("/")
pieces[-1] = EditTags(pieces[-1])
value = "/".join(pieces)
+ elif key == "ro.bootimage.build.fingerprint":
+ pieces = value.split("/")
+ pieces[-1] = EditTags(pieces[-1])
+ value = "/".join(pieces)
elif key == "ro.build.description":
pieces = value.split(" ")
assert len(pieces) == 5
diff --git a/tools/releasetools/sparse_img.py b/tools/releasetools/sparse_img.py
index 07f3c1c..013044f 100644
--- a/tools/releasetools/sparse_img.py
+++ b/tools/releasetools/sparse_img.py
@@ -210,6 +210,16 @@
nonzero_blocks = []
reference = '\0' * self.blocksize
+ # Workaround for bug 23227672. For squashfs, we don't have a system.map. So
+ # the whole system image will be treated as a single file. But for some
+ # unknown bug, the updater will be killed due to OOM when writing back the
+ # patched image to flash (observed on lenok-userdebug MEA49). Prior to
+ # getting a real fix, we evenly divide the non-zero blocks into smaller
+ # groups (currently 1024 blocks or 4MB per group).
+ # Bug: 23227672
+ MAX_BLOCKS_PER_GROUP = 1024
+ nonzero_groups = []
+
f = self.simg_f
for s, e in remaining:
for b in range(s, e):
@@ -232,12 +242,22 @@
nonzero_blocks.append(b)
nonzero_blocks.append(b+1)
- assert zero_blocks or nonzero_blocks or clobbered_blocks
+ if len(nonzero_blocks) >= MAX_BLOCKS_PER_GROUP:
+ nonzero_groups.append(nonzero_blocks)
+ # Clear the list.
+ nonzero_blocks = []
+
+ if nonzero_blocks:
+ nonzero_groups.append(nonzero_blocks)
+ nonzero_blocks = []
+
+ assert zero_blocks or nonzero_groups or clobbered_blocks
if zero_blocks:
out["__ZERO"] = rangelib.RangeSet(data=zero_blocks)
- if nonzero_blocks:
- out["__NONZERO"] = rangelib.RangeSet(data=nonzero_blocks)
+ if nonzero_groups:
+ for i, blocks in enumerate(nonzero_groups):
+ out["__NONZERO-%d" % i] = rangelib.RangeSet(data=blocks)
if clobbered_blocks:
out["__COPY"] = clobbered_blocks