[轉載]recovery 升級前相容性檢查(Vendor Interface Object)

西西人發表於2020-11-24

https://blog.csdn.net/csdn66_2016/article/details/81704720

  從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生成規則)


   
  1. # Device Manifest
  2. ifdef DEVICE_MANIFEST_FILE
  3. # $(DEVICE_MANIFEST_FILE) can be a list of files
  4. include $(CLEAR_VARS)
  5. LOCAL_MODULE := device_manifest.xml
  6. LOCAL_MODULE_STEM := manifest.xml
  7. LOCAL_MODULE_CLASS := ETC
  8. LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vintf
  9. GEN := $(local-generated-sources-dir)/manifest.xml
  10. $(GEN): PRIVATE_DEVICE_MANIFEST_FILE := $(DEVICE_MANIFEST_FILE)
  11. $(GEN): $(DEVICE_MANIFEST_FILE) $(HOST_OUT_EXECUTABLES)/assemble_vintf
  12. BOARD_SEPOLICY_VERS= $(BOARD_SEPOLICY_VERS) \
  13. PRODUCT_ENFORCE_VINTF_MANIFEST= $(PRODUCT_ENFORCE_VINTF_MANIFEST) \
  14. PRODUCT_SHIPPING_API_LEVEL= $(PRODUCT_SHIPPING_API_LEVEL) \
  15. $(HOST_OUT_EXECUTABLES)/assemble_vintf -o $@ \
  16. -i $(call normalize-path-list,$(PRIVATE_DEVICE_MANIFEST_FILE))
  17. LOCAL_PREBUILT_MODULE_FILE := $(GEN)
  18. include $(BUILD_PREBUILT)
  19. BUILT_VENDOR_MANIFEST := $(LOCAL_BUILT_MODULE)
  20. endif

system/libhidl/vintfdata/Android.mk(定義了Device Compatibility Matrix / Framework Manifest編譯規則)


   
  1. # Device Compatibility Matrix
  2. ifdef DEVICE_MATRIX_FILE
  3. DEVICE_MATRIX_INPUT_FILE := $(DEVICE_MATRIX_FILE)
  4. else
  5. DEVICE_MATRIX_INPUT_FILE := $(LOCAL_PATH)/device_compatibility_matrix.default.xml
  6. endif
  7. include $(CLEAR_VARS)
  8. LOCAL_MODULE := device_compatibility_matrix.xml
  9. LOCAL_MODULE_STEM := compatibility_matrix.xml
  10. LOCAL_MODULE_CLASS := ETC
  11. LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vintf
  12. GEN := $(local-generated-sources-dir)/compatibility_matrix.xml
  13. $(GEN): PRIVATE_VINTF_VNDK_VERSION := $(VINTF_VNDK_VERSION)
  14. $(GEN): $(DEVICE_MATRIX_INPUT_FILE) $(HOST_OUT_EXECUTABLES)/assemble_vintf
  15. REQUIRED_VNDK_VERSION= $(PRIVATE_VINTF_VNDK_VERSION) \
  16. BOARD_SYSTEMSDK_VERSIONS= "$(BOARD_SYSTEMSDK_VERSIONS)" \
  17. $(HOST_OUT_EXECUTABLES)/assemble_vintf -i $< -o $@
  18. LOCAL_PREBUILT_MODULE_FILE := $(GEN)
  19. include $(BUILD_PREBUILT)
  20. BUILT_VENDOR_MATRIX := $(LOCAL_BUILT_MODULE)
  21. # Framework Manifest
  22. include $(CLEAR_VARS)
  23. LOCAL_MODULE := framework_manifest.xml
  24. LOCAL_MODULE_STEM := manifest.xml
  25. LOCAL_MODULE_CLASS := ETC
  26. LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/vintf
  27. GEN := $(local-generated-sources-dir)/manifest.xml
  28. $(GEN): PRIVATE_FLAGS :=
  29. ifeq ( $(PRODUCT_ENFORCE_VINTF_MANIFEST),true)
  30. ifdef BUILT_VENDOR_MATRIX
  31. $(GEN): $(BUILT_VENDOR_MATRIX)
  32. $(GEN): PRIVATE_FLAGS += -c "$(BUILT_VENDOR_MATRIX)"
  33. endif
  34. endif
  35. $(GEN): PRIVATE_VINTF_VNDK_VERSION := $(VINTF_VNDK_VERSION)
  36. $(GEN): PRIVATE_FRAMEWORK_MANIFEST_INPUT_FILES := $(FRAMEWORK_MANIFEST_INPUT_FILES)
  37. $(GEN): $(FRAMEWORK_MANIFEST_INPUT_FILES) $(HOST_OUT_EXECUTABLES)/assemble_vintf
  38. PROVIDED_VNDK_VERSIONS= "$(PRIVATE_VINTF_VNDK_VERSION) $(PRODUCT_EXTRA_VNDK_VERSIONS)" \
  39. PLATFORM_SYSTEMSDK_VERSIONS= "$(PLATFORM_SYSTEMSDK_VERSIONS)" \
  40. $(HOST_OUT_EXECUTABLES)/assemble_vintf \
  41. -i $(call normalize-path-list,$(PRIVATE_FRAMEWORK_MANIFEST_INPUT_FILES)) \
  42. -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

 

參考:

https://www.jianshu.com/p/a9ea323f892c

https://source.android.com/devices/architecture/vintf/

          

相關文章