Merge "Revert "Switch to llvm-ar""
diff --git a/core/allowed_ndk_types.mk b/core/allowed_ndk_types.mk
new file mode 100644
index 0000000..b5a85ca
--- /dev/null
+++ b/core/allowed_ndk_types.mk
@@ -0,0 +1,87 @@
+# Determines the types of NDK modules the current module is allowed to link to.
+# Input variables:
+# LOCAL_MODULE
+# LOCAL_MODULE_CLASS
+# LOCAL_NDK_STL_VARIANT
+# LOCAL_SDK_VERSION
+# Output variables:
+# my_ndk_stl_family: Family of the NDK STL.
+# my_ndk_stl_link_type: STL link type, static or shared.
+# my_allowed_ndk_types: Types of NDK modules that may be linked.
+# my_warn_ndk_types: Types of NDK modules that shouldn't be linked, but are.
+
+my_allowed_ndk_types :=
+my_warn_ndk_types :=
+my_ndk_stl_family :=
+my_ndk_stl_link_type :=
+
+ifdef LOCAL_SDK_VERSION
+ ifeq ($(LOCAL_NDK_STL_VARIANT),)
+ my_ndk_stl_family := system
+ my_ndk_stl_link_type := shared
+ else ifeq ($(LOCAL_NDK_STL_VARIANT),system)
+ my_ndk_stl_family := system
+ my_ndk_stl_link_type := shared
+ else ifeq ($(LOCAL_NDK_STL_VARIANT),c++_shared)
+ my_ndk_stl_family := libc++
+ my_ndk_stl_link_type := shared
+ 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
+ else
+ $(call pretty-error,invalid LOCAL_NDK_STL_VARIANT: $(LOCAL_NDK_STL_VARIANT))
+ endif
+
+ ifeq ($(LOCAL_MODULE_CLASS),STATIC_LIBRARIES)
+ # The "none" link type indicates that nothing is actually linked. Since
+ # this is a static library, it's still up to the final use of the
+ # library whether a static or shared STL should be used.
+ my_ndk_stl_link_type := none
+ endif
+
+ # The system STL is only the C++ ABI layer, so it's compatible with any STL.
+ my_allowed_ndk_types += native:ndk:system:shared
+ my_allowed_ndk_types += native:ndk:system:none
+
+ # Libaries that don't use the STL can be linked to anything.
+ my_allowed_ndk_types += native:ndk:none:none
+
+ # And it's always okay to link a static library that uses your own STL type.
+ # Since nothing was actually linked for the static library, it is up to the
+ # first linked library in the dependency chain which gets used.
+ my_allowed_ndk_types += native:ndk:$(my_ndk_stl_family):none
+
+ ifeq ($(LOCAL_MODULE_CLASS),APPS)
+ # For an app package, it's actually okay to depend on any set of STLs.
+ # If any of the individual libraries depend on each other they've
+ # 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 \
+
+ # The "none" link type that used by static libraries is intentionally
+ # omitted here. We should only be dealing with shared libraries in
+ # LOCAL_JNI_SHARED_LIBRARIES.
+ else ifeq ($(my_ndk_stl_link_type),shared)
+ # Modules linked to a shared STL can only use another shared STL.
+ my_allowed_ndk_types += native:ndk:$(my_ndk_stl_family):shared
+ endif
+ # 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
+ ifeq ($(LOCAL_MODULE_CLASS),APPS)
+ # CTS is bad and it should feel bad: http://b/13249737
+ my_warn_ndk_types += native:ndk:libc++:static
+ endif
+endif
diff --git a/core/binary.mk b/core/binary.mk
index 92f9959..06b0d0e 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -189,7 +189,7 @@
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 gnustl_static, $(LOCAL_NDK_STL_VARIANT))))
+ ifneq (1,$(words $(filter none system stlport_static stlport_shared 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))
@@ -232,17 +232,11 @@
my_ldlibs += -ldl
my_ndk_cpp_std_version := c++11
- else # LOCAL_NDK_STL_VARIANT is not c++_* either
- ifneq (,$(filter gnustl_%, $(LOCAL_NDK_STL_VARIANT)))
- my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/gnu-libstdc++/$($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NDK_GCC_VERSION)/libs/$(my_cpu_variant)/include \
- $(my_ndk_source_root)/cxx-stl/gnu-libstdc++/$($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NDK_GCC_VERSION)/include
- my_ndk_stl_static_lib := $(my_ndk_source_root)/cxx-stl/gnu-libstdc++/$($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NDK_GCC_VERSION)/libs/$(my_cpu_variant)/libgnustl_static.a
else # LOCAL_NDK_STL_VARIANT must be none
# Do nothing.
endif
endif
endif
- endif
endif
ifneq ($(LOCAL_USE_VNDK),)
@@ -1404,10 +1398,12 @@
## other NDK-built libraries
####################################################
+include $(BUILD_SYSTEM)/allowed_ndk_types.mk
+
ifdef LOCAL_SDK_VERSION
-my_link_type := native:ndk
-my_warn_types :=
-my_allowed_types := native:ndk
+my_link_type := native:ndk:$(my_ndk_stl_family):$(my_ndk_stl_link_type)
+my_warn_types := $(my_warn_ndk_types)
+my_allowed_types := $(my_allowed_ndk_types)
else ifdef LOCAL_USE_VNDK
_name := $(patsubst %.vendor,%,$(LOCAL_MODULE))
ifneq ($(filter $(_name),$(VNDK_CORE_LIBRARIES) $(VNDK_SAMEPROCESS_LIBRARIES) $(LLNDK_LIBRARIES)),)
@@ -1427,8 +1423,8 @@
endif
else
my_link_type := native:platform
-my_warn_types :=
-my_allowed_types := native:ndk native:platform
+my_warn_types := $(my_warn_ndk_types)
+my_allowed_types := $(my_allowed_ndk_types) native:platform
endif
my_link_deps := $(addprefix STATIC_LIBRARIES:,$(my_whole_static_libraries) $(my_static_libraries))
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 89a39a8..255c02b 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -287,7 +287,7 @@
# Check BOARD_VNDK_VERSION
define check_vndk_version
$(eval vndk_path := prebuilts/vndk/v$(1)) \
- $(if $(wildcard $(vndk_path)/Android.bp),,$(error VNDK version $(1) not found))
+ $(if $(wildcard $(vndk_path)/*/Android.bp),,$(error VNDK version $(1) not found))
endef
ifdef BOARD_VNDK_VERSION
diff --git a/core/install_jni_libs_internal.mk b/core/install_jni_libs_internal.mk
index 265d482..80e0c24 100644
--- a/core/install_jni_libs_internal.mk
+++ b/core/install_jni_libs_internal.mk
@@ -108,15 +108,16 @@
endif # outer my_prebuilt_jni_libs
# Verify that all included libraries are built against the NDK
+include $(BUILD_SYSTEM)/allowed_ndk_types.mk
ifneq ($(strip $(LOCAL_JNI_SHARED_LIBRARIES)),)
ifneq ($(LOCAL_SDK_VERSION),)
my_link_type := app:sdk
-my_warn_types := native:platform
-my_allowed_types := native:ndk
+my_warn_types := native:platform $(my_warn_ndk_types)
+my_allowed_types := $(my_allowed_ndk_types)
else
my_link_type := app:platform
-my_warn_types :=
-my_allowed_types := native:ndk native:platform native:vendor native:vndk native:vndk_private
+my_warn_types := $(my_warn_ndk_types)
+my_allowed_types := $(my_allowed_ndk_types) native:platform native:vendor native:vndk native:vndk_private
endif
my_link_deps := $(addprefix SHARED_LIBRARIES:,$(LOCAL_JNI_SHARED_LIBRARIES))
diff --git a/core/java_library.mk b/core/java_library.mk
index e4916b8..8cf0074 100644
--- a/core/java_library.mk
+++ b/core/java_library.mk
@@ -42,6 +42,8 @@
ifeq (true,$(LOCAL_EMMA_INSTRUMENT))
ifeq (true,$(EMMA_INSTRUMENT_STATIC))
LOCAL_STATIC_JAVA_LIBRARIES += jacocoagent
+# Exclude jacoco classes from proguard
+LOCAL_PROGUARD_FLAGS += -include $(BUILD_SYSTEM)/proguard.jacoco.flags
endif # LOCAL_EMMA_INSTRUMENT
endif # EMMA_INSTRUMENT_STATIC
else
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 2a63817..e153a8a 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -275,6 +275,8 @@
ifneq ($(LOCAL_SRC_FILES)$(LOCAL_STATIC_JAVA_LIBRARIES)$(LOCAL_SOURCE_FILES_ALL_GENERATED),)
# Only add jacocoagent if the package contains some java code
LOCAL_STATIC_JAVA_LIBRARIES += jacocoagent
+# Exclude jacoco classes from proguard
+LOCAL_PROGUARD_FLAGS += -include $(BUILD_SYSTEM)/proguard.jacoco.flags
endif # Contains java code
else
ifdef LOCAL_SDK_VERSION
@@ -361,6 +363,8 @@
$(full_classes_compiled_jar): $(data_binding_stamp)
endif # LOCAL_DATA_BINDING
+resource_export_package :=
+
ifeq ($(need_compile_res),true)
###############################
@@ -427,7 +431,6 @@
$(proguard_options_file): $(R_file_stamp)
-resource_export_package :=
ifdef LOCAL_EXPORT_PACKAGE_RESOURCES
# Put this module's resources into a PRODUCT-agnositc package that
# other packages can use to build their own PRODUCT-agnostic R.java (etc.)
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 2a9ad1f..d934338 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -173,8 +173,10 @@
endif
export_cflags :=
+include $(BUILD_SYSTEM)/allowed_ndk_types.mk
+
ifdef LOCAL_SDK_VERSION
-my_link_type := native:ndk
+my_link_type := native:ndk:$(my_ndk_stl_family):$(my_ndk_stl_link_type)
else ifdef LOCAL_USE_VNDK
_name := $(patsubst %.vendor,%,$(LOCAL_MODULE))
ifneq ($(filter $(_name),$(VNDK_CORE_LIBRARIES) $(VNDK_SAMEPROCESS_LIBRARIES) $(LLNDK_LIBRARIES)),)
diff --git a/core/target_test_internal.mk b/core/target_test_internal.mk
index 59a3a9e..d84d3d9 100644
--- a/core/target_test_internal.mk
+++ b/core/target_test_internal.mk
@@ -12,8 +12,6 @@
my_ndk_gtest_suffix := _c++
else ifneq ($(filter stlport_,$(LOCAL_NDK_STL_VARIANT)),)
my_ndk_gtest_suffix := _stlport
- else ifneq ($(filter gnustl_,$(LOCAL_NDK_STL_VARIANT)),)
- my_ndk_gtest_suffix := _gnustl
else # system STL, use stlport
my_ndk_gtest_suffix := _stlport
endif
diff --git a/core/tasks/vndk.mk b/core/tasks/vndk.mk
index e42e0bd..3604aed 100644
--- a/core/tasks/vndk.mk
+++ b/core/tasks/vndk.mk
@@ -20,6 +20,9 @@
# PLATFORM_VNDK_VERSION must be set.
ifneq (,$(PLATFORM_VNDK_VERSION))
+# BOARD_VNDK_RUNTIME_DISABLE must not be set to 'true'.
+ifneq ($(BOARD_VNDK_RUNTIME_DISABLE),true)
+
# Returns arch-specific libclang_rt.ubsan* library name.
# Because VNDK_CORE_LIBRARIES includes all arch variants for libclang_rt.ubsan*
# libs, the arch-specific libs are selected separately.
@@ -75,13 +78,10 @@
else
vndk_core_libs := $(addsuffix .vendor,$(filter-out libclang_rt.ubsan%,$(VNDK_CORE_LIBRARIES)))
- # for TARGET_ARCH
vndk_core_libs += $(call clang-ubsan-vndk-core)
-
- # TODO(b/69834489): Package additional arch variants
- # ifdef TARGET_2ND_ARCH
- # vndk_core_libs += $(call clang-ubsan-vndk-core,true)
- # endif
+ ifdef TARGET_2ND_ARCH
+ vndk_core_libs += $(call clang-ubsan-vndk-core,true)
+ endif
endif
vndk_sp_libs := $(addsuffix .vendor,$(VNDK_SAMEPROCESS_LIBRARIES))
@@ -140,40 +140,41 @@
#######################################
# vndk_snapshot_zip
-vndk_snapshot_arch := $(vndk_snapshot_out)/arch-$(TARGET_ARCH)-$(TARGET_ARCH_VARIANT)
+vndk_snapshot_variant := $(vndk_snapshot_out)/$(TARGET_ARCH)
+vndk_lib_dir := $(vndk_snapshot_variant)/arch-$(TARGET_ARCH)-$(TARGET_ARCH_VARIANT)
+vndk_lib_dir_2nd := $(vndk_snapshot_variant)/arch-$(TARGET_2ND_ARCH)-$(TARGET_2ND_ARCH_VARIANT)
vndk_snapshot_zip := $(PRODUCT_OUT)/android-vndk-$(TARGET_ARCH).zip
$(vndk_snapshot_zip): PRIVATE_VNDK_SNAPSHOT_OUT := $(vndk_snapshot_out)
-$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT := $(vndk_snapshot_arch)/shared/vndk-core
+$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT := $(vndk_lib_dir)/shared/vndk-core
$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES := \
$(call paths-of-intermediates,$(foreach lib,$(vndk_core_libs),$(lib):$(lib).so),SHARED_LIBRARIES)
-$(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT := $(vndk_snapshot_arch)/shared/vndk-sp
+$(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT := $(vndk_lib_dir)/shared/vndk-sp
$(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES := \
$(call paths-of-intermediates,$(foreach lib,$(vndk_sp_libs),$(lib):$(lib).so),SHARED_LIBRARIES)
-$(vndk_snapshot_zip): PRIVATE_CONFIGS_OUT := $(vndk_snapshot_arch)/configs
+$(vndk_snapshot_zip): PRIVATE_CONFIGS_OUT := $(vndk_snapshot_variant)/configs
$(vndk_snapshot_zip): PRIVATE_CONFIGS_INTERMEDIATES := \
$(call paths-of-intermediates,$(foreach txt,$(vndk_prebuilt_txts), \
$(txt):$(patsubst %.txt,%.$(PLATFORM_VNDK_VERSION).txt,$(txt))),ETC) \
$(vndk_snapshot_configs)
-$(vndk_snapshot_zip): PRIVATE_NOTICE_FILES_OUT := $(vndk_snapshot_arch)/NOTICE_FILES
+$(vndk_snapshot_zip): PRIVATE_NOTICE_FILES_OUT := $(vndk_snapshot_variant)/NOTICE_FILES
$(vndk_snapshot_zip): PRIVATE_NOTICE_FILES_INTERMEDIATES := \
$(call paths-of-notice-files,$(vndk_core_libs),vndk) \
$(call paths-of-notice-files,$(vndk_sp_libs),vndk-sp)
-# TODO(b/69834489): Package additional arch variants
-# ifdef TARGET_2ND_ARCH
-# vndk_snapshot_arch_2ND := $(vndk_snapshot_out)/arch-$(TARGET_2ND_ARCH)-$(TARGET_2ND_ARCH_VARIANT)
-# $(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT_2ND := $(vndk_snapshot_arch_2ND)/shared/vndk-core
-# $(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES_2ND := \
-# $(call paths-of-intermediates,$(foreach lib,$(vndk_core_libs),$(lib):$(lib).so),SHARED_LIBRARIES,true)
-# $(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT_2ND := $(vndk_snapshot_arch_2ND)/shared/vndk-sp
-# $(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES_2ND := \
-# $(call paths-of-intermediates,$(foreach lib,$(vndk_sp_libs),$(lib):$(lib).so),SHARED_LIBRARIES,true)
-# endif
+ifdef TARGET_2ND_ARCH
+$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_OUT_2ND := $(vndk_lib_dir_2nd)/shared/vndk-core
+$(vndk_snapshot_zip): PRIVATE_VNDK_CORE_INTERMEDIATES_2ND := \
+ $(call paths-of-intermediates,$(foreach lib,$(vndk_core_libs),$(lib):$(lib).so),SHARED_LIBRARIES,true)
+
+$(vndk_snapshot_zip): PRIVATE_VNDK_SP_OUT_2ND := $(vndk_lib_dir_2nd)/shared/vndk-sp
+$(vndk_snapshot_zip): PRIVATE_VNDK_SP_INTERMEDIATES_2ND := \
+ $(call paths-of-intermediates,$(foreach lib,$(vndk_sp_libs),$(lib):$(lib).so),SHARED_LIBRARIES,true)
+endif
# Args
# $(1): destination directory
@@ -206,13 +207,12 @@
$(PRIVATE_CONFIGS_OUT),$(PRIVATE_CONFIGS_INTERMEDIATES))
$(call private-copy-vndk-intermediates, \
$(PRIVATE_NOTICE_FILES_OUT),$(PRIVATE_NOTICE_FILES_INTERMEDIATES))
-# TODO(b/69834489): Package additional arch variants
-# ifdef TARGET_2ND_ARCH
-# $(call private-copy-vndk-intermediates, \
-# $(PRIVATE_VNDK_CORE_OUT_2ND),$(PRIVATE_VNDK_CORE_INTERMEDIATES_2ND))
-# $(call private-copy-vndk-intermediates, \
-# $(PRIVATE_VNDK_SP_OUT_2ND),$(PRIVATE_VNDK_SP_INTERMEDIATES_2ND))
-# endif
+ifdef TARGET_2ND_ARCH
+ $(call private-copy-vndk-intermediates, \
+ $(PRIVATE_VNDK_CORE_OUT_2ND),$(PRIVATE_VNDK_CORE_INTERMEDIATES_2ND))
+ $(call private-copy-vndk-intermediates, \
+ $(PRIVATE_VNDK_SP_OUT_2ND),$(PRIVATE_VNDK_SP_INTERMEDIATES_2ND))
+endif
$(hide) $(SOONG_ZIP) -o $@ -C $(PRIVATE_VNDK_SNAPSHOT_OUT) -D $(PRIVATE_VNDK_SNAPSHOT_OUT)
.PHONY: vndk
@@ -232,27 +232,28 @@
vndk_snapshot_top :=
vndk_snapshot_out :=
vndk_snapshot_configs_out :=
-vndk_snapshot_arch :=
+vndk_snapshot_variant :=
+vndk_lib_dir :=
+vndk_lib_dir_2nd :=
vndk_snapshot_dependencies :=
-# TODO(b/69834489): Package additional arch variants
-# ifdef TARGET_2ND_ARCH
-# vndk_snapshot_arch_2ND :=
-# endif
+
+else # BOARD_VNDK_RUNTIME_DISABLE is set to 'true'
+error_msg := "CANNOT generate VNDK snapshot. BOARD_VNDK_RUNTIME_DISABLE must not be set to 'true'."
+endif # BOARD_VNDK_RUNTIME_DISABLE
else # PLATFORM_VNDK_VERSION is NOT set
-
-.PHONY: vndk
-vndk:
- $(call echo-error,$(current_makefile),CANNOT generate VNDK snapshot. PLATFORM_VNDK_VERSION must be set.)
- exit 1
-
+error_msg := "CANNOT generate VNDK snapshot. PLATFORM_VNDK_VERSION must be set."
endif # PLATFORM_VNDK_VERSION
else # BOARD_VNDK_VERSION is NOT set to 'current'
+error_msg := "CANNOT generate VNDK snapshot. BOARD_VNDK_VERSION must be set to 'current'."
+endif # BOARD_VNDK_VERSION
+
+ifneq (,$(error_msg))
.PHONY: vndk
vndk:
- $(call echo-error,$(current_makefile),CANNOT generate VNDK snapshot. BOARD_VNDK_VERSION must be set to 'current'.)
+ $(call echo-error,$(current_makefile),$(error_msg))
exit 1
-endif # BOARD_VNDK_VERSION
+endif
diff --git a/target/board/treble_common.mk b/target/board/treble_common.mk
index 44f601f..b4777b6 100644
--- a/target/board/treble_common.mk
+++ b/target/board/treble_common.mk
@@ -53,9 +53,20 @@
# Set emulator framebuffer display device buffer count to 3
NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3
-BOARD_FLASH_BLOCK_SIZE := 512
+# Audio
+USE_XML_AUDIO_POLICY_CONF := 1
# b/64700195: add minimum support for odm.img
# Currently odm.img can only be built by `make custom_images`.
# Adding /odm mount point under root directory.
BOARD_ROOT_EXTRA_FOLDERS += odm
+
+# Android Verified Boot (AVB):
+# Builds a special vbmeta.img that disables AVB verification.
+# Otherwise, AVB will prevent the device from booting the generic system.img.
+# Also checks that BOARD_AVB_ENABLE is not set, to prevent adding verity
+# metadata into system.img.
+ifeq ($(BOARD_AVB_ENABLE),true)
+$(error BOARD_AVB_ENABLE cannot be set for Treble GSI)
+endif
+BOARD_BUILD_DISABLED_VBMETAIMAGE := true
diff --git a/target/product/treble_common.mk b/target/product/treble_common.mk
index c385352..5880bf8 100644
--- a/target/product/treble_common.mk
+++ b/target/product/treble_common.mk
@@ -42,8 +42,6 @@
PRODUCT_PACKAGES += \
libvulkan \
-# Audio:
-USE_XML_AUDIO_POLICY_CONF := 1
# The following policy XML files are used as fallback for
# vendors/devices not using XML to configure audio policy.
PRODUCT_COPY_FILES += \
@@ -72,16 +70,6 @@
PRODUCT_COPY_FILES += \
device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml
-# Android Verified Boot (AVB):
-# Builds a special vbmeta.img that disables AVB verification.
-# Otherwise, AVB will prevent the device from booting the generic system.img.
-# Also checks that BOARD_AVB_ENABLE is not set, to prevent adding verity
-# metadata into system.img.
-ifeq ($(BOARD_AVB_ENABLE),true)
-$(error BOARD_AVB_ENABLE cannot be set for Treble GSI)
-endif
-BOARD_BUILD_DISABLED_VBMETAIMAGE := true
-
#GSI support for the devices that disable VNDK enforcing
PRODUCT_COPY_FILES += \
system/core/rootdir/etc/ld.config.txt:system/etc/ld.config.noenforce.txt \
diff --git a/target/product/vndk/Android.mk b/target/product/vndk/Android.mk
index ea8c95e..a134d02 100644
--- a/target/product/vndk/Android.mk
+++ b/target/product/vndk/Android.mk
@@ -94,9 +94,9 @@
vndk_current
else
LOCAL_REQUIRED_MODULES := \
- vndk_v$(BOARD_VNDK_VERSION)
+ vndk_v$(BOARD_VNDK_VERSION)_$(TARGET_ARCH)
endif
LOCAL_REQUIRED_MODULES += \
- $(foreach vndk_ver,$(PRODUCT_EXTRA_VNDK_VERSIONS),vndk_v$(vndk_ver))
+ $(foreach vndk_ver,$(PRODUCT_EXTRA_VNDK_VERSIONS),vndk_v$(vndk_ver)_$(TARGET_ARCH))
include $(BUILD_PHONY_PACKAGE)
endif # BOARD_VNDK_VERSION is set
diff --git a/tools/adbs b/tools/adbs
index a8f06c0..8d73630 100755
--- a/tools/adbs
+++ b/tools/adbs
@@ -20,7 +20,7 @@
import string
import sys
-sys.path.insert(0, os.path.dirname(__file__) + "/../../development/scripts")
+sys.path.insert(0, os.path.dirname(__file__) + "/../../../development/scripts")
import stack_core
import symbol
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 3bb8b9c..ed60188 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -15,27 +15,33 @@
# limitations under the License.
"""
-Build image output_image_file from input_directory, properties_file, and target_out_dir
+Builds output_image from the given input_directory, properties_file,
+and writes the image to target_output_directory.
-Usage: build_image input_directory properties_file output_image_file target_out_dir
-
+Usage: build_image.py input_directory properties_file output_image \\
+ target_output_directory
"""
+
+from __future__ import print_function
+
import os
import os.path
import re
-import subprocess
-import sys
-import common
import shlex
import shutil
+import subprocess
+import sys
+
+import common
import sparse_img
-import tempfile
+
OPTIONS = common.OPTIONS
FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
BLOCK_SIZE = 4096
+
def RunCommand(cmd, verbose=None):
"""Echo and run the given command.
@@ -56,6 +62,7 @@
print(output.rstrip())
return (output, p.returncode)
+
def GetVerityFECSize(partition_size):
cmd = ["fec", "-s", str(partition_size)]
output, exit_code = RunCommand(cmd, False)
@@ -63,6 +70,7 @@
return False, 0
return True, int(output)
+
def GetVerityTreeSize(partition_size):
cmd = ["build_verity_tree", "-s", str(partition_size)]
output, exit_code = RunCommand(cmd, False)
@@ -70,6 +78,7 @@
return False, 0
return True, int(output)
+
def GetVerityMetadataSize(partition_size):
cmd = ["system/extras/verity/build_verity_metadata.py", "size",
str(partition_size)]
@@ -78,6 +87,7 @@
return False, 0
return True, int(output)
+
def GetVeritySize(partition_size, fec_supported):
success, verity_tree_size = GetVerityTreeSize(partition_size)
if not success:
@@ -93,16 +103,19 @@
return verity_size + fec_size
return verity_size
+
def GetSimgSize(image_file):
simg = sparse_img.SparseImage(image_file, build_map=False)
return simg.blocksize * simg.total_blocks
+
def ZeroPadSimg(image_file, pad_size):
blocks = pad_size // BLOCK_SIZE
print("Padding %d blocks (%d bytes)" % (blocks, pad_size))
simg = sparse_img.SparseImage(image_file, mode="r+b", build_map=False)
simg.AppendFillChunk(0, blocks)
+
def AVBCalcMaxImageSize(avbtool, footer_type, partition_size, additional_args):
"""Calculates max image size for a given partition size.
@@ -115,8 +128,8 @@
Returns:
The maximum image size or 0 if an error occurred.
"""
- cmd =[avbtool, "add_%s_footer" % footer_type,
- "--partition_size", partition_size, "--calc_max_image_size"]
+ cmd = [avbtool, "add_%s_footer" % footer_type,
+ "--partition_size", partition_size, "--calc_max_image_size"]
cmd.extend(shlex.split(additional_args))
(output, exit_code) = RunCommand(cmd)
@@ -125,6 +138,7 @@
else:
return int(output)
+
def AVBAddFooter(image_path, avbtool, footer_type, partition_size,
partition_name, key_path, algorithm, salt,
additional_args):
@@ -140,14 +154,15 @@
algorithm: Name of algorithm to use or None.
salt: The salt to use (a hexadecimal string) or None.
additional_args: Additional arguments to pass to 'avbtool
- add_hashtree_image'.
+ add_hashtree_image'.
+
Returns:
True if the operation succeeded.
"""
- cmd =[avbtool, "add_%s_footer" % footer_type,
- "--partition_size", partition_size,
- "--partition_name", partition_name,
- "--image", image_path]
+ cmd = [avbtool, "add_%s_footer" % footer_type,
+ "--partition_size", partition_size,
+ "--partition_name", partition_name,
+ "--image", image_path]
if key_path and algorithm:
cmd.extend(["--key", key_path, "--algorithm", algorithm])
@@ -159,12 +174,15 @@
(_, exit_code) = RunCommand(cmd)
return exit_code == 0
+
def AdjustPartitionSizeForVerity(partition_size, fec_supported):
"""Modifies the provided partition size to account for the verity metadata.
This information is used to size the created image appropriately.
+
Args:
partition_size: the size of the partition to be verified.
+
Returns:
A tuple of the size of the partition adjusted for verity metadata, and
the size of verity metadata.
@@ -201,30 +219,34 @@
AdjustPartitionSizeForVerity.results[key] = (result, verity_size)
return (result, verity_size)
+
AdjustPartitionSizeForVerity.results = {}
+
def BuildVerityFEC(sparse_image_path, verity_path, verity_fec_path,
padding_size):
cmd = ["fec", "-e", "-p", str(padding_size), sparse_image_path,
verity_path, verity_fec_path]
output, exit_code = RunCommand(cmd)
if exit_code != 0:
- print "Could not build FEC data! Error: %s" % output
+ print("Could not build FEC data! Error: %s" % output)
return False
return True
+
def BuildVerityTree(sparse_image_path, verity_image_path, prop_dict):
cmd = ["build_verity_tree", "-A", FIXED_SALT, sparse_image_path,
verity_image_path]
output, exit_code = RunCommand(cmd)
if exit_code != 0:
- print "Could not build verity tree! Error: %s" % output
+ print("Could not build verity tree! Error: %s" % output)
return False
root, salt = output.split()
prop_dict["verity_root_hash"] = root
prop_dict["verity_salt"] = salt
return True
+
def BuildVerityMetadata(image_size, verity_metadata_path, root_hash, salt,
block_device, signer_path, key, signer_args,
verity_disable):
@@ -237,10 +259,11 @@
cmd.append("--verity_disable")
output, exit_code = RunCommand(cmd)
if exit_code != 0:
- print "Could not build verity metadata! Error: %s" % output
+ print("Could not build verity metadata! Error: %s" % output)
return False
return True
+
def Append2Simg(sparse_image_path, unsparse_image_path, error_message):
"""Appends the unsparse image to the given sparse image.
@@ -253,18 +276,23 @@
cmd = ["append2simg", sparse_image_path, unsparse_image_path]
output, exit_code = RunCommand(cmd)
if exit_code != 0:
- print "%s: %s" % (error_message, output)
+ print("%s: %s" % (error_message, output))
return False
return True
+
def Append(target, file_to_append, error_message):
- # appending file_to_append to target
- with open(target, "a") as out_file:
- with open(file_to_append, "r") as input_file:
+ """Appends file_to_append to target."""
+ try:
+ with open(target, "a") as out_file, open(file_to_append, "r") as input_file:
for line in input_file:
out_file.write(line)
+ except IOError:
+ print(error_message)
+ return False
return True
+
def BuildVerifiedImage(data_image_path, verity_image_path,
verity_metadata_path, verity_fec_path,
padding_size, fec_supported):
@@ -286,6 +314,7 @@
return False
return True
+
def UnsparseImage(sparse_image_path, replace=True):
img_dir = os.path.dirname(sparse_image_path)
unsparse_image_path = "unsparse_" + os.path.basename(sparse_image_path)
@@ -302,6 +331,7 @@
return False, None
return True, unsparse_image_path
+
def MakeVerityEnabledImage(out_file, fec_supported, prop_dict):
"""Creates an image that is verifiable using dm-verity.
@@ -360,14 +390,12 @@
return True
+
def ConvertBlockMapToBaseFs(block_map_file):
base_fs_file = common.MakeTempFile(prefix="script_gen_", suffix=".base_fs")
-
convert_command = ["blk_alloc_to_base_fs", block_map_file, base_fs_file]
(_, exit_code) = RunCommand(convert_command)
- if exit_code != 0:
- return None
- return base_fs_file
+ return base_fs_file if exit_code == 0 else None
def CheckHeadroom(ext4fs_output, prop_dict):
@@ -396,7 +424,8 @@
ext4fs_stats = re.compile(
r'Created filesystem with .* (?P<used_blocks>[0-9]+)/'
r'(?P<total_blocks>[0-9]+) blocks')
- m = ext4fs_stats.match(ext4fs_output.strip().split('\n')[-1])
+ last_line = ext4fs_output.strip().split('\n')[-1]
+ m = ext4fs_stats.match(last_line)
used_blocks = int(m.groupdict().get('used_blocks'))
total_blocks = int(m.groupdict().get('total_blocks'))
headroom_blocks = int(prop_dict['partition_headroom']) / BLOCK_SIZE
@@ -418,7 +447,8 @@
in_dir: path of input directory.
prop_dict: property dictionary.
out_file: path of the output image file.
- target_out: path of the product out directory to read device specific FS config files.
+ target_out: path of the product out directory to read device specific FS
+ config files.
Returns:
True iff the image is built successfully.
@@ -427,10 +457,10 @@
# /system and the ramdisk, and can be mounted at the root of the file system.
origin_in = in_dir
fs_config = prop_dict.get("fs_config")
- if (prop_dict.get("system_root_image") == "true"
- and prop_dict["mount_point"] == "system"):
+ if (prop_dict.get("system_root_image") == "true" and
+ prop_dict["mount_point"] == "system"):
in_dir = common.MakeTempDir()
- # Change the mount point to "/"
+ # Change the mount point to "/".
prop_dict["mount_point"] = "/"
if fs_config:
# We need to merge the fs_config files of system and ramdisk.
@@ -446,7 +476,7 @@
build_command = []
fs_type = prop_dict.get("fs_type", "")
- run_fsck = False
+ run_e2fsck = False
fs_spans_partition = True
if fs_type.startswith("squash"):
@@ -460,8 +490,8 @@
# verified.
if verity_supported and is_verity_partition:
partition_size = int(prop_dict.get("partition_size"))
- (adjusted_size, verity_size) = AdjustPartitionSizeForVerity(partition_size,
- verity_fec_supported)
+ (adjusted_size, verity_size) = AdjustPartitionSizeForVerity(
+ partition_size, verity_fec_supported)
if not adjusted_size:
return False
prop_dict["partition_size"] = str(adjusted_size)
@@ -480,8 +510,8 @@
partition_size = prop_dict["partition_size"]
# avb_add_hash_footer_args or avb_add_hashtree_footer_args.
additional_args = prop_dict["avb_add_" + avb_footer_type + "_footer_args"]
- max_image_size = AVBCalcMaxImageSize(avbtool, avb_footer_type, partition_size,
- additional_args)
+ max_image_size = AVBCalcMaxImageSize(avbtool, avb_footer_type,
+ partition_size, additional_args)
if max_image_size == 0:
return False
prop_dict["partition_size"] = str(max_image_size)
@@ -491,7 +521,7 @@
build_command = [prop_dict["ext_mkuserimg"]]
if "extfs_sparse_flag" in prop_dict:
build_command.append(prop_dict["extfs_sparse_flag"])
- run_fsck = True
+ run_e2fsck = True
build_command.extend([in_dir, out_file, fs_type,
prop_dict["mount_point"]])
build_command.append(prop_dict["partition_size"])
@@ -545,7 +575,7 @@
build_command.extend(["-zo", prop_dict["squashfs_compressor_opt"]])
if "squashfs_block_size" in prop_dict:
build_command.extend(["-b", prop_dict["squashfs_block_size"]])
- if "squashfs_disable_4k_align" in prop_dict and prop_dict.get("squashfs_disable_4k_align") == "true":
+ if prop_dict.get("squashfs_disable_4k_align") == "true":
build_command.extend(["-a"])
elif fs_type.startswith("f2fs"):
build_command = ["mkf2fsuserimg.sh"]
@@ -575,18 +605,14 @@
shutil.rmtree(staging_system, ignore_errors=True)
shutil.copytree(origin_in, staging_system, symlinks=True)
- ext4fs_output = None
- if fs_type.startswith("ext4"):
- (ext4fs_output, exit_code) = RunCommand(build_command)
- else:
- (_, exit_code) = RunCommand(build_command)
+ (mkfs_output, exit_code) = RunCommand(build_command)
if exit_code != 0:
print("Error: '%s' failed with exit code %d" % (build_command, exit_code))
return False
# Check if there's enough headroom space available for ext4 image.
if "partition_headroom" in prop_dict and fs_type.startswith("ext4"):
- if not CheckHeadroom(ext4fs_output, prop_dict):
+ if not CheckHeadroom(mkfs_output, prop_dict):
return False
if not fs_spans_partition:
@@ -600,7 +626,7 @@
if verity_supported and is_verity_partition:
ZeroPadSimg(out_file, partition_size - image_size)
- # create the verified image if this is to be verified
+ # Create the verified image if this is to be verified.
if verity_supported and is_verity_partition:
if not MakeVerityEnabledImage(out_file, verity_fec_supported, prop_dict):
return False
@@ -616,11 +642,12 @@
salt = prop_dict.get("avb_salt")
# avb_add_hash_footer_args or avb_add_hashtree_footer_args
additional_args = prop_dict["avb_add_" + avb_footer_type + "_footer_args"]
- if not AVBAddFooter(out_file, avbtool, avb_footer_type, original_partition_size,
- partition_name, key_path, algorithm, salt, additional_args):
+ if not AVBAddFooter(out_file, avbtool, avb_footer_type,
+ original_partition_size, partition_name, key_path,
+ algorithm, salt, additional_args):
return False
- if run_fsck and prop_dict.get("skip_fsck") != "true":
+ if run_e2fsck and prop_dict.get("skip_fsck") != "true":
success, unsparse_image = UnsparseImage(out_file, replace=False)
if not success:
return False
@@ -632,7 +659,8 @@
os.remove(unsparse_image)
if exit_code != 0:
- print("Error: '%s' failed with exit code %d" % (e2fsck_command, exit_code))
+ print("Error: '%s' failed with exit code %d" % (e2fsck_command,
+ exit_code))
return False
return True
@@ -699,7 +727,8 @@
copy_prop("system_base_fs_file", "base_fs_file")
copy_prop("system_extfs_inode_count", "extfs_inode_count")
elif mount_point == "system_other":
- # We inherit the selinux policies of /system since we contain some of its files.
+ # We inherit the selinux policies of /system since we contain some of its
+ # files.
d["mount_point"] = "system"
copy_prop("avb_system_hashtree_enable", "avb_hashtree_enable")
copy_prop("avb_system_add_hashtree_footer_args",
@@ -721,7 +750,7 @@
copy_prop("fs_type", "fs_type")
copy_prop("userdata_fs_type", "fs_type")
copy_prop("userdata_size", "partition_size")
- copy_prop("flash_logical_block_size","flash_logical_block_size")
+ copy_prop("flash_logical_block_size", "flash_logical_block_size")
copy_prop("flash_erase_block_size", "flash_erase_block_size")
elif mount_point == "cache":
copy_prop("cache_fs_type", "fs_type")
@@ -767,7 +796,7 @@
def main(argv):
if len(argv) != 4:
- print __doc__
+ print(__doc__)
sys.exit(1)
in_dir = argv[0]
@@ -796,14 +825,14 @@
elif image_filename == "oem.img":
mount_point = "oem"
else:
- print >> sys.stderr, "error: unknown image file name ", image_filename
+ print("error: unknown image file name ", image_filename, file=sys.stderr)
sys.exit(1)
image_properties = ImagePropFromGlobalDict(glob_dict, mount_point)
if not BuildImage(in_dir, image_properties, out_file, target_out):
- print >> sys.stderr, "error: failed to build %s from %s" % (out_file,
- in_dir)
+ print("error: failed to build %s from %s" % (out_file, in_dir),
+ file=sys.stderr)
sys.exit(1)
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 03e808f..ebebd63 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -792,11 +792,22 @@
def ReadApkCerts(tf_zip):
- """Given a target_files ZipFile, parse the META/apkcerts.txt file
- and return a tuple with the following elements: (1) a dictionary that maps
- packages to certs (based on the "certificate" and "private_key" attributes
- in the file. (2) A string representing the extension of compressed APKs in
- the target files (e.g ".gz" ".bro")."""
+ """Parses the APK certs info from a given target-files zip.
+
+ Given a target-files ZipFile, parses the META/apkcerts.txt entry and returns a
+ tuple with the following elements: (1) a dictionary that maps packages to
+ certs (based on the "certificate" and "private_key" attributes in the file;
+ (2) a string representing the extension of compressed APKs in the target files
+ (e.g ".gz", ".bro").
+
+ Args:
+ tf_zip: The input target_files ZipFile (already open).
+
+ Returns:
+ (certmap, ext): certmap is a dictionary that maps packages to certs; ext is
+ the extension string of compressed APKs (e.g. ".gz"), or None if there's
+ no compressed APKs.
+ """
certmap = {}
compressed_extension = None
@@ -812,41 +823,51 @@
line = line.strip()
if not line:
continue
- m = re.match(r'^name="(?P<NAME>.*)"\s+certificate="(?P<CERT>.*)"\s+'
- r'private_key="(?P<PRIVKEY>.*?)"(\s+compressed="(?P<COMPRESSED>.*)")?$',
- line)
- if m:
- matches = m.groupdict()
- cert = matches["CERT"]
- privkey = matches["PRIVKEY"]
- name = matches["NAME"]
- this_compressed_extension = matches["COMPRESSED"]
- public_key_suffix_len = len(OPTIONS.public_key_suffix)
- private_key_suffix_len = len(OPTIONS.private_key_suffix)
- if cert in SPECIAL_CERT_STRINGS and not privkey:
- certmap[name] = cert
- elif (cert.endswith(OPTIONS.public_key_suffix) and
- privkey.endswith(OPTIONS.private_key_suffix) and
- cert[:-public_key_suffix_len] == privkey[:-private_key_suffix_len]):
- certmap[name] = cert[:-public_key_suffix_len]
- else:
- raise ValueError("failed to parse line from apkcerts.txt:\n" + line)
- if this_compressed_extension:
- # Only count the installed files.
- filename = name + '.' + this_compressed_extension
- if filename not in installed_files:
- continue
- # Make sure that all the values in the compression map have the same
- # extension. We don't support multiple compression methods in the same
- # system image.
- if compressed_extension:
- if this_compressed_extension != compressed_extension:
- raise ValueError("multiple compressed extensions : %s vs %s",
- (compressed_extension, this_compressed_extension))
- else:
- compressed_extension = this_compressed_extension
+ m = re.match(
+ r'^name="(?P<NAME>.*)"\s+certificate="(?P<CERT>.*)"\s+'
+ r'private_key="(?P<PRIVKEY>.*?)"(\s+compressed="(?P<COMPRESSED>.*)")?$',
+ line)
+ if not m:
+ continue
- return (certmap, ("." + compressed_extension) if compressed_extension else None)
+ matches = m.groupdict()
+ cert = matches["CERT"]
+ privkey = matches["PRIVKEY"]
+ name = matches["NAME"]
+ this_compressed_extension = matches["COMPRESSED"]
+
+ public_key_suffix_len = len(OPTIONS.public_key_suffix)
+ private_key_suffix_len = len(OPTIONS.private_key_suffix)
+ if cert in SPECIAL_CERT_STRINGS and not privkey:
+ certmap[name] = cert
+ elif (cert.endswith(OPTIONS.public_key_suffix) and
+ privkey.endswith(OPTIONS.private_key_suffix) and
+ cert[:-public_key_suffix_len] == privkey[:-private_key_suffix_len]):
+ certmap[name] = cert[:-public_key_suffix_len]
+ else:
+ raise ValueError("Failed to parse line from apkcerts.txt:\n" + line)
+
+ if not this_compressed_extension:
+ continue
+
+ # Only count the installed files.
+ filename = name + '.' + this_compressed_extension
+ if filename not in installed_files:
+ continue
+
+ # Make sure that all the values in the compression map have the same
+ # extension. We don't support multiple compression methods in the same
+ # system image.
+ if compressed_extension:
+ if this_compressed_extension != compressed_extension:
+ raise ValueError(
+ "Multiple compressed extensions: {} vs {}".format(
+ compressed_extension, this_compressed_extension))
+ else:
+ compressed_extension = this_compressed_extension
+
+ return (certmap,
+ ("." + compressed_extension) if compressed_extension else None)
COMMON_DOCSTRING = """
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index ed454ca..8fb4600 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -353,6 +353,128 @@
os.remove(zip_file.name)
+class CommonApkUtilsTest(unittest.TestCase):
+ """Tests the APK utils related functions."""
+
+ APKCERTS_TXT1 = (
+ 'name="RecoveryLocalizer.apk" certificate="certs/devkey.x509.pem"'
+ ' private_key="certs/devkey.pk8"\n'
+ 'name="Settings.apk"'
+ ' certificate="build/target/product/security/platform.x509.pem"'
+ ' private_key="build/target/product/security/platform.pk8"\n'
+ 'name="TV.apk" certificate="PRESIGNED" private_key=""\n'
+ )
+
+ APKCERTS_CERTMAP1 = {
+ 'RecoveryLocalizer.apk' : 'certs/devkey',
+ 'Settings.apk' : 'build/target/product/security/platform',
+ 'TV.apk' : 'PRESIGNED',
+ }
+
+ APKCERTS_TXT2 = (
+ 'name="Compressed1.apk" certificate="certs/compressed1.x509.pem"'
+ ' private_key="certs/compressed1.pk8" compressed="gz"\n'
+ 'name="Compressed2a.apk" certificate="certs/compressed2.x509.pem"'
+ ' private_key="certs/compressed2.pk8" compressed="gz"\n'
+ 'name="Compressed2b.apk" certificate="certs/compressed2.x509.pem"'
+ ' private_key="certs/compressed2.pk8" compressed="gz"\n'
+ 'name="Compressed3.apk" certificate="certs/compressed3.x509.pem"'
+ ' private_key="certs/compressed3.pk8" compressed="gz"\n'
+ )
+
+ APKCERTS_CERTMAP2 = {
+ 'Compressed1.apk' : 'certs/compressed1',
+ 'Compressed2a.apk' : 'certs/compressed2',
+ 'Compressed2b.apk' : 'certs/compressed2',
+ 'Compressed3.apk' : 'certs/compressed3',
+ }
+
+ APKCERTS_TXT3 = (
+ 'name="Compressed4.apk" certificate="certs/compressed4.x509.pem"'
+ ' private_key="certs/compressed4.pk8" compressed="xz"\n'
+ )
+
+ APKCERTS_CERTMAP3 = {
+ 'Compressed4.apk' : 'certs/compressed4',
+ }
+
+ def tearDown(self):
+ common.Cleanup()
+
+ @staticmethod
+ def _write_apkcerts_txt(apkcerts_txt, additional=None):
+ if additional is None:
+ additional = []
+ target_files = common.MakeTempFile(suffix='.zip')
+ with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+ target_files_zip.writestr('META/apkcerts.txt', apkcerts_txt)
+ for entry in additional:
+ target_files_zip.writestr(entry, '')
+ return target_files
+
+ def test_ReadApkCerts_NoncompressedApks(self):
+ target_files = self._write_apkcerts_txt(self.APKCERTS_TXT1)
+ with zipfile.ZipFile(target_files, 'r') as input_zip:
+ certmap, ext = common.ReadApkCerts(input_zip)
+
+ self.assertDictEqual(self.APKCERTS_CERTMAP1, certmap)
+ self.assertIsNone(ext)
+
+ def test_ReadApkCerts_CompressedApks(self):
+ # We have "installed" Compressed1.apk.gz only. Note that Compressed3.apk is
+ # not stored in '.gz' format, so it shouldn't be considered as installed.
+ target_files = self._write_apkcerts_txt(
+ self.APKCERTS_TXT2,
+ ['Compressed1.apk.gz', 'Compressed3.apk'])
+
+ with zipfile.ZipFile(target_files, 'r') as input_zip:
+ certmap, ext = common.ReadApkCerts(input_zip)
+
+ self.assertDictEqual(self.APKCERTS_CERTMAP2, certmap)
+ self.assertEqual('.gz', ext)
+
+ # Alternative case with '.xz'.
+ target_files = self._write_apkcerts_txt(
+ self.APKCERTS_TXT3, ['Compressed4.apk.xz'])
+
+ with zipfile.ZipFile(target_files, 'r') as input_zip:
+ certmap, ext = common.ReadApkCerts(input_zip)
+
+ self.assertDictEqual(self.APKCERTS_CERTMAP3, certmap)
+ self.assertEqual('.xz', ext)
+
+ def test_ReadApkCerts_CompressedAndNoncompressedApks(self):
+ target_files = self._write_apkcerts_txt(
+ self.APKCERTS_TXT1 + self.APKCERTS_TXT2,
+ ['Compressed1.apk.gz', 'Compressed3.apk'])
+
+ with zipfile.ZipFile(target_files, 'r') as input_zip:
+ certmap, ext = common.ReadApkCerts(input_zip)
+
+ certmap_merged = self.APKCERTS_CERTMAP1.copy()
+ certmap_merged.update(self.APKCERTS_CERTMAP2)
+ self.assertDictEqual(certmap_merged, certmap)
+ self.assertEqual('.gz', ext)
+
+ def test_ReadApkCerts_MultipleCompressionMethods(self):
+ target_files = self._write_apkcerts_txt(
+ self.APKCERTS_TXT2 + self.APKCERTS_TXT3,
+ ['Compressed1.apk.gz', 'Compressed4.apk.xz'])
+
+ with zipfile.ZipFile(target_files, 'r') as input_zip:
+ self.assertRaises(ValueError, common.ReadApkCerts, input_zip)
+
+ def test_ReadApkCerts_MismatchingKeys(self):
+ malformed_apkcerts_txt = (
+ 'name="App1.apk" certificate="certs/cert1.x509.pem"'
+ ' private_key="certs/cert2.pk8"\n'
+ )
+ target_files = self._write_apkcerts_txt(malformed_apkcerts_txt)
+
+ with zipfile.ZipFile(target_files, 'r') as input_zip:
+ self.assertRaises(ValueError, common.ReadApkCerts, input_zip)
+
+
class InstallRecoveryScriptFormatTest(unittest.TestCase):
"""Checks the format of install-recovery.sh.