從android P(9.0)版本開始,我們發現編譯出來的OTA升級了里面多了一個文件,compatibility.zip,這個里面存儲這system與vendor分區的一些特性,用來做升級前的兼容性檢查。其實從android O開始已經增加了這個功能,但是沒有默認打開。直到android P上,已經默認打開了。
解壓compatibility.zip后,內容如下:
我們先從google的官方了解下這個功能。
https://source.android.com/devices/architecture/vintf/
Framework(system)和Device(vendor)匹配的框架如下:
Manifest 描述了提供給對方的feature, Matrix 描述了需要對方提供的feature。Manifest 和 Matrix 在OTA升級前會進行匹配檢查,以確保framework和device是兼容的。總的來說,manifest是提供端,matrix是需求端。
下面以android P最新的aosp的code為例。
Framework Manifest:
manifest.xml的源文件由google手動生成,其存在路徑:
system/libhidl/vintfdata/manifest.xml
system/libhidl/vintfdata/manifest_healthd_exclude.xml
至於xml的內容就不貼上來了,可以到對應的目錄去查看源文件。manifest.xml的格式可以參考官方文檔即可,也不在此詳細講解。
Framework Compatibility Matrix:
Framework compatibility matrix描述的是framework對 device的需求。這個matrix文件是和Android Framework Image(system.img)關聯的。Framework compatibility matrix的這些需要被device manifest支持。
compatibility matrix源文件路徑:
hardware/interfaces/compatibility_matrices/compatibility_matrix.1.xml
hardware/interfaces/compatibility_matrices/compatibility_matrix.2.xml
hardware/interfaces/compatibility_matrices/compatibility_matrix.3.xml
hardware/interfaces/compatibility_matrices/compatibility_matrix.empty.xml
hardware/interfaces/compatibility_matrices/compatibility_matrix.legacy.xml
Device Manifest:
由BoardConfig.mk中定義
device/xxxx/xxxx/BoardConfig.mk定義:
DEVICE_MANIFEST_FILE := device/xxxx/xxxx/manifest.xml
源文件為 device/xxxx/xxxx/manifest.xml
Device Compatibility Matrix:
如果BoardConfig.mk中有定義,則以定義的文件為源文件:
#DEVICE_MATRIX_FILE := device/amlogic/common/compatibility_matrix.xml
如果沒有定義,則使用缺省的源文件:
system/libhidl/vintfdata/device_compatibility_matrix.default.xml
如上,我們找到了device manifest,device compatibility matrix,framework manifest,framework compatibility matrix各自對應的源文件,然后我們通過編譯規則生成最終的xml文件。
build/make/target/board/Android.mk(定義了Device Manifest生成規則)
# Device Manifest ifdef DEVICE_MANIFEST_FILE # $(DEVICE_MANIFEST_FILE) can be a list of files include $(CLEAR_VARS) LOCAL_MODULE := device_manifest.xml LOCAL_MODULE_STEM := manifest.xml LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vintf GEN := $(local-generated-sources-dir)/manifest.xml $(GEN): PRIVATE_DEVICE_MANIFEST_FILE := $(DEVICE_MANIFEST_FILE) $(GEN): $(DEVICE_MANIFEST_FILE) $(HOST_OUT_EXECUTABLES)/assemble_vintf BOARD_SEPOLICY_VERS=$(BOARD_SEPOLICY_VERS) \ PRODUCT_ENFORCE_VINTF_MANIFEST=$(PRODUCT_ENFORCE_VINTF_MANIFEST) \ PRODUCT_SHIPPING_API_LEVEL=$(PRODUCT_SHIPPING_API_LEVEL) \ $(HOST_OUT_EXECUTABLES)/assemble_vintf -o $@ \ -i $(call normalize-path-list,$(PRIVATE_DEVICE_MANIFEST_FILE)) LOCAL_PREBUILT_MODULE_FILE := $(GEN) include $(BUILD_PREBUILT) BUILT_VENDOR_MANIFEST := $(LOCAL_BUILT_MODULE) endif
system/libhidl/vintfdata/Android.mk(定義了Device Compatibility Matrix / Framework Manifest編譯規則)
# Device Compatibility Matrix ifdef DEVICE_MATRIX_FILE DEVICE_MATRIX_INPUT_FILE := $(DEVICE_MATRIX_FILE) else DEVICE_MATRIX_INPUT_FILE := $(LOCAL_PATH)/device_compatibility_matrix.default.xml endif include $(CLEAR_VARS) LOCAL_MODULE := device_compatibility_matrix.xml LOCAL_MODULE_STEM := compatibility_matrix.xml LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vintf GEN := $(local-generated-sources-dir)/compatibility_matrix.xml $(GEN): PRIVATE_VINTF_VNDK_VERSION := $(VINTF_VNDK_VERSION) $(GEN): $(DEVICE_MATRIX_INPUT_FILE) $(HOST_OUT_EXECUTABLES)/assemble_vintf REQUIRED_VNDK_VERSION=$(PRIVATE_VINTF_VNDK_VERSION) \ BOARD_SYSTEMSDK_VERSIONS="$(BOARD_SYSTEMSDK_VERSIONS)" \ $(HOST_OUT_EXECUTABLES)/assemble_vintf -i $< -o $@ LOCAL_PREBUILT_MODULE_FILE := $(GEN) include $(BUILD_PREBUILT) BUILT_VENDOR_MATRIX := $(LOCAL_BUILT_MODULE) # Framework Manifest include $(CLEAR_VARS) LOCAL_MODULE := framework_manifest.xml LOCAL_MODULE_STEM := manifest.xml LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/vintf GEN := $(local-generated-sources-dir)/manifest.xml $(GEN): PRIVATE_FLAGS := ifeq ($(PRODUCT_ENFORCE_VINTF_MANIFEST),true) ifdef BUILT_VENDOR_MATRIX $(GEN): $(BUILT_VENDOR_MATRIX) $(GEN): PRIVATE_FLAGS += -c "$(BUILT_VENDOR_MATRIX)" endif endif $(GEN): PRIVATE_VINTF_VNDK_VERSION := $(VINTF_VNDK_VERSION) $(GEN): PRIVATE_FRAMEWORK_MANIFEST_INPUT_FILES := $(FRAMEWORK_MANIFEST_INPUT_FILES) $(GEN): $(FRAMEWORK_MANIFEST_INPUT_FILES) $(HOST_OUT_EXECUTABLES)/assemble_vintf PROVIDED_VNDK_VERSIONS="$(PRIVATE_VINTF_VNDK_VERSION) $(PRODUCT_EXTRA_VNDK_VERSIONS)" \ PLATFORM_SYSTEMSDK_VERSIONS="$(PLATFORM_SYSTEMSDK_VERSIONS)" \ $(HOST_OUT_EXECUTABLES)/assemble_vintf \ -i $(call normalize-path-list,$(PRIVATE_FRAMEWORK_MANIFEST_INPUT_FILES)) \ -o $@ $(PRIVATE_FLAGS)
hardware/interfaces/compatibility_matrices/Android.mk
hardware/interfaces/compatibility_matrices/compatibility_matrix.mk (定義了Framework Compatibility Matrix規則)
# 詳細規則請查看源文件,就不貼代碼了
有了上述源文件及編譯規則,則可以生成最終的xml文件了, 具體的調用,都是使用了out/host/linux-x86/bin/assemble_vintf工具。
生成的最終的xml對應的分區路徑如下:
/system/compatibility_matrix.xml
/system/etc/vintf/manifest.xml
/vendor/etc/vintf/compatibility_matrix.xml
/vendor/etc/vintf/manifest.xml
至此,我們在升級過程,可以從升級包update.zip中獲取manifest與matrix文件(system_manifest.xml system_matrix.xml vendor_manifest.xml vendor_matrix.xml),然后掛載/system /vendor分區,與system/vendor分區對應的xml對比校驗,檢查是否符合升級條件。滿足條件,則繼續后面的升級,如果不滿足條件,則終止升級。
具體的代碼實現,bootable/recovery/install.cpp中
在升級包的完整性校驗完成之后,就進行兼容性校驗,最終的實現調用的接口是(system/libvintf/VintfObject.cpp):android::vintf::VintfObjectRecovery::CheckCompatibility
參考: