Merge commit 'b89ec38113a22d09b0832ed2d3cb8fc413a14a75' into HEAD

This commit is contained in:
Bill Yi
2015-02-19 14:30:26 -08:00
59 changed files with 1317 additions and 408 deletions

View File

@@ -302,6 +302,11 @@ $(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)/system/app/*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
# API 22!
$(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/*)
# Move to libc++ as the default STL. # Move to libc++ as the default STL.
$(call add-clean-step, rm -rf $(OUT_DIR)) $(call add-clean-step, rm -rf $(OUT_DIR))
@@ -315,6 +320,11 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/default.prop)
# an ABI change since the names will mangle differently. # an ABI change since the names will mangle differently.
$(call add-clean-step, rm -rf $(OUT_DIR)) $(call add-clean-step, rm -rf $(OUT_DIR))
# 5.1!
$(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/*)
# Remove ro.product.locale.language/country and add ro.product.locale # Remove ro.product.locale.language/country and add ro.product.locale
# instead. # instead.
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)

View File

@@ -183,6 +183,7 @@ ifneq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_OEM_PROPERTIES),)
echo "import /oem/oem.prop $(prop)" >> $@;) echo "import /oem/oem.prop $(prop)" >> $@;)
endif endif
$(hide) TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \ $(hide) TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
TARGET_BUILD_FLAVOR="$(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)" \
TARGET_DEVICE="$(TARGET_DEVICE)" \ TARGET_DEVICE="$(TARGET_DEVICE)" \
PRODUCT_NAME="$(TARGET_PRODUCT)" \ PRODUCT_NAME="$(TARGET_PRODUCT)" \
PRODUCT_BRAND="$(PRODUCT_BRAND)" \ PRODUCT_BRAND="$(PRODUCT_BRAND)" \
@@ -492,14 +493,14 @@ else ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)) # TARGE
$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(BOOT_SIGNER) $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(BOOT_SIGNER)
$(call pretty,"Target boot image: $@") $(call pretty,"Target boot image: $@")
$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@ $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
$(BOOT_SIGNER) /boot $@ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY) $@ $(BOOT_SIGNER) /boot $@ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $@
$(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE)) $(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE))
.PHONY: bootimage-nodeps .PHONY: bootimage-nodeps
bootimage-nodeps: $(MKBOOTIMG) $(BOOT_SIGNER) bootimage-nodeps: $(MKBOOTIMG) $(BOOT_SIGNER)
@echo "make $@: ignoring dependencies" @echo "make $@: ignoring dependencies"
$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET) $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET)
$(BOOT_SIGNER) /boot $(INSTALLED_BOOTIMAGE_TARGET) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY) $(INSTALLED_BOOTIMAGE_TARGET) $(BOOT_SIGNER) /boot $(INSTALLED_BOOTIMAGE_TARGET) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $(INSTALLED_BOOTIMAGE_TARGET)
$(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE)) $(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE))
else # PRODUCT_SUPPORTS_VERITY != true else # PRODUCT_SUPPORTS_VERITY != true
@@ -661,6 +662,13 @@ endif
endif endif
endif endif
# These options tell the recovery updater/installer how to mount the partitions writebale.
# <fstype>=<fstype_opts>[|<fstype_opts>]...
# fstype_opts := <opt>[,<opt>]...
# opt := <name>[=<value>]
# The following worked on Nexus devices with Kernel 3.1, 3.4, 3.10
DEFAULT_TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS := ext4=max_batch_time=0,commit=1,data=ordered,barrier=1,errors=panic,nodelalloc
ifneq (true,$(TARGET_USERIMAGES_SPARSE_EXT_DISABLED)) ifneq (true,$(TARGET_USERIMAGES_SPARSE_EXT_DISABLED))
INTERNAL_USERIMAGES_SPARSE_EXT_FLAG := -s INTERNAL_USERIMAGES_SPARSE_EXT_FLAG := -s
endif endif
@@ -687,13 +695,16 @@ INTERNAL_USERIMAGES_DEPS += $(SELINUX_FC)
define generate-userimage-prop-dictionary define generate-userimage-prop-dictionary
$(if $(INTERNAL_USERIMAGES_EXT_VARIANT),$(hide) echo "fs_type=$(INTERNAL_USERIMAGES_EXT_VARIANT)" >> $(1)) $(if $(INTERNAL_USERIMAGES_EXT_VARIANT),$(hide) echo "fs_type=$(INTERNAL_USERIMAGES_EXT_VARIANT)" >> $(1))
$(if $(BOARD_SYSTEMIMAGE_PARTITION_SIZE),$(hide) echo "system_size=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)" >> $(1)) $(if $(BOARD_SYSTEMIMAGE_PARTITION_SIZE),$(hide) echo "system_size=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)" >> $(1))
$(if $(BOARD_SYSTEMIMAGE_JOURNAL_SIZE),$(hide) echo "system_journal_size=$(BOARD_SYSTEMIMAGE_JOURNAL_SIZE)" >> $(1))
$(if $(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "userdata_fs_type=$(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE)" >> $(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_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)) $(if $(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "cache_fs_type=$(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
$(if $(BOARD_CACHEIMAGE_PARTITION_SIZE),$(hide) echo "cache_size=$(BOARD_CACHEIMAGE_PARTITION_SIZE)" >> $(1)) $(if $(BOARD_CACHEIMAGE_PARTITION_SIZE),$(hide) echo "cache_size=$(BOARD_CACHEIMAGE_PARTITION_SIZE)" >> $(1))
$(if $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "vendor_fs_type=$(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE)" >> $(1)) $(if $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "vendor_fs_type=$(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
$(if $(BOARD_VENDORIMAGE_PARTITION_SIZE),$(hide) echo "vendor_size=$(BOARD_VENDORIMAGE_PARTITION_SIZE)" >> $(1)) $(if $(BOARD_VENDORIMAGE_PARTITION_SIZE),$(hide) echo "vendor_size=$(BOARD_VENDORIMAGE_PARTITION_SIZE)" >> $(1))
$(if $(BOARD_VENDORIMAGE_JOURNAL_SIZE),$(hide) echo "vendor_journal_size=$(BOARD_VENDORIMAGE_JOURNAL_SIZE)" >> $(1))
$(if $(BOARD_OEMIMAGE_PARTITION_SIZE),$(hide) echo "oem_size=$(BOARD_OEMIMAGE_PARTITION_SIZE)" >> $(1)) $(if $(BOARD_OEMIMAGE_PARTITION_SIZE),$(hide) echo "oem_size=$(BOARD_OEMIMAGE_PARTITION_SIZE)" >> $(1))
$(if $(BOARD_OEMIMAGE_JOURNAL_SIZE),$(hide) echo "oem_journal_size=$(BOARD_OEMIMAGE_JOURNAL_SIZE)" >> $(1))
$(if $(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG),$(hide) echo "extfs_sparse_flag=$(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG)" >> $(1)) $(if $(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG),$(hide) echo "extfs_sparse_flag=$(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG)" >> $(1))
$(hide) echo "selinux_fc=$(SELINUX_FC)" >> $(1) $(hide) echo "selinux_fc=$(SELINUX_FC)" >> $(1)
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)" >> $(1)) $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)" >> $(1))
@@ -726,12 +737,8 @@ ifneq (,$(PRODUCT_AAPT_PREF_CONFIG))
# If PRODUCT_AAPT_PREF_CONFIG includes a dpi bucket, then use that value. # If PRODUCT_AAPT_PREF_CONFIG includes a dpi bucket, then use that value.
recovery_density := $(filter %dpi,$(PRODUCT_AAPT_PREF_CONFIG)) recovery_density := $(filter %dpi,$(PRODUCT_AAPT_PREF_CONFIG))
else else
# Otherwise, use the highest density that appears in PRODUCT_AAPT_CONFIG. # Otherwise, use the default medium density.
# Order is important here; we'll take the first one that's found. recovery_densities := mdpi
recovery_densities := $(filter $(PRODUCT_AAPT_CONFIG_SP),xxxhdpi xxhdpi xhdpi hdpi tvdpi mdpi ldpi)
ifneq (,$(recovery_densities))
recovery_density := $(word 1,$(recovery_densities))
endif
endif endif
ifneq (,$(wildcard $(recovery_resources_common)-$(recovery_density))) ifneq (,$(wildcard $(recovery_resources_common)-$(recovery_density)))
@@ -834,7 +841,7 @@ define build-recoveryimage-target
$(hide) $(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk) $(hide) $(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)
$(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1) $(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1)
$(if $(filter true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)),\ $(if $(filter true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)),\
$(BOOT_SIGNER) /recovery $(1) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY) $(1)) $(BOOT_SIGNER) /recovery $(1) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $(1))
$(hide) $(call assert-max-image-size,$(1),$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)) $(hide) $(call assert-max-image-size,$(1),$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))
@echo ----- Made recovery image: $(1) -------- @echo ----- Made recovery image: $(1) --------
endef endef
@@ -1217,6 +1224,12 @@ vendorimage-nodeps: | $(INTERNAL_USERIMAGES_DEPS)
endif # BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE endif # BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
# -----------------------------------------------------------------
# bring in the installer image generation defines if necessary
ifeq ($(TARGET_USE_DISKINSTALLER),true)
include bootable/diskinstaller/config.mk
endif
# ----------------------------------------------------------------- # -----------------------------------------------------------------
# host tools needed to build dist and OTA packages # host tools needed to build dist and OTA packages
@@ -1382,6 +1395,12 @@ ifdef BOARD_BOOTIMAGE_PARTITION_SIZE
endif endif
ifdef BOARD_RECOVERYIMAGE_PARTITION_SIZE ifdef BOARD_RECOVERYIMAGE_PARTITION_SIZE
$(hide) echo "recovery_size=$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt $(hide) echo "recovery_size=$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)" >> $(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
else
$(hide) echo "recovery_mount_options=$(DEFAULT_TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS)" >> $(zip_root)/META/misc_info.txt
endif endif
$(hide) echo "tool_extensions=$(tool_extensions)" >> $(zip_root)/META/misc_info.txt $(hide) echo "tool_extensions=$(tool_extensions)" >> $(zip_root)/META/misc_info.txt
$(hide) echo "default_system_dev_certificate=$(DEFAULT_SYSTEM_DEV_CERTIFICATE)" >> $(zip_root)/META/misc_info.txt $(hide) echo "default_system_dev_certificate=$(DEFAULT_SYSTEM_DEV_CERTIFICATE)" >> $(zip_root)/META/misc_info.txt
@@ -1392,6 +1411,7 @@ endif
$(hide) echo "use_set_metadata=1" >> $(zip_root)/META/misc_info.txt $(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 "multistage_support=1" >> $(zip_root)/META/misc_info.txt
$(hide) echo "update_rename_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" >> $(zip_root)/META/misc_info.txt
ifneq ($(OEM_THUMBPRINT_PROPERTIES),) ifneq ($(OEM_THUMBPRINT_PROPERTIES),)
# OTA scripts are only interested in fingerprint related properties # OTA scripts are only interested in fingerprint related properties
$(hide) echo "oem_fingerprint_properties=$(OEM_THUMBPRINT_PROPERTIES)" >> $(zip_root)/META/misc_info.txt $(hide) echo "oem_fingerprint_properties=$(OEM_THUMBPRINT_PROPERTIES)" >> $(zip_root)/META/misc_info.txt
@@ -1484,10 +1504,14 @@ endif
name := $(name)-symbols-$(FILE_NAME_TAG) name := $(name)-symbols-$(FILE_NAME_TAG)
SYMBOLS_ZIP := $(PRODUCT_OUT)/$(name).zip SYMBOLS_ZIP := $(PRODUCT_OUT)/$(name).zip
# For apps_only build we'll establish the dependency later in build/core/main.mk.
ifndef TARGET_BUILD_APPS
$(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE) $(INSTALLED_BOOTIMAGE_TARGET) $(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE) $(INSTALLED_BOOTIMAGE_TARGET)
endif
$(SYMBOLS_ZIP):
@echo "Package symbols: $@" @echo "Package symbols: $@"
$(hide) rm -rf $@ $(hide) rm -rf $@
$(hide) mkdir -p $(dir $@) $(hide) mkdir -p $(dir $@) $(TARGET_OUT_UNSTRIPPED)
$(hide) zip -qr $@ $(TARGET_OUT_UNSTRIPPED) $(hide) zip -qr $@ $(TARGET_OUT_UNSTRIPPED)
# ----------------------------------------------------------------- # -----------------------------------------------------------------

View File

@@ -11,13 +11,27 @@ else
full_android_manifest := $(LOCAL_PATH)/$(LOCAL_MANIFEST_FILE) full_android_manifest := $(LOCAL_PATH)/$(LOCAL_MANIFEST_FILE)
endif endif
my_full_libs_manifest_files := $(LOCAL_FULL_LIBS_MANIFEST_FILES)
my_full_libs_manifest_deps := $(LOCAL_FULL_LIBS_MANIFEST_FILES)
# Set up dependency on aar libraries
ifdef LOCAL_STATIC_JAVA_AAR_LIBRARIES
my_full_libs_manifest_deps += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/classes.jar)
my_full_libs_manifest_files += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/AndroidManifest.xml)
LOCAL_RESOURCE_DIR += $(foreach lib, $(LOCAL_STATIC_JAVA_AAR_LIBRARIES),\
$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/aar/res)
endif
# Set up rules to merge library manifest files # Set up rules to merge library manifest files
ifdef LOCAL_FULL_LIBS_MANIFEST_FILES ifdef my_full_libs_manifest_files
main_android_manifest := $(full_android_manifest) main_android_manifest := $(full_android_manifest)
full_android_manifest := $(intermediates.COMMON)/AndroidManifest.xml full_android_manifest := $(intermediates.COMMON)/AndroidManifest.xml
$(full_android_manifest): PRIVATE_LIBS_MANIFESTS := $(LOCAL_FULL_LIBS_MANIFEST_FILES) $(full_android_manifest): PRIVATE_LIBS_MANIFESTS := $(my_full_libs_manifest_files)
$(full_android_manifest) : $(main_android_manifest) $(LOCAL_FULL_LIBS_MANIFEST_FILES) $(full_android_manifest) : $(main_android_manifest) $(my_full_libs_manifest_deps)
@echo "Merge android manifest files: $@ <-- $^" @echo "Merge android manifest files: $@ <-- $< $(PRIVATE_LIBS_MANIFESTS)"
@mkdir -p $(dir $@) @mkdir -p $(dir $@)
$(hide) $(ANDROID_MANIFEST_MERGER) --main $< --libs $(PRIVATE_LIBS_MANIFESTS) \ $(hide) $(ANDROID_MANIFEST_MERGER) --main $< --libs $(PRIVATE_LIBS_MANIFESTS) \
--out $@ --out $@

View File

@@ -7,7 +7,7 @@ To make these errors go away, you have two choices:
errors above. errors above.
2) You can update current.txt by executing the following command: 2) You can update current.txt by executing the following command:
make %UPDATE_API% make update-api
To submit the revised current.txt to the main Android repository, To submit the revised current.txt to the main Android repository,
you will need approval. you will need approval.

View File

@@ -210,7 +210,9 @@ endif
#################################################### ####################################################
## Add FDO flags if FDO is turned on and supported ## Add FDO flags if FDO is turned on and supported
#################################################### ## Please note that we will do option filtering during FDO build.
## i.e. Os->O2, remove -fno-early-inline and -finline-limit.
##################################################################
ifeq ($(strip $(LOCAL_FDO_SUPPORT)), true) ifeq ($(strip $(LOCAL_FDO_SUPPORT)), true)
ifeq ($(strip $(LOCAL_IS_HOST_MODULE)),) ifeq ($(strip $(LOCAL_IS_HOST_MODULE)),)
my_cflags += $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_FDO_CFLAGS) my_cflags += $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_FDO_CFLAGS)
@@ -992,6 +994,21 @@ my_asflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flag
my_ldflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(my_ldflags)) my_ldflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(my_ldflags))
endif endif
ifeq ($(LOCAL_FDO_SUPPORT), true)
build_with_fdo := false
ifeq ($(BUILD_FDO_INSTRUMENT), true)
build_with_fdo := true
endif
ifeq ($(BUILD_FDO_OPTIMIZE), true)
build_with_fdo := true
endif
ifeq ($(build_with_fdo), true)
my_cflags := $(patsubst -Os,-O2,$(my_cflags))
fdo_incompatible_flags=-fno-early-inlining -finline-limit=%
my_cflags := $(filter-out $(fdo_incompatible_flags),$(my_cflags))
endif
endif
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_YACCFLAGS := $(LOCAL_YACCFLAGS) $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_YACCFLAGS := $(LOCAL_YACCFLAGS)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASFLAGS := $(my_asflags) $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASFLAGS := $(my_asflags)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CONLYFLAGS := $(my_conlyflags) $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CONLYFLAGS := $(my_conlyflags)

View File

@@ -132,23 +132,11 @@ endif # if not ONE_SHOT_MAKEFILE dont_bother
previous_build_config_file := $(PRODUCT_OUT)/previous_build_config.mk previous_build_config_file := $(PRODUCT_OUT)/previous_build_config.mk
# TODO: this special case for the sdk is only necessary while "sdk"
# is a valid make target. Eventually, it will just be a product, at
# which point TARGET_PRODUCT will handle it and we can avoid this check
# of MAKECMDGOALS. The "addprefix" is just to keep things pretty.
ifneq ($(TARGET_PRODUCT),sdk)
building_sdk := $(addprefix -,$(filter sdk,$(MAKECMDGOALS)))
else
# Don't bother with this extra part when explicitly building the sdk product.
building_sdk :=
endif
# A change in the list of aapt configs warrants an installclean, too. # A change in the list of aapt configs warrants an installclean, too.
aapt_config_list := $(strip $(PRODUCT_AAPT_CONFIG) $(PRODUCT_AAPT_PREF_CONFIG)) aapt_config_list := $(strip $(PRODUCT_AAPT_CONFIG) $(PRODUCT_AAPT_PREF_CONFIG))
current_build_config := \ current_build_config := \
$(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)$(building_sdk)-{$(aapt_config_list)} $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)-{$(aapt_config_list)}
building_sdk :=
aapt_config_list := aapt_config_list :=
force_installclean := false force_installclean := false
@@ -220,6 +208,7 @@ installclean_files := \
$(PRODUCT_OUT)/obj/JAVA_LIBRARIES \ $(PRODUCT_OUT)/obj/JAVA_LIBRARIES \
$(PRODUCT_OUT)/obj/FAKE \ $(PRODUCT_OUT)/obj/FAKE \
$(PRODUCT_OUT)/obj/EXECUTABLES/adbd_intermediates \ $(PRODUCT_OUT)/obj/EXECUTABLES/adbd_intermediates \
$(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libfs_mgr_intermediates \
$(PRODUCT_OUT)/obj/EXECUTABLES/init_intermediates \ $(PRODUCT_OUT)/obj/EXECUTABLES/init_intermediates \
$(PRODUCT_OUT)/obj/ETC/mac_permissions.xml_intermediates \ $(PRODUCT_OUT)/obj/ETC/mac_permissions.xml_intermediates \
$(PRODUCT_OUT)/obj/ETC/sepolicy_intermediates \ $(PRODUCT_OUT)/obj/ETC/sepolicy_intermediates \

View File

@@ -30,6 +30,7 @@ LOCAL_MODULE_TAGS:=
LOCAL_SRC_FILES:= LOCAL_SRC_FILES:=
LOCAL_PREBUILT_OBJ_FILES:= LOCAL_PREBUILT_OBJ_FILES:=
LOCAL_STATIC_JAVA_LIBRARIES:= LOCAL_STATIC_JAVA_LIBRARIES:=
LOCAL_STATIC_JAVA_AAR_LIBRARIES:=
LOCAL_STATIC_LIBRARIES:= LOCAL_STATIC_LIBRARIES:=
# Group static libraries with "-Wl,--start-group" and "-Wl,--end-group" when linking. # Group static libraries with "-Wl,--start-group" and "-Wl,--end-group" when linking.
LOCAL_GROUP_STATIC_LIBRARIES:= LOCAL_GROUP_STATIC_LIBRARIES:=
@@ -168,6 +169,8 @@ LOCAL_MODULE_HOST_ARCH:=
LOCAL_NO_FPIE := LOCAL_NO_FPIE :=
LOCAL_CXX_STL := default LOCAL_CXX_STL := default
LOCAL_NATIVE_COVERAGE := LOCAL_NATIVE_COVERAGE :=
LOCAL_DPI_VARIANTS:=
LOCAL_DPI_FILE_STEM:=
# arch specific variables # arch specific variables
LOCAL_SRC_FILES_$(TARGET_ARCH):= LOCAL_SRC_FILES_$(TARGET_ARCH):=

View File

@@ -27,7 +27,7 @@ ifneq ($(findstring Linux,$(UNAME)),)
ifdef USE_MINGW ifdef USE_MINGW
HOST_ACP_UNAVAILABLE := true HOST_ACP_UNAVAILABLE := true
TOOLS_EXE_SUFFIX := TOOLS_EXE_SUFFIX :=
$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -DUSE_MINGW $(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -DUSE_MINGW -DWIN32_LEAN_AND_MEAN
$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -Wno-unused-parameter $(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -Wno-unused-parameter
$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += --sysroot=prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32 $(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += --sysroot=prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32
$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -m32 $(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -m32

70
core/dpi_specific_apk.mk Normal file
View File

@@ -0,0 +1,70 @@
# Set up rules to build dpi-specific apk, with whatever else from the base apk.
# Input variable: my_dpi, and all other variables set up in package_internal.mk.
#
dpi_apk_name := $(LOCAL_MODULE)_$(my_dpi)
dpi_intermediate := $(call intermediates-dir-for,APPS,$(dpi_apk_name))
built_dpi_apk := $(dpi_intermediate)/package.apk
# Set up all the target-specific variables.
$(built_dpi_apk): PRIVATE_MODULE := $(dpi_apk_name)
$(built_dpi_apk): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) $(PRODUCT_AAPT_FLAGS) $($(LOCAL_PACKAGE_NAME)_aapt_flags_$(my_dpi))
# Clear PRIVATE_PRODUCT_AAPT_CONFIG to include everything by default.
$(built_dpi_apk): PRIVATE_PRODUCT_AAPT_CONFIG :=
$(built_dpi_apk): PRIVATE_PRODUCT_AAPT_PREF_CONFIG := $(my_dpi)
$(built_dpi_apk): PRIVATE_ANDROID_MANIFEST := $(full_android_manifest)
$(built_dpi_apk): PRIVATE_RESOURCE_DIR := $(LOCAL_RESOURCE_DIR)
$(built_dpi_apk): PRIVATE_ASSET_DIR := $(LOCAL_ASSET_DIR)
$(built_dpi_apk): PRIVATE_AAPT_INCLUDES := $(all_library_res_package_exports)
ifneq (,$(filter-out current system_current, $(LOCAL_SDK_VERSION)))
$(built_dpi_apk): PRIVATE_DEFAULT_APP_TARGET_SDK := $(LOCAL_SDK_VERSION)
else
$(built_dpi_apk): PRIVATE_DEFAULT_APP_TARGET_SDK := $(DEFAULT_APP_TARGET_SDK)
endif
$(built_dpi_apk): PRIVATE_MANIFEST_PACKAGE_NAME := $(LOCAL_MANIFEST_PACKAGE_NAME)
$(built_dpi_apk): PRIVATE_MANIFEST_INSTRUMENTATION_FOR := $(LOCAL_INSTRUMENTATION_FOR)
$(built_dpi_apk): PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries_with_abis)
$(built_dpi_apk): PRIVATE_JNI_SHARED_LIBRARIES_ABI := $(jni_shared_libraries_abis)
$(built_dpi_apk): PRIVATE_DEX_FILE := $(built_dex)
# Note that PRIVATE_CLASS_INTERMEDIATES_DIR points to the base apk's intermediate dir.
$(built_dpi_apk): PRIVATE_CLASS_INTERMEDIATES_DIR := $(intermediates)/classes
$(built_dpi_apk): PRIVATE_EXTRA_JAR_ARGS := $(extra_jar_args)
$(built_dpi_apk): PRIVATE_PRIVATE_KEY := $(private_key)
$(built_dpi_apk): PRIVATE_CERTIFICATE := $(certificate)
$(built_dpi_apk): PRIVATE_ADDITIONAL_CERTIFICATES := $(foreach c,\
$(LOCAL_ADDITIONAL_CERTIFICATES), $(c).x509.pem $(c).pk8)
# Set up dependenncies and the build recipe.
$(built_dpi_apk) : $(R_file_stamp)
$(built_dpi_apk) : $(all_library_res_package_export_deps)
$(built_dpi_apk) : $(built_dex)
$(built_dpi_apk) : $(private_key) $(certificate) $(SIGNAPK_JAR)
$(built_dpi_apk) : $(AAPT) | $(ZIPALIGN)
$(built_dpi_apk) : $(all_res_assets) $(jni_shared_libraries) $(full_android_manifest)
@echo "target Package: $(PRIVATE_MODULE) ($@)"
$(create-empty-package)
$(add-assets-to-package)
ifneq ($(jni_shared_libraries),)
$(add-jni-shared-libs-to-package)
endif
ifneq ($(full_classes_jar),)
$(add-dex-to-package)
endif
$(add-carried-java-resources)
ifneq ($(extra_jar_args),)
$(add-java-resources-to-package)
endif
$(sign-package)
$(align-package)
# Set up global variables to register this apk to the higher-level dependency graph.
ALL_MODULES += $(dpi_apk_name)
ALL_MODULES.$(dpi_apk_name).CLASS := APPS
ALL_MODULES.$(dpi_apk_name).BUILT := $(built_dpi_apk)
PACKAGES := $(PACKAGES) $(dpi_apk_name)
PACKAGES.$(dpi_apk_name).PRIVATE_KEY := $(private_key)
PACKAGES.$(dpi_apk_name).CERTIFICATE := $(certificate)
# Phony targets used by "apps_only".
.PHONY: $(dpi_apk_name)
$(dpi_apk_name) : $(built_dpi_apk)

View File

@@ -17,16 +17,13 @@ endif
# know its results before base_rules.mk is included. # know its results before base_rules.mk is included.
include $(BUILD_SYSTEM)/configure_module_stem.mk include $(BUILD_SYSTEM)/configure_module_stem.mk
# base_rules.make defines $(intermediates), but we need its value intermediates := $(call local-intermediates-dir,,$(LOCAL_2ND_ARCH_VAR_PREFIX))
# before we include base_rules. Make a guess, and verify that
# it's correct once the real value is defined.
guessed_intermediates := $(call local-intermediates-dir,,$(LOCAL_2ND_ARCH_VAR_PREFIX))
# Define the target that is the unmodified output of the linker. # Define the target that is the unmodified output of the linker.
# The basename of this target must be the same as the final output # The basename of this target must be the same as the final output
# binary name, because it's used to set the "soname" in the binary. # binary name, because it's used to set the "soname" in the binary.
# The includer of this file will define a rule to build this target. # The includer of this file will define a rule to build this target.
linked_module := $(guessed_intermediates)/LINKED/$(my_built_module_stem) linked_module := $(intermediates)/LINKED/$(my_built_module_stem)
ALL_ORIGINAL_DYNAMIC_BINARIES += $(linked_module) ALL_ORIGINAL_DYNAMIC_BINARIES += $(linked_module)
@@ -41,11 +38,6 @@ LOCAL_INTERMEDIATE_TARGETS := $(linked_module)
include $(BUILD_SYSTEM)/binary.mk include $(BUILD_SYSTEM)/binary.mk
################################### ###################################
# Make sure that our guess at the value of intermediates was correct.
ifneq ($(intermediates),$(guessed_intermediates))
$(error Internal error: guessed path '$(guessed_intermediates)' doesn't match '$(intermediates))
endif
########################################################### ###########################################################
## Compress ## Compress
########################################################### ###########################################################

View File

@@ -100,9 +100,15 @@ endif
my_prebuilt_jni_libs := $(addprefix $(LOCAL_PATH)/, \ my_prebuilt_jni_libs := $(addprefix $(LOCAL_PATH)/, \
$(filter-out @%, $(my_prebuilt_jni_libs))) $(filter-out @%, $(my_prebuilt_jni_libs)))
ifdef my_prebuilt_jni_libs ifdef my_prebuilt_jni_libs
ifdef my_embed_jni
# Embed my_prebuilt_jni_libs to the apk
my_jni_shared_libraries += $(my_prebuilt_jni_libs)
else # not my_embed_jni
# Install my_prebuilt_jni_libs as separate files.
$(foreach lib, $(my_prebuilt_jni_libs), \ $(foreach lib, $(my_prebuilt_jni_libs), \
$(eval $(call copy-one-file, $(lib), $(my_app_lib_path)/$(notdir $(lib))))) $(eval $(call copy-one-file, $(lib), $(my_app_lib_path)/$(notdir $(lib)))))
$(LOCAL_INSTALLED_MODULE) : | $(addprefix $(my_app_lib_path)/, $(notdir $(my_prebuilt_jni_libs))) $(LOCAL_INSTALLED_MODULE) : | $(addprefix $(my_app_lib_path)/, $(notdir $(my_prebuilt_jni_libs)))
endif # my_embed_jni
endif # inner my_prebuilt_jni_libs endif # inner my_prebuilt_jni_libs
endif # outer my_prebuilt_jni_libs endif # outer my_prebuilt_jni_libs

View File

@@ -52,6 +52,9 @@ else
endif endif
endif endif
# LOCAL_STATIC_JAVA_AAR_LIBRARIES are special LOCAL_STATIC_JAVA_LIBRARIES
LOCAL_STATIC_JAVA_LIBRARIES := $(strip $(LOCAL_STATIC_JAVA_LIBRARIES) $(LOCAL_STATIC_JAVA_AAR_LIBRARIES))
LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES)) LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES))
LOCAL_BUILT_MODULE_STEM := $(strip $(LOCAL_BUILT_MODULE_STEM)) LOCAL_BUILT_MODULE_STEM := $(strip $(LOCAL_BUILT_MODULE_STEM))

View File

@@ -922,6 +922,9 @@ ifneq ($(TARGET_BUILD_APPS),)
$(PROGUARD_DICT_ZIP) : $(apps_only_installed_files) $(PROGUARD_DICT_ZIP) : $(apps_only_installed_files)
$(call dist-for-goals,apps_only, $(PROGUARD_DICT_ZIP)) $(call dist-for-goals,apps_only, $(PROGUARD_DICT_ZIP))
$(SYMBOLS_ZIP) : $(apps_only_installed_files)
$(call dist-for-goals,apps_only, $(SYMBOLS_ZIP))
.PHONY: apps_only .PHONY: apps_only
apps_only: $(unbundled_build_modules) apps_only: $(unbundled_build_modules)

View File

@@ -123,7 +123,8 @@ endif
all_res_assets := $(strip $(all_assets) $(all_resources)) all_res_assets := $(strip $(all_assets) $(all_resources))
package_expected_intermediates_COMMON := $(call local-intermediates-dir,COMMON) intermediates.COMMON := $(call local-intermediates-dir,COMMON)
# If no assets or resources were found, clear the directory variables so # If no assets or resources were found, clear the directory variables so
# we don't try to build them. # we don't try to build them.
ifneq (true,$(need_compile_asset)) ifneq (true,$(need_compile_asset))
@@ -136,7 +137,7 @@ else
# Make sure that R_file_stamp inherits the proper PRIVATE vars. # Make sure that R_file_stamp inherits the proper PRIVATE vars.
# If R.stamp moves, be sure to update the framework makefile, # If R.stamp moves, be sure to update the framework makefile,
# which has intimate knowledge of its location. # which has intimate knowledge of its location.
R_file_stamp := $(package_expected_intermediates_COMMON)/src/R.stamp R_file_stamp := $(intermediates.COMMON)/src/R.stamp
LOCAL_INTERMEDIATE_TARGETS += $(R_file_stamp) LOCAL_INTERMEDIATE_TARGETS += $(R_file_stamp)
endif endif
@@ -156,7 +157,7 @@ endif
proguard_options_file := proguard_options_file :=
ifneq ($(LOCAL_PROGUARD_ENABLED),custom) ifneq ($(LOCAL_PROGUARD_ENABLED),custom)
ifeq ($(need_compile_res),true) ifeq ($(need_compile_res),true)
proguard_options_file := $(package_expected_intermediates_COMMON)/proguard_options proguard_options_file := $(intermediates.COMMON)/proguard_options
endif # need_compile_res endif # need_compile_res
endif # !custom endif # !custom
LOCAL_PROGUARD_FLAGS := $(addprefix -include ,$(proguard_options_file)) $(LOCAL_PROGUARD_FLAGS) LOCAL_PROGUARD_FLAGS := $(addprefix -include ,$(proguard_options_file)) $(LOCAL_PROGUARD_FLAGS)
@@ -192,6 +193,8 @@ endif # LOCAL_EMMA_INSTRUMENT
rs_compatibility_jni_libs := rs_compatibility_jni_libs :=
include $(BUILD_SYSTEM)/android_manifest.mk
################################# #################################
include $(BUILD_SYSTEM)/java.mk include $(BUILD_SYSTEM)/java.mk
################################# #################################
@@ -201,8 +204,6 @@ ifeq ($(LOCAL_SDK_RES_VERSION),)
LOCAL_SDK_RES_VERSION:=$(LOCAL_SDK_VERSION) LOCAL_SDK_RES_VERSION:=$(LOCAL_SDK_VERSION)
endif endif
include $(BUILD_SYSTEM)/android_manifest.mk
$(LOCAL_INTERMEDIATE_TARGETS): \ $(LOCAL_INTERMEDIATE_TARGETS): \
PRIVATE_ANDROID_MANIFEST := $(full_android_manifest) PRIVATE_ANDROID_MANIFEST := $(full_android_manifest)
ifneq (,$(filter-out current system_current, $(LOCAL_SDK_VERSION))) ifneq (,$(filter-out current system_current, $(LOCAL_SDK_VERSION)))
@@ -223,11 +224,6 @@ ifeq ($(need_compile_res),true)
# At the same time, this will copy the R.java file to a central # At the same time, this will copy the R.java file to a central
# 'R' directory to make it easier to add the files to an IDE. # 'R' directory to make it easier to add the files to an IDE.
# #
#TODO: use PRIVATE_SOURCE_INTERMEDIATES_DIR instead of
# $(intermediates.COMMON)/src
ifneq ($(package_expected_intermediates_COMMON),$(intermediates.COMMON))
$(error $(LOCAL_MODULE): internal error: expected intermediates.COMMON "$(package_expected_intermediates_COMMON)" != intermediates.COMMON "$(intermediates.COMMON)")
endif
$(R_file_stamp): PRIVATE_RESOURCE_PUBLICS_OUTPUT := \ $(R_file_stamp): PRIVATE_RESOURCE_PUBLICS_OUTPUT := \
$(intermediates.COMMON)/public_resources.xml $(intermediates.COMMON)/public_resources.xml
@@ -410,6 +406,16 @@ endif
@# Alignment must happen after all other zip operations. @# Alignment must happen after all other zip operations.
$(align-package) $(align-package)
###############################
## Build dpi-specific apks, if it's apps_only build.
ifdef TARGET_BUILD_APPS
ifdef LOCAL_DPI_VARIANTS
$(foreach d, $(LOCAL_DPI_VARIANTS), \
$(eval my_dpi := $(d)) \
$(eval include $(BUILD_SYSTEM)/dpi_specific_apk.mk))
endif
endif
############################### ###############################
## Rule to build the odex file ## Rule to build the odex file
ifdef LOCAL_DEX_PREOPT ifdef LOCAL_DEX_PREOPT

View File

@@ -117,6 +117,19 @@ endif # LOCAL_STRIP_MODULE not true
ifeq ($(LOCAL_MODULE_CLASS),APPS) ifeq ($(LOCAL_MODULE_CLASS),APPS)
PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES)) PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
# Select dpi-specific source
ifdef LOCAL_DPI_VARIANTS
my_dpi := $(firstword $(filter $(LOCAL_DPI_VARIANTS),$(PRODUCT_AAPT_PREF_CONFIG) $(PRODUCT_AAPT_PREBUILT_DPI)))
ifdef my_dpi
ifdef LOCAL_DPI_FILE_STEM
my_prebuilt_dpi_file_stem := $(LOCAL_DPI_FILE_STEM)
else
my_prebuilt_dpi_file_stem := $(LOCAL_MODULE)_%.apk
endif
my_prebuilt_src_file := $(dir $(my_prebuilt_src_file))$(subst %,$(my_dpi),$(my_prebuilt_dpi_file_stem))
endif # my_dpi
endif # LOCAL_DPI_VARIANTS
rs_compatibility_jni_libs := rs_compatibility_jni_libs :=
include $(BUILD_SYSTEM)/install_jni_libs.mk include $(BUILD_SYSTEM)/install_jni_libs.mk
@@ -250,10 +263,26 @@ ifeq ($(LOCAL_IS_HOST_MODULE)$(LOCAL_MODULE_CLASS),JAVA_LIBRARIES)
# while the deps should be in the common dir, so we make a copy in the common dir. # while the deps should be in the common dir, so we make a copy in the common dir.
# For nonstatic library, $(common_javalib_jar) is the dependency file, # For nonstatic library, $(common_javalib_jar) is the dependency file,
# while $(common_classes_jar) is used to link. # while $(common_classes_jar) is used to link.
common_classes_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE),,COMMON)/classes.jar common_classes_jar := $(intermediates.COMMON)/classes.jar
common_javalib_jar := $(dir $(common_classes_jar))javalib.jar common_javalib_jar := $(intermediates.COMMON)/javalib.jar
$(common_classes_jar) : $(my_prebuilt_src_file) | $(ACP) $(common_classes_jar) $(common_javalib_jar): PRIVATE_MODULE := $(LOCAL_MODULE)
ifneq ($(filter %.aar, $(my_prebuilt_src_file)),)
# This is .aar file, archive of classes.jar and Android resources.
my_src_jar := $(intermediates.COMMON)/aar/classes.jar
$(my_src_jar) : $(my_prebuilt_src_file)
$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@)
$(hide) unzip -qo -d $(dir $@) $<
# Make sure the extracted classes.jar has a new timestamp.
$(hide) touch $@
else
# This is jar file.
my_src_jar := $(my_prebuilt_src_file)
endif
$(common_classes_jar) : $(my_src_jar) | $(ACP)
$(transform-prebuilt-to-target) $(transform-prebuilt-to-target)
$(common_javalib_jar) : $(common_classes_jar) | $(ACP) $(common_javalib_jar) : $(common_classes_jar) | $(ACP)

View File

@@ -70,6 +70,7 @@ _product_var_list := \
PRODUCT_LOCALES \ PRODUCT_LOCALES \
PRODUCT_AAPT_CONFIG \ PRODUCT_AAPT_CONFIG \
PRODUCT_AAPT_PREF_CONFIG \ PRODUCT_AAPT_PREF_CONFIG \
PRODUCT_AAPT_PREBUILT_DPI \
PRODUCT_PACKAGES \ PRODUCT_PACKAGES \
PRODUCT_PACKAGES_DEBUG \ PRODUCT_PACKAGES_DEBUG \
PRODUCT_PACKAGES_ENG \ PRODUCT_PACKAGES_ENG \

View File

@@ -274,19 +274,9 @@ ifneq (,$(extra_locales))
endif endif
# Add PRODUCT_LOCALES to PRODUCT_AAPT_CONFIG # Add PRODUCT_LOCALES to PRODUCT_AAPT_CONFIG
PRODUCT_AAPT_CONFIG := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_AAPT_CONFIG)) PRODUCT_AAPT_CONFIG := $(strip $(PRODUCT_LOCALES) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_AAPT_CONFIG))
PRODUCT_AAPT_CONFIG := $(PRODUCT_LOCALES) $(PRODUCT_AAPT_CONFIG)
PRODUCT_AAPT_PREF_CONFIG := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_AAPT_PREF_CONFIG)) PRODUCT_AAPT_PREF_CONFIG := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_AAPT_PREF_CONFIG))
PRODUCT_AAPT_PREBUILT_DPI := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_AAPT_PREBUILT_DPI))
# Default to medium-density assets.
# (Can be overridden in the device config, e.g.: PRODUCT_AAPT_CONFIG += hdpi)
PRODUCT_AAPT_CONFIG := $(strip \
$(PRODUCT_AAPT_CONFIG) \
$(if $(filter %dpi,$(PRODUCT_AAPT_CONFIG)),,mdpi))
PRODUCT_AAPT_PREF_CONFIG := $(strip $(PRODUCT_AAPT_PREF_CONFIG))
# Everyone gets nodpi and anydpi assets which are density-independent.
PRODUCT_AAPT_CONFIG += nodpi anydpi
# Keep a copy of the space-separated config # Keep a copy of the space-separated config
PRODUCT_AAPT_CONFIG_SP := $(PRODUCT_AAPT_CONFIG) PRODUCT_AAPT_CONFIG_SP := $(PRODUCT_AAPT_CONFIG)
@@ -294,8 +284,6 @@ PRODUCT_AAPT_CONFIG_SP := $(PRODUCT_AAPT_CONFIG)
# Convert spaces to commas. # Convert spaces to commas.
PRODUCT_AAPT_CONFIG := \ PRODUCT_AAPT_CONFIG := \
$(subst $(space),$(comma),$(strip $(PRODUCT_AAPT_CONFIG))) $(subst $(space),$(comma),$(strip $(PRODUCT_AAPT_CONFIG)))
PRODUCT_AAPT_PREF_CONFIG := \
$(subst $(space),$(comma),$(strip $(PRODUCT_AAPT_PREF_CONFIG)))
# product-scoped aapt flags # product-scoped aapt flags
PRODUCT_AAPT_FLAGS := PRODUCT_AAPT_FLAGS :=

View File

@@ -31,6 +31,11 @@ last_released_sdk_version := $(lastword $(call numerically_sort, \
)\ )\
)) ))
.PHONY: check-public-api
checkapi : check-public-api
.PHONY: update-api
# INTERNAL_PLATFORM_API_FILE is the one build by droiddoc. # INTERNAL_PLATFORM_API_FILE is the one build by droiddoc.
# Note that since INTERNAL_PLATFORM_API_FILE is the byproduct of api-stubs module, # Note that since INTERNAL_PLATFORM_API_FILE is the byproduct of api-stubs module,
# (See frameworks/base/Android.mk) # (See frameworks/base/Android.mk)
@@ -39,7 +44,7 @@ last_released_sdk_version := $(lastword $(call numerically_sort, \
# Check that the API we're building hasn't broken the last-released # Check that the API we're building hasn't broken the last-released
# SDK version. # SDK version.
$(eval $(call check-api, \ $(eval $(call check-api, \
checkapi-last, \ checkpublicapi-last, \
$(SRC_API_DIR)/$(last_released_sdk_version).txt, \ $(SRC_API_DIR)/$(last_released_sdk_version).txt, \
$(INTERNAL_PLATFORM_API_FILE), \ $(INTERNAL_PLATFORM_API_FILE), \
frameworks/base/api/removed.txt, \ frameworks/base/api/removed.txt, \
@@ -48,14 +53,14 @@ $(eval $(call check-api, \
-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \ -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-error 16 -error 17 -error 18 , \ -error 16 -error 17 -error 18 , \
cat $(BUILD_SYSTEM)/apicheck_msg_last.txt, \ cat $(BUILD_SYSTEM)/apicheck_msg_last.txt, \
checkapi, \ check-public-api, \
$(call doc-timestamp-for,api-stubs) \ $(call doc-timestamp-for,api-stubs) \
)) ))
# Check that the API we're building hasn't changed from the not-yet-released # Check that the API we're building hasn't changed from the not-yet-released
# SDK version. # SDK version.
$(eval $(call check-api, \ $(eval $(call check-api, \
checkapi-current, \ checkpublicapi-current, \
frameworks/base/api/current.txt, \ frameworks/base/api/current.txt, \
$(INTERNAL_PLATFORM_API_FILE), \ $(INTERNAL_PLATFORM_API_FILE), \
frameworks/base/api/removed.txt, \ frameworks/base/api/removed.txt, \
@@ -64,21 +69,23 @@ $(eval $(call check-api, \
-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \ -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \ -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
-error 25 -error 26 -error 27, \ -error 25 -error 26 -error 27, \
sed -e 's/%UPDATE_API%/update-api/g' $(BUILD_SYSTEM)/apicheck_msg_current.txt, \ cat $(BUILD_SYSTEM)/apicheck_msg_current.txt, \
checkapi, \ check-public-api, \
$(call doc-timestamp-for,api-stubs) \ $(call doc-timestamp-for,api-stubs) \
)) ))
.PHONY: update-api .PHONY: update-public-api
update-api: $(INTERNAL_PLATFORM_API_FILE) | $(ACP) update-public-api: $(INTERNAL_PLATFORM_API_FILE) | $(ACP)
@echo Copying current.txt @echo Copying current.txt
$(hide) $(ACP) $(INTERNAL_PLATFORM_API_FILE) frameworks/base/api/current.txt $(hide) $(ACP) $(INTERNAL_PLATFORM_API_FILE) frameworks/base/api/current.txt
@echo Copying removed.txt @echo Copying removed.txt
$(hide) $(ACP) $(INTERNAL_PLATFORM_REMOVED_API_FILE) frameworks/base/api/removed.txt $(hide) $(ACP) $(INTERNAL_PLATFORM_REMOVED_API_FILE) frameworks/base/api/removed.txt
update-api : update-public-api
#####################Check System API##################### #####################Check System API#####################
.PHONY: checksystemapi .PHONY: check-system-api
checkapi : check-system-api
# Check that the System API we're building hasn't broken the last-released # Check that the System API we're building hasn't broken the last-released
# SDK version. # SDK version.
@@ -92,7 +99,7 @@ $(eval $(call check-api, \
-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \ -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-error 16 -error 17 -error 18 , \ -error 16 -error 17 -error 18 , \
cat $(BUILD_SYSTEM)/apicheck_msg_last.txt, \ cat $(BUILD_SYSTEM)/apicheck_msg_last.txt, \
checksystemapi, \ check-system-api, \
$(call doc-timestamp-for,system-api-stubs) \ $(call doc-timestamp-for,system-api-stubs) \
)) ))
@@ -108,12 +115,14 @@ $(eval $(call check-api, \
-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \ -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \ -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
-error 25 -error 26 -error 27, \ -error 25 -error 26 -error 27, \
sed -e 's/%UPDATE_API%/update-system-api/g' $(BUILD_SYSTEM)/apicheck_msg_current.txt, \ cat $(BUILD_SYSTEM)/apicheck_msg_current.txt, \
checksystemapi, \ check-system-api, \
$(call doc-timestamp-for,system-api-stubs) \ $(call doc-timestamp-for,system-api-stubs) \
)) ))
.PHONY: update-system-api .PHONY: update-system-api
update-api : update-system-api
update-system-api: $(INTERNAL_PLATFORM_SYSTEM_API_FILE) | $(ACP) update-system-api: $(INTERNAL_PLATFORM_SYSTEM_API_FILE) | $(ACP)
@echo Copying system-current.txt @echo Copying system-current.txt
$(hide) $(ACP) $(INTERNAL_PLATFORM_SYSTEM_API_FILE) frameworks/base/api/system-current.txt $(hide) $(ACP) $(INTERNAL_PLATFORM_SYSTEM_API_FILE) frameworks/base/api/system-current.txt

View File

@@ -41,7 +41,7 @@ ifeq "" "$(PLATFORM_VERSION)"
# which is the version that we reveal to the end user. # which is the version that we reveal to the end user.
# Update this value when the platform version changes (rather # Update this value when the platform version changes (rather
# than overriding it somewhere else). Can be an arbitrary string. # than overriding it somewhere else). Can be an arbitrary string.
PLATFORM_VERSION := 5.0.50.50.50.50 PLATFORM_VERSION := 5.1
endif endif
ifeq "" "$(PLATFORM_SDK_VERSION)" ifeq "" "$(PLATFORM_SDK_VERSION)"
@@ -53,7 +53,7 @@ ifeq "" "$(PLATFORM_SDK_VERSION)"
# intermediate builds). During development, this number remains at the # intermediate builds). During development, this number remains at the
# SDK version the branch is based on and PLATFORM_VERSION_CODENAME holds # SDK version the branch is based on and PLATFORM_VERSION_CODENAME holds
# the code-name of the new development work. # the code-name of the new development work.
PLATFORM_SDK_VERSION := 21 PLATFORM_SDK_VERSION := 22
endif endif
ifeq "" "$(PLATFORM_VERSION_CODENAME)" ifeq "" "$(PLATFORM_VERSION_CODENAME)"

View File

@@ -578,7 +578,8 @@ function tapas()
{ {
local arch="$(echo $* | xargs -n 1 echo | \grep -E '^(arm|x86|mips|armv5|arm64|x86_64|mips64)$' | xargs)" local arch="$(echo $* | xargs -n 1 echo | \grep -E '^(arm|x86|mips|armv5|arm64|x86_64|mips64)$' | xargs)"
local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)" local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)"
local apps="$(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|arm|x86|mips|armv5|arm64|x86_64|mips64)$' | xargs)" local density="$(echo $* | xargs -n 1 echo | \grep -E '^(ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi)$' | xargs)"
local apps="$(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|arm|x86|mips|armv5|arm64|x86_64|mips64|ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi)$' | xargs)"
if [ $(echo $arch | wc -w) -gt 1 ]; then if [ $(echo $arch | wc -w) -gt 1 ]; then
echo "tapas: Error: Multiple build archs supplied: $arch" echo "tapas: Error: Multiple build archs supplied: $arch"
@@ -588,6 +589,10 @@ function tapas()
echo "tapas: Error: Multiple build variants supplied: $variant" echo "tapas: Error: Multiple build variants supplied: $variant"
return return
fi fi
if [ $(echo $density | wc -w) -gt 1 ]; then
echo "tapas: Error: Multiple densities supplied: $density"
return
fi
local product=full local product=full
case $arch in case $arch in
@@ -604,9 +609,13 @@ function tapas()
if [ -z "$apps" ]; then if [ -z "$apps" ]; then
apps=all apps=all
fi fi
if [ -z "$density" ]; then
density=alldpi
fi
export TARGET_PRODUCT=$product export TARGET_PRODUCT=$product
export TARGET_BUILD_VARIANT=$variant export TARGET_BUILD_VARIANT=$variant
export TARGET_BUILD_DENSITY=$density
export TARGET_BUILD_TYPE=release export TARGET_BUILD_TYPE=release
export TARGET_BUILD_APPS=$apps export TARGET_BUILD_APPS=$apps
@@ -892,6 +901,85 @@ function pid()
fi fi
} }
# coredump_setup - enable core dumps globally for any process
# that has the core-file-size limit set correctly
#
# NOTE: You must call also coredump_enable for a specific process
# if its core-file-size limit is not set already.
# NOTE: Core dumps are written to ramdisk; they will not survive a reboot!
function coredump_setup()
{
echo "Getting root...";
adb root;
adb wait-for-device;
echo "Remounting root parition read-write...";
adb shell mount -w -o remount -t rootfs rootfs;
sleep 1;
adb wait-for-device;
adb shell mkdir -p /cores;
adb shell mount -t tmpfs tmpfs /cores;
adb shell chmod 0777 /cores;
echo "Granting SELinux permission to dump in /cores...";
adb shell restorecon -R /cores;
echo "Set core pattern.";
adb shell 'echo /cores/core.%p > /proc/sys/kernel/core_pattern';
echo "Done."
}
# coredump_enable - enable core dumps for the specified process
# $1 = PID of process (e.g., $(pid mediaserver))
#
# NOTE: coredump_setup must have been called as well for a core
# dump to actually be generated.
function coredump_enable()
{
local PID=$1;
if [ -z "$PID" ]; then
printf "Expecting a PID!\n";
return;
fi;
echo "Setting core limit for $PID to infinite...";
adb shell prlimit $PID 4 -1 -1
}
# core - send SIGV and pull the core for process
# $1 = PID of process (e.g., $(pid mediaserver))
#
# NOTE: coredump_setup must be called once per boot for core dumps to be
# enabled globally.
function core()
{
local PID=$1;
if [ -z "$PID" ]; then
printf "Expecting a PID!\n";
return;
fi;
local CORENAME=core.$PID;
local COREPATH=/cores/$CORENAME;
local SIG=SEGV;
coredump_enable $1;
local done=0;
while [ $(adb shell "[ -d /proc/$PID ] && echo -n yes") ]; do
printf "\tSending SIG%s to %d...\n" $SIG $PID;
adb shell kill -$SIG $PID;
sleep 1;
done;
adb shell "while [ ! -f $COREPATH ] ; do echo waiting for $COREPATH to be generated; sleep 1; done"
echo "Done: core is under $COREPATH on device.";
}
# systemstack - dump the current stack trace of all threads in the system process # systemstack - dump the current stack trace of all threads in the system process
# to the usual ANR traces file # to the usual ANR traces file
function systemstack() function systemstack()

View File

@@ -25,13 +25,13 @@ TARGET_2ND_ARCH := arm
TARGET_2ND_CPU_ABI := armeabi-v7a TARGET_2ND_CPU_ABI := armeabi-v7a
TARGET_2ND_CPU_ABI2 := armeabi TARGET_2ND_CPU_ABI2 := armeabi
ifdef TARGET_BUILD_APPS ifneq ($(TARGET_BUILD_APPS)$(filter cts,$(MAKECMDGOALS)),)
# DO NOT USE # DO NOT USE
# DO NOT USE # DO NOT USE
# #
# This architecture / CPU variant must NOT be used for any 64 bit # This architecture / CPU variant must NOT be used for any 64 bit
# platform builds. It is the lowest common denominator required # platform builds. It is the lowest common denominator required
# to build an unbundled application for all supported 32 and 64 bit # to build an unbundled application or cts for all supported 32 and 64 bit
# platforms. # platforms.
# #
# If you're building a 64 bit platform (and not an application) the # If you're building a 64 bit platform (and not an application) the
@@ -76,10 +76,9 @@ BUILD_EMULATOR_OPENGL := true
USE_OPENGL_RENDERER := true USE_OPENGL_RENDERER := true
TARGET_USERIMAGES_USE_EXT4 := true TARGET_USERIMAGES_USE_EXT4 := true
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 845427200 BOARD_SYSTEMIMAGE_PARTITION_SIZE := 943718400
BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016 BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
BOARD_FLASH_BLOCK_SIZE := 512 BOARD_FLASH_BLOCK_SIZE := 512
TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true

View File

@@ -53,7 +53,7 @@ BUILD_EMULATOR_OPENGL := true
USE_OPENGL_RENDERER := true USE_OPENGL_RENDERER := true
TARGET_USERIMAGES_USE_EXT4 := true TARGET_USERIMAGES_USE_EXT4 := true
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 786432000 BOARD_SYSTEMIMAGE_PARTITION_SIZE := 838860800
BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016 BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4

View File

@@ -41,7 +41,7 @@ BUILD_EMULATOR_OPENGL := true
USE_OPENGL_RENDERER := true USE_OPENGL_RENDERER := true
TARGET_USERIMAGES_USE_EXT4 := true TARGET_USERIMAGES_USE_EXT4 := true
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 943718400 # 900MB BOARD_SYSTEMIMAGE_PARTITION_SIZE := 1073741824 # 1GB
BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016 BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4

View File

@@ -15,9 +15,10 @@
# #
# Base configuration for communication-oriented android devices # Base configuration for communication-oriented android devices
# (phones, tablets, etc.). If you want a change to apply to ALL # (phones, tablets, etc.). If you want a change to apply to ALMOST ALL
# devices (including non-phones and non-tablets), modify # devices (including non-phones and non-tablets), modify
# core_minimal.mk instead. # core_minimal.mk instead. If you care about wearables, you need to modify
# core_tiny.mk in addition to core_minimal.mk.
PRODUCT_PACKAGES += \ PRODUCT_PACKAGES += \
BasicDreams \ BasicDreams \

View File

@@ -43,6 +43,7 @@ PRODUCT_PACKAGES += \
DefaultContainerService \ DefaultContainerService \
SettingsProvider \ SettingsProvider \
Shell \ Shell \
bcc \
bu \ bu \
com.android.location.provider \ com.android.location.provider \
com.android.location.provider.xml \ com.android.location.provider.xml \

View File

@@ -47,7 +47,7 @@ PRODUCT_PROPERTY_OVERRIDES := \
PRODUCT_LOCALES := en_US PRODUCT_LOCALES := en_US
# Include drawables for all densities # Include drawables for all densities
PRODUCT_AAPT_CONFIG := normal hdpi xhdpi xxhdpi PRODUCT_AAPT_CONFIG := normal
# Get some sounds # Get some sounds
$(call inherit-product-if-exists, frameworks/base/data/sounds/AllAudio.mk) $(call inherit-product-if-exists, frameworks/base/data/sounds/AllAudio.mk)

View File

@@ -60,6 +60,7 @@ $(call inherit-product-if-exists, external/google-fonts/dancing-script/fonts.mk)
$(call inherit-product-if-exists, external/google-fonts/carrois-gothic-sc/fonts.mk) $(call inherit-product-if-exists, external/google-fonts/carrois-gothic-sc/fonts.mk)
$(call inherit-product-if-exists, external/google-fonts/coming-soon/fonts.mk) $(call inherit-product-if-exists, external/google-fonts/coming-soon/fonts.mk)
$(call inherit-product-if-exists, external/google-fonts/cutive-mono/fonts.mk) $(call inherit-product-if-exists, external/google-fonts/cutive-mono/fonts.mk)
$(call inherit-product-if-exists, external/lohit-fonts/fonts.mk)
$(call inherit-product-if-exists, external/noto-fonts/fonts.mk) $(call inherit-product-if-exists, external/noto-fonts/fonts.mk)
$(call inherit-product-if-exists, external/naver-fonts/fonts.mk) $(call inherit-product-if-exists, external/naver-fonts/fonts.mk)
$(call inherit-product-if-exists, frameworks/base/data/keyboards/keyboards.mk) $(call inherit-product-if-exists, frameworks/base/data/keyboards/keyboards.mk)

View File

@@ -21,4 +21,4 @@
# These are all the locales that have translations and are displayable # These are all the locales that have translations and are displayable
# by TextView in this branch. # by TextView in this branch.
PRODUCT_LOCALES := en_AU en_US en_IN fr_FR it_IT es_ES et_EE de_DE nl_NL cs_CZ pl_PL ja_JP zh_TW zh_CN zh_HK ru_RU ko_KR nb_NO es_US da_DK el_GR tr_TR pt_PT pt_BR rm_CH sv_SE bg_BG ca_ES en_GB fi_FI hi_IN hr_HR hu_HU in_ID iw_IL lt_LT lv_LV ro_RO sk_SK sl_SI sr_RS uk_UA vi_VN tl_PH ar_EG fa_IR th_TH sw_TZ ms_MY af_ZA zu_ZA am_ET hi_IN en_XA ar_XB fr_CA km_KH lo_LA ne_NP si_LK mn_MN hy_AM az_AZ ka_GE my_MM mr_IN ml_IN is_IS mk_MK ky_KG eu_ES gl_ES bn_BD ta_IN kn_IN te_IN uz_UZ ur_PK kk_KZ PRODUCT_LOCALES := en_US en_AU en_IN fr_FR it_IT es_ES et_EE de_DE nl_NL cs_CZ pl_PL ja_JP zh_TW zh_CN zh_HK ru_RU ko_KR nb_NO es_US da_DK el_GR tr_TR pt_PT pt_BR rm_CH sv_SE bg_BG ca_ES en_GB fi_FI hi_IN hr_HR hu_HU in_ID iw_IL lt_LT lv_LV ro_RO sk_SK sl_SI sr_RS uk_UA vi_VN tl_PH ar_EG fa_IR th_TH sw_TZ ms_MY af_ZA zu_ZA am_ET hi_IN en_XA ar_XB fr_CA km_KH lo_LA ne_NP si_LK mn_MN hy_AM az_AZ ka_GE my_MM mr_IN ml_IN is_IS mk_MK ky_KG eu_ES gl_ES bn_BD ta_IN kn_IN te_IN uz_UZ ur_PK kk_KZ

View File

@@ -95,14 +95,10 @@ $(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk)
-include external/svox/pico/lang/PicoLangFrFrInSystem.mk -include external/svox/pico/lang/PicoLangFrFrInSystem.mk
-include external/svox/pico/lang/PicoLangItItInSystem.mk -include external/svox/pico/lang/PicoLangItItInSystem.mk
# locale + densities. en_US is both first and in alphabetical order to # locale. en_US is both first and in alphabetical order to
# ensure this is the default locale. # ensure this is the default locale.
PRODUCT_LOCALES := \ PRODUCT_LOCALES := \
en_US \ en_US \
ldpi \
hdpi \
mdpi \
xhdpi \
ar_EG \ ar_EG \
ar_IL \ ar_IL \
bg_BG \ bg_BG \

Binary file not shown.

View File

@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIID/TCCAuWgAwIBAgIJAJcPmDkJqolJMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g
VmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UE
AwwHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
Fw0xNDExMDYxOTA3NDBaFw00MjAzMjQxOTA3NDBaMIGUMQswCQYDVQQGEwJVUzET
MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
A1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UEAwwHQW5kcm9p
ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAOjreE0vTVSRenuzO9vnaWfk0eQzYab0gqpi
6xAzi6dmD+ugoEKJmbPiuE5Dwf21isZ9uhUUu0dQM46dK4ocKxMRrcnmGxydFn6o
fs3ODJMXOkv2gKXL/FdbEPdDbxzdu8z3yk+W67udM/fW7WbaQ3DO0knu+izKak/3
T41c5uoXmQ81UNtAzRGzGchNVXMmWuTGOkg6U+0I2Td7K8yvUMWhAWPPpKLtVH9r
AL5TzjYNR92izdKcz3AjRsI3CTjtpiVABGeX0TcjRSuZB7K9EK56HV+OFNS6I1NP
jdD7FIShyGlqqZdUOkAUZYanbpgeT5N7QL6uuqcGpoTOkalu6kkCAwEAAaNQME4w
HQYDVR0OBBYEFH5DM/m7oArf4O3peeKO0ZIEkrQPMB8GA1UdIwQYMBaAFH5DM/m7
oArf4O3peeKO0ZIEkrQPMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB
AHO3NSvDE5jFvMehGGtS8BnFYdFKRIglDMc4niWSzhzOVYRH4WajxdtBWc5fx0ix
NF/+hVKVhP6AIOQa+++sk+HIi7RvioPPbhjcsVlZe7cUEGrLSSveGouQyc+j0+m6
JF84kszIl5GGNMTnx0XRPO+g8t6h5LWfnVydgZfpGRRg+WHewk1U2HlvTjIceb0N
dcoJ8WKJAFWdcuE7VIm4w+vF/DYX/A2Oyzr2+QRhmYSv1cusgAeC1tvH4ap+J1Lg
UnOu5Kh/FqPLLSwNVQp4Bu7b9QFfqK8Moj84bj88NqRGZgDyqzuTrFxn6FW7dmyA
yttuAJAEAymk1mipd9+zp38=
-----END CERTIFICATE-----

Binary file not shown.

View File

@@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDQxdVrH2RB1eg5
17/gBmLzW1Ds10RG6ctNZMhxppMOLnEZViKGv1VNRhxqK/JKTv2UujgZ94SJcDub
G+DwAwaGZKQqDYUa0VU2cng8TYPcnYGPdJ7Usckp6tdg64vns7e+VVf0dOyEovR+
JyeYUz05OhUMYP9xJIhpA2XnXe5Ekb9iTFSYo9uBpoXDD4IY7aOqUxSbv9wMtyIp
dl+oTm0+kqRRi4KoxGHV0CzDseEUuWG/Kp/7aVF9Sg45NcC6KYvrGysUKA+Bt09O
feDn/HRpT9SfRElJa5DRms33UBUtnom15F4yd4vvFgubB0nkPOUuwfZhTFfgeuY4
H2bHkjKbAgMBAAECggEAMpFYqkPGQvQO9cO+ZALoAM4Dgfp6PTrv1WUt7+lLAUpa
dqqYXk8F2Fu9EjJm03ziix237QI5Bhk7Nsy/5SK2d+L0qILx1JcTrsZ3PRQBdnRo
J1k2B4qwkQii9oTXNF4hiWaekUWo7E+ULOJLAuhWkf/xjTgJZ1xT9iuuiSYFSnIa
9ABNH0vCaKEkW/4ri6fdtXmO26C/ltJlnozl86x07PIFh4uBas7/40E8ykFP00CS
zdhMh+2DGyCb1Q0eJ1IfGILNatkLNEd2BHgQ7qNBkN9yShZfhvIPblr5gSUlZplX
diV20ZGLAfByKWgZZWKkwl9KzaisL/J/4dr2UlSVEQKBgQDxAYTsgoTkkP0TKzr3
i3ljT8OuVOj6TwZVBJYe2MIJ3veivS3gWB53FpsKthbib7y8ifIakn15mQkNCK5R
7H7F5lvZCNnB6shY5Dz7nLJxKLALcAg+d12l3gTbFQeFDs0iQQJF7P8hs/GPF7kY
Layb7EF0uzYjyHJCKtFdaZaeZwKBgQDdwvCb7NJVeGTcE97etL+8acu9y4GlqKEF
o0Vkw8TjNKj/KuDkbkAk9hXxU1ZCmDU3y6r8CVHYl0Sqh08plEhkYB/j3sFy81zY
3xu/rLFysBwjeJHHlPjRTYkdKr9pABmm8NIEShvu9u8i+mpOhjbX72HxZL+i4Fou
gz58wEdBrQKBgG8CfyKdn+7UJe3tbLTXRquK8xxauhGJ0uXYPfmpZ/8596C7OOVs
UWQTQoj1hKb6RtolRCIfNbKL3hJl3D2aDG7Fg6r9m6fpqCzhvIE9FShwUF6EVRfI
zZb4JA5xqkwMnEpZ3V0uI/p3Mx3xFG3ho+8SLLhC/1YOHysBI/y+BQWjAoGAYiqQ
PkXYWhOAeleleeqDUdF3al3y1zVNimRbLJ7owjcmdEYz5YrUhEgXMIvWjIY6UKes
2gL6IynbMK3TIjHM1fojQ8jw04TdXfdtnizBJGbHHgCab8IHXwe2oZ2xu7ZapKbI
ITP5J5BSDabSdk49attB/Qy/NEeiRCK+/5RSNsUCgYAg6vX9VqMEkhPHeoFfdLGD
EQPPN6QLrQ4Zif0GKxH96znNSv0rXdNp9t0kyapdgzMuCwIEuOkCSiKgmfjTWnYO
qh5HMUuD2VbfWwI9jVujQMRmqiaFF7VxxA1bP5j1hJlI6cn1Fjlpi+NsNZN4nm3Q
92SEwX2vDgjrU0NAtFFL1Q==
-----END PRIVATE KEY-----

View File

@@ -17,7 +17,11 @@
# Provides dependencies necessary for verified boot # Provides dependencies necessary for verified boot
PRODUCT_SUPPORTS_VERITY := true PRODUCT_SUPPORTS_VERITY := true
PRODUCT_VERITY_SIGNING_KEY := build/target/product/security/verity_private_dev_key
# The dev key is used to sign boot and recovery images, and the verity
# metadata table. Actual product deliverables will be re-signed by hand.
# We expect this file to exist with the suffixes ".x509.pem" and ".pk8".
PRODUCT_VERITY_SIGNING_KEY := build/target/product/security/verity
PRODUCT_PACKAGES += \ PRODUCT_PACKAGES += \
verity_key verity_key

View File

@@ -16,6 +16,7 @@ echo "ro.build.type=$TARGET_BUILD_TYPE"
echo "ro.build.user=$USER" echo "ro.build.user=$USER"
echo "ro.build.host=`hostname`" echo "ro.build.host=`hostname`"
echo "ro.build.tags=$BUILD_VERSION_TAGS" echo "ro.build.tags=$BUILD_VERSION_TAGS"
echo "ro.build.flavor=$TARGET_BUILD_FLAVOR"
echo "ro.product.model=$PRODUCT_MODEL" echo "ro.product.model=$PRODUCT_MODEL"
echo "ro.product.brand=$PRODUCT_BRAND" echo "ro.product.brand=$PRODUCT_BRAND"
echo "ro.product.name=$PRODUCT_NAME" echo "ro.product.name=$PRODUCT_NAME"

View File

@@ -466,6 +466,9 @@ a.back-link {
text-transform: uppercase; text-transform: uppercase;
} }
.content-header .paging-links {
margin-top:-25px;
}
.paging-links { .paging-links {
position: relative; position: relative;
height:30px; } height:30px; }
@@ -3062,15 +3065,15 @@ select.ide option {
font-size:16px; font-size:16px;
font-weight:500; font-weight:500;
} }
/* hide all except eclipse by default */ /* hide all except studio by default */
.select-ide.studio, .select-ide.eclipse,
.select-ide.other { .select-ide.other {
display:none; display:none;
} }
/* ... unless eclipse also includes one of the others */ /* ... unless studio also includes one of the others */
.select-ide.eclipse.studio, .select-ide.studio.eclipse,
.select-ide.eclipse.other { .select-ide.studio.other {
display:block; display:none;
} }
@@ -3152,6 +3155,7 @@ div#deprecatedSticker {
-webkit-box-shadow:-5px 5px 10px #ccc; -webkit-box-shadow:-5px 5px 10px #ccc;
} }
div#langMessage,
div#naMessage { div#naMessage {
display:none; display:none;
width:555px; width:555px;
@@ -3159,6 +3163,8 @@ div#naMessage {
margin:0 auto; margin:0 auto;
} }
div#langMessage>div,
div#naMessage div { div#naMessage div {
z-index:99; z-index:99;
width:450px; width:450px;
@@ -3172,12 +3178,16 @@ div#naMessage div {
-webkit-box-shadow:-10px 10px 40px #888; -webkit-box-shadow:-10px 10px 40px #888;
} }
/* IE6 can't position fixed */ /* IE6 can't position fixed */
* html div#langMessage>div,
* html div#naMessage div { position:absolute; } * html div#naMessage div { position:absolute; }
div#naMessage strong { div#naMessage strong {
font-size:1.1em; font-size:1.1em;
} }
div#langMessage .lang {
display:none;
}
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Slideshow Controls & Next/Prev Slideshow Controls & Next/Prev
@@ -4056,7 +4066,7 @@ EndColorStr='#ececec');
height: 38px; height: 38px;
} }
#header-wrapper #nav-x ul.nav-x li { #header-wrapper #nav-x ul.nav-x li {
margin-right: 36px !important; margin-right: 31px !important;
margin-top: 5px; margin-top: 5px;
margin-bottom: 0px; margin-bottom: 0px;
height: 30px; height: 30px;
@@ -4414,7 +4424,7 @@ body.reference a[name] {
} }
#header-wrap.quicknav { #header-wrap.quicknav {
height:196px; height:216px;
} }
@@ -6940,38 +6950,76 @@ a.landing-button:visited {
display:none; display:none;
position:fixed; position:fixed;
top:0; top:0;
left:-10px; left:0;
width:102%; width:100%;
height:100%; height:100%;
background-color:rgba(0,0,0,0.7); background-color:rgba(0,0,0,0.8);
z-index:99; z-index:9999;
} }
#video-frame { #video-frame {
width:940px; width:940px;
height:526.4px; height:100%;
margin:80px auto 0; margin:72px auto;
display:none; display:none;
position:relative;
} }
.video-close { .video-close {
cursor: pointer; cursor: pointer;
position: relative; position: absolute;
left: 940px; right: -49px;
top: 0; top: -49px;
pointer-events: all; pointer-events: all;
} }
#icon-video-close { #icon-video-close {
background-image: url("../images/close.png"); background-image: url("../images/close-white.png");
background-position: 0 0; background-image: -webkit-image-set(url(../images/close-white.png) 1x, url(../images/close-white_2x.png) 2x);
height: 36px; background-repeat: no-repeat;
width: 36px; background-position: 0 0;
display:block; background-size: 36px 36px;
height: 36px;
width: 36px;
display:block;
} }
#icon-video-close:hover {
background-image: url("../images/close-grey.png");
background-image: -webkit-image-set(url(../images/close-grey.png) 1x, url(../images/close-grey_2x.png) 2x);
}
/* Preload the hover images */
a.video-shadowbox-button.white:after {
display:none;
content:url("../images/close-grey.png") url("../images/close-grey_2x.png");
}
a.video-shadowbox-button.white {
background-image: url("../images/play-circle-white.png");
background-image: -webkit-image-set(url(../images/play-circle-white.png) 1x, url(../images/play-circle-white_2x.png) 2x);
background-size: 36px 36px;
background-repeat: no-repeat;
background-position: right;
padding: 16px 42px 16px 8px;
font-size: 18px;
font-weight: 500;
line-height: 24px;
color: #fff;
text-decoration:none;
}
a.video-shadowbox-button.white:hover {
color:#bababa !important;
background-image: url("../images/play-circle-grey.png");
background-image: -webkit-image-set(url(../images/play-circle-grey.png) 1x, url(../images/play-circle-grey_2x.png) 2x);
}
/* Preload the hover images */
a.video-shadowbox-button.white:after {
display:none;
content:url("../images/play-circle-grey.png") url("../images/play-circle-grey_2x.png");
}
/****************** /******************
Styles for d.a.c/index: Styles for d.a.c/index:
@@ -7352,7 +7400,7 @@ a.home-new-cta-btn:hover,
/* Helpouts widget */ /* Helpouts widget */
.resource-card-6x2.helpouts-card { .resource-card-6x2.helpouts-card {
width: 220px; width: 255px;
height: 40px; height: 40px;
position:absolute; position:absolute;
z-index:999; z-index:999;
@@ -7389,4 +7437,4 @@ a.home-new-cta-btn:hover,
.resource-card-6x2 > .card-bg.helpouts-card-bg:after { .resource-card-6x2 > .card-bg.helpouts-card-bg:after {
display:none; display:none;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -21,6 +21,17 @@ $.ajaxSetup({
$(document).ready(function() { $(document).ready(function() {
// show lang dialog if the URL includes /intl/
//if (location.pathname.substring(0,6) == "/intl/") {
// var lang = location.pathname.split('/')[2];
// if (lang != getLangPref()) {
// $("#langMessage a.yes").attr("onclick","changeLangPref('" + lang
// + "', true); $('#langMessage').hide(); return false;");
// $("#langMessage .lang." + lang).show();
// $("#langMessage").show();
// }
//}
// load json file for JD doc search suggestions // load json file for JD doc search suggestions
$.getScript(toRoot + 'jd_lists_unified.js'); $.getScript(toRoot + 'jd_lists_unified.js');
// load json file for Android API search suggestions // load json file for Android API search suggestions
@@ -223,6 +234,8 @@ $(document).ready(function() {
$("#nav-x li.engage a").addClass("selected"); $("#nav-x li.engage a").addClass("selected");
} else if (secondFrag == "monetize") { } else if (secondFrag == "monetize") {
$("#nav-x li.monetize a").addClass("selected"); $("#nav-x li.monetize a").addClass("selected");
} else if (secondFrag == "analyze") {
$("#nav-x li.analyze a").addClass("selected");
} else if (secondFrag == "tools") { } else if (secondFrag == "tools") {
$("#nav-x li.disttools a").addClass("selected"); $("#nav-x li.disttools a").addClass("selected");
} else if (secondFrag == "stories") { } else if (secondFrag == "stories") {
@@ -547,10 +560,147 @@ false; // navigate across topic boundaries only in design docs
cookiePath = "distribute_"; cookiePath = "distribute_";
} }
/* setup shadowbox for any videos that want it */
var $videoLinks = $("a.video-shadowbox-button, a.notice-developers-video");
if ($videoLinks.length) {
// if there's at least one, add the shadowbox HTML to the body
$('body').prepend(
'<div id="video-container">'+
'<div id="video-frame">'+
'<div class="video-close">'+
'<span id="icon-video-close" onclick="closeVideo()">&nbsp;</span>'+
'</div>'+
'<div id="youTubePlayer"></div>'+
'</div>'+
'</div>');
// loads the IFrame Player API code asynchronously.
$.getScript("https://www.youtube.com/iframe_api");
$videoLinks.each(function() {
var videoId = $(this).attr('href').split('?v=')[1];
$(this).click(function(event) {
event.preventDefault();
startYouTubePlayer(videoId);
});
});
}
}); });
// END of the onload event // END of the onload event
var youTubePlayer;
function onYouTubeIframeAPIReady() {
}
/* Returns the height the shadowbox video should be. It's based on the current
height of the "video-frame" element, which is 100% height for the window.
Then minus the margin so the video isn't actually the full window height. */
function getVideoHeight() {
var frameHeight = $("#video-frame").height();
var marginTop = $("#video-frame").css('margin-top').split('px')[0];
return frameHeight - (marginTop * 2);
}
var mPlayerPaused = false;
function startYouTubePlayer(videoId) {
$("#video-container").show();
$("#video-frame").show();
mPlayerPaused = false;
// compute the size of the player so it's centered in window
var maxWidth = 940; // the width of the web site content
var videoAspect = .5625; // based on 1280x720 resolution
var maxHeight = maxWidth * videoAspect;
var videoHeight = getVideoHeight();
var videoWidth = videoHeight / videoAspect;
if (videoWidth > maxWidth) {
videoWidth = maxWidth;
videoHeight = maxHeight;
}
$("#video-frame").css('width', videoWidth);
// check if we've already created this player
if (youTubePlayer == null) {
// check if there's a start time specified
var idAndHash = videoId.split("#");
var startTime = 0;
if (idAndHash.length > 1) {
startTime = idAndHash[1].split("t=")[1] != undefined ? idAndHash[1].split("t=")[1] : 0;
}
// enable localized player
var lang = getLangPref();
var captionsOn = lang == 'en' ? 0 : 1;
youTubePlayer = new YT.Player('youTubePlayer', {
height: videoHeight,
width: videoWidth,
videoId: idAndHash[0],
playerVars: {start: startTime, hl: lang, cc_load_policy: captionsOn},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
} else {
// reset the size in case the user adjusted the window since last play
youTubePlayer.setSize(videoWidth, videoHeight);
// if a video different from the one already playing was requested, cue it up
if (videoId != youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0]) {
youTubePlayer.cueVideoById(videoId);
}
youTubePlayer.playVideo();
}
}
function onPlayerReady(event) {
event.target.playVideo();
mPlayerPaused = false;
}
function closeVideo() {
try {
youTubePlayer.pauseVideo();
} catch(e) {
}
$("#video-container").fadeOut(200);
}
/* Track youtube playback for analytics */
function onPlayerStateChange(event) {
// Video starts, send the video ID
if (event.data == YT.PlayerState.PLAYING) {
if (mPlayerPaused) {
ga('send', 'event', 'Videos', 'Resume',
youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0]);
} else {
// track the start playing event so we know from which page the video was selected
ga('send', 'event', 'Videos', 'Start: ' +
youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0],
'on: ' + document.location.href);
}
mPlayerPaused = false;
}
// Video paused, send video ID and video elapsed time
if (event.data == YT.PlayerState.PAUSED) {
ga('send', 'event', 'Videos', 'Paused',
youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0],
youTubePlayer.getCurrentTime());
mPlayerPaused = true;
}
// Video finished, send video ID and video elapsed time
if (event.data == YT.PlayerState.ENDED) {
ga('send', 'event', 'Videos', 'Finished',
youTubePlayer.getVideoUrl().split('?v=')[1].split('&')[0].split('%')[0],
youTubePlayer.getCurrentTime());
mPlayerPaused = true;
}
}
function initExpandableNavItems(rootTag) { function initExpandableNavItems(rootTag) {
$(rootTag + ' li.nav-section .nav-section-header').click(function() { $(rootTag + ' li.nav-section .nav-section-header').click(function() {
var section = $(this).closest('li.nav-section'); var section = $(this).closest('li.nav-section');
@@ -658,7 +808,7 @@ function toggleFullscreen(enable) {
setTimeout(updateSidenavFixedWidth,delay); // need to wait a moment for css to switch setTimeout(updateSidenavFixedWidth,delay); // need to wait a moment for css to switch
enabled = false; enabled = false;
} }
writeCookie("fullscreen", enabled, null, null); writeCookie("fullscreen", enabled, null);
setNavBarLeftPos(); setNavBarLeftPos();
resizeNav(delay); resizeNav(delay);
updateSideNavPosition(); updateSideNavPosition();
@@ -819,7 +969,7 @@ function reInitScrollbars() {
function saveNavPanels() { function saveNavPanels() {
var basePath = getBaseUri(location.pathname); var basePath = getBaseUri(location.pathname);
var section = basePath.substring(1,basePath.indexOf("/",1)); var section = basePath.substring(1,basePath.indexOf("/",1));
writeCookie("height", resizePackagesNav.css("height"), section, null); writeCookie("height", resizePackagesNav.css("height"), section);
} }
@@ -900,16 +1050,12 @@ function readCookie(cookie) {
return 0; return 0;
} }
function writeCookie(cookie, val, section, expiration) { function writeCookie(cookie, val, section) {
if (val==undefined) return; if (val==undefined) return;
section = section == null ? "_" : "_"+section+"_"; section = section == null ? "_" : "_"+section+"_";
if (expiration == null) { var age = 2*365*24*60*60; // set max-age to 2 years
var date = new Date();
date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week
expiration = date.toGMTString();
}
var cookieValue = cookie_namespace + section + cookie + "=" + val var cookieValue = cookie_namespace + section + cookie + "=" + val
+ "; expires=" + expiration+"; path=/"; + "; max-age=" + age +"; path=/";
document.cookie = cookieValue; document.cookie = cookieValue;
} }
@@ -1149,9 +1295,7 @@ function swapNav() {
nav_pref = NAV_PREF_TREE; nav_pref = NAV_PREF_TREE;
init_default_navtree(toRoot); init_default_navtree(toRoot);
} }
var date = new Date(); writeCookie("nav", nav_pref, "reference");
date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
writeCookie("nav", nav_pref, "reference", date.toGMTString());
$("#nav-panels").toggle(); $("#nav-panels").toggle();
$("#panel-link").toggle(); $("#panel-link").toggle();
@@ -1219,11 +1363,7 @@ function changeNavLang(lang) {
} }
function changeLangPref(lang, submit) { function changeLangPref(lang, submit) {
var date = new Date(); writeCookie("pref_lang", lang, null);
expires = date.toGMTString(date.setTime(date.getTime()+(10*365*24*60*60*1000)));
// keep this for 50 years
//alert("expires: " + expires)
writeCookie("pref_lang", lang, null, expires);
// ####### TODO: Remove this condition once we're stable on devsite ####### // ####### TODO: Remove this condition once we're stable on devsite #######
// This condition is only needed if we still need to support legacy GAE server // This condition is only needed if we still need to support legacy GAE server
@@ -1642,8 +1782,8 @@ var gDocsListLength = 0;
function onSuggestionClick(link) { function onSuggestionClick(link) {
// When user clicks a suggested document, track it // When user clicks a suggested document, track it
ga('send', 'event', 'Suggestion Click', 'clicked: ' + $(link).text(), ga('send', 'event', 'Suggestion Click', 'clicked: ' + $(link).attr('href'),
'from: ' + $("#search_autocomplete").val()); 'query: ' + $("#search_autocomplete").val().toLowerCase());
} }
function set_item_selected($li, selected) function set_item_selected($li, selected)
@@ -1988,7 +2128,7 @@ function search_changed(e, kd, toroot)
// Search for matching JD docs // Search for matching JD docs
if (text.length >= 3) { if (text.length >= 2) {
// Regex to match only the beginning of a word // Regex to match only the beginning of a word
var textRegex = new RegExp("\\b" + text.toLowerCase(), "g"); var textRegex = new RegExp("\\b" + text.toLowerCase(), "g");
@@ -2616,8 +2756,8 @@ function addResultClickListeners() {
$("#searchResults a.gs-title").each(function(index, link) { $("#searchResults a.gs-title").each(function(index, link) {
// When user clicks enter for Google search results, track it // When user clicks enter for Google search results, track it
$(link).click(function() { $(link).click(function() {
ga('send', 'event', 'Google Click', 'clicked: ' + $(this).text(), ga('send', 'event', 'Google Click', 'clicked: ' + $(this).attr('href'),
'from: ' + $("#search_autocomplete").val()); 'query: ' + $("#search_autocomplete").val().toLowerCase());
}); });
}); });
} }
@@ -2732,10 +2872,7 @@ function changeApiLevel() {
selectedLevel = parseInt($("#apiLevelSelector option:selected").val()); selectedLevel = parseInt($("#apiLevelSelector option:selected").val());
toggleVisisbleApis(selectedLevel, "body"); toggleVisisbleApis(selectedLevel, "body");
var date = new Date(); writeCookie(API_LEVEL_COOKIE, selectedLevel, null);
date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
var expiration = date.toGMTString();
writeCookie(API_LEVEL_COOKIE, selectedLevel, null, expiration);
if (selectedLevel < minLevel) { if (selectedLevel < minLevel) {
var thing = ($("#jd-header").html().indexOf("package") != -1) ? "package" : "class"; var thing = ($("#jd-header").html().indexOf("package") != -1) ? "package" : "class";
@@ -4216,4 +4353,4 @@ function showSamples() {
} }
} }
} }
})(); })();

View File

@@ -3,6 +3,52 @@
<?cs call:preview_masthead() ?> <?cs call:preview_masthead() ?>
<?cs else ?> <?cs else ?>
<a name="top"></a> <a name="top"></a>
<!-- dialog to prompt lang pref change when loaded from hardcoded URL
<div id="langMessage" style="display:none">
<div>
<div class="lang en">
<p>You requested a page in English, would you like to proceed with this language setting?</p>
</div>
<div class="lang es">
<p>You requested a page in Spanish (Español), would you like to proceed with this language setting?</p>
</div>
<div class="lang ja">
<p>You requested a page in Japanese (), would you like to proceed with this language setting?</p>
</div>
<div class="lang ko">
<p>You requested a page in Korean (), would you like to proceed with this language setting?</p>
</div>
<div class="lang ru">
<p>You requested a page in Russian (Русский), would you like to proceed with this language setting?</p>
</div>
<div class="lang zh-cn">
<p>You requested a page in Simplified Chinese (), would you like to proceed with this language setting?</p>
</div>
<div class="lang zh-tw">
<p>You requested a page in Traditional Chinese (), would you like to proceed with this language setting?</p>
</div>
<a href="#" class="button yes" onclick="return false;">
<span class="lang en">Yes</span>
<span class="lang es"></span>
<span class="lang ja">Yes</span>
<span class="lang ko">Yes</span>
<span class="lang ru">Yes</span>
<span class="lang zh-cn"></span>
<span class="lang zh-tw"></span>
</a>
<a href="#" class="button" onclick="$('#langMessage').hide();return false;">
<span class="lang en">No</span>
<span class="lang es">No</span>
<span class="lang ja">No</span>
<span class="lang ko">No</span>
<span class="lang ru">No</span>
<span class="lang zh-cn"></span>
<span class="lang zh-tw"></span>
</a>
</div>
</div> -->
<?cs if:!devsite ?><?cs # leave out the global header for devsite; it is in devsite template ?> <?cs if:!devsite ?><?cs # leave out the global header for devsite; it is in devsite template ?>
<!-- Header --> <!-- Header -->
<div id="header-wrapper"> <div id="header-wrapper">
@@ -125,6 +171,7 @@
<li><a href="<?cs var:toroot ?>distribute/users/index.html">Get Users</a></li> <li><a href="<?cs var:toroot ?>distribute/users/index.html">Get Users</a></li>
<li><a href="<?cs var:toroot ?>distribute/engage/index.html">Engage &amp; Retain</a></li> <li><a href="<?cs var:toroot ?>distribute/engage/index.html">Engage &amp; Retain</a></li>
<li><a href="<?cs var:toroot ?>distribute/monetize/index.html">Monetize</a></li> <li><a href="<?cs var:toroot ?>distribute/monetize/index.html">Monetize</a></li>
<li><a href="<?cs var:toroot ?>distribute/analyze/index.html">Analyze</a></li>
<li><a href="<?cs var:toroot ?>distribute/tools/index.html">Tools &amp; Reference</a></li> <li><a href="<?cs var:toroot ?>distribute/tools/index.html">Tools &amp; Reference</a></li>
<li><a href="<?cs var:toroot ?>distribute/stories/index.html">Developer Stories</a></li> <li><a href="<?cs var:toroot ?>distribute/stories/index.html">Developer Stories</a></li>
</ul> </ul>
@@ -160,31 +207,20 @@
<div class="wrap" style="position:relative;z-index:1"> <div class="wrap" style="position:relative;z-index:1">
<?cs if:reference ?> <?cs if:reference ?>
<?cs # HIDE HELPOUTS RECRUIT BANNER
<a id="helpoutsLink" class="resource resource-card resource-card-6x2x3 resource-card-6x2 helpouts-card" <a id="helpoutsLink" class="resource resource-card resource-card-6x2x3 resource-card-6x2 helpouts-card"
href="http://helpouts.google.com/partner/landing/provider/googledevelopers" target="_blank"> href="http://helpouts.google.com/partner/landing/provider/googledevelopers?utm_source=dac&utm_medium=banner&utm_campaign=android_provider_banner3" target="_blank">
<div class="card-bg helpouts-card-bg"></div> <div class="card-bg helpouts-card-bg"></div>
<div class="card-info"> <div class="card-info">
<div class="helpouts-description"> <div class="helpouts-description">
<div class="text">Help developers solve problems<br/> <div class="text">Help Android Wear and TV developers<br/>
<span id="helpoutsLinkText" class="link-color" style="display:block;padding-top:5px;text-align:right">Learn more</span> <span id="helpoutsLinkText" class="link-color"
style="display:block;padding-top:5px;text-align:right">Learn more</span>
</div> </div>
</div> </div>
</div> </div>
</a> </a>
<script> # END HIDE HELPOUTS ?>
var textA = "LEARN MORE";
var linkA = "http://helpouts.google.com/partner/landing/provider/googledevelopers?utm_source=android_banner1&utm_medium=banner&utm_campaign=android_provider_banner1";
var textB = "SIGN UP NOW";
var linkB = "http://helpouts.google.com/partner/landing/provider/googledevelopers?utm_source=android_banner2&utm_medium=banner&utm_campaign=android_provider_banner2";
if (Math.floor(1/Math.random()) > 1) {
$("a#helpoutsLink").attr('href', linkA);
$("span#helpoutsLinkText").text(textA);
} else {
$("a#helpoutsLink").attr('href', linkB);
$("span#helpoutsLinkText").text(textB);
}
</script>
<?cs /if ?> <?cs /if ?>
<ul class="nav-x col-9 develop" style="width:100%"> <ul class="nav-x col-9 develop" style="width:100%">
@@ -233,7 +269,7 @@
</div> </div>
<!-- /Sendondary x-nav DEVELOP --> <!-- /Sendondary x-nav DEVELOP -->
<?cs elif:distribute || googleplay || essentials || users || engage || monetize || disttools || stories ?> <?cs elif:distribute || googleplay || essentials || users || engage || monetize || analyze || disttools || stories ?>
<!-- Secondary distribute x-nav --> <!-- Secondary distribute x-nav -->
<div id="nav-x"> <div id="nav-x">
<div class="wrap"> <div class="wrap">
@@ -249,6 +285,9 @@
<li class="monetize"><a href="<?cs var:toroot ?>distribute/monetize/index.html" <li class="monetize"><a href="<?cs var:toroot ?>distribute/monetize/index.html"
>Monetize</a> >Monetize</a>
</li> </li>
<li class="analyze"><a href="<?cs var:toroot ?>distribute/analyze/index.html"
>Analyze</a>
</li>
<li class="disttools"><a href="<?cs var:toroot ?>distribute/tools/index.html" <li class="disttools"><a href="<?cs var:toroot ?>distribute/tools/index.html"
>Tools</a> >Tools</a>
</li> </li>
@@ -346,4 +385,4 @@ color:#666;font-weight:100;font-size:27px;">L Developer Preview</h1></div>
?> ?>
<?cs /def ?> <?cs /def ?>

View File

@@ -112,6 +112,20 @@ def:engage_nav() ?>
</script> </script>
<?cs /def ?><?cs <?cs /def ?><?cs
def:analyze_nav() ?>
<div class="wrap clearfix" id="body-content">
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
<?cs include:"../../../../frameworks/base/docs/html/distribute/analyze/analyze_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
<script>
$(document).ready(function() {
scrollIntoView("devdoc-nav");
});
</script>
<?cs /def ?><?cs
def:monetize_nav() ?> def:monetize_nav() ?>
<div class="wrap clearfix" id="body-content"> <div class="wrap clearfix" id="body-content">
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement"> <div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
@@ -449,8 +463,8 @@ def:header_search_widget() ?>
<option value="ja"></option> <option value="ja"></option>
<option value="ko"></option> <option value="ko"></option>
<option value="ru">Русский</option> <option value="ru">Русский</option>
<option value="zh-cn"> ()</option> <option value="zh-cn">)</option>
<option value="zh-tw"> ()</option> <option value="zh-tw">)</option>
</select> </select>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
@@ -544,6 +558,8 @@ def:custom_left_nav() ?><?cs
call:engage_nav() ?><?cs call:engage_nav() ?><?cs
elif:monetize ?><?cs elif:monetize ?><?cs
call:monetize_nav() ?><?cs call:monetize_nav() ?><?cs
elif:analyze ?><?cs
call:analyze_nav() ?><?cs
elif:disttools ?><?cs elif:disttools ?><?cs
call:disttools_nav() ?><?cs call:disttools_nav() ?><?cs
elif:stories ?><?cs elif:stories ?><?cs

View File

@@ -194,10 +194,10 @@ include:"header.cs" ?>
<?cs include:"trailer.cs" ?> <?cs include:"trailer.cs" ?>
<script src="https://developer.android.com/ytblogger_lists_unified.js" type="text/javascript"></script> <script src="https://developer.android.com/ytblogger_lists_unified.js" type="text/javascript"></script>
<script src="<?cs var:toroot ?>jd_lists_unified.js?v=3" type="text/javascript"></script> <script src="<?cs var:toroot ?>jd_lists_unified.js?v=8" type="text/javascript"></script>
<script src="<?cs var:toroot ?>jd_extras.js?v=4" type="text/javascript"></script> <script src="<?cs var:toroot ?>jd_extras.js?v=9" type="text/javascript"></script>
<script src="<?cs var:toroot ?>jd_collections.js?v=4" type="text/javascript"></script> <script src="<?cs var:toroot ?>jd_collections.js?v=9" type="text/javascript"></script>
<script src="<?cs var:toroot ?>jd_tag_helpers.js?v=3" type="text/javascript"></script> <script src="<?cs var:toroot ?>jd_tag_helpers.js?v=5" type="text/javascript"></script>
</body> </body>
</html> </html>

View File

@@ -24,8 +24,8 @@
<meta name="Description" content="<?cs var:page.metaDescription ?>"><?cs <meta name="Description" content="<?cs var:page.metaDescription ?>"><?cs
/if ?> /if ?>
<link rel="shortcut icon" type="image/x-icon" href="<?cs var:toroot ?>favicon.ico" /> <link rel="shortcut icon" type="image/x-icon" href="<?cs var:toroot ?>favicon.ico" />
<title><?cs <title><?cs
if:page.title ?><?cs if:page.title ?><?cs
var:page.title ?> | <?cs var:page.title ?> | <?cs
/if ?>Android Developers</title> /if ?>Android Developers</title>
@@ -38,7 +38,7 @@ if:android.whichdoc != 'online' ?>http:<?cs
if:android.whichdoc != 'online' ?>http:<?cs if:android.whichdoc != 'online' ?>http:<?cs
/if ?>//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" /if ?>//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold"
title="roboto"> title="roboto">
<link href="<?cs var:toroot ?>assets/css/default.css?v=2" rel="stylesheet" type="text/css"> <link href="<?cs var:toroot ?>assets/css/default.css?v=5" rel="stylesheet" type="text/css">
<?cs if:reference && !(reference.gms || reference.gcm || preview) ?> <?cs if:reference && !(reference.gms || reference.gcm || preview) ?>
<!-- FULLSCREEN STYLESHEET --> <!-- FULLSCREEN STYLESHEET -->
@@ -62,7 +62,14 @@ else
var metaTags = [<?cs var:meta.tags ?>]; var metaTags = [<?cs var:meta.tags ?>];
var devsite = <?cs if:devsite ?>true<?cs else ?>false<?cs /if ?>; var devsite = <?cs if:devsite ?>true<?cs else ?>false<?cs /if ?>;
</script> </script>
<script src="<?cs var:toroot ?>assets/js/docs.js?v=2" type="text/javascript"></script> <script src="<?cs var:toroot ?>assets/js/docs.js?v=3" type="text/javascript"></script>
<?cs if:helpoutsWidget ?>
<script type="text/javascript" src="https://helpouts.google.com/ps/res/embed.js" defer async
data-helpouts-embed data-helpouts-vertical="programming"
data-helpouts-tags="<?cs var:page.tags ?>" data-helpouts-prefix="android"
data-helpouts-standalone="true"></script>
<?cs /if ?>
<script> <script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){

View File

@@ -6,7 +6,7 @@
<?cs each:anno = obj.showAnnotations ?> <?cs each:anno = obj.showAnnotations ?>
<?cs if:first(anno) ?> <?cs if:first(anno) ?>
<span class='annotation-message'> <span class='annotation-message'>
Included in documention by the annotations: Included in documentation by the annotations:
<?cs /if ?> <?cs /if ?>
@<?cs var:anno.type.label ?> @<?cs var:anno.type.label ?>
<?cs if:last(anno) == 0 ?> <?cs if:last(anno) == 0 ?>

View File

@@ -264,89 +264,25 @@
<h4><a href='' class="expandable" <div class="pax col-13 online" style="margin:0;">
onclick="toggleExpandable(this,'.pax');hideExpandable('.myide,.reqs');return false;"
>VIEW ALL DOWNLOADS AND SIZES</a></h4>
<div class="pax col-13 online" style="display:none;margin:0;"> <h3>SDK Tools Only</h3>
<p>If you prefer to use a different IDE or run the tools from the
command line or with build scripts, you can instead download the stand-alone Android SDK Tools.
These packages provide the basic SDK tools for app development, without an IDE.
Also see the <a href="<?cs var:toroot ?>tools/sdk/tools-notes.html">SDK tools release notes</a>.</p>
<p class="table-caption"><strong>ADT Bundle</strong></p>
<table class="download"> <table class="download">
<tr> <tr>
<th>Platform</th> <th>Platform</th>
<th>Package</th> <th>Package</th>
<th>Size</th> <th>Size</th>
<th>MD5 Checksum</th> <th>SHA-1 Checksum</th>
</tr> </tr>
<tr> <tr>
<td>Windows 32-bit</td> <td rowspan="2">Windows</td>
<td>
<a onClick="return onDownload(this)" id="win-bundle32"
href="https://dl.google.com/android/adt/<?cs var:sdk.win32_bundle_download ?>"><?cs var:sdk.win32_bundle_download ?></a>
</td>
<td><?cs var:sdk.win32_bundle_bytes ?> bytes</td>
<td><?cs var:sdk.win32_bundle_checksum ?></td>
</tr>
<tr>
<td>Windows 64-bit</td>
<td>
<a onClick="return onDownload(this)" id="win-bundle64"
href="https://dl.google.com/android/adt/<?cs var:sdk.win64_bundle_download ?>"><?cs var:sdk.win64_bundle_download ?></a>
</td>
<td><?cs var:sdk.win64_bundle_bytes ?> bytes</td>
<td><?cs var:sdk.win64_bundle_checksum ?></td>
</tr>
<tr>
<td><nobr>Mac OS X 64-bit</nobr></td>
<td>
<a onClick="return onDownload(this)" id="mac-bundle64"
href="https://dl.google.com/android/adt/<?cs var:sdk.mac64_bundle_download ?>"><?cs var:sdk.mac64_bundle_download ?></a>
</td>
<td><?cs var:sdk.mac64_bundle_bytes ?> bytes</td>
<td><?cs var:sdk.mac64_bundle_checksum ?></td>
</tr>
<tr>
<td>Linux 32-bit</td>
<td>
<a onClick="return onDownload(this)" id="linux-bundle32"
href="https://dl.google.com/android/adt/<?cs var:sdk.linux32_bundle_download ?>"><?cs var:sdk.linux32_bundle_download ?></a>
</td>
<td><?cs var:sdk.linux32_bundle_bytes ?> bytes</td>
<td><?cs var:sdk.linux32_bundle_checksum ?></td>
</tr>
<tr>
<td>Linux 64-bit</td>
<td>
<a onClick="return onDownload(this)" id="linux-bundle64"
href="https://dl.google.com/android/adt/<?cs var:sdk.linux64_bundle_download ?>"><?cs var:sdk.linux64_bundle_download ?></a>
</td>
<td><?cs var:sdk.linux64_bundle_bytes ?> bytes</td>
<td><?cs var:sdk.linux64_bundle_checksum ?></td>
</tr>
</table>
<p class="table-caption"><strong>SDK Tools Only</strong></p>
<table class="download">
<tr>
<th>Platform</th>
<th>Package</th>
<th>Size</th>
<th>MD5 Checksum</th>
</tr>
<tr>
<td rowspan="2">Windows<br>32 &amp; 64-bit</td>
<td>
<a onclick="return onDownload(this)" href="http://dl.google.com/android/<?cs var:sdk.win_download
?>"><?cs var:sdk.win_download ?></a>
</td>
<td><?cs var:sdk.win_bytes ?> bytes</td>
<td><?cs var:sdk.win_checksum ?></td>
</tr>
<tr>
<!-- blank TD from Windows rowspan -->
<td> <td>
<a onclick="return onDownload(this)" id="win-tools" href="http://dl.google.com/android/<?cs <a onclick="return onDownload(this)" id="win-tools" href="http://dl.google.com/android/<?cs
var:sdk.win_installer var:sdk.win_installer
@@ -356,7 +292,16 @@ var:sdk.win_installer
<td><?cs var:sdk.win_installer_checksum ?></td> <td><?cs var:sdk.win_installer_checksum ?></td>
</tr> </tr>
<tr> <tr>
<td><nobr>Mac OS X</nobr><br>32 &amp; 64-bit</td> <!-- blank TD from Windows rowspan -->
<td>
<a onclick="return onDownload(this)" href="http://dl.google.com/android/<?cs var:sdk.win_download
?>"><?cs var:sdk.win_download ?></a>
</td>
<td><?cs var:sdk.win_bytes ?> bytes</td>
<td><?cs var:sdk.win_checksum ?></td>
</tr>
<tr>
<td><nobr>Mac OS X</nobr></td>
<td> <td>
<a onclick="return onDownload(this)" id="mac-tools" href="http://dl.google.com/android/<?cs <a onclick="return onDownload(this)" id="mac-tools" href="http://dl.google.com/android/<?cs
var:sdk.mac_download var:sdk.mac_download
@@ -366,7 +311,7 @@ var:sdk.mac_download
<td><?cs var:sdk.mac_checksum ?></td> <td><?cs var:sdk.mac_checksum ?></td>
</tr> </tr>
<tr> <tr>
<td>Linux<br>32 &amp; 64-bit</td> <td>Linux</td>
<td> <td>
<a onclick="return onDownload(this)" id="linux-tools" href="http://dl.google.com/android/<?cs <a onclick="return onDownload(this)" id="linux-tools" href="http://dl.google.com/android/<?cs
var:sdk.linux_download var:sdk.linux_download
@@ -377,6 +322,79 @@ var:sdk.linux_download
</tr> </tr>
</table> </table>
<h3>All Android Studio Packages</h3>
<p>Select a specific Android Studio package for your platform. Also see the
<a href="<?cs var:toroot ?>tools/revisions/studio.html">Android Studio release notes</a>.</p>
<table class="download">
<tr>
<th>Platform</th>
<th>Package</th>
<th>Size</th>
<th>SHA-1 Checksum</th>
</tr>
<tr>
<td rowspan="3">Windows</td>
<td>
<a onclick="return onDownload(this)" id="win-bundle"
href="https://dl.google.com/dl/android/studio/install/<?cs var:studio.version ?>/<?cs var:studio.win_bundle_exe_download ?>"
><?cs var:studio.win_bundle_exe_download ?></a><br>(Recommended)
</td>
<td><?cs var:studio.win_bundle_exe_bytes ?> bytes</td>
<td><?cs var:studio.win_bundle_exe_checksum ?></td>
</tr>
<tr>
<!-- blank TD from Windows rowspan -->
<td>
<a onclick="return onDownload(this)"
href="https://dl.google.com/dl/android/studio/install/<?cs var:studio.version ?>/<?cs var:studio.win_notools_exe_download ?>"
><?cs var:studio.win_notools_exe_download ?></a><br>(No SDK tools included)
</td>
<td><?cs var:studio.win_notools_exe_bytes ?> bytes</td>
<td><?cs var:studio.win_notools_exe_checksum ?></td>
</tr>
<tr>
<!-- blank TD from Windows rowspan -->
<td>
<a onclick="return onDownload(this)"
href="https://dl.google.com/dl/android/studio/ide-zips/<?cs var:studio.version ?>/<?cs var:studio.win_bundle_download ?>"
><?cs var:studio.win_bundle_download ?></a>
</td>
<td><?cs var:studio.win_bundle_bytes ?> bytes</td>
<td><?cs var:studio.win_bundle_checksum ?></td>
</tr>
<tr>
<td><nobr>Mac OS X</nobr></td>
<td>
<a onclick="return onDownload(this)" id="mac-bundle"
href="https://dl.google.com/dl/android/studio/install/<?cs var:studio.version ?>/<?cs var:studio.mac_bundle_download ?>"
><?cs var:studio.mac_bundle_download ?></a>
</td>
<td><?cs var:studio.mac_bundle_bytes ?> bytes</td>
<td><?cs var:studio.mac_bundle_checksum ?></td>
</tr>
<tr>
<td>Linux</td>
<td>
<a onclick="return onDownload(this)" id="linux-bundle"
href="https://dl.google.com/dl/android/studio/ide-zips/<?cs var:studio.version ?>/<?cs var:studio.linux_bundle_download ?>"
><?cs var:studio.linux_bundle_download ?></a>
</td>
<td><?cs var:studio.linux_bundle_bytes ?> bytes</td>
<td><?cs var:studio.linux_bundle_checksum ?></td>
</tr>
</table>
</div><!-- end pax --> </div><!-- end pax -->
@@ -397,7 +415,9 @@ var:sdk.linux_download
var bundlename; var bundlename;
var $toolslink; var $toolslink;
if (navigator.appVersion.indexOf("Win")!=-1) { if (navigator.appVersion.indexOf("Mobile")!=-1) {
// Do nothing for any "mobile" user agent
} else if (navigator.appVersion.indexOf("Win")!=-1) {
os = "Windows"; os = "Windows";
bundlename = '#win-bundle'; bundlename = '#win-bundle';
$toolslink = $('#win-tools'); $toolslink = $('#win-tools');
@@ -405,26 +425,18 @@ var:sdk.linux_download
os = "Mac"; os = "Mac";
bundlename = '#mac-bundle'; bundlename = '#mac-bundle';
$toolslink = $('#mac-tools'); $toolslink = $('#mac-tools');
} else if (navigator.appVersion.indexOf("Linux")!=-1) { } else if (navigator.appVersion.indexOf("Linux")!=-1 && navigator.appVersion.indexOf("Android")==-1) {
os = "Linux"; os = "Linux";
bundlename = '#linux-bundle'; bundlename = '#linux-bundle';
$toolslink = $('#linux-tools'); $toolslink = $('#linux-tools');
} }
if (os) { if (os != undefined) {
$('#not-supported').hide(); $('#not-supported').hide();
/* set up primary adt download button */ /* set up primary Android Studio download button */
$('#download-bundle-button').show(); $('.download-bundle-button').append(" <br/><span class='small'>for " + os + "</span>");
$('#download-bundle-button').append("Download Eclipse ADT <br/><span class='small'>with the Android SDK for " + os + "</span>"); $('.download-bundle-button').click(function() {return onDownload(this,true,true);}).attr('href', bundlename);
$('#download-bundle-button').click(function() {return onDownload(this,true,true);}).attr('href', bundlename);
/* set up sdk tools only button */
$('#download-tools-button').show();
$('#download-tools-button').append("Download the stand-alone Android SDK Tools for " + os);
$('#download-tools-button').click(function() {return onDownload(this,true);}).attr('href', $toolslink.attr('href'));
} else {
$('.pax').show();
} }
@@ -437,44 +449,29 @@ var:sdk.linux_download
$("#downloadForRealz").html("Download " + $(link).text()); $("#downloadForRealz").html("Download " + $(link).text());
} }
/* if it's a bundle, show the 32/64-bit picker */ $("#downloadForRealz").attr('bundle', bundle);
if (bundle) { $("a#downloadForRealz").attr("name", $(link).attr('href'));
$("#downloadForRealz").attr('bundle','true');
if ($("#downloadForRealz").text().indexOf("Mac") == -1) {
$("p#bitpicker").show();
} else {
/* mac is always 64 bit, so set it checked */
$("p#bitpicker input[value=64]").attr('checked', true);
}
/* save link name until the bit version is chosen */
$("#downloadForRealz").attr('name',$(link).attr('href'));
} else {
/* if not using bundle, set download button to ignore bitpicker and set url */
$("#downloadForRealz").attr('bundle','false');
$("#downloadForRealz").attr('href',$(link).attr('href'));
/* set picker checked as a fake default */
$("p#bitpicker input[value=64]").attr('checked', true);
$("a#next-link").html("Setting Up an Existing IDE").attr('href',toRoot + 'sdk/installing/index.html');
}
$("#tos").fadeIn('fast'); $("#tos").show();
$("#landing").fadeOut('fast'); $("#landing").hide();
location.hash = "download"; location.hash = "top";
return false; return false;
} }
function onAgreeChecked() { function onAgreeChecked() {
/* verify that the TOS is agreed and a bit version is chosen */ /* verify that the TOS is agreed */
if ($("input#agree").is(":checked") && $("#bitpicker input:checked").length) { if ($("input#agree").is(":checked")) {
/* if downloading the bundle */ /* if downloading the bundle */
if ($("#downloadForRealz").attr('bundle')) { if ($("#downloadForRealz").attr('bundle')) {
/* construct the name of the link we want based on the bit version */ /* construct the name of the link we want */
linkId = $("a#downloadForRealz").attr("name") + $("#bitpicker input:checked").val(); linkId = $("a#downloadForRealz").attr("name");
/* set the real url for download */ /* set the real url for download */
$("a#downloadForRealz").attr("href", $(linkId).attr("href")); $("a#downloadForRealz").attr("href", $(linkId).attr("href"));
} else {
$("a#downloadForRealz").attr("href", $("a#downloadForRealz").attr("name"));
} }
/* reveal the download button */ /* reveal the download button */
@@ -485,25 +482,28 @@ var:sdk.linux_download
} }
function onDownloadForRealz(link) { function onDownloadForRealz(link) {
if ($("input#agree").is(':checked') && $("#bitpicker input:checked").length) { if ($("input#agree").is(':checked')) {
location.hash = "";
location.hash = "top";
$("div.sdk-terms").slideUp(); $("div.sdk-terms").slideUp();
$("h1#tos-header").text('Now redirecting to the install instructions...'); $("h1#tos-header").text('Now downloading...');
$("#sdk-terms-form,.sdk-terms-intro").fadeOut('slow', function() { $(".sdk-terms-intro").text('You\'ll be redirected to the install instructions in a moment.');
$("#sdk-terms-form").fadeOut('slow', function() {
setTimeout(function() { setTimeout(function() {
if ($("#downloadForRealz").attr('bundle') == 'true') { if ($("#downloadForRealz").attr('bundle') == 'true') {
// User downloaded the ADT Bundle // User downloaded the studio Bundle
window.location = "/sdk/installing/index.html?pkg=adt"; window.location = "/sdk/installing/index.html?pkg=studio";
} else { } else {
// User downloaded the SDK Tools // User downloaded the SDK Tools
window.location = "/sdk/installing/index.html?pkg=tools"; window.location = "/sdk/installing/index.html?pkg=tools";
} }
}, 500); }, 3000);
}); });
ga('send', 'event', 'SDK', 'IDE and Tools', $("#downloadForRealz").html()); ga('send', 'event', 'SDK', 'IDE and Tools', $("#downloadForRealz").html());
return true; return true;
} else { } else {
$("label#agreeLabel,#bitpicker input").parent().stop().animate({color: "#258AAF"}, 200, $("label#agreeLabel").parent().stop().animate({color: "#258AAF"}, 200,
function() {$("label#agreeLabel,#bitpicker input").parent().stop().animate({color: "#222"}, 200)} function() {$("label#agreeLabel").parent().stop().animate({color: "#222"}, 200)}
); );
return false; return false;
} }

View File

@@ -45,10 +45,28 @@ import common
OPTIONS = common.OPTIONS OPTIONS = common.OPTIONS
OPTIONS.add_missing = False
OPTIONS.rebuild_recovery = False
def AddSystem(output_zip, prefix="IMAGES/"): 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 """Turn the contents of SYSTEM into a system image and store it in
output_zip.""" output_zip."""
prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "system.img")
if os.path.exists(prebuilt_path):
print "system.img already exists in %s, no need to rebuild..." % (prefix,)
return
def output_sink(fn, data):
ofile = open(os.path.join(OPTIONS.input_tmp,"SYSTEM",fn), "w")
ofile.write(data)
ofile.close()
if OPTIONS.rebuild_recovery:
print("Building new recovery patch")
common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink, recovery_img, boot_img,
info_dict=OPTIONS.info_dict)
block_list = common.MakeTempFile(prefix="system-blocklist-", suffix=".map") block_list = common.MakeTempFile(prefix="system-blocklist-", suffix=".map")
imgname = BuildSystem(OPTIONS.input_tmp, OPTIONS.info_dict, imgname = BuildSystem(OPTIONS.input_tmp, OPTIONS.info_dict,
block_list=block_list) block_list=block_list)
@@ -67,6 +85,12 @@ def BuildSystem(input_dir, info_dict, block_list=None):
def AddVendor(output_zip, prefix="IMAGES/"): def AddVendor(output_zip, prefix="IMAGES/"):
"""Turn the contents of VENDOR into a vendor image and store in it """Turn the contents of VENDOR into a vendor image and store in it
output_zip.""" output_zip."""
prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "vendor.img")
if os.path.exists(prebuilt_path):
print "vendor.img already exists in %s, no need to rebuild..." % (prefix,)
return
block_list = common.MakeTempFile(prefix="vendor-blocklist-", suffix=".map") block_list = common.MakeTempFile(prefix="vendor-blocklist-", suffix=".map")
imgname = BuildVendor(OPTIONS.input_tmp, OPTIONS.info_dict, imgname = BuildVendor(OPTIONS.input_tmp, OPTIONS.info_dict,
block_list=block_list) block_list=block_list)
@@ -131,6 +155,11 @@ def CreateImage(input_dir, info_dict, what, block_list=None):
def AddUserdata(output_zip, prefix="IMAGES/"): def AddUserdata(output_zip, prefix="IMAGES/"):
"""Create an empty userdata image and store it in output_zip.""" """Create an empty userdata image and store it in output_zip."""
prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "userdata.img")
if os.path.exists(prebuilt_path):
print "userdata.img already exists in %s, no need to rebuild..." % (prefix,)
return
image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict, image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict,
"data") "data")
# We only allow yaffs to have a 0/missing partition_size. # We only allow yaffs to have a 0/missing partition_size.
@@ -165,6 +194,11 @@ def AddUserdata(output_zip, prefix="IMAGES/"):
def AddCache(output_zip, prefix="IMAGES/"): def AddCache(output_zip, prefix="IMAGES/"):
"""Create an empty cache image and store it in output_zip.""" """Create an empty cache image and store it in output_zip."""
prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "cache.img")
if os.path.exists(prebuilt_path):
print "cache.img already exists in %s, no need to rebuild..." % (prefix,)
return
image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict, image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict,
"cache") "cache")
# The build system has to explicitly request for cache.img. # The build system has to explicitly request for cache.img.
@@ -197,10 +231,11 @@ def AddCache(output_zip, prefix="IMAGES/"):
def AddImagesToTargetFiles(filename): def AddImagesToTargetFiles(filename):
OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename) OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)
for n in input_zip.namelist(): if not OPTIONS.add_missing:
if n.startswith("IMAGES/"): for n in input_zip.namelist():
print "target_files appears to already contain images." if n.startswith("IMAGES/"):
sys.exit(1) print "target_files appears to already contain images."
sys.exit(1)
try: try:
input_zip.getinfo("VENDOR/") input_zip.getinfo("VENDOR/")
@@ -221,19 +256,35 @@ def AddImagesToTargetFiles(filename):
print "\n\n++++ " + s + " ++++\n\n" print "\n\n++++ " + s + " ++++\n\n"
banner("boot") banner("boot")
boot_image = common.GetBootableImage( prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
"IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT") boot_image = None
if boot_image: if os.path.exists(prebuilt_path):
boot_image.AddToZip(output_zip) print "boot.img already exists in IMAGES/, no need to rebuild..."
if OPTIONS.rebuild_recovery:
boot_image = common.GetBootableImage(
"IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
else:
boot_image = common.GetBootableImage(
"IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
if boot_image:
boot_image.AddToZip(output_zip)
banner("recovery") banner("recovery")
recovery_image = common.GetBootableImage( recovery_image = None
"IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY") prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "recovery.img")
if recovery_image: if os.path.exists(prebuilt_path):
recovery_image.AddToZip(output_zip) print "recovery.img already exists in IMAGES/, no need to rebuild..."
if OPTIONS.rebuild_recovery:
recovery_image = common.GetBootableImage(
"IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY")
else:
recovery_image = common.GetBootableImage(
"IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY")
if recovery_image:
recovery_image.AddToZip(output_zip)
banner("system") banner("system")
AddSystem(output_zip) AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image)
if has_vendor: if has_vendor:
banner("vendor") banner("vendor")
AddVendor(output_zip) AddVendor(output_zip)
@@ -244,9 +295,24 @@ def AddImagesToTargetFiles(filename):
output_zip.close() output_zip.close()
def main(argv): def main(argv):
args = common.ParseOptions(argv, __doc__)
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
else:
return False
return True
args = common.ParseOptions(argv, __doc__,
extra_opts="ar",
extra_long_opts=["add_missing",
"rebuild_recovery",
],
extra_option_handler=option_handler)
if len(args) != 1: if len(args) != 1:
common.Usage(__doc__) common.Usage(__doc__)

View File

@@ -16,6 +16,7 @@ from __future__ import print_function
from collections import deque, OrderedDict from collections import deque, OrderedDict
from hashlib import sha1 from hashlib import sha1
import heapq
import itertools import itertools
import multiprocessing import multiprocessing
import os import os
@@ -142,9 +143,16 @@ class Transfer(object):
self.goes_before = {} self.goes_before = {}
self.goes_after = {} self.goes_after = {}
self.stash_before = []
self.use_stash = []
self.id = len(by_id) self.id = len(by_id)
by_id.append(self) by_id.append(self)
def NetStashChange(self):
return (sum(sr.size() for (_, sr) in self.stash_before) -
sum(sr.size() for (_, sr) in self.use_stash))
def __str__(self): def __str__(self):
return (str(self.id) + ": <" + str(self.src_ranges) + " " + self.style + return (str(self.id) + ": <" + str(self.src_ranges) + " " + self.style +
" to " + str(self.tgt_ranges) + ">") " to " + str(self.tgt_ranges) + ">")
@@ -182,11 +190,14 @@ class Transfer(object):
# original image. # original image.
class BlockImageDiff(object): class BlockImageDiff(object):
def __init__(self, tgt, src=None, threads=None): def __init__(self, tgt, src=None, threads=None, version=2):
if threads is None: if threads is None:
threads = multiprocessing.cpu_count() // 2 threads = multiprocessing.cpu_count() // 2
if threads == 0: threads = 1 if threads == 0: threads = 1
self.threads = threads self.threads = threads
self.version = version
assert version in (1, 2)
self.tgt = tgt self.tgt = tgt
if src is None: if src is None:
@@ -221,7 +232,12 @@ class BlockImageDiff(object):
self.FindVertexSequence() self.FindVertexSequence()
# Fix up the ordering dependencies that the sequence didn't # Fix up the ordering dependencies that the sequence didn't
# satisfy. # satisfy.
self.RemoveBackwardEdges() if self.version == 1:
self.RemoveBackwardEdges()
else:
self.ReverseBackwardEdges()
self.ImproveVertexSequence()
# Double-check our work. # Double-check our work.
self.AssertSequenceGood() self.AssertSequenceGood()
@@ -231,18 +247,87 @@ class BlockImageDiff(object):
def WriteTransfers(self, prefix): def WriteTransfers(self, prefix):
out = [] out = []
out.append("1\n") # format version number
total = 0 total = 0
performs_read = False performs_read = False
stashes = {}
stashed_blocks = 0
max_stashed_blocks = 0
free_stash_ids = []
next_stash_id = 0
for xf in self.transfers: for xf in self.transfers:
# zero [rangeset] if self.version < 2:
# new [rangeset] assert not xf.stash_before
# bsdiff patchstart patchlen [src rangeset] [tgt rangeset] assert not xf.use_stash
# imgdiff patchstart patchlen [src rangeset] [tgt rangeset]
# move [src rangeset] [tgt rangeset] for s, sr in xf.stash_before:
# erase [rangeset] assert s not in stashes
if free_stash_ids:
sid = heapq.heappop(free_stash_ids)
else:
sid = next_stash_id
next_stash_id += 1
stashes[s] = sid
stashed_blocks += sr.size()
out.append("stash %d %s\n" % (sid, sr.to_string_raw()))
if stashed_blocks > max_stashed_blocks:
max_stashed_blocks = stashed_blocks
if self.version == 1:
src_string = xf.src_ranges.to_string_raw()
elif self.version == 2:
# <# blocks> <src ranges>
# OR
# <# blocks> <src ranges> <src locs> <stash refs...>
# OR
# <# blocks> - <stash refs...>
size = xf.src_ranges.size()
src_string = [str(size)]
unstashed_src_ranges = xf.src_ranges
mapped_stashes = []
for s, sr in xf.use_stash:
sid = stashes.pop(s)
stashed_blocks -= sr.size()
unstashed_src_ranges = unstashed_src_ranges.subtract(sr)
sr = xf.src_ranges.map_within(sr)
mapped_stashes.append(sr)
src_string.append("%d:%s" % (sid, sr.to_string_raw()))
heapq.heappush(free_stash_ids, sid)
if unstashed_src_ranges:
src_string.insert(1, unstashed_src_ranges.to_string_raw())
if xf.use_stash:
mapped_unstashed = xf.src_ranges.map_within(unstashed_src_ranges)
src_string.insert(2, mapped_unstashed.to_string_raw())
mapped_stashes.append(mapped_unstashed)
self.AssertPartition(RangeSet(data=(0, size)), mapped_stashes)
else:
src_string.insert(1, "-")
self.AssertPartition(RangeSet(data=(0, size)), mapped_stashes)
src_string = " ".join(src_string)
# both versions:
# zero <rangeset>
# new <rangeset>
# erase <rangeset>
#
# version 1:
# bsdiff patchstart patchlen <src rangeset> <tgt rangeset>
# imgdiff patchstart patchlen <src rangeset> <tgt rangeset>
# move <src rangeset> <tgt rangeset>
#
# version 2:
# bsdiff patchstart patchlen <tgt rangeset> <src_string>
# imgdiff patchstart patchlen <tgt rangeset> <src_string>
# move <tgt rangeset> <src_string>
tgt_size = xf.tgt_ranges.size() tgt_size = xf.tgt_ranges.size()
@@ -255,17 +340,27 @@ class BlockImageDiff(object):
assert xf.tgt_ranges assert xf.tgt_ranges
assert xf.src_ranges.size() == tgt_size assert xf.src_ranges.size() == tgt_size
if xf.src_ranges != xf.tgt_ranges: if xf.src_ranges != xf.tgt_ranges:
out.append("%s %s %s\n" % ( if self.version == 1:
xf.style, out.append("%s %s %s\n" % (
xf.src_ranges.to_string_raw(), xf.tgt_ranges.to_string_raw())) xf.style,
xf.src_ranges.to_string_raw(), xf.tgt_ranges.to_string_raw()))
elif self.version == 2:
out.append("%s %s %s\n" % (
xf.style,
xf.tgt_ranges.to_string_raw(), src_string))
total += tgt_size total += tgt_size
elif xf.style in ("bsdiff", "imgdiff"): elif xf.style in ("bsdiff", "imgdiff"):
performs_read = True performs_read = True
assert xf.tgt_ranges assert xf.tgt_ranges
assert xf.src_ranges assert xf.src_ranges
out.append("%s %d %d %s %s\n" % ( if self.version == 1:
xf.style, xf.patch_start, xf.patch_len, out.append("%s %d %d %s %s\n" % (
xf.src_ranges.to_string_raw(), xf.tgt_ranges.to_string_raw())) xf.style, xf.patch_start, xf.patch_len,
xf.src_ranges.to_string_raw(), xf.tgt_ranges.to_string_raw()))
elif self.version == 2:
out.append("%s %d %d %s %s\n" % (
xf.style, xf.patch_start, xf.patch_len,
xf.tgt_ranges.to_string_raw(), src_string))
total += tgt_size total += tgt_size
elif xf.style == "zero": elif xf.style == "zero":
assert xf.tgt_ranges assert xf.tgt_ranges
@@ -276,7 +371,10 @@ class BlockImageDiff(object):
else: else:
raise ValueError, "unknown transfer style '%s'\n" % (xf.style,) raise ValueError, "unknown transfer style '%s'\n" % (xf.style,)
out.insert(1, str(total) + "\n")
# 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)
all_tgt = RangeSet(data=(0, self.tgt.total_blocks)) all_tgt = RangeSet(data=(0, self.tgt.total_blocks))
if performs_read: if performs_read:
@@ -289,12 +387,24 @@ class BlockImageDiff(object):
else: else:
# if nothing is read (ie, this is a full OTA), then we can start # if nothing is read (ie, this is a full OTA), then we can start
# by erasing the entire partition. # by erasing the entire partition.
out.insert(2, "erase %s\n" % (all_tgt.to_string_raw(),)) out.insert(0, "erase %s\n" % (all_tgt.to_string_raw(),))
out.insert(0, "%d\n" % (self.version,)) # format version number
out.insert(1, str(total) + "\n")
if self.version >= 2:
# version 2 only: after the total block count, we give the number
# of stash slots needed, and the maximum size needed (in blocks)
out.insert(2, str(next_stash_id) + "\n")
out.insert(3, str(max_stashed_blocks) + "\n")
with open(prefix + ".transfer.list", "wb") as f: with open(prefix + ".transfer.list", "wb") as f:
for i in out: for i in out:
f.write(i) f.write(i)
if self.version >= 2:
print("max stashed blocks: %d (%d bytes)\n" % (
max_stashed_blocks, max_stashed_blocks * self.tgt.blocksize))
def ComputePatches(self, prefix): def ComputePatches(self, prefix):
print("Reticulating splines...") print("Reticulating splines...")
diff_q = [] diff_q = []
@@ -409,7 +519,13 @@ class BlockImageDiff(object):
# Imagine processing the transfers in order. # Imagine processing the transfers in order.
for xf in self.transfers: for xf in self.transfers:
# Check that the input blocks for this transfer haven't yet been touched. # Check that the input blocks for this transfer haven't yet been touched.
assert not touched.overlaps(xf.src_ranges)
x = xf.src_ranges
if self.version >= 2:
for _, sr in xf.use_stash:
x = x.subtract(sr)
assert not touched.overlaps(x)
# Check that the output blocks for this transfer haven't yet been touched. # Check that the output blocks for this transfer haven't yet been touched.
assert not touched.overlaps(xf.tgt_ranges) assert not touched.overlaps(xf.tgt_ranges)
# Touch all the blocks written by this transfer. # Touch all the blocks written by this transfer.
@@ -418,6 +534,47 @@ class BlockImageDiff(object):
# Check that we've written every target block. # Check that we've written every target block.
assert touched == self.tgt.care_map assert touched == self.tgt.care_map
def ImproveVertexSequence(self):
print("Improving vertex order...")
# At this point our digraph is acyclic; we reversed any edges that
# were backwards in the heuristically-generated sequence. The
# previously-generated order is still acceptable, but we hope to
# find a better order that needs less memory for stashed data.
# Now we do a topological sort to generate a new vertex order,
# using a greedy algorithm to choose which vertex goes next
# whenever we have a choice.
# Make a copy of the edge set; this copy will get destroyed by the
# algorithm.
for xf in self.transfers:
xf.incoming = xf.goes_after.copy()
xf.outgoing = xf.goes_before.copy()
L = [] # the new vertex order
# S is the set of sources in the remaining graph; we always choose
# the one that leaves the least amount of stashed data after it's
# executed.
S = [(u.NetStashChange(), u.order, u) for u in self.transfers
if not u.incoming]
heapq.heapify(S)
while S:
_, _, xf = heapq.heappop(S)
L.append(xf)
for u in xf.outgoing:
del u.incoming[xf]
if not u.incoming:
heapq.heappush(S, (u.NetStashChange(), u.order, u))
# if this fails then our graph had a cycle.
assert len(L) == len(self.transfers)
self.transfers = L
for i, xf in enumerate(L):
xf.order = i
def RemoveBackwardEdges(self): def RemoveBackwardEdges(self):
print("Removing backward edges...") print("Removing backward edges...")
in_order = 0 in_order = 0
@@ -425,19 +582,17 @@ class BlockImageDiff(object):
lost_source = 0 lost_source = 0
for xf in self.transfers: for xf in self.transfers:
io = 0
ooo = 0
lost = 0 lost = 0
size = xf.src_ranges.size() size = xf.src_ranges.size()
for u in xf.goes_before: for u in xf.goes_before:
# xf should go before u # xf should go before u
if xf.order < u.order: if xf.order < u.order:
# it does, hurray! # it does, hurray!
io += 1 in_order += 1
else: else:
# it doesn't, boo. trim the blocks that u writes from xf's # it doesn't, boo. trim the blocks that u writes from xf's
# source, so that xf can go after u. # source, so that xf can go after u.
ooo += 1 out_of_order += 1
assert xf.src_ranges.overlaps(u.tgt_ranges) assert xf.src_ranges.overlaps(u.tgt_ranges)
xf.src_ranges = xf.src_ranges.subtract(u.tgt_ranges) xf.src_ranges = xf.src_ranges.subtract(u.tgt_ranges)
xf.intact = False xf.intact = False
@@ -448,8 +603,6 @@ class BlockImageDiff(object):
lost = size - xf.src_ranges.size() lost = size - xf.src_ranges.size()
lost_source += lost lost_source += lost
in_order += io
out_of_order += ooo
print((" %d/%d dependencies (%.2f%%) were violated; " print((" %d/%d dependencies (%.2f%%) were violated; "
"%d source blocks removed.") % "%d source blocks removed.") %
@@ -458,6 +611,48 @@ class BlockImageDiff(object):
if (in_order + out_of_order) else 0.0, if (in_order + out_of_order) else 0.0,
lost_source)) lost_source))
def ReverseBackwardEdges(self):
print("Reversing backward edges...")
in_order = 0
out_of_order = 0
stashes = 0
stash_size = 0
for xf in self.transfers:
lost = 0
size = xf.src_ranges.size()
for u in xf.goes_before.copy():
# xf should go before u
if xf.order < u.order:
# it does, hurray!
in_order += 1
else:
# it doesn't, boo. modify u to stash the blocks that it
# writes that xf wants to read, and then require u to go
# before xf.
out_of_order += 1
overlap = xf.src_ranges.intersect(u.tgt_ranges)
assert overlap
u.stash_before.append((stashes, overlap))
xf.use_stash.append((stashes, overlap))
stashes += 1
stash_size += overlap.size()
# reverse the edge direction; now xf must go after u
del xf.goes_before[u]
del u.goes_after[xf]
xf.goes_after[u] = None # value doesn't matter
u.goes_before[xf] = None
print((" %d/%d dependencies (%.2f%%) were violated; "
"%d source blocks stashed.") %
(out_of_order, in_order + out_of_order,
(out_of_order * 100.0 / (in_order + out_of_order))
if (in_order + out_of_order) else 0.0,
stash_size))
def FindVertexSequence(self): def FindVertexSequence(self):
print("Finding vertex sequence...") print("Finding vertex sequence...")

View File

@@ -160,7 +160,7 @@ def MakeVerityEnabledImage(out_file, prop_dict):
# get properties # get properties
image_size = prop_dict["partition_size"] image_size = prop_dict["partition_size"]
block_dev = prop_dict["verity_block_device"] block_dev = prop_dict["verity_block_device"]
signer_key = prop_dict["verity_key"] signer_key = prop_dict["verity_key"] + ".pk8"
signer_path = prop_dict["verity_signer_cmd"] signer_path = prop_dict["verity_signer_cmd"]
# make a tempdir # make a tempdir
@@ -240,6 +240,8 @@ def BuildImage(in_dir, prop_dict, out_file,
build_command.extend([in_dir, out_file, fs_type, build_command.extend([in_dir, out_file, fs_type,
prop_dict["mount_point"]]) prop_dict["mount_point"]])
build_command.append(prop_dict["partition_size"]) build_command.append(prop_dict["partition_size"])
if "journal_size" in prop_dict:
build_command.extend(["-j", prop_dict["journal_size"]])
if "timestamp" in prop_dict: if "timestamp" in prop_dict:
build_command.extend(["-T", str(prop_dict["timestamp"])]) build_command.extend(["-T", str(prop_dict["timestamp"])])
if fs_config is not None: if fs_config is not None:
@@ -320,6 +322,7 @@ def ImagePropFromGlobalDict(glob_dict, mount_point):
if mount_point == "system": if mount_point == "system":
copy_prop("fs_type", "fs_type") copy_prop("fs_type", "fs_type")
copy_prop("system_size", "partition_size") copy_prop("system_size", "partition_size")
copy_prop("system_journal_size", "journal_size")
copy_prop("system_verity_block_device", "verity_block_device") copy_prop("system_verity_block_device", "verity_block_device")
elif mount_point == "data": elif mount_point == "data":
# Copy the generic fs type first, override with specific one if available. # Copy the generic fs type first, override with specific one if available.
@@ -332,10 +335,12 @@ def ImagePropFromGlobalDict(glob_dict, mount_point):
elif mount_point == "vendor": elif mount_point == "vendor":
copy_prop("vendor_fs_type", "fs_type") copy_prop("vendor_fs_type", "fs_type")
copy_prop("vendor_size", "partition_size") copy_prop("vendor_size", "partition_size")
copy_prop("vendor_journal_size", "journal_size")
copy_prop("vendor_verity_block_device", "verity_block_device") copy_prop("vendor_verity_block_device", "verity_block_device")
elif mount_point == "oem": elif mount_point == "oem":
copy_prop("fs_type", "fs_type") copy_prop("fs_type", "fs_type")
copy_prop("oem_size", "partition_size") copy_prop("oem_size", "partition_size")
copy_prop("oem_journal_size", "journal_size")
return d return d

View File

@@ -347,7 +347,7 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None):
if info_dict.get("verity_key", None): if info_dict.get("verity_key", None):
path = "/" + os.path.basename(sourcedir).lower() path = "/" + os.path.basename(sourcedir).lower()
cmd = ["boot_signer", path, img.name, info_dict["verity_key"], img.name] cmd = ["boot_signer", path, img.name, info_dict["verity_key"] + ".pk8", info_dict["verity_key"] + ".x509.pem", img.name]
p = Run(cmd, stdout=subprocess.PIPE) p = Run(cmd, stdout=subprocess.PIPE)
p.communicate() p.communicate()
assert p.returncode == 0, "boot_signer of %s image failed" % path assert p.returncode == 0, "boot_signer of %s image failed" % path
@@ -1030,7 +1030,14 @@ class BlockDifference:
self.partition = partition self.partition = partition
self.check_first_block = check_first_block self.check_first_block = check_first_block
b = blockimgdiff.BlockImageDiff(tgt, src, threads=OPTIONS.worker_threads) version = 1
if OPTIONS.info_dict:
version = max(
int(i) for i in
OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
b = blockimgdiff.BlockImageDiff(tgt, src, threads=OPTIONS.worker_threads,
version=version)
tmpdir = tempfile.mkdtemp() tmpdir = tempfile.mkdtemp()
OPTIONS.tempfiles.append(tmpdir) OPTIONS.tempfiles.append(tmpdir)
self.path = os.path.join(tmpdir, partition) self.path = os.path.join(tmpdir, partition)
@@ -1041,9 +1048,16 @@ class BlockDifference:
def WriteScript(self, script, output_zip, progress=None): def WriteScript(self, script, output_zip, progress=None):
if not self.src: if not self.src:
# write the output unconditionally # write the output unconditionally
if progress: script.ShowProgress(progress, 0) script.Print("Patching %s image unconditionally..." % (self.partition,))
self._WriteUpdate(script, output_zip) else:
script.Print("Patching %s image after verification." % (self.partition,))
if progress: script.ShowProgress(progress, 0)
self._WriteUpdate(script, output_zip)
def WriteVerifyScript(self, script):
if not self.src:
script.Print("Image %s will be patched unconditionally." % (self.partition,))
else: else:
if self.check_first_block: if self.check_first_block:
self._CheckFirstBlock(script) self._CheckFirstBlock(script)
@@ -1051,9 +1065,7 @@ class BlockDifference:
script.AppendExtra('if range_sha1("%s", "%s") == "%s" then' % script.AppendExtra('if range_sha1("%s", "%s") == "%s" then' %
(self.device, self.src.care_map.to_string_raw(), (self.device, self.src.care_map.to_string_raw(),
self.src.TotalSha1())) self.src.TotalSha1()))
script.Print("Patching %s image..." % (self.partition,)) script.Print("Verified %s image..." % (self.partition,))
if progress: script.ShowProgress(progress, 0)
self._WriteUpdate(script, output_zip)
script.AppendExtra(('else\n' script.AppendExtra(('else\n'
' (range_sha1("%s", "%s") == "%s") ||\n' ' (range_sha1("%s", "%s") == "%s") ||\n'
' abort("%s partition has unexpected contents");\n' ' abort("%s partition has unexpected contents");\n'

View File

@@ -164,14 +164,25 @@ class EdifyGenerator(object):
self.script.append(('apply_patch_space(%d) || abort("Not enough free space ' self.script.append(('apply_patch_space(%d) || abort("Not enough free space '
'on /system to apply patches.");') % (amount,)) 'on /system to apply patches.");') % (amount,))
def Mount(self, mount_point): def Mount(self, mount_point, mount_options_by_format=""):
"""Mount the partition with the given mount_point.""" """Mount the partition with the given mount_point.
mount_options_by_format:
[fs_type=option[,option]...[|fs_type=option[,option]...]...]
where option is optname[=optvalue]
E.g. ext4=barrier=1,nodelalloc,errors=panic|f2fs=errors=recover
"""
fstab = self.info.get("fstab", None) fstab = self.info.get("fstab", None)
if fstab: if fstab:
p = fstab[mount_point] p = fstab[mount_point]
self.script.append('mount("%s", "%s", "%s", "%s");' % mount_dict = {}
if mount_options_by_format is not None:
for option in mount_options_by_format.split("|"):
if "=" in option:
key, value = option.split("=", 1)
mount_dict[key] = value
self.script.append('mount("%s", "%s", "%s", "%s", "%s");' %
(p.fs_type, common.PARTITION_TYPES[p.fs_type], (p.fs_type, common.PARTITION_TYPES[p.fs_type],
p.device, p.mount_point)) p.device, p.mount_point, mount_dict.get(p.fs_type, "")))
self.mounts.add(p.mount_point) self.mounts.add(p.mount_point)
def UnpackPackageDir(self, src, dst): def UnpackPackageDir(self, src, dst):
@@ -190,6 +201,17 @@ class EdifyGenerator(object):
"""Log a message to the screen (if the logs are visible).""" """Log a message to the screen (if the logs are visible)."""
self.script.append('ui_print("%s");' % (message,)) self.script.append('ui_print("%s");' % (message,))
def TunePartition(self, partition, *options):
fstab = self.info.get("fstab", None)
if fstab:
p = fstab[partition]
if (p.fs_type not in ( "ext2", "ext3", "ext4")):
raise ValueError("Partition %s cannot be tuned\n" % (partition,))
self.script.append('tune2fs(' +
"".join(['"%s", ' % (i,) for i in options]) +
'"%s") || abort("Failed to tune partition %s");'
% ( p.device,partition));
def FormatPartition(self, partition): def FormatPartition(self, partition):
"""Format the given partition, specified by its mount point (eg, """Format the given partition, specified by its mount point (eg,
"/system").""" "/system")."""
@@ -312,6 +334,10 @@ class EdifyGenerator(object):
"""Append text verbatim to the output script.""" """Append text verbatim to the output script."""
self.script.append(extra) self.script.append(extra)
def Unmount(self, mount_point):
self.script.append('unmount("%s");' % (mount_point,))
self.mounts.remove(mount_point);
def UnmountAll(self): def UnmountAll(self):
for p in sorted(self.mounts): for p in sorted(self.mounts):
self.script.append('unmount("%s");' % (p,)) self.script.append('unmount("%s");' % (p,))

View File

@@ -37,6 +37,10 @@ Usage: ota_from_target_files [flags] input_target_files output_ota_package
Generate an incremental OTA using the given target-files zip as Generate an incremental OTA using the given target-files zip as
the starting build. the starting build.
-v (--verify)
Remount and verify the checksums of the files written to the
system and vendor (if used) partitions. Incremental builds only.
-o (--oem_settings) <file> -o (--oem_settings) <file>
Use the file to specify the expected OEM-specific properties Use the file to specify the expected OEM-specific properties
on the OEM partition of the intended device. on the OEM partition of the intended device.
@@ -104,6 +108,7 @@ import sparse_img
OPTIONS = common.OPTIONS OPTIONS = common.OPTIONS
OPTIONS.package_key = None OPTIONS.package_key = None
OPTIONS.incremental_source = None OPTIONS.incremental_source = None
OPTIONS.verify = False
OPTIONS.require_verbatim = set() OPTIONS.require_verbatim = set()
OPTIONS.prohibit_verbatim = set(("system/build.prop",)) OPTIONS.prohibit_verbatim = set(("system/build.prop",))
OPTIONS.patch_threshold = 0.95 OPTIONS.patch_threshold = 0.95
@@ -462,11 +467,12 @@ def WriteFullOTAPackage(input_zip, output_zip):
script = edify_generator.EdifyGenerator(3, OPTIONS.info_dict) script = edify_generator.EdifyGenerator(3, OPTIONS.info_dict)
oem_props = OPTIONS.info_dict.get("oem_fingerprint_properties") oem_props = OPTIONS.info_dict.get("oem_fingerprint_properties")
recovery_mount_options = OPTIONS.info_dict.get("recovery_mount_options")
oem_dict = None oem_dict = None
if oem_props is not None and len(oem_props) > 0: if oem_props is not None and len(oem_props) > 0:
if OPTIONS.oem_source is None: if OPTIONS.oem_source is None:
raise common.ExternalError("OEM source required for this build") raise common.ExternalError("OEM source required for this build")
script.Mount("/oem") script.Mount("/oem", recovery_mount_options)
oem_dict = common.LoadDictionaryFromLines(open(OPTIONS.oem_source).readlines()) oem_dict = common.LoadDictionaryFromLines(open(OPTIONS.oem_source).readlines())
metadata = {"post-build": CalculateFingerprint( metadata = {"post-build": CalculateFingerprint(
@@ -527,13 +533,13 @@ def WriteFullOTAPackage(input_zip, output_zip):
bcb_dev = {"bcb_dev": fs.device} bcb_dev = {"bcb_dev": fs.device}
common.ZipWriteStr(output_zip, "recovery.img", recovery_img.data) common.ZipWriteStr(output_zip, "recovery.img", recovery_img.data)
script.AppendExtra(""" script.AppendExtra("""
if get_stage("%(bcb_dev)s", "stage") == "2/3" then if get_stage("%(bcb_dev)s") == "2/3" then
""" % bcb_dev) """ % bcb_dev)
script.WriteRawImage("/recovery", "recovery.img") script.WriteRawImage("/recovery", "recovery.img")
script.AppendExtra(""" script.AppendExtra("""
set_stage("%(bcb_dev)s", "3/3"); set_stage("%(bcb_dev)s", "3/3");
reboot_now("%(bcb_dev)s", "recovery"); reboot_now("%(bcb_dev)s", "recovery");
else if get_stage("%(bcb_dev)s", "stage") == "3/3" then else if get_stage("%(bcb_dev)s") == "3/3" then
""" % bcb_dev) """ % bcb_dev)
device_specific.FullOTA_InstallBegin() device_specific.FullOTA_InstallBegin()
@@ -548,8 +554,11 @@ else if get_stage("%(bcb_dev)s", "stage") == "3/3" then
if "selinux_fc" in OPTIONS.info_dict: if "selinux_fc" in OPTIONS.info_dict:
WritePolicyConfig(OPTIONS.info_dict["selinux_fc"], output_zip) WritePolicyConfig(OPTIONS.info_dict["selinux_fc"], output_zip)
recovery_mount_options = OPTIONS.info_dict.get("recovery_mount_options")
system_items = ItemSet("system", "META/filesystem_config.txt") system_items = ItemSet("system", "META/filesystem_config.txt")
script.ShowProgress(system_progress, 0) script.ShowProgress(system_progress, 0)
if block_based: if block_based:
# Full OTA is done as an "incremental" against an empty source # Full OTA is done as an "incremental" against an empty source
# image. This has the effect of writing new data from the package # image. This has the effect of writing new data from the package
@@ -561,7 +570,7 @@ else if get_stage("%(bcb_dev)s", "stage") == "3/3" then
system_diff.WriteScript(script, output_zip) system_diff.WriteScript(script, output_zip)
else: else:
script.FormatPartition("/system") script.FormatPartition("/system")
script.Mount("/system") script.Mount("/system", recovery_mount_options)
if not has_recovery_patch: if not has_recovery_patch:
script.UnpackPackageDir("recovery", "/system") script.UnpackPackageDir("recovery", "/system")
script.UnpackPackageDir("system", "/system") script.UnpackPackageDir("system", "/system")
@@ -594,7 +603,7 @@ else if get_stage("%(bcb_dev)s", "stage") == "3/3" then
vendor_diff.WriteScript(script, output_zip) vendor_diff.WriteScript(script, output_zip)
else: else:
script.FormatPartition("/vendor") script.FormatPartition("/vendor")
script.Mount("/vendor") script.Mount("/vendor", recovery_mount_options)
script.UnpackPackageDir("vendor", "/vendor") script.UnpackPackageDir("vendor", "/vendor")
symlinks = CopyPartitionFiles(vendor_items, input_zip, output_zip) symlinks = CopyPartitionFiles(vendor_items, input_zip, output_zip)
@@ -745,11 +754,12 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
vendor_diff = None vendor_diff = None
oem_props = OPTIONS.target_info_dict.get("oem_fingerprint_properties") oem_props = OPTIONS.target_info_dict.get("oem_fingerprint_properties")
recovery_mount_options = OPTIONS.target_info_dict.get("recovery_mount_options")
oem_dict = None oem_dict = None
if oem_props is not None and len(oem_props) > 0: if oem_props is not None and len(oem_props) > 0:
if OPTIONS.oem_source is None: if OPTIONS.oem_source is None:
raise common.ExternalError("OEM source required for this build") raise common.ExternalError("OEM source required for this build")
script.Mount("/oem") script.Mount("/oem", recovery_mount_options)
oem_dict = common.LoadDictionaryFromLines(open(OPTIONS.oem_source).readlines()) oem_dict = common.LoadDictionaryFromLines(open(OPTIONS.oem_source).readlines())
AppendAssertions(script, OPTIONS.target_info_dict, oem_dict) AppendAssertions(script, OPTIONS.target_info_dict, oem_dict)
@@ -785,14 +795,14 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
bcb_dev = {"bcb_dev": fs.device} bcb_dev = {"bcb_dev": fs.device}
common.ZipWriteStr(output_zip, "recovery.img", target_recovery.data) common.ZipWriteStr(output_zip, "recovery.img", target_recovery.data)
script.AppendExtra(""" script.AppendExtra("""
if get_stage("%(bcb_dev)s", "stage") == "2/3" then if get_stage("%(bcb_dev)s") == "2/3" then
""" % bcb_dev) """ % bcb_dev)
script.AppendExtra("sleep(20);\n"); script.AppendExtra("sleep(20);\n");
script.WriteRawImage("/recovery", "recovery.img") script.WriteRawImage("/recovery", "recovery.img")
script.AppendExtra(""" script.AppendExtra("""
set_stage("%(bcb_dev)s", "3/3"); set_stage("%(bcb_dev)s", "3/3");
reboot_now("%(bcb_dev)s", "recovery"); reboot_now("%(bcb_dev)s", "recovery");
else if get_stage("%(bcb_dev)s", "stage") != "3/3" then else if get_stage("%(bcb_dev)s") != "3/3" then
""" % bcb_dev) """ % bcb_dev)
script.Print("Verifying current system...") script.Print("Verifying current system...")
@@ -836,6 +846,11 @@ reboot_now("%(bcb_dev)s", "");
else else
""" % bcb_dev) """ % bcb_dev)
# Verify the existing partitions.
system_diff.WriteVerifyScript(script)
if vendor_diff:
vendor_diff.WriteVerifyScript(script)
script.Comment("---- start making changes here ----") script.Comment("---- start making changes here ----")
device_specific.IncrementalOTA_InstallBegin() device_specific.IncrementalOTA_InstallBegin()
@@ -935,7 +950,7 @@ class FileDifference:
raise common.ExternalError("\"%s\" must be sent verbatim" % (fn,)) raise common.ExternalError("\"%s\" must be sent verbatim" % (fn,))
print "send", fn, "verbatim" print "send", fn, "verbatim"
tf.AddToZip(output_zip) tf.AddToZip(output_zip)
verbatim_targets.append((fn, tf.size)) verbatim_targets.append((fn, tf.size, tf.sha1))
if fn in target_data.keys(): if fn in target_data.keys():
AddToKnownPaths(fn, known_paths) AddToKnownPaths(fn, known_paths)
elif tf.sha1 != sf.sha1: elif tf.sha1 != sf.sha1:
@@ -956,7 +971,7 @@ class FileDifference:
# or a patch + rename cannot take place due to the target # or a patch + rename cannot take place due to the target
# directory not existing # directory not existing
tf.AddToZip(output_zip) tf.AddToZip(output_zip)
verbatim_targets.append((tf.name, tf.size)) verbatim_targets.append((tf.name, tf.size, tf.sha1))
if sf.name in renames: if sf.name in renames:
del renames[sf.name] del renames[sf.name]
AddToKnownPaths(tf.name, known_paths) AddToKnownPaths(tf.name, known_paths)
@@ -976,6 +991,13 @@ class FileDifference:
so_far += sf.size so_far += sf.size
return so_far return so_far
def EmitExplicitTargetVerification(self, script):
for fn, size, sha1 in self.verbatim_targets:
if (fn[-1] != "/"):
script.FileCheck("/"+fn, sha1)
for tf, _, _, _ in self.patch_list:
script.FileCheck(tf.name, tf.sha1)
def RemoveUnneededFiles(self, script, extras=()): def RemoveUnneededFiles(self, script, extras=()):
script.DeleteFiles(["/"+i[0] for i in self.verbatim_targets] + script.DeleteFiles(["/"+i[0] for i in self.verbatim_targets] +
["/"+i for i in sorted(self.source_data) ["/"+i for i in sorted(self.source_data)
@@ -1035,11 +1057,12 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
OPTIONS.target_info_dict) OPTIONS.target_info_dict)
oem_props = OPTIONS.info_dict.get("oem_fingerprint_properties") oem_props = OPTIONS.info_dict.get("oem_fingerprint_properties")
recovery_mount_options = OPTIONS.info_dict.get("recovery_mount_options")
oem_dict = None oem_dict = None
if oem_props is not None and len(oem_props) > 0: if oem_props is not None and len(oem_props) > 0:
if OPTIONS.oem_source is None: if OPTIONS.oem_source is None:
raise common.ExternalError("OEM source required for this build") raise common.ExternalError("OEM source required for this build")
script.Mount("/oem") script.Mount("/oem", recovery_mount_options)
oem_dict = common.LoadDictionaryFromLines(open(OPTIONS.oem_source).readlines()) oem_dict = common.LoadDictionaryFromLines(open(OPTIONS.oem_source).readlines())
metadata = {"pre-device": GetOemProperty("ro.product.device", oem_props, oem_dict, metadata = {"pre-device": GetOemProperty("ro.product.device", oem_props, oem_dict,
@@ -1059,10 +1082,10 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
info_dict=OPTIONS.info_dict) info_dict=OPTIONS.info_dict)
system_diff = FileDifference("system", source_zip, target_zip, output_zip) system_diff = FileDifference("system", source_zip, target_zip, output_zip)
script.Mount("/system") script.Mount("/system", recovery_mount_options)
if HasVendorPartition(target_zip): if HasVendorPartition(target_zip):
vendor_diff = FileDifference("vendor", source_zip, target_zip, output_zip) vendor_diff = FileDifference("vendor", source_zip, target_zip, output_zip)
script.Mount("/vendor") script.Mount("/vendor", recovery_mount_options)
else: else:
vendor_diff = None vendor_diff = None
@@ -1133,14 +1156,14 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
bcb_dev = {"bcb_dev": fs.device} bcb_dev = {"bcb_dev": fs.device}
common.ZipWriteStr(output_zip, "recovery.img", target_recovery.data) common.ZipWriteStr(output_zip, "recovery.img", target_recovery.data)
script.AppendExtra(""" script.AppendExtra("""
if get_stage("%(bcb_dev)s", "stage") == "2/3" then if get_stage("%(bcb_dev)s") == "2/3" then
""" % bcb_dev) """ % bcb_dev)
script.AppendExtra("sleep(20);\n"); script.AppendExtra("sleep(20);\n");
script.WriteRawImage("/recovery", "recovery.img") script.WriteRawImage("/recovery", "recovery.img")
script.AppendExtra(""" script.AppendExtra("""
set_stage("%(bcb_dev)s", "3/3"); set_stage("%(bcb_dev)s", "3/3");
reboot_now("%(bcb_dev)s", "recovery"); reboot_now("%(bcb_dev)s", "recovery");
else if get_stage("%(bcb_dev)s", "stage") != "3/3" then else if get_stage("%(bcb_dev)s") != "3/3" then
""" % bcb_dev) """ % bcb_dev)
script.Print("Verifying current system...") script.Print("Verifying current system...")
@@ -1346,7 +1369,19 @@ endif;
endif; endif;
""" % bcb_dev) """ % bcb_dev)
if OPTIONS.verify and system_diff:
script.Print("Remounting and verifying system partition files...")
script.Unmount("/system")
script.Mount("/system")
system_diff.EmitExplicitTargetVerification(script)
if OPTIONS.verify and vendor_diff:
script.Print("Remounting and verifying vendor partition files...")
script.Unmount("/vendor")
script.Mount("/vendor")
vendor_diff.EmitExplicitTargetVerification(script)
script.AddToZip(target_zip, output_zip, input_path=OPTIONS.updater_binary) script.AddToZip(target_zip, output_zip, input_path=OPTIONS.updater_binary)
WriteMetadata(metadata, output_zip) WriteMetadata(metadata, output_zip)
@@ -1382,6 +1417,8 @@ def main(argv):
OPTIONS.two_step = True OPTIONS.two_step = True
elif o == "--no_signing": elif o == "--no_signing":
OPTIONS.no_signing = True OPTIONS.no_signing = True
elif o in ("--verify"):
OPTIONS.verify = True
elif o == "--block": elif o == "--block":
OPTIONS.block_based = True OPTIONS.block_based = True
elif o in ("-b", "--binary"): elif o in ("-b", "--binary"):
@@ -1407,6 +1444,7 @@ def main(argv):
"block", "block",
"binary=", "binary=",
"oem_settings=", "oem_settings=",
"verify",
"no_fallback_to_full", "no_fallback_to_full",
], ],
extra_option_handler=option_handler) extra_option_handler=option_handler)

View File

@@ -24,7 +24,9 @@ class RangeSet(object):
lots of runs.""" lots of runs."""
def __init__(self, data=None): def __init__(self, data=None):
if data: if isinstance(data, str):
self._parse_internal(data)
elif data:
self.data = tuple(self._remove_pairs(data)) self.data = tuple(self._remove_pairs(data))
else: else:
self.data = () self.data = ()
@@ -46,6 +48,9 @@ class RangeSet(object):
else: else:
return self.to_string() return self.to_string()
def __repr__(self):
return '<RangeSet("' + self.to_string() + '")>'
@classmethod @classmethod
def parse(cls, text): def parse(cls, text):
"""Parse a text string consisting of a space-separated list of """Parse a text string consisting of a space-separated list of
@@ -59,7 +64,9 @@ class RangeSet(object):
"15-20 30 10-14" is not, even though they represent the same set "15-20 30 10-14" is not, even though they represent the same set
of blocks (and the two RangeSets will compare equal with ==). of blocks (and the two RangeSets will compare equal with ==).
""" """
return cls(text)
def _parse_internal(self, text):
data = [] data = []
last = -1 last = -1
monotonic = True monotonic = True
@@ -81,9 +88,8 @@ class RangeSet(object):
else: else:
monotonic = True monotonic = True
data.sort() data.sort()
r = RangeSet(cls._remove_pairs(data)) self.data = tuple(self._remove_pairs(data))
r.monotonic = monotonic self.monotonic = monotonic
return r
@staticmethod @staticmethod
def _remove_pairs(source): def _remove_pairs(source):
@@ -113,7 +119,13 @@ class RangeSet(object):
def union(self, other): def union(self, other):
"""Return a new RangeSet representing the union of this RangeSet """Return a new RangeSet representing the union of this RangeSet
with the argument.""" with the argument.
>>> RangeSet("10-19 30-34").union(RangeSet("18-29"))
<RangeSet("10-34")>
>>> RangeSet("10-19 30-34").union(RangeSet("22 32"))
<RangeSet("10-19 22 30-34")>
"""
out = [] out = []
z = 0 z = 0
for p, d in heapq.merge(zip(self.data, itertools.cycle((+1, -1))), for p, d in heapq.merge(zip(self.data, itertools.cycle((+1, -1))),
@@ -125,7 +137,13 @@ class RangeSet(object):
def intersect(self, other): def intersect(self, other):
"""Return a new RangeSet representing the intersection of this """Return a new RangeSet representing the intersection of this
RangeSet with the argument.""" RangeSet with the argument.
>>> RangeSet("10-19 30-34").intersect(RangeSet("18-32"))
<RangeSet("18-19 30-32")>
>>> RangeSet("10-19 30-34").intersect(RangeSet("22-28"))
<RangeSet("")>
"""
out = [] out = []
z = 0 z = 0
for p, d in heapq.merge(zip(self.data, itertools.cycle((+1, -1))), for p, d in heapq.merge(zip(self.data, itertools.cycle((+1, -1))),
@@ -137,7 +155,13 @@ class RangeSet(object):
def subtract(self, other): def subtract(self, other):
"""Return a new RangeSet representing subtracting the argument """Return a new RangeSet representing subtracting the argument
from this RangeSet.""" from this RangeSet.
>>> RangeSet("10-19 30-34").subtract(RangeSet("18-32"))
<RangeSet("10-17 33-34")>
>>> RangeSet("10-19 30-34").subtract(RangeSet("22-28"))
<RangeSet("10-19 30-34")>
"""
out = [] out = []
z = 0 z = 0
@@ -150,7 +174,13 @@ class RangeSet(object):
def overlaps(self, other): def overlaps(self, other):
"""Returns true if the argument has a nonempty overlap with this """Returns true if the argument has a nonempty overlap with this
RangeSet.""" RangeSet.
>>> RangeSet("10-19 30-34").overlaps(RangeSet("18-32"))
True
>>> RangeSet("10-19 30-34").overlaps(RangeSet("22-28"))
False
"""
# This is like intersect, but we can stop as soon as we discover the # This is like intersect, but we can stop as soon as we discover the
# output is going to be nonempty. # output is going to be nonempty.
@@ -164,7 +194,11 @@ class RangeSet(object):
def size(self): def size(self):
"""Returns the total size of the RangeSet (ie, how many integers """Returns the total size of the RangeSet (ie, how many integers
are in the set).""" are in the set).
>>> RangeSet("10-19 30-34").size()
15
"""
total = 0 total = 0
for i, p in enumerate(self.data): for i, p in enumerate(self.data):
@@ -173,3 +207,37 @@ class RangeSet(object):
else: else:
total -= p total -= p
return total return total
def map_within(self, other):
"""'other' should be a subset of 'self'. Returns a RangeSet
representing what 'other' would get translated to if the integers
of 'self' were translated down to be contiguous starting at zero.
>>> RangeSet("0-9").map_within(RangeSet("3-4"))
<RangeSet("3-4")>
>>> RangeSet("10-19").map_within(RangeSet("13-14"))
<RangeSet("3-4")>
>>> RangeSet("10-19 30-39").map_within(RangeSet("17-19 30-32"))
<RangeSet("7-12")>
>>> RangeSet("10-19 30-39").map_within(RangeSet("12-13 17-19 30-32"))
<RangeSet("2-3 7-12")>
"""
out = []
offset = 0
start = None
for p, d in heapq.merge(zip(self.data, itertools.cycle((-5, +5))),
zip(other.data, itertools.cycle((-1, +1)))):
if d == -5:
start = p
elif d == +5:
offset += p-start
start = None
else:
out.append(offset + p - start)
return RangeSet(data=out)
if __name__ == "__main__":
import doctest
doctest.testmod()

View File

@@ -199,6 +199,7 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
print "NOT signing: %s" % (name,) print "NOT signing: %s" % (name,)
output_tf_zip.writestr(out_info, data) output_tf_zip.writestr(out_info, data)
elif info.filename in ("SYSTEM/build.prop", elif info.filename in ("SYSTEM/build.prop",
"VENDOR/build.prop",
"RECOVERY/RAMDISK/default.prop"): "RECOVERY/RAMDISK/default.prop"):
print "rewriting %s:" % (info.filename,) print "rewriting %s:" % (info.filename,)
new_data = RewriteProps(data, misc_info) new_data = RewriteProps(data, misc_info)
@@ -296,12 +297,12 @@ def RewriteProps(data, misc_info):
original_line = line original_line = line
if line and line[0] != '#' and "=" in line: if line and line[0] != '#' and "=" in line:
key, value = line.split("=", 1) key, value = line.split("=", 1)
if (key == "ro.build.fingerprint" if (key in ("ro.build.fingerprint", "ro.vendor.build.fingerprint")
and misc_info.get("oem_fingerprint_properties") is None): and misc_info.get("oem_fingerprint_properties") is None):
pieces = value.split("/") pieces = value.split("/")
pieces[-1] = EditTags(pieces[-1]) pieces[-1] = EditTags(pieces[-1])
value = "/".join(pieces) value = "/".join(pieces)
elif (key == "ro.build.thumbprint" elif (key in ("ro.build.thumbprint", "ro.vendor.build.thumbprint")
and misc_info.get("oem_fingerprint_properties") is not None): and misc_info.get("oem_fingerprint_properties") is not None):
pieces = value.split("/") pieces = value.split("/")
pieces[-1] = EditTags(pieces[-1]) pieces[-1] = EditTags(pieces[-1])