Merge "Iterate through the sorted file map when finding transfers"
diff --git a/Changes.md b/Changes.md
index 3e48bad..37bbad0 100644
--- a/Changes.md
+++ b/Changes.md
@@ -92,6 +92,11 @@
attribute to the root element `<manifest>`. If `PRODUCT_COMPATIBILITY_MATRIX_LEVEL_OVERRIDE`
is 26 or 27, you can add `"target-level"="1"` to your device manifest instead.
+### Stop using USE_CLANG_PLATFORM_BUILD {#USE_CLANG_PLATFORM_BUILD}
+
+Clang is the default and only supported Android compiler, so there is no reason
+for this option to exist.
+
### Other envsetup.sh variables {#other_envsetup_variables}
* ANDROID_TOOLCHAIN
diff --git a/core/allowed_ndk_types.mk b/core/allowed_ndk_types.mk
index b5a85ca..b88b9e8 100644
--- a/core/allowed_ndk_types.mk
+++ b/core/allowed_ndk_types.mk
@@ -28,12 +28,6 @@
else ifeq ($(LOCAL_NDK_STL_VARIANT),c++_static)
my_ndk_stl_family := libc++
my_ndk_stl_link_type := static
- else ifeq ($(LOCAL_NDK_STL_VARIANT),stlport_shared)
- my_ndk_stl_family := stlport
- my_ndk_stl_link_type := shared
- else ifeq ($(LOCAL_NDK_STL_VARIANT),stlport_static)
- my_ndk_stl_family := stlport
- my_ndk_stl_link_type := static
else ifeq ($(LOCAL_NDK_STL_VARIANT),none)
my_ndk_stl_family := none
my_ndk_stl_link_type := none
@@ -66,8 +60,7 @@
# already been checked for consistency, and if they don't they'll be
# kept isolated by RTLD_LOCAL anyway.
my_allowed_ndk_types += \
- native:ndk:libc++:shared native:ndk:libc++:static \
- native:ndk:stlport:shared native:ndk:stlport:static \
+ native:ndk:libc++:shared native:ndk:libc++:static
# The "none" link type that used by static libraries is intentionally
# omitted here. We should only be dealing with shared libraries in
@@ -79,7 +72,11 @@
# Else we are a non-static library that uses a static STL, and are
# incompatible with all other shared libraries that use an STL.
else
- my_allowed_ndk_types := native:ndk:none:none native:ndk:system:shared
+ my_allowed_ndk_types := \
+ native:ndk:none:none \
+ native:ndk:system:none \
+ native:ndk:system:shared \
+
ifeq ($(LOCAL_MODULE_CLASS),APPS)
# CTS is bad and it should feel bad: http://b/13249737
my_warn_ndk_types += native:ndk:libc++:static
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 9234abe..313c302 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -499,18 +499,22 @@
# separate the multiple architectures into subdirectories of the testcase folder.
arch_dir :=
is_native :=
+multi_arch :=
ifeq ($(LOCAL_MODULE_CLASS),NATIVE_TESTS)
is_native := true
+ multi_arch := true
endif
ifeq ($(LOCAL_MODULE_CLASS),NATIVE_BENCHMARK)
is_native := true
+ multi_arch := true
endif
ifdef LOCAL_MULTILIB
- is_native := true
+ multi_arch := true
endif
-ifdef is_native
+ifdef multi_arch
arch_dir := /$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
endif
+multi_arch :=
# The module itself.
$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
@@ -537,14 +541,23 @@
ifeq (true, $(LOCAL_IS_HOST_MODULE))
is_instrumentation_test := false
endif
+ # If LOCAL_MODULE_CLASS is not APPS, it's certainly not an instrumentation
+ # test. However, some packages for test data also have LOCAL_MODULE_CLASS
+ # set to APPS. These will require flag LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG
+ # to disable auto-generating test config file.
+ ifneq (APPS, $(LOCAL_MODULE_CLASS))
+ is_instrumentation_test := false
+ endif
endif
# CTS modules can be used for test data, so test config files must be
# explicitly created using AndroidTest.xml
ifeq (,$(filter cts, $(LOCAL_COMPATIBILITY_SUITE)))
- ifeq (true, $(filter true,$(is_native) $(is_instrumentation_test)))
- include $(BUILD_SYSTEM)/autogen_test_config.mk
- test_config := $(autogen_test_config_file)
- autogen_test_config_file :=
+ ifneq (true, $(LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG))
+ ifeq (true, $(filter true,$(is_native) $(is_instrumentation_test)))
+ include $(BUILD_SYSTEM)/autogen_test_config.mk
+ test_config := $(autogen_test_config_file)
+ autogen_test_config_file :=
+ endif
endif
endif
endif
diff --git a/core/binary.mk b/core/binary.mk
index 06b0d0e..e3da7d2 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -189,24 +189,14 @@
ifeq (,$(LOCAL_NDK_STL_VARIANT))
LOCAL_NDK_STL_VARIANT := system
endif
- ifneq (1,$(words $(filter none system stlport_static stlport_shared c++_static c++_shared, $(LOCAL_NDK_STL_VARIANT))))
+ ifneq (1,$(words $(filter none system c++_static c++_shared, $(LOCAL_NDK_STL_VARIANT))))
$(error $(LOCAL_PATH): Unknown LOCAL_NDK_STL_VARIANT $(LOCAL_NDK_STL_VARIANT))
endif
+
ifeq (system,$(LOCAL_NDK_STL_VARIANT))
my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/system/include
my_system_shared_libraries += libstdc++
- else # LOCAL_NDK_STL_VARIANT is not system
- ifneq (,$(filter stlport_%, $(LOCAL_NDK_STL_VARIANT)))
- my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/stlport/stlport
- my_system_shared_libraries += libstdc++
- ifeq (stlport_static,$(LOCAL_NDK_STL_VARIANT))
- my_ndk_stl_static_lib := $(my_ndk_source_root)/cxx-stl/stlport/libs/$(my_cpu_variant)/libstlport_static.a
- my_ldlibs += -ldl
- else
- my_ndk_stl_shared_lib_fullpath := $(my_ndk_source_root)/cxx-stl/stlport/libs/$(my_cpu_variant)/libstlport_shared.so
- endif
- else # LOCAL_NDK_STL_VARIANT is not stlport_* either
- ifneq (,$(filter c++_%, $(LOCAL_NDK_STL_VARIANT)))
+ else ifneq (,$(filter c++_%, $(LOCAL_NDK_STL_VARIANT)))
my_ndk_stl_include_path := \
$(my_ndk_source_root)/cxx-stl/llvm-libc++/include
my_ndk_stl_include_path += \
@@ -235,8 +225,6 @@
else # LOCAL_NDK_STL_VARIANT must be none
# Do nothing.
endif
- endif
- endif
endif
ifneq ($(LOCAL_USE_VNDK),)
@@ -366,11 +354,6 @@
my_clang := true
endif
endif
-# Add option to make gcc the default for device build
-else ifeq ($(USE_CLANG_PLATFORM_BUILD),false)
- ifeq ($(my_clang),)
- my_clang := false
- endif
else ifeq ($(my_clang),)
my_clang := true
endif
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index b4a03ea..b2522ee 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -55,6 +55,7 @@
LOCAL_DEX_PREOPT_IMAGE_LOCATION:=
LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING:=
LOCAL_DEX_PREOPT:= # '',true,false,nostripping
+LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG:=
LOCAL_DONT_CHECK_MODULE:=
# Don't delete the META_INF dir when merging static Java libraries.
LOCAL_DONT_DELETE_JAR_META_INF:=
diff --git a/core/combo/TARGET_linux-arm.mk b/core/combo/TARGET_linux-arm.mk
index 73b1c04..01cf3f5 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -50,7 +50,7 @@
endif
ifeq ($(strip $(TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT)),)
-TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT := armv5te
+$(error TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT must be set)
endif
TARGET_ARCH_SPECIFIC_MAKEFILE := $(BUILD_COMBOS)/arch/$(TARGET_$(combo_2nd_arch_prefix)ARCH)/$(TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT).mk
diff --git a/core/combo/arch/arm/armv5te-vfp.mk b/core/combo/arch/arm/armv5te-vfp.mk
deleted file mode 100644
index 75299ac..0000000
--- a/core/combo/arch/arm/armv5te-vfp.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-# At the moment, use the same settings than the one
-# for armv5te, since TARGET_ARCH_VARIANT := armv5te-vfp
-# will only be used to select an optimized VFP-capable assembly
-# interpreter loop for Dalvik.
-#
-include $(BUILD_COMBOS)/arch/arm/armv5te.mk
-
diff --git a/core/combo/arch/arm/armv5te.mk b/core/combo/arch/arm/armv5te.mk
deleted file mode 100644
index bd75695..0000000
--- a/core/combo/arch/arm/armv5te.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-# Configuration for Linux on ARM.
-# Generating binaries for the ARMv5TE architecture and higher
-#
-
diff --git a/core/combo/select.mk b/core/combo/select.mk
index 94e37c6..eab4c72 100644
--- a/core/combo/select.mk
+++ b/core/combo/select.mk
@@ -28,7 +28,7 @@
# Set reasonable defaults for the various variables
-$(combo_var_prefix)GLOBAL_ARFLAGS := cqsD
+$(combo_var_prefix)GLOBAL_ARFLAGS := cqsD -format=gnu
$(combo_var_prefix)STATIC_LIB_SUFFIX := .a
diff --git a/core/config.mk b/core/config.mk
index b03f21f..255c848 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -76,6 +76,7 @@
ANDROID_PRE_BUILD_PATHS \
,See $(CHANGES_URL)#other_envsetup_variables)
$(KATI_obsolete_var PRODUCT_COMPATIBILITY_MATRIX_LEVEL_OVERRIDE,Set FCM Version in device manifest instead. See $(CHANGES_URL)#PRODUCT_COMPATIBILITY_MATRIX_LEVEL_OVERRIDE)
+$(KATI_obsolete_var USE_CLANG_PLATFORM_BUILD,Clang is the only supported Android compiler. See $(CHANGES_URL)#USE_CLANG_PLATFORM_BUILD)
CHANGES_URL :=
@@ -609,13 +610,13 @@
LEX := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/flex/flex-2.5.39
# The default PKGDATADIR built in the prebuilt bison is a relative path
-# external/bison/data.
+# prebuilts/build-tools/common/bison.
# To run bison from elsewhere you need to set up enviromental variable
# BISON_PKGDATADIR.
-BISON_PKGDATADIR := $(PWD)/external/bison/data
-BISON := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/bison/bison
+BISON_PKGDATADIR := $(PWD)/prebuilts/build-tools/common/bison
+BISON := prebuilts/build-tools/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/bin/bison
YACC := $(BISON) -d
-BISON_DATA := $(wildcard external/bison/data/* external/bison/data/*/*)
+BISON_DATA := $(wildcard $(BISON_PKGDATADIR)/* $(BISON_PKGDATADIR)/*/*)
YASM := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/yasm/yasm
@@ -825,8 +826,6 @@
endif
$(.KATI_obsolete_var DEVICE_FRAMEWORK_MANIFEST_FILE,No one should ever need to use this.)
-FRAMEWORK_COMPATIBILITY_MATRIX_FILES := $(wildcard hardware/interfaces/compatibility_matrix.*.xml)
-
BUILD_NUMBER_FROM_FILE := $$(cat $(OUT_DIR)/build_number.txt)
BUILD_DATETIME_FROM_FILE := $$(cat $(OUT_DIR)/build_date.txt)
diff --git a/core/cxx_stl_setup.mk b/core/cxx_stl_setup.mk
index f07659d..5171b8a 100644
--- a/core/cxx_stl_setup.mk
+++ b/core/cxx_stl_setup.mk
@@ -74,6 +74,16 @@
ifneq ($(filter $(my_cxx_stl),libc++ libc++_static),)
my_cflags += -D_USING_LIBCXX
+ ifeq ($($(my_prefix)OS),darwin)
+ # libc++'s headers are annotated with availability macros that indicate
+ # which version of Mac OS was the first to ship with a libc++ feature
+ # available in its *system's* libc++.dylib. We do not use the system's
+ # library, but rather ship our own. As such, these availability
+ # attributes are meaningless for us but cause build breaks when we try
+ # to use code that would not be available in the system's dylib.
+ my_cppflags += -D_LIBCPP_DISABLE_AVAILABILITY
+ endif
+
# Note that the structure of this means that LOCAL_CXX_STL := libc++ will
# use the static libc++ for static executables.
ifeq ($(my_link_type),dynamic)
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 255c02b..05add60 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -657,13 +657,3 @@
ifeq ($(CALLED_FROM_SETUP),true)
PRINT_BUILD_CONFIG ?= true
endif
-
-ifeq ($(USE_CLANG_PLATFORM_BUILD),)
-USE_CLANG_PLATFORM_BUILD := true
-endif
-
-ifneq ($(USE_CLANG_PLATFORM_BUILD),true)
-ifneq ($(USE_CLANG_PLATFORM_BUILD),false)
-$(error USE_CLANG_PLATFORM_BUILD must be true or false)
-endif
-endif
diff --git a/core/install_jni_libs_internal.mk b/core/install_jni_libs_internal.mk
index 80e0c24..ab5fd2c 100644
--- a/core/install_jni_libs_internal.mk
+++ b/core/install_jni_libs_internal.mk
@@ -24,16 +24,11 @@
ifdef my_embed_jni
# App explicitly requires the prebuilt NDK stl shared libraies.
# The NDK stl shared libraries should never go to the system image.
-ifneq ($(filter $(LOCAL_NDK_STL_VARIANT), stlport_shared c++_shared),)
+ifeq ($(LOCAL_NDK_STL_VARIANT),c++_shared)
ifndef LOCAL_SDK_VERSION
$(error LOCAL_SDK_VERSION must be defined with LOCAL_NDK_STL_VARIANT, \
LOCAL_PACKAGE_NAME=$(LOCAL_PACKAGE_NAME))
endif
-endif
-ifeq (stlport_shared,$(LOCAL_NDK_STL_VARIANT))
-my_jni_shared_libraries += \
- $(HISTORICAL_NDK_VERSIONS_ROOT)/$(LOCAL_NDK_VERSION)/sources/cxx-stl/stlport/libs/$(TARGET_$(my_2nd_arch_prefix)CPU_ABI)/libstlport_shared.so
-else ifeq (c++_shared,$(LOCAL_NDK_STL_VARIANT))
my_jni_shared_libraries += \
$(HISTORICAL_NDK_VERSIONS_ROOT)/$(LOCAL_NDK_VERSION)/sources/cxx-stl/llvm-libc++/libs/$(TARGET_$(my_2nd_arch_prefix)CPU_ABI)/libc++_shared.so
endif
diff --git a/core/soong_config.mk b/core/soong_config.mk
index bbad4c8..c7eefc9 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -110,7 +110,6 @@
$(call add_json_bool, Device_uses_hwc2, $(filter true,$(TARGET_USES_HWC2)))
$(call add_json_list, DeviceKernelHeaders, $(TARGET_PROJECT_SYSTEM_INCLUDES))
$(call add_json_bool, DevicePrefer32BitExecutables, $(filter true,$(TARGET_PREFER_32_BIT_EXECUTABLES)))
-$(call add_json_val, DeviceUsesClang, $(if $(USE_CLANG_PLATFORM_BUILD),$(USE_CLANG_PLATFORM_BUILD),false))
$(call add_json_str, DeviceVndkVersion, $(BOARD_VNDK_VERSION))
$(call add_json_str, Platform_vndk_version, $(PLATFORM_VNDK_VERSION))
$(call add_json_list, ExtraVndkVersions, $(PRODUCT_EXTRA_VNDK_VERSIONS))
diff --git a/core/target_test_internal.mk b/core/target_test_internal.mk
index d84d3d9..b5c3a7c 100644
--- a/core/target_test_internal.mk
+++ b/core/target_test_internal.mk
@@ -8,13 +8,9 @@
ifndef LOCAL_SDK_VERSION
LOCAL_STATIC_LIBRARIES += libgtest_main libgtest
else
- ifneq (,$(filter c++_%,$(LOCAL_NDK_STL_VARIANT)))
- my_ndk_gtest_suffix := _c++
- else ifneq ($(filter stlport_,$(LOCAL_NDK_STL_VARIANT)),)
- my_ndk_gtest_suffix := _stlport
- else # system STL, use stlport
- my_ndk_gtest_suffix := _stlport
- endif
+ # TODO(danalbert): Remove the suffix from the module since we only need the
+ # one variant now.
+ my_ndk_gtest_suffix := _c++
LOCAL_STATIC_LIBRARIES += \
libgtest_main_ndk$(my_ndk_gtest_suffix) \
libgtest_ndk$(my_ndk_gtest_suffix)
diff --git a/envsetup.sh b/envsetup.sh
index 394df65..372dffb 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -8,7 +8,7 @@
Selects <product_name> as the product to build, and <build_variant> as the variant to
build, and stores those selections in the environment to be read by subsequent
invocations of 'm' etc.
-- tapas: tapas [<App1> <App2> ...] [arm|x86|mips|armv5|arm64|x86_64|mips64] [eng|userdebug|user]
+- tapas: tapas [<App1> <App2> ...] [arm|x86|mips|arm64|x86_64|mips64] [eng|userdebug|user]
- croot: Changes directory to the top of the tree.
- m: Makes from the top of the tree.
- mm: Builds all of the modules in the current directory, but not their dependencies.
@@ -51,7 +51,7 @@
cached_vars=`cat $T/build/envsetup.sh | tr '()' ' ' | awk '{for(i=1;i<=NF;i++) if($i~/get_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`
cached_abs_vars=`cat $T/build/envsetup.sh | tr '()' ' ' | awk '{for(i=1;i<=NF;i++) if($i~/get_abs_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`
# Call the build system to dump the "<val>=<value>" pairs as a shell script.
- build_dicts_script=`\cd $T; build/soong/soong_ui.bash --dumpvars-mode \
+ build_dicts_script=`\builtin cd $T; build/soong/soong_ui.bash --dumpvars-mode \
--vars="$cached_vars" \
--abs-vars="$cached_abs_vars" \
--var-prefix=var_cache_ \
@@ -661,10 +661,10 @@
function tapas()
{
local showHelp="$(echo $* | xargs -n 1 echo | \grep -E '^(help)$' | xargs)"
- 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|arm64|x86_64|mips64)$' | xargs)"
local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | 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)"
+ local apps="$(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|arm|x86|mips|arm64|x86_64|mips64|ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi)$' | xargs)"
if [ "$showHelp" != "" ]; then
$(gettop)/build/make/tapasHelp.sh
@@ -688,7 +688,6 @@
case $arch in
x86) product=aosp_x86;;
mips) product=aosp_mips;;
- armv5) product=generic_armv5;;
arm64) product=aosp_arm64;;
x86_64) product=aosp_x86_64;;
mips64) product=aosp_mips64;;
diff --git a/tapasHelp.sh b/tapasHelp.sh
index 058ac1d..38b3e34 100755
--- a/tapasHelp.sh
+++ b/tapasHelp.sh
@@ -6,7 +6,7 @@
cd ../..
TOP="${PWD}"
-message='usage: tapas [<App1> <App2> ...] [arm|x86|mips|armv5|arm64|x86_64|mips64] [eng|userdebug|user]
+message='usage: tapas [<App1> <App2> ...] [arm|x86|mips|arm64|x86_64|mips64] [eng|userdebug|user]
tapas selects individual apps to be built by the Android build system. Unlike
"lunch", "tapas" does not request the building of images for a device.
diff --git a/target/board/Android.mk b/target/board/Android.mk
index f4d6b93..ae6be92 100644
--- a/target/board/Android.mk
+++ b/target/board/Android.mk
@@ -99,60 +99,3 @@
include $(BUILD_PREBUILT)
BUILT_SYSTEM_MANIFEST := $(LOCAL_BUILT_MODULE)
-# Framework Compatibility Matrix
-include $(CLEAR_VARS)
-LOCAL_MODULE := framework_compatibility_matrix.xml
-LOCAL_MODULE_STEM := compatibility_matrix.xml
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)
-
-GEN := $(local-generated-sources-dir)/compatibility_matrix.xml
-
-$(GEN): PRIVATE_FLAGS :=
-
-ifdef BUILT_VENDOR_MANIFEST
-$(GEN): $(BUILT_VENDOR_MANIFEST)
-$(GEN): PRIVATE_FLAGS += -c "$(BUILT_VENDOR_MANIFEST)"
-endif
-
-ifeq (true,$(BOARD_AVB_ENABLE))
-$(GEN): $(AVBTOOL)
-# INTERNAL_AVB_SYSTEM_SIGNING_ARGS consists of BOARD_AVB_SYSTEM_KEY_PATH and
-# BOARD_AVB_SYSTEM_ALGORITHM. We should add the dependency of key path, which
-# is a file, here.
-$(GEN): $(BOARD_AVB_SYSTEM_KEY_PATH)
-# Use deferred assignment (=) instead of immediate assignment (:=).
-# Otherwise, cannot get INTERNAL_AVB_SYSTEM_SIGNING_ARGS.
-FRAMEWORK_VBMETA_VERSION = $$("$(AVBTOOL)" add_hashtree_footer \
- --print_required_libavb_version \
- $(INTERNAL_AVB_SYSTEM_SIGNING_ARGS) \
- $(BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS))
-else
-FRAMEWORK_VBMETA_VERSION := 0.0
-endif
-
-# All kernel versions that the system image works with.
-KERNEL_VERSIONS := 3.18 4.4 4.9
-KERNEL_CONFIG_DATA := kernel/configs
-
-$(GEN): $(foreach version,$(KERNEL_VERSIONS),\
- $(wildcard $(KERNEL_CONFIG_DATA)/android-$(version)/android-base*.cfg))
-$(GEN): PRIVATE_FLAGS += $(foreach version,$(KERNEL_VERSIONS),\
- --kernel=$(version):$(call normalize-path-list,\
- $(wildcard $(KERNEL_CONFIG_DATA)/android-$(version)/android-base*.cfg)))
-
-KERNEL_VERSIONS :=
-KERNEL_CONFIG_DATA :=
-
-$(GEN): $(FRAMEWORK_COMPATIBILITY_MATRIX_FILES) $(HOST_OUT_EXECUTABLES)/assemble_vintf
- # TODO(b/37405869) (b/37715375) inject avb versions as well for devices that have avb enabled.
- POLICYVERS=$(POLICYVERS) \
- BOARD_SEPOLICY_VERS=$(BOARD_SEPOLICY_VERS) \
- FRAMEWORK_VBMETA_VERSION=$(FRAMEWORK_VBMETA_VERSION) \
- PRODUCT_ENFORCE_VINTF_MANIFEST=$(PRODUCT_ENFORCE_VINTF_MANIFEST) \
- $(HOST_OUT_EXECUTABLES)/assemble_vintf \
- -i $(call normalize-path-list,$(FRAMEWORK_COMPATIBILITY_MATRIX_FILES)) \
- -o $@ $(PRIVATE_FLAGS)
-LOCAL_PREBUILT_MODULE_FILE := $(GEN)
-include $(BUILD_PREBUILT)
-BUILT_SYSTEM_COMPATIBILITY_MATRIX := $(LOCAL_BUILT_MODULE)
diff --git a/target/board/generic/sepolicy/bootanim.te b/target/board/generic/sepolicy/bootanim.te
index b23e1ca..e4f7c73 100644
--- a/target/board/generic/sepolicy/bootanim.te
+++ b/target/board/generic/sepolicy/bootanim.te
@@ -3,7 +3,6 @@
#TODO: This can safely be ignored until b/62954877 is fixed
dontaudit bootanim system_data_file:dir read;
-allow bootanim vendor_file:file { execute getattr open read };
allow bootanim graphics_device:chr_file { read ioctl open };
set_prop(bootanim, qemu_prop)
diff --git a/target/board/generic_armv5/AndroidBoard.mk b/target/board/generic_armv5/AndroidBoard.mk
deleted file mode 100644
index 7daff27..0000000
--- a/target/board/generic_armv5/AndroidBoard.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
--include build/target/board/generic/AndroidBoard.mk
diff --git a/target/board/generic_armv5/BoardConfig.mk b/target/board/generic_armv5/BoardConfig.mk
deleted file mode 100644
index 016937a..0000000
--- a/target/board/generic_armv5/BoardConfig.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-include build/target/board/generic/BoardConfig.mk
-
-TARGET_ARCH_VARIANT := armv5te
-TARGET_CPU_ABI := armeabi
-TARGET_CPU_ABI2 :=
-
-WITH_DEXPREOPT := false
diff --git a/target/board/generic_armv5/README.txt b/target/board/generic_armv5/README.txt
deleted file mode 100644
index 25d590a..0000000
--- a/target/board/generic_armv5/README.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-The "generic_armv5" product defines a non-hardware-specific target
-without a kernel or bootloader.
-
-It is not a product "base class"; no other products inherit
-from it or use it in any way.
diff --git a/target/board/generic_armv5/device.mk b/target/board/generic_armv5/device.mk
deleted file mode 100644
index 7c4aaf2..0000000
--- a/target/board/generic_armv5/device.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-include build/target/board/generic/device.mk
diff --git a/target/board/generic_armv5/system.prop b/target/board/generic_armv5/system.prop
deleted file mode 100644
index 137a0f9..0000000
--- a/target/board/generic_armv5/system.prop
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# system.prop for generic sdk
-#
-
-rild.libpath=/system/lib/libreference-ril.so
-rild.libargs=-d /dev/ttyS0
diff --git a/target/board/treble_common.mk b/target/board/treble_common.mk
index b4777b6..a8c9bc5 100644
--- a/target/board/treble_common.mk
+++ b/target/board/treble_common.mk
@@ -36,18 +36,6 @@
# Generic AOSP image always requires separate vendor.img
TARGET_COPY_OUT_VENDOR := vendor
-# Enable dex pre-opt to speed up initial boot
-ifeq ($(HOST_OS),linux)
- ifeq ($(WITH_DEXPREOPT),)
- WITH_DEXPREOPT := true
- WITH_DEXPREOPT_PIC := true
- ifneq ($(TARGET_BUILD_VARIANT),user)
- # Retain classes.dex in APK's for non-user builds
- DEX_PREOPT_DEFAULT := nostripping
- endif
- endif
-endif
-
# Generic AOSP image does NOT support HWC1
TARGET_USES_HWC2 := true
# Set emulator framebuffer display device buffer count to 3
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index 9e2adee..85330b3 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -36,7 +36,6 @@
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/aosp_arm.mk \
$(LOCAL_DIR)/full.mk \
- $(LOCAL_DIR)/generic_armv5.mk \
$(LOCAL_DIR)/aosp_x86.mk \
$(LOCAL_DIR)/full_x86.mk \
$(LOCAL_DIR)/aosp_mips.mk \
diff --git a/target/product/generic_armv5.mk b/target/product/generic_armv5.mk
deleted file mode 100644
index daa321a..0000000
--- a/target/product/generic_armv5.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# This is a generic product that isn't specialized for a specific device.
-# It includes the base Android platform.
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/generic.mk)
-
-# Overrides
-PRODUCT_BRAND := generic_armv5
-PRODUCT_DEVICE := generic_armv5
-PRODUCT_NAME := generic_armv5
diff --git a/tools/adbs b/tools/adbs
deleted file mode 100755
index 8d73630..0000000
--- a/tools/adbs
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import os.path
-import re
-import string
-import sys
-
-sys.path.insert(0, os.path.dirname(__file__) + "/../../../development/scripts")
-import stack_core
-import symbol
-
-if __name__ == '__main__':
- # pass the options to adb
- adb_cmd = "adb " + ' '.join(sys.argv[1:])
-
- # create tracer for line parsing
- tracer = stack_core.TraceConverter()
-
- # invoke the adb command and filter its output
- stream = os.popen(adb_cmd)
- while (True):
- line = stream.readline()
- if (line == ''):
- break
- if(tracer.ProcessLine(line) == False):
- print(line.strip())
- sys.stdout.flush()
-
- # adb itself aborts
- stream.close()
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index 0c44faf..7a81928 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -77,14 +77,14 @@
with temporary=True) to this one."""
self.script.extend(other.script)
- def AssertOemProperty(self, name, values):
+ def AssertOemProperty(self, name, values, oem_no_mount):
"""Assert that a property on the OEM paritition matches allowed values."""
if not name:
raise ValueError("must specify an OEM property")
if not values:
raise ValueError("must specify the OEM value")
- get_prop_command = None
- if common.OPTIONS.oem_no_mount:
+
+ if oem_no_mount:
get_prop_command = 'getprop("%s")' % name
else:
get_prop_command = 'file_getprop("/oem/oem.prop", "%s")' % name
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index d5ac922..f474a6c 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -49,8 +49,10 @@
-o (--oem_settings) <main_file[,additional_files...]>
Comma seperated list of files used to specify the expected OEM-specific
- properties on the OEM partition of the intended device.
- Multiple expected values can be used by providing multiple files.
+ properties on the OEM partition of the intended device. Multiple expected
+ values can be used by providing multiple files. Only the first dict will
+ be used to compute fingerprint, while the rest will be used to assert
+ OEM-specific properties.
--oem_no_mount
For devices with OEM-specific properties but without an OEM partition,
@@ -128,16 +130,11 @@
from __future__ import print_function
-import sys
-
-if sys.hexversion < 0x02070000:
- print("Python 2.7 or newer is required.", file=sys.stderr)
- sys.exit(1)
-
import multiprocessing
import os.path
-import subprocess
import shlex
+import subprocess
+import sys
import tempfile
import zipfile
@@ -145,6 +142,11 @@
import edify_generator
import sparse_img
+if sys.hexversion < 0x02070000:
+ print("Python 2.7 or newer is required.", file=sys.stderr)
+ sys.exit(1)
+
+
OPTIONS = common.OPTIONS
OPTIONS.package_key = None
OPTIONS.incremental_source = None
@@ -163,7 +165,6 @@
OPTIONS.updater_binary = None
OPTIONS.oem_source = None
OPTIONS.oem_no_mount = False
-OPTIONS.fallback_to_full = True
OPTIONS.full_radio = False
OPTIONS.full_bootloader = False
# Stash size cannot exceed cache_size * threshold.
@@ -179,6 +180,136 @@
UNZIP_PATTERN = ['IMAGES/*', 'META/*']
+class BuildInfo(object):
+ """A class that holds the information for a given build.
+
+ This class wraps up the property querying for a given source or target build.
+ It abstracts away the logic of handling OEM-specific properties, and caches
+ the commonly used properties such as fingerprint.
+
+ There are two types of info dicts: a) build-time info dict, which is generated
+ at build time (i.e. included in a target_files zip); b) OEM info dict that is
+ specified at package generation time (via command line argument
+ '--oem_settings'). If a build doesn't use OEM-specific properties (i.e. not
+ having "oem_fingerprint_properties" in build-time info dict), all the queries
+ would be answered based on build-time info dict only. Otherwise if using
+ OEM-specific properties, some of them will be calculated from two info dicts.
+
+ Users can query properties similarly as using a dict() (e.g. info['fstab']),
+ or to query build properties via GetBuildProp() or GetVendorBuildProp().
+
+ Attributes:
+ info_dict: The build-time info dict.
+ is_ab: Whether it's a build that uses A/B OTA.
+ oem_dicts: A list of OEM dicts.
+ oem_props: A list of OEM properties that should be read from OEM dicts; None
+ if the build doesn't use any OEM-specific property.
+ fingerprint: The fingerprint of the build, which would be calculated based
+ on OEM properties if applicable.
+ device: The device name, which could come from OEM dicts if applicable.
+ """
+
+ def __init__(self, info_dict, oem_dicts):
+ """Initializes a BuildInfo instance with the given dicts.
+
+ Arguments:
+ info_dict: The build-time info dict.
+ oem_dicts: A list of OEM dicts (which is parsed from --oem_settings). Note
+ that it always uses the first dict to calculate the fingerprint or the
+ device name. The rest would be used for asserting OEM properties only
+ (e.g. one package can be installed on one of these devices).
+ """
+ self.info_dict = info_dict
+ self.oem_dicts = oem_dicts
+
+ self._is_ab = info_dict.get("ab_update") == "true"
+ self._oem_props = info_dict.get("oem_fingerprint_properties")
+
+ if self._oem_props:
+ assert oem_dicts, "OEM source required for this build"
+
+ # These two should be computed only after setting self._oem_props.
+ self._device = self.GetOemProperty("ro.product.device")
+ self._fingerprint = self.CalculateFingerprint()
+
+ @property
+ def is_ab(self):
+ return self._is_ab
+
+ @property
+ def device(self):
+ return self._device
+
+ @property
+ def fingerprint(self):
+ return self._fingerprint
+
+ @property
+ def oem_props(self):
+ return self._oem_props
+
+ def __getitem__(self, key):
+ return self.info_dict[key]
+
+ def get(self, key, default=None):
+ return self.info_dict.get(key, default)
+
+ def GetBuildProp(self, prop):
+ """Returns the inquired build property."""
+ try:
+ return self.info_dict.get("build.prop", {})[prop]
+ except KeyError:
+ raise common.ExternalError("couldn't find %s in build.prop" % (prop,))
+
+ def GetVendorBuildProp(self, prop):
+ """Returns the inquired vendor build property."""
+ try:
+ return self.info_dict.get("vendor.build.prop", {})[prop]
+ except KeyError:
+ raise common.ExternalError(
+ "couldn't find %s in vendor.build.prop" % (prop,))
+
+ def GetOemProperty(self, key):
+ if self.oem_props is not None and key in self.oem_props:
+ return self.oem_dicts[0][key]
+ return self.GetBuildProp(key)
+
+ def CalculateFingerprint(self):
+ if self.oem_props is None:
+ return self.GetBuildProp("ro.build.fingerprint")
+ return "%s/%s/%s:%s" % (
+ self.GetOemProperty("ro.product.brand"),
+ self.GetOemProperty("ro.product.name"),
+ self.GetOemProperty("ro.product.device"),
+ self.GetBuildProp("ro.build.thumbprint"))
+
+ def WriteMountOemScript(self, script):
+ assert self.oem_props is not None
+ recovery_mount_options = self.info_dict.get("recovery_mount_options")
+ script.Mount("/oem", recovery_mount_options)
+
+ def WriteDeviceAssertions(self, script, oem_no_mount):
+ # Read the property directly if not using OEM properties.
+ if not self.oem_props:
+ script.AssertDevice(self.device)
+ return
+
+ # Otherwise assert OEM properties.
+ if not self.oem_dicts:
+ raise common.ExternalError(
+ "No OEM file provided to answer expected assertions")
+
+ for prop in self.oem_props.split():
+ values = []
+ for oem_dict in self.oem_dicts:
+ if prop in oem_dict:
+ values.append(oem_dict[prop])
+ if not values:
+ raise common.ExternalError(
+ "The OEM file is missing the property %s" % (prop,))
+ script.AssertOemProperty(prop, values, oem_no_mount)
+
+
def SignOutput(temp_zip_name, output_zip_name):
pw = OPTIONS.key_passwords[OPTIONS.package_key]
@@ -186,37 +317,15 @@
whole_file=True)
-def AppendAssertions(script, info_dict, oem_dicts=None):
- oem_props = info_dict.get("oem_fingerprint_properties")
- if not oem_props:
- device = GetBuildProp("ro.product.device", info_dict)
- script.AssertDevice(device)
- else:
- if not oem_dicts:
- raise common.ExternalError(
- "No OEM file provided to answer expected assertions")
- for prop in oem_props.split():
- values = []
- for oem_dict in oem_dicts:
- if oem_dict.get(prop):
- values.append(oem_dict[prop])
- if not values:
- raise common.ExternalError(
- "The OEM file is missing the property %s" % prop)
- script.AssertOemProperty(prop, values)
-
-
-def _LoadOemDicts(script, recovery_mount_options=None):
+def _LoadOemDicts(oem_source):
"""Returns the list of loaded OEM properties dict."""
- oem_dicts = None
- if OPTIONS.oem_source is None:
- raise common.ExternalError("OEM source required for this build")
- if not OPTIONS.oem_no_mount and script:
- script.Mount("/oem", recovery_mount_options)
+ if not oem_source:
+ return None
+
oem_dicts = []
- for oem_file in OPTIONS.oem_source:
- oem_dicts.append(common.LoadDictionaryFromLines(
- open(oem_file).readlines()))
+ for oem_file in oem_source:
+ with open(oem_file) as fp:
+ oem_dicts.append(common.LoadDictionaryFromLines(fp.readlines()))
return oem_dicts
@@ -267,25 +376,30 @@
return False
-def HasTrebleEnabled(target_files_zip, info_dict):
+def HasTrebleEnabled(target_files_zip, target_info):
return (HasVendorPartition(target_files_zip) and
- GetBuildProp("ro.treble.enabled", info_dict) == "true")
+ target_info.GetBuildProp("ro.treble.enabled") == "true")
-def GetOemProperty(name, oem_props, oem_dict, info_dict):
- if oem_props is not None and name in oem_props:
- return oem_dict[name]
- return GetBuildProp(name, info_dict)
+def WriteFingerprintAssertion(script, target_info, source_info):
+ source_oem_props = source_info.oem_props
+ target_oem_props = target_info.oem_props
-
-def CalculateFingerprint(oem_props, oem_dict, info_dict):
- if oem_props is None:
- return GetBuildProp("ro.build.fingerprint", info_dict)
- return "%s/%s/%s:%s" % (
- GetOemProperty("ro.product.brand", oem_props, oem_dict, info_dict),
- GetOemProperty("ro.product.name", oem_props, oem_dict, info_dict),
- GetOemProperty("ro.product.device", oem_props, oem_dict, info_dict),
- GetBuildProp("ro.build.thumbprint", info_dict))
+ if source_oem_props is None and target_oem_props is None:
+ script.AssertSomeFingerprint(
+ source_info.fingerprint, target_info.fingerprint)
+ elif source_oem_props is not None and target_oem_props is not None:
+ script.AssertSomeThumbprint(
+ target_info.GetBuildProp("ro.build.thumbprint"),
+ source_info.GetBuildProp("ro.build.thumbprint"))
+ elif source_oem_props is None and target_oem_props is not None:
+ script.AssertFingerprintOrThumbprint(
+ source_info.fingerprint,
+ target_info.GetBuildProp("ro.build.thumbprint"))
+ else:
+ script.AssertFingerprintOrThumbprint(
+ target_info.fingerprint,
+ source_info.GetBuildProp("ro.build.thumbprint"))
def GetImage(which, tmpdir):
@@ -313,9 +427,8 @@
return sparse_img.SparseImage(path, mappath, clobbered_blocks)
-def AddCompatibilityArchiveIfTrebleEnabled(target_zip, output_zip,
- target_info_dict,
- source_info_dict=None):
+def AddCompatibilityArchiveIfTrebleEnabled(target_zip, output_zip, target_info,
+ source_info=None):
"""Adds compatibility info into the output zip if it's Treble-enabled target.
Metadata used for on-device compatibility verification is retrieved from
@@ -328,9 +441,9 @@
Args:
target_zip: Zip file containing the source files to be included for OTA.
output_zip: Zip file that will be sent for OTA.
- target_info_dict: The dict that holds the target build info.
- source_info_dict: The dict that holds the source build info, if generating
- an incremental OTA; None otherwise.
+ target_info: The BuildInfo instance that holds the target build info.
+ source_info: The BuildInfo instance that holds the source build info, if
+ generating an incremental OTA; None otherwise.
"""
def AddCompatibilityArchive(system_updated, vendor_updated):
@@ -353,8 +466,8 @@
# Create new archive.
compatibility_archive = tempfile.NamedTemporaryFile()
- compatibility_archive_zip = zipfile.ZipFile(compatibility_archive, "w",
- compression=zipfile.ZIP_DEFLATED)
+ compatibility_archive_zip = zipfile.ZipFile(
+ compatibility_archive, "w", compression=zipfile.ZIP_DEFLATED)
# Add metadata.
for file_name in compatibility_files:
@@ -375,59 +488,55 @@
# Will only proceed if the target has enabled the Treble support (as well as
# having a /vendor partition).
- if not HasTrebleEnabled(target_zip, target_info_dict):
+ if not HasTrebleEnabled(target_zip, target_info):
return
# We don't support OEM thumbprint in Treble world (which calculates
# fingerprints in a different way as shown in CalculateFingerprint()).
- assert not target_info_dict.get("oem_fingerprint_properties")
+ assert not target_info.oem_props
# Full OTA carries the info for system/vendor both.
- if source_info_dict is None:
+ if source_info is None:
AddCompatibilityArchive(True, True)
return
- assert not source_info_dict.get("oem_fingerprint_properties")
+ assert not source_info.oem_props
- source_fp = GetBuildProp("ro.build.fingerprint", source_info_dict)
- target_fp = GetBuildProp("ro.build.fingerprint", target_info_dict)
+ source_fp = source_info.fingerprint
+ target_fp = target_info.fingerprint
system_updated = source_fp != target_fp
- source_fp_vendor = GetVendorBuildProp("ro.vendor.build.fingerprint",
- source_info_dict)
- target_fp_vendor = GetVendorBuildProp("ro.vendor.build.fingerprint",
- target_info_dict)
+ source_fp_vendor = source_info.GetVendorBuildProp(
+ "ro.vendor.build.fingerprint")
+ target_fp_vendor = target_info.GetVendorBuildProp(
+ "ro.vendor.build.fingerprint")
vendor_updated = source_fp_vendor != target_fp_vendor
AddCompatibilityArchive(system_updated, vendor_updated)
def WriteFullOTAPackage(input_zip, output_zip):
- # TODO: how to determine this? We don't know what version it will
- # be installed on top of. For now, we expect the API just won't
- # change very often. Similarly for fstab, it might have changed
- # in the target build.
- script = edify_generator.EdifyGenerator(3, OPTIONS.info_dict)
+ target_info = BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
- oem_props = OPTIONS.info_dict.get("oem_fingerprint_properties")
- oem_dicts = None
- if oem_props:
- recovery_mount_options = OPTIONS.info_dict.get("recovery_mount_options")
- oem_dicts = _LoadOemDicts(script, recovery_mount_options)
+ # We don't know what version it will be installed on top of. We expect the API
+ # just won't change very often. Similarly for fstab, it might have changed in
+ # the target build.
+ target_api_version = target_info["recovery_api_version"]
+ script = edify_generator.EdifyGenerator(target_api_version, target_info)
- target_fp = CalculateFingerprint(oem_props, oem_dicts and oem_dicts[0],
- OPTIONS.info_dict)
+ if target_info.oem_props and not OPTIONS.oem_no_mount:
+ target_info.WriteMountOemScript(script)
+
metadata = {
- "post-build": target_fp,
- "pre-device": GetOemProperty("ro.product.device", oem_props,
- oem_dicts and oem_dicts[0],
- OPTIONS.info_dict),
- "post-timestamp": GetBuildProp("ro.build.date.utc", OPTIONS.info_dict),
+ "post-build": target_info.fingerprint,
+ "pre-device": target_info.device,
+ "post-timestamp": target_info.GetBuildProp("ro.build.date.utc"),
+ "ota-type" : "BLOCK",
}
device_specific = common.DeviceSpecificParams(
input_zip=input_zip,
- input_version=OPTIONS.info_dict["recovery_api_version"],
+ input_version=target_api_version,
output_zip=output_zip,
script=script,
input_tmp=OPTIONS.input_tmp,
@@ -436,13 +545,12 @@
assert HasRecoveryPatch(input_zip)
- metadata["ota-type"] = "BLOCK"
-
- ts = GetBuildProp("ro.build.date.utc", OPTIONS.info_dict)
- ts_text = GetBuildProp("ro.build.date", OPTIONS.info_dict)
+ # Assertions (e.g. downgrade check, device properties check).
+ ts = target_info.GetBuildProp("ro.build.date.utc")
+ ts_text = target_info.GetBuildProp("ro.build.date")
script.AssertOlderBuild(ts, ts_text)
- AppendAssertions(script, OPTIONS.info_dict, oem_dicts)
+ target_info.WriteDeviceAssertions(script, OPTIONS.oem_no_mount)
device_specific.FullOTA_Assertions()
# Two-step package strategy (in chronological order, which is *not*
@@ -468,9 +576,9 @@
recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
OPTIONS.input_tmp, "RECOVERY")
if OPTIONS.two_step:
- if not OPTIONS.info_dict.get("multistage_support", None):
+ if not target_info.get("multistage_support"):
assert False, "two-step packages not supported by this build"
- fs = OPTIONS.info_dict["fstab"]["/misc"]
+ fs = target_info["fstab"]["/misc"]
assert fs.fs_type.upper() == "EMMC", \
"two-step packages only supported on devices with EMMC /misc partitions"
bcb_dev = {"bcb_dev": fs.device}
@@ -492,7 +600,7 @@
script.Comment("Stage 3/3")
# Dump fingerprints
- script.Print("Target: %s" % target_fp)
+ script.Print("Target: {}".format(target_info.fingerprint))
device_specific.FullOTA_InstallBegin()
@@ -525,10 +633,9 @@
vendor_diff = common.BlockDifference("vendor", vendor_tgt)
vendor_diff.WriteScript(script, output_zip)
- AddCompatibilityArchiveIfTrebleEnabled(input_zip, output_zip,
- OPTIONS.info_dict)
+ AddCompatibilityArchiveIfTrebleEnabled(input_zip, output_zip, target_info)
- common.CheckSize(boot_img.data, "boot.img", OPTIONS.info_dict)
+ common.CheckSize(boot_img.data, "boot.img", target_info)
common.ZipWriteStr(output_zip, "boot.img", boot_img.data)
script.ShowProgress(0.05, 5)
@@ -575,29 +682,12 @@
compress_type=zipfile.ZIP_STORED)
-def GetBuildProp(prop, info_dict):
- """Returns the inquired build property from a given info_dict."""
- try:
- return info_dict.get("build.prop", {})[prop]
- except KeyError:
- raise common.ExternalError("couldn't find %s in build.prop" % (prop,))
-
-
-def GetVendorBuildProp(prop, info_dict):
- """Returns the inquired vendor build property from a given info_dict."""
- try:
- return info_dict.get("vendor.build.prop", {})[prop]
- except KeyError:
- raise common.ExternalError(
- "couldn't find %s in vendor.build.prop" % (prop,))
-
-
-def HandleDowngradeMetadata(metadata):
+def HandleDowngradeMetadata(metadata, target_info, source_info):
# Only incremental OTAs are allowed to reach here.
assert OPTIONS.incremental_source is not None
- post_timestamp = GetBuildProp("ro.build.date.utc", OPTIONS.target_info_dict)
- pre_timestamp = GetBuildProp("ro.build.date.utc", OPTIONS.source_info_dict)
+ post_timestamp = target_info.GetBuildProp("ro.build.date.utc")
+ pre_timestamp = source_info.GetBuildProp("ro.build.date.utc")
is_downgrade = long(post_timestamp) < long(pre_timestamp)
if OPTIONS.downgrade:
@@ -607,72 +697,65 @@
metadata["ota-downgrade"] = "yes"
elif OPTIONS.timestamp:
if not is_downgrade:
- raise RuntimeError("--timestamp specified but no timestamp hack needed: "
- "pre: %s, post: %s" % (pre_timestamp, post_timestamp))
+ raise RuntimeError("--override_timestamp specified but no timestamp hack "
+ "needed: pre: %s, post: %s" % (pre_timestamp,
+ post_timestamp))
metadata["post-timestamp"] = str(long(pre_timestamp) + 1)
else:
if is_downgrade:
raise RuntimeError("Downgrade detected based on timestamp check: "
- "pre: %s, post: %s. Need to specify --timestamp OR "
- "--downgrade to allow building the incremental." % (
- pre_timestamp, post_timestamp))
+ "pre: %s, post: %s. Need to specify "
+ "--override_timestamp OR --downgrade to allow "
+ "building the incremental." % (pre_timestamp,
+ post_timestamp))
metadata["post-timestamp"] = post_timestamp
def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
- source_version = OPTIONS.source_info_dict["recovery_api_version"]
- target_version = OPTIONS.target_info_dict["recovery_api_version"]
+ target_info = BuildInfo(OPTIONS.target_info_dict, OPTIONS.oem_dicts)
+ source_info = BuildInfo(OPTIONS.source_info_dict, OPTIONS.oem_dicts)
- if source_version == 0:
+ target_api_version = target_info["recovery_api_version"]
+ source_api_version = source_info["recovery_api_version"]
+ if source_api_version == 0:
print("WARNING: generating edify script for a source that "
"can't install it.")
- script = edify_generator.EdifyGenerator(
- source_version, OPTIONS.target_info_dict,
- fstab=OPTIONS.source_info_dict["fstab"])
- source_oem_props = OPTIONS.source_info_dict.get("oem_fingerprint_properties")
- target_oem_props = OPTIONS.target_info_dict.get("oem_fingerprint_properties")
- oem_dicts = None
- if source_oem_props or target_oem_props:
- recovery_mount_options = OPTIONS.source_info_dict.get(
- "recovery_mount_options")
- oem_dicts = _LoadOemDicts(script, recovery_mount_options)
+ script = edify_generator.EdifyGenerator(
+ source_api_version, target_info, fstab=source_info["fstab"])
+
+ if target_info.oem_props or source_info.oem_props:
+ if not OPTIONS.oem_no_mount:
+ source_info.WriteMountOemScript(script)
metadata = {
- "pre-device": GetOemProperty("ro.product.device", source_oem_props,
- oem_dicts and oem_dicts[0],
- OPTIONS.source_info_dict),
+ "pre-device": source_info.device,
"ota-type": "BLOCK",
}
- HandleDowngradeMetadata(metadata)
+ HandleDowngradeMetadata(metadata, target_info, source_info)
device_specific = common.DeviceSpecificParams(
source_zip=source_zip,
- source_version=source_version,
+ source_version=source_api_version,
target_zip=target_zip,
- target_version=target_version,
+ target_version=target_api_version,
output_zip=output_zip,
script=script,
metadata=metadata,
- info_dict=OPTIONS.source_info_dict)
+ info_dict=source_info)
- source_fp = CalculateFingerprint(source_oem_props, oem_dicts and oem_dicts[0],
- OPTIONS.source_info_dict)
- target_fp = CalculateFingerprint(target_oem_props, oem_dicts and oem_dicts[0],
- OPTIONS.target_info_dict)
- metadata["pre-build"] = source_fp
- metadata["post-build"] = target_fp
- metadata["pre-build-incremental"] = GetBuildProp(
- "ro.build.version.incremental", OPTIONS.source_info_dict)
- metadata["post-build-incremental"] = GetBuildProp(
- "ro.build.version.incremental", OPTIONS.target_info_dict)
+ metadata["pre-build"] = source_info.fingerprint
+ metadata["post-build"] = target_info.fingerprint
+ metadata["pre-build-incremental"] = source_info.GetBuildProp(
+ "ro.build.version.incremental")
+ metadata["post-build-incremental"] = target_info.GetBuildProp(
+ "ro.build.version.incremental")
source_boot = common.GetBootableImage(
- "/tmp/boot.img", "boot.img", OPTIONS.source_tmp, "BOOT",
- OPTIONS.source_info_dict)
+ "/tmp/boot.img", "boot.img", OPTIONS.source_tmp, "BOOT", source_info)
target_boot = common.GetBootableImage(
- "/tmp/boot.img", "boot.img", OPTIONS.target_tmp, "BOOT")
+ "/tmp/boot.img", "boot.img", OPTIONS.target_tmp, "BOOT", target_info)
updating_boot = (not OPTIONS.two_step and
(source_boot.data != target_boot.data))
@@ -683,19 +766,18 @@
system_tgt = GetImage("system", OPTIONS.target_tmp)
blockimgdiff_version = max(
- int(i) for i in
- OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
+ int(i) for i in target_info.get("blockimgdiff_versions", "1").split(","))
assert blockimgdiff_version >= 3
# Check the first block of the source system partition for remount R/W only
# if the filesystem is ext4.
- system_src_partition = OPTIONS.source_info_dict["fstab"]["/system"]
+ system_src_partition = source_info["fstab"]["/system"]
check_first_block = system_src_partition.fs_type == "ext4"
# Disable using imgdiff for squashfs. 'imgdiff -z' expects input files to be
# in zip formats. However with squashfs, a) all files are compressed in LZ4;
# b) the blocks listed in block map may not contain all the bytes for a given
# file (because they're rounded to be 4K-aligned).
- system_tgt_partition = OPTIONS.target_info_dict["fstab"]["/system"]
+ system_tgt_partition = target_info["fstab"]["/system"]
disable_imgdiff = (system_src_partition.fs_type == "squashfs" or
system_tgt_partition.fs_type == "squashfs")
system_diff = common.BlockDifference("system", system_tgt, system_src,
@@ -711,7 +793,7 @@
# Check first block of vendor partition for remount R/W only if
# disk type is ext4
- vendor_partition = OPTIONS.source_info_dict["fstab"]["/vendor"]
+ vendor_partition = source_info["fstab"]["/vendor"]
check_first_block = vendor_partition.fs_type == "ext4"
disable_imgdiff = vendor_partition.fs_type == "squashfs"
vendor_diff = common.BlockDifference("vendor", vendor_tgt, vendor_src,
@@ -722,10 +804,10 @@
vendor_diff = None
AddCompatibilityArchiveIfTrebleEnabled(
- target_zip, output_zip, OPTIONS.target_info_dict,
- OPTIONS.source_info_dict)
+ target_zip, output_zip, target_info, source_info)
- AppendAssertions(script, OPTIONS.target_info_dict, oem_dicts)
+ # Assertions (e.g. device properties check).
+ target_info.WriteDeviceAssertions(script, OPTIONS.oem_no_mount)
device_specific.IncrementalOTA_Assertions()
# Two-step incremental package strategy (in chronological order,
@@ -751,12 +833,12 @@
# (allow recovery to mark itself finished and reboot)
if OPTIONS.two_step:
- if not OPTIONS.source_info_dict.get("multistage_support", None):
+ if not source_info.get("multistage_support"):
assert False, "two-step packages not supported by this build"
fs = OPTIONS.source_info_dict["fstab"]["/misc"]
assert fs.fs_type.upper() == "EMMC", \
"two-step packages only supported on devices with EMMC /misc partitions"
- bcb_dev = {"bcb_dev": fs.device}
+ bcb_dev = {"bcb_dev" : fs.device}
common.ZipWriteStr(output_zip, "recovery.img", target_recovery.data)
script.AppendExtra("""
if get_stage("%(bcb_dev)s") == "2/3" then
@@ -776,27 +858,14 @@
script.Comment("Stage 1/3")
# Dump fingerprints
- script.Print("Source: %s" % (source_fp,))
- script.Print("Target: %s" % (target_fp,))
+ script.Print("Source: {}".format(source_info.fingerprint))
+ script.Print("Target: {}".format(target_info.fingerprint))
script.Print("Verifying current system...")
device_specific.IncrementalOTA_VerifyBegin()
- if source_oem_props is None and target_oem_props is None:
- script.AssertSomeFingerprint(source_fp, target_fp)
- elif source_oem_props is not None and target_oem_props is not None:
- script.AssertSomeThumbprint(
- GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict),
- GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
- elif source_oem_props is None and target_oem_props is not None:
- script.AssertFingerprintOrThumbprint(
- source_fp,
- GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict))
- else:
- script.AssertFingerprintOrThumbprint(
- target_fp,
- GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
+ WriteFingerprintAssertion(script, target_info, source_info)
# Check the required cache size (i.e. stashed blocks).
size = []
@@ -806,8 +875,7 @@
size.append(vendor_diff.required_cache)
if updating_boot:
- boot_type, boot_device = common.GetTypeAndDevice(
- "/boot", OPTIONS.source_info_dict)
+ boot_type, boot_device = common.GetTypeAndDevice("/boot", source_info)
d = common.Difference(target_boot, source_boot)
_, _, d = d.ComputePatch()
if d is None:
@@ -984,7 +1052,8 @@
cmd.extend(["-passin", "pass:" + pw] if pw else ["-nocrypt"])
rsa_key = common.MakeTempFile(prefix="key-", suffix=".key")
cmd.extend(["-out", rsa_key])
- p1 = common.Run(cmd, verbose=False, stdout=log_file, stderr=subprocess.STDOUT)
+ p1 = common.Run(cmd, verbose=False, stdout=log_file,
+ stderr=subprocess.STDOUT)
p1.communicate()
assert p1.returncode == 0, "openssl pkcs8 failed"
@@ -993,35 +1062,32 @@
output_zip = zipfile.ZipFile(temp_zip_file, "w",
compression=zipfile.ZIP_DEFLATED)
- # Metadata to comply with Android OTA package format.
- oem_props = OPTIONS.info_dict.get("oem_fingerprint_properties", None)
- oem_dicts = None
- if oem_props:
- oem_dicts = _LoadOemDicts(None)
+ if source_file is not None:
+ target_info = BuildInfo(OPTIONS.target_info_dict, OPTIONS.oem_dicts)
+ source_info = BuildInfo(OPTIONS.source_info_dict, OPTIONS.oem_dicts)
+ else:
+ target_info = BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
+ source_info = None
+ # Metadata to comply with Android OTA package format.
metadata = {
- "post-build": CalculateFingerprint(oem_props, oem_dicts and oem_dicts[0],
- OPTIONS.info_dict),
- "post-build-incremental" : GetBuildProp("ro.build.version.incremental",
- OPTIONS.info_dict),
- "pre-device": GetOemProperty("ro.product.device", oem_props,
- oem_dicts and oem_dicts[0],
- OPTIONS.info_dict),
- "ota-required-cache": "0",
- "ota-type": "AB",
+ "post-build" : target_info.fingerprint,
+ "post-build-incremental" : target_info.GetBuildProp(
+ "ro.build.version.incremental"),
+ "ota-required-cache" : "0",
+ "ota-type" : "AB",
}
if source_file is not None:
- metadata["pre-build"] = CalculateFingerprint(oem_props,
- oem_dicts and oem_dicts[0],
- OPTIONS.source_info_dict)
- metadata["pre-build-incremental"] = GetBuildProp(
- "ro.build.version.incremental", OPTIONS.source_info_dict)
+ metadata["pre-device"] = source_info.device
+ metadata["pre-build"] = source_info.fingerprint
+ metadata["pre-build-incremental"] = source_info.GetBuildProp(
+ "ro.build.version.incremental")
- HandleDowngradeMetadata(metadata)
+ HandleDowngradeMetadata(metadata, target_info, source_info)
else:
- metadata["post-timestamp"] = GetBuildProp(
- "ro.build.date.utc", OPTIONS.info_dict)
+ metadata["pre-device"] = target_info.device
+ metadata["post-timestamp"] = target_info.GetBuildProp("ro.build.date.utc")
# 1. Generate payload.
payload_file = common.MakeTempFile(prefix="payload-", suffix=".bin")
@@ -1120,23 +1186,23 @@
# If dm-verity is supported for the device, copy contents of care_map
# into A/B OTA package.
target_zip = zipfile.ZipFile(target_file, "r")
- if (OPTIONS.info_dict.get("verity") == "true" or
- OPTIONS.info_dict.get("avb_enable") == "true"):
+ if (target_info.get("verity") == "true" or
+ target_info.get("avb_enable") == "true"):
care_map_path = "META/care_map.txt"
namelist = target_zip.namelist()
if care_map_path in namelist:
care_map_data = target_zip.read(care_map_path)
common.ZipWriteStr(output_zip, "care_map.txt", care_map_data,
- compress_type=zipfile.ZIP_STORED)
+ compress_type=zipfile.ZIP_STORED)
else:
print("Warning: cannot find care map file in target_file package")
- # OPTIONS.source_info_dict must be None for incrementals.
+ # source_info must be None for full OTAs.
if source_file is None:
- assert OPTIONS.source_info_dict is None
+ assert source_info is None
AddCompatibilityArchiveIfTrebleEnabled(
- target_zip, output_zip, OPTIONS.info_dict, OPTIONS.source_info_dict)
+ target_zip, output_zip, target_info, source_info)
common.ZipClose(target_zip)
@@ -1221,8 +1287,6 @@
OPTIONS.block_based = True
elif o in ("-b", "--binary"):
OPTIONS.updater_binary = a
- elif o in ("--no_fallback_to_full",):
- OPTIONS.fallback_to_full = False
elif o == "--stash_threshold":
try:
OPTIONS.stash_threshold = float(a)
@@ -1260,7 +1324,6 @@
"oem_settings=",
"oem_no_mount",
"verify",
- "no_fallback_to_full",
"stash_threshold=",
"log_diff=",
"payload_signer=",
@@ -1289,12 +1352,15 @@
# Load the dict file from the zip directly to have a peek at the OTA type.
# For packages using A/B update, unzipping is not needed.
if OPTIONS.extracted_input is not None:
- OPTIONS.info_dict = common.LoadInfoDict(OPTIONS.extracted_input, OPTIONS.extracted_input)
+ OPTIONS.info_dict = common.LoadInfoDict(OPTIONS.extracted_input,
+ OPTIONS.extracted_input)
else:
input_zip = zipfile.ZipFile(args[0], "r")
OPTIONS.info_dict = common.LoadInfoDict(input_zip)
common.ZipClose(input_zip)
+ OPTIONS.oem_dicts = _LoadOemDicts(OPTIONS.oem_source)
+
ab_update = OPTIONS.info_dict.get("ab_update") == "true"
# Use the default key to sign the package if not specified with package_key.
@@ -1337,7 +1403,8 @@
if OPTIONS.extracted_input is not None:
OPTIONS.input_tmp = OPTIONS.extracted_input
OPTIONS.target_tmp = OPTIONS.input_tmp
- OPTIONS.info_dict = common.LoadInfoDict(OPTIONS.input_tmp, OPTIONS.input_tmp)
+ OPTIONS.info_dict = common.LoadInfoDict(OPTIONS.input_tmp,
+ OPTIONS.input_tmp)
input_zip = zipfile.ZipFile(args[0], "r")
else:
print("unzipping target target-files...")
@@ -1394,8 +1461,7 @@
if OPTIONS.incremental_source is None:
WriteFullOTAPackage(input_zip, output_zip)
- # Generate an incremental OTA. It will fall back to generate a full OTA on
- # failure unless no_fallback_to_full is specified.
+ # Generate an incremental OTA.
else:
print("unzipping source target-files...")
OPTIONS.source_tmp, source_zip = common.UnzipTemp(
@@ -1407,22 +1473,14 @@
if OPTIONS.verbose:
print("--- source info ---")
common.DumpInfoDict(OPTIONS.source_info_dict)
- try:
- WriteBlockIncrementalOTAPackage(input_zip, source_zip, output_zip)
- if OPTIONS.log_diff:
- out_file = open(OPTIONS.log_diff, 'w')
+
+ WriteBlockIncrementalOTAPackage(input_zip, source_zip, output_zip)
+
+ if OPTIONS.log_diff:
+ with open(OPTIONS.log_diff, 'w') as out_file:
import target_files_diff
- target_files_diff.recursiveDiff('',
- OPTIONS.source_tmp,
- OPTIONS.input_tmp,
- out_file)
- out_file.close()
- except ValueError:
- if not OPTIONS.fallback_to_full:
- raise
- print("--- failed to build incremental; falling back to full ---")
- OPTIONS.incremental_source = None
- WriteFullOTAPackage(input_zip, output_zip)
+ target_files_diff.recursiveDiff(
+ '', OPTIONS.source_tmp, OPTIONS.input_tmp, out_file)
common.ZipClose(output_zip)
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
new file mode 100644
index 0000000..0948c61
--- /dev/null
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -0,0 +1,302 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import copy
+import unittest
+
+import common
+from ota_from_target_files import (
+ _LoadOemDicts, BuildInfo, WriteFingerprintAssertion)
+
+
+class MockScriptWriter(object):
+ """A class that mocks edify_generator.EdifyGenerator.
+
+ It simply pushes the incoming arguments onto script stack, which is to assert
+ the calls to EdifyGenerator functions.
+ """
+
+ def __init__(self):
+ self.script = []
+
+ def Mount(self, *args):
+ self.script.append(('Mount',) + args)
+
+ def AssertDevice(self, *args):
+ self.script.append(('AssertDevice',) + args)
+
+ def AssertOemProperty(self, *args):
+ self.script.append(('AssertOemProperty',) + args)
+
+ def AssertFingerprintOrThumbprint(self, *args):
+ self.script.append(('AssertFingerprintOrThumbprint',) + args)
+
+ def AssertSomeFingerprint(self, *args):
+ self.script.append(('AssertSomeFingerprint',) + args)
+
+ def AssertSomeThumbprint(self, *args):
+ self.script.append(('AssertSomeThumbprint',) + args)
+
+
+class BuildInfoTest(unittest.TestCase):
+
+ TEST_INFO_DICT = {
+ 'build.prop' : {
+ 'ro.product.device' : 'product-device',
+ 'ro.product.name' : 'product-name',
+ 'ro.build.fingerprint' : 'build-fingerprint',
+ 'ro.build.foo' : 'build-foo',
+ },
+ 'vendor.build.prop' : {
+ 'ro.vendor.build.fingerprint' : 'vendor-build-fingerprint',
+ },
+ 'property1' : 'value1',
+ 'property2' : 4096,
+ }
+
+ TEST_INFO_DICT_USES_OEM_PROPS = {
+ 'build.prop' : {
+ 'ro.product.name' : 'product-name',
+ 'ro.build.thumbprint' : 'build-thumbprint',
+ 'ro.build.bar' : 'build-bar',
+ },
+ 'vendor.build.prop' : {
+ 'ro.vendor.build.fingerprint' : 'vendor-build-fingerprint',
+ },
+ 'property1' : 'value1',
+ 'property2' : 4096,
+ 'oem_fingerprint_properties' : 'ro.product.device ro.product.brand',
+ }
+
+ TEST_OEM_DICTS = [
+ {
+ 'ro.product.brand' : 'brand1',
+ 'ro.product.device' : 'device1',
+ },
+ {
+ 'ro.product.brand' : 'brand2',
+ 'ro.product.device' : 'device2',
+ },
+ {
+ 'ro.product.brand' : 'brand3',
+ 'ro.product.device' : 'device3',
+ },
+ ]
+
+ def test_init(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT, None)
+ self.assertEqual('product-device', target_info.device)
+ self.assertEqual('build-fingerprint', target_info.fingerprint)
+ self.assertFalse(target_info.is_ab)
+ self.assertIsNone(target_info.oem_props)
+
+ def test_init_with_oem_props(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ self.assertEqual('device1', target_info.device)
+ self.assertEqual('brand1/product-name/device1:build-thumbprint',
+ target_info.fingerprint)
+
+ # Swap the order in oem_dicts, which would lead to different BuildInfo.
+ oem_dicts = copy.copy(self.TEST_OEM_DICTS)
+ oem_dicts[0], oem_dicts[2] = oem_dicts[2], oem_dicts[0]
+ target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS, oem_dicts)
+ self.assertEqual('device3', target_info.device)
+ self.assertEqual('brand3/product-name/device3:build-thumbprint',
+ target_info.fingerprint)
+
+ # Missing oem_dict should be rejected.
+ self.assertRaises(AssertionError, BuildInfo,
+ self.TEST_INFO_DICT_USES_OEM_PROPS, None)
+
+ def test___getitem__(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT, None)
+ self.assertEqual('value1', target_info['property1'])
+ self.assertEqual(4096, target_info['property2'])
+ self.assertEqual('build-foo', target_info['build.prop']['ro.build.foo'])
+
+ def test___getitem__with_oem_props(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ self.assertEqual('value1', target_info['property1'])
+ self.assertEqual(4096, target_info['property2'])
+ self.assertRaises(KeyError,
+ lambda: target_info['build.prop']['ro.build.foo'])
+
+ def test_get(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT, None)
+ self.assertEqual('value1', target_info.get('property1'))
+ self.assertEqual(4096, target_info.get('property2'))
+ self.assertEqual(4096, target_info.get('property2', 1024))
+ self.assertEqual(1024, target_info.get('property-nonexistent', 1024))
+ self.assertEqual('build-foo', target_info.get('build.prop')['ro.build.foo'])
+
+ def test_get_with_oem_props(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ self.assertEqual('value1', target_info.get('property1'))
+ self.assertEqual(4096, target_info.get('property2'))
+ self.assertEqual(4096, target_info.get('property2', 1024))
+ self.assertEqual(1024, target_info.get('property-nonexistent', 1024))
+ self.assertIsNone(target_info.get('build.prop').get('ro.build.foo'))
+ self.assertRaises(KeyError,
+ lambda: target_info.get('build.prop')['ro.build.foo'])
+
+ def test_GetBuildProp(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT, None)
+ self.assertEqual('build-foo', target_info.GetBuildProp('ro.build.foo'))
+ self.assertRaises(common.ExternalError, target_info.GetBuildProp,
+ 'ro.build.nonexistent')
+
+ def test_GetBuildProp_with_oem_props(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ self.assertEqual('build-bar', target_info.GetBuildProp('ro.build.bar'))
+ self.assertRaises(common.ExternalError, target_info.GetBuildProp,
+ 'ro.build.nonexistent')
+
+ def test_GetVendorBuildProp(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT, None)
+ self.assertEqual('vendor-build-fingerprint',
+ target_info.GetVendorBuildProp(
+ 'ro.vendor.build.fingerprint'))
+ self.assertRaises(common.ExternalError, target_info.GetVendorBuildProp,
+ 'ro.build.nonexistent')
+
+ def test_GetVendorBuildProp_with_oem_props(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ self.assertEqual('vendor-build-fingerprint',
+ target_info.GetVendorBuildProp(
+ 'ro.vendor.build.fingerprint'))
+ self.assertRaises(common.ExternalError, target_info.GetVendorBuildProp,
+ 'ro.build.nonexistent')
+
+ def test_WriteMountOemScript(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ script_writer = MockScriptWriter()
+ target_info.WriteMountOemScript(script_writer)
+ self.assertEqual([('Mount', '/oem', None)], script_writer.script)
+
+ def test_WriteDeviceAssertions(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT, None)
+ script_writer = MockScriptWriter()
+ target_info.WriteDeviceAssertions(script_writer, False)
+ self.assertEqual([('AssertDevice', 'product-device')], script_writer.script)
+
+ def test_WriteDeviceAssertions_with_oem_props(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ script_writer = MockScriptWriter()
+ target_info.WriteDeviceAssertions(script_writer, False)
+ self.assertEqual(
+ [
+ ('AssertOemProperty', 'ro.product.device',
+ ['device1', 'device2', 'device3'], False),
+ ('AssertOemProperty', 'ro.product.brand',
+ ['brand1', 'brand2', 'brand3'], False),
+ ],
+ script_writer.script)
+
+ def test_WriteFingerprintAssertion_without_oem_props(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT, None)
+ source_info_dict = copy.deepcopy(self.TEST_INFO_DICT)
+ source_info_dict['build.prop']['ro.build.fingerprint'] = (
+ 'source-build-fingerprint')
+ source_info = BuildInfo(source_info_dict, None)
+
+ script_writer = MockScriptWriter()
+ WriteFingerprintAssertion(script_writer, target_info, source_info)
+ self.assertEqual(
+ [('AssertSomeFingerprint', 'source-build-fingerprint',
+ 'build-fingerprint')],
+ script_writer.script)
+
+ def test_WriteFingerprintAssertion_with_source_oem_props(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT, None)
+ source_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+
+ script_writer = MockScriptWriter()
+ WriteFingerprintAssertion(script_writer, target_info, source_info)
+ self.assertEqual(
+ [('AssertFingerprintOrThumbprint', 'build-fingerprint',
+ 'build-thumbprint')],
+ script_writer.script)
+
+ def test_WriteFingerprintAssertion_with_target_oem_props(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ source_info = BuildInfo(self.TEST_INFO_DICT, None)
+
+ script_writer = MockScriptWriter()
+ WriteFingerprintAssertion(script_writer, target_info, source_info)
+ self.assertEqual(
+ [('AssertFingerprintOrThumbprint', 'build-fingerprint',
+ 'build-thumbprint')],
+ script_writer.script)
+
+ def test_WriteFingerprintAssertion_with_both_oem_props(self):
+ target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ source_info_dict = copy.deepcopy(self.TEST_INFO_DICT_USES_OEM_PROPS)
+ source_info_dict['build.prop']['ro.build.thumbprint'] = (
+ 'source-build-thumbprint')
+ source_info = BuildInfo(source_info_dict, self.TEST_OEM_DICTS)
+
+ script_writer = MockScriptWriter()
+ WriteFingerprintAssertion(script_writer, target_info, source_info)
+ self.assertEqual(
+ [('AssertSomeThumbprint', 'build-thumbprint',
+ 'source-build-thumbprint')],
+ script_writer.script)
+
+
+class LoadOemDictsTest(unittest.TestCase):
+
+ def tearDown(self):
+ common.Cleanup()
+
+ def test_NoneDict(self):
+ self.assertIsNone(_LoadOemDicts(None))
+
+ def test_SingleDict(self):
+ dict_file = common.MakeTempFile()
+ with open(dict_file, 'w') as dict_fp:
+ dict_fp.write('abc=1\ndef=2\nxyz=foo\na.b.c=bar\n')
+
+ oem_dicts = _LoadOemDicts([dict_file])
+ self.assertEqual(1, len(oem_dicts))
+ self.assertEqual('foo', oem_dicts[0]['xyz'])
+ self.assertEqual('bar', oem_dicts[0]['a.b.c'])
+
+ def test_MultipleDicts(self):
+ oem_source = []
+ for i in range(3):
+ dict_file = common.MakeTempFile()
+ with open(dict_file, 'w') as dict_fp:
+ dict_fp.write(
+ 'ro.build.index={}\ndef=2\nxyz=foo\na.b.c=bar\n'.format(i))
+ oem_source.append(dict_file)
+
+ oem_dicts = _LoadOemDicts(oem_source)
+ self.assertEqual(3, len(oem_dicts))
+ for i, oem_dict in enumerate(oem_dicts):
+ self.assertEqual('2', oem_dict['def'])
+ self.assertEqual('foo', oem_dict['xyz'])
+ self.assertEqual('bar', oem_dict['a.b.c'])
+ self.assertEqual('{}'.format(i), oem_dict['ro.build.index'])