Thực thi giao diện phân vùng sản phẩm

Android 11 tách phân vùng product , làm cho phân vùng này độc lập với phân vùng systemvendor . Là một phần của những thay đổi này, giờ đây bạn có thể kiểm soát quyền truy cập của phân vùng product vào các giao diện gốc và Java (tương tự như cách thực thi giao diện hoạt động đối với các phân vùng vendor ).

Thực thi giao diện gốc

Để bật tính năng thực thi giao diện gốc, hãy đặt PRODUCT_PRODUCT_VNDK_VERSION thành current . (Phiên bản được tự động đặt thành current khi cấp API vận chuyển cho mục tiêu lớn hơn 29.) Việc thực thi cho phép:

  • Các mô-đun gốc trong phân vùng product cần liên kết:
    • Tĩnh hoặc động đối với các mô-đun khác trong phân vùng product bao gồm các thư viện tĩnh, chia sẻ hoặc tiêu đề.
    • Tự động tới các thư viện VNĐK trong phân vùng system .
  • Thư viện JNI trong các APK chưa được nhóm trong phân vùng product để liên kết với các thư viện trong /product/lib hoặc /product/lib64 (thư viện này bổ sung cho các thư viện NDK).

Việc thực thi không cho phép các liên kết khác đến các phân vùng khác ngoài phân vùng product .

Xây dựng thực thi thời gian (Android.bp)

Trong Android 11, các mô-đun hệ thống có thể tạo biến thể hình ảnh sản phẩm bên cạnh các biến thể hình ảnh cốt lõi và hình ảnh nhà cung cấp. Khi bật tính năng thực thi giao diện gốc ( PRODUCT_PRODUCT_VNDK_VERSION được đặt thành current ):

  • Các mô-đun gốc trong phân vùng product nằm trong biến thể sản phẩm thay vì biến thể cốt lõi.

  • Các mô-đun có product_available: true trong tệp Android.bp có sẵn cho biến thể sản phẩm.

  • Các thư viện hoặc tệp nhị phân chỉ định product_specific: true có thể liên kết với các thư viện khác chỉ định product_specific: true hoặc product_available: true trong tệp Android.bp của chúng.

  • Thư viện VNĐK phải có product_available: true trong tệp Android.bp của họ để tệp nhị phân product có thể liên kết với lib VNĐK.

Bảng sau đây tóm tắt các thuộc tính Android.bp được sử dụng để tạo các biến thể hình ảnh.

Thuộc tính trong Android.bp Các biến thể được tạo
Trước khi thi hành Sau khi thực thi
mặc định (không có) cốt lõi

(bao gồm /system , /system_ext/product )

cốt lõi

(bao gồm /system/system_ext nhưng không bao gồm /product )

system_ext_specific: true cốt lõi cốt lõi
product_specific: true cốt lõi sản phẩm
vendor: true người bán người bán
vendor_available: true cốt lõi, nhà cung cấp cốt lõi, nhà cung cấp
product_available: true không áp dụng sản phẩm cốt lõi
vendor_available: trueproduct_available: true không áp dụng cốt lõi, sản phẩm, nhà cung cấp
system_ext_specific: truevendor_available: true cốt lõi, nhà cung cấp cốt lõi, nhà cung cấp
product_specific: truevendor_available: true cốt lõi, nhà cung cấp sản phẩm, nhà cung cấp

Thực thi thời gian xây dựng (Android.mk)

Khi bật tính năng thực thi giao diện gốc, các mô-đun gốc được cài đặt vào phân vùng product có loại liên kết native:product chỉ có thể liên kết với các mô-đun native:product hoặc native:vndk khác. Việc cố gắng liên kết đến bất kỳ mô-đun nào ngoài những mô-đun này sẽ khiến hệ thống xây dựng tạo ra lỗi kiểm tra loại liên kết.

Thực thi thời gian chạy

Khi bật tính năng thực thi giao diện gốc, cấu hình trình liên kết cho trình liên kết bionic không cho phép các quy trình hệ thống sử dụng thư viện product , tạo một phần product cho các quy trình product không thể liên kết đến các thư viện bên ngoài phân vùng product (tuy nhiên, các quy trình đó có thể link tới thư viện VNĐK). Những nỗ lực vi phạm cấu hình liên kết thời gian chạy sẽ khiến quá trình không thành công và tạo ra thông báo lỗi CANNOT LINK EXECUTABLE .

Thực thi giao diện Java

Để bật tính năng thực thi giao diện Java, hãy đặt PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE thành true . (Giá trị được đặt tự động thành true khi cấp API vận chuyển cho mục tiêu lớn hơn 29.) Khi được bật, tính năng thực thi sẽ cho phép/không cho phép quyền truy cập sau.

API /hệ thống /system_ext /sản phẩm /người bán /dữ liệu
API công khai
@SystemApi
@ẩn API

Giống như trong phân vùng vendor , một ứng dụng hoặc thư viện Java trong phân vùng product chỉ được phép sử dụng các API hệ thống và công khai; không được phép liên kết đến thư viện sử dụng API ẩn. Hạn chế này bao gồm liên kết tại thời điểm xây dựng và phản ánh trong thời gian chạy.

Xây dựng thực thi thời gian

Tại thời điểm xây dựng, Make và Soong xác minh rằng các mô-đun Java trong phân vùng product không sử dụng API ẩn bằng cách kiểm tra các trường platform_apissdk_version . sdk_version của ứng dụng trong phân vùng product phải chứa phiên bản API current , system_current hoặc số và trường platform_apis phải trống.

Thực thi thời gian chạy

Thời gian chạy Android xác minh rằng các ứng dụng trong phân vùng product không sử dụng các API ẩn, bao gồm cả phản chiếu. Để biết chi tiết, hãy tham khảo Hạn chế đối với giao diện không phải SDK .

Cho phép thực thi giao diện sản phẩm

Sử dụng các bước trong phần này để kích hoạt thực thi giao diện sản phẩm.

Bước chân Nhiệm vụ Yêu cầu
1 Xác định tệp tạo hệ thống của riêng bạn để chỉ định các gói cho phân vùng system , sau đó đặt kiểm tra yêu cầu đường dẫn tạo phẩm trong device.mk (để ngăn các mô-đun phi hệ thống cài đặt vào phân vùng system ). N
2 Dọn dẹp danh sách được phép. N
3 Thực thi các giao diện gốc và xác định lỗi liên kết thời gian chạy (có thể chạy song song với quá trình thực thi Java). Y
4 Thực thi các giao diện Java và xác minh hành vi thời gian chạy (có thể chạy song song với thực thi gốc). Y
5 Kiểm tra hành vi thời gian chạy. Y
6 Cập nhật device.mk với việc thực thi giao diện sản phẩm. Y

Bước 1: Tạo tệp thực hiện và bật kiểm tra đường dẫn giả tạo

Trong bước này, bạn xác định tệp system hệ thống.

  1. Tạo một tệp thực hiện xác định các gói cho phân vùng system . Ví dụ: tạo tệp oem_system.mk với nội dung sau:

    $(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system.mk)
    $(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system.mk)
    
    # Applications
    PRODUCT_PACKAGES += \
        CommonSystemApp1 \
        CommonSystemApp2 \
        CommonSystemApp3 \
    
    # Binaries
    PRODUCT_PACKAGES += \
        CommonSystemBin1 \
        CommonSystemBin2 \
        CommonSystemBin3 \
    
    # Libraries
    PRODUCT_PACKAGES += \
        CommonSystemLib1 \
        CommonSystemLib2 \
        CommonSystemLib3 \
    
    PRODUCT_SYSTEM_NAME := oem_system
    PRODUCT_SYSTEM_BRAND := Android
    PRODUCT_SYSTEM_MANUFACTURER := Android
    PRODUCT_SYSTEM_MODEL := oem_system
    PRODUCT_SYSTEM_DEVICE := generic
    
    # For system-as-root devices, system.img should be mounted at /, so we
    # include ROOT here.
    _my_paths := \
     $(TARGET_COPY_OUT_ROOT)/ \
     $(TARGET_COPY_OUT_SYSTEM)/ \
    
    $(call require-artifacts-in-path, $(_my_paths),)
    
  2. Trong tệp device.mk , hãy kế thừa tệp makefile chung cho phân vùng system và bật kiểm tra các yêu cầu về đường dẫn tạo tác. Ví dụ:

    $(call inherit-product, $(SRC_TARGET_DIR)/product/oem_system.mk)
    
    # Enable artifact path requirements checking
    PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := strict
    

Giới thiệu về các yêu cầu đối với đường dẫn tạo tác

Khi PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS được đặt thành true hoặc strict , hệ thống xây dựng sẽ ngăn các gói được xác định trong các tệp tạo tệp khác cài đặt vào các đường dẫn được xác định trong require-artifacts-in-path ngăn các gói được xác định trong tệp tạo tệp hiện tại cài đặt các tạo phẩm bên ngoài các đường dẫn được xác định trong require-artifacts-in-path .

Trong ví dụ trên, với PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS được đặt thành strict , các tệp makefile bên ngoài oem_system.mk không thể bao gồm các mô-đun được cài đặt vào phân vùng root hoặc phân vùng system . Để bao gồm các mô-đun này, bạn phải xác định chúng trong chính tệp oem_system.mk hoặc trong tệp tạo tệp được bao gồm. Nỗ lực cài đặt mô-đun vào các đường dẫn không được phép sẽ gây ra lỗi bản dựng. Để khắc phục sự cố, hãy thực hiện một trong các thao tác sau:

  • Tùy chọn 1: Đưa mô-đun hệ thống vào các tệp tạo tệp có trong oem_system.mk . Điều này làm cho yêu cầu về đường dẫn tạo tác được đáp ứng (vì các mô-đun hiện tồn tại trong một tệp tạo tệp được bao gồm) và do đó cho phép cài đặt vào tập hợp các đường dẫn trong `require-artifacts-in-path.

  • Tùy chọn 2: Cài đặt mô-đun vào phân vùng system_ext hoặc product (và không cài đặt mô-đun vào phân vùng system ).

  • Tùy chọn 3: Thêm mô-đun vào PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST . Danh sách này cho phép cài đặt các mô-đun.

Bước 2: Làm trống danh sách được phép

Trong bước này, bạn làm trống PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST để tất cả các thiết bị chia sẻ oem_system.mk cũng có thể chia sẻ một hình ảnh system . Để làm trống danh sách được phép, hãy di chuyển bất kỳ mô-đun nào trong danh sách sang phân vùng system_ext hoặc product hoặc thêm chúng vào tệp tạo system . Bước này là tùy chọn vì không cần phải xác định hình ảnh system chung để kích hoạt thực thi giao diện sản phẩm. Tuy nhiên, việc làm trống danh sách được phép sẽ hữu ích cho việc xác định ranh giới system bằng system_ext .

Bước 3: Thực thi giao diện gốc

Ở bước này, bạn đặt PRODUCT_PRODUCT_VNDK_VERSION := current , sau đó tìm lỗi bản dựng và thời gian chạy rồi giải quyết chúng. Để kiểm tra nhật ký và khởi động thiết bị cũng như tìm và sửa lỗi liên kết thời gian chạy:

  1. Đặt PRODUCT_PRODUCT_VNDK_VERSION := current .

  2. Xây dựng thiết bị và tìm kiếm lỗi xây dựng. Bạn có thể thấy một vài điểm dừng xây dựng cho các biến thể sản phẩm hoặc biến thể cốt lõi bị thiếu. Các khoảng nghỉ thông thường bao gồm:

    • Bất kỳ mô-đun hidl_interface nào có product_specific: true sẽ không khả dụng cho các mô-đun hệ thống. Để khắc phục, hãy thay thế product_specific: true bằng system_ext_specfic: true .
    • Các mô-đun có thể thiếu biến thể sản phẩm cần thiết cho các mô-đun sản phẩm. Để khắc phục, hãy cung cấp mô-đun đó cho phân vùng product bằng cách đặt product_available: true hoặc di chuyển mô-đun sang phân vùng product bằng cách đặt product_specific: true .
  3. Giải quyết các lỗi xây dựng và đảm bảo rằng thiết bị được xây dựng thành công.

  4. Flash hình ảnh và tìm kiếm lỗi thời gian chạy trong quá trình khởi động và nhật ký thiết bị.

    • Nếu thẻ trình linker từ nhật ký trường hợp thử nghiệm hiển thị thông báo CANNOT LINK EXECUTABLE thì tệp tạo thiếu phần phụ thuộc (và không được ghi lại tại thời điểm xây dựng).
    • Để kiểm tra nó từ hệ thống xây dựng, hãy thêm thư viện cần thiết vào trường shared_libs: hoặc required:
  5. Giải quyết các phần phụ thuộc còn thiếu bằng cách sử dụng hướng dẫn ở trên.

Bước 4: Thực thi giao diện Java

Trong bước này, bạn đặt PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true , sau đó tìm và sửa các lỗi bản dựng phát sinh. Hãy tìm hai loại lỗi cụ thể:

  • Lỗi loại liên kết. Lỗi này cho biết rằng một ứng dụng liên kết đến các mô-đun Java có sdk_version rộng hơn. Để khắc phục, bạn có thể mở rộng sdk_version của ứng dụng hoặc hạn chế sdk_version của thư viện. Lỗi ví dụ:

    error: frameworks/base/packages/SystemUI/Android.bp:138:1: module "SystemUI" variant "android_common": compiles against system API, but dependency "telephony-common" is compiling against private API.Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.
    
  • Lỗi biểu tượng. Lỗi này cho biết rằng không thể tìm thấy biểu tượng vì biểu tượng đó nằm trong API ẩn. Để khắc phục, hãy sử dụng API hiển thị (không bị ẩn) hoặc tìm giải pháp thay thế. Lỗi ví dụ:

    frameworks/opt/net/voip/src/java/com/android/server/sip/SipSessionGroup.java:1051: error: cannot find symbol
                ProxyAuthenticate proxyAuth = (ProxyAuthenticate)response.getHeader(
                                               ^
      symbol:   class ProxyAuthenticate
      location: class SipSessionGroup.SipSessionImpl
    

Bước 5: Kiểm tra hành vi thời gian chạy

Trong bước này, bạn xác minh hành vi thời gian chạy như mong đợi. Đối với các ứng dụng có thể gỡ lỗi, bạn có thể giám sát việc sử dụng API ẩn bằng nhật ký bằng StrictMode.detectNonSdkApiUsage (tạo nhật ký khi ứng dụng sử dụng API ẩn). Ngoài ra, bạn có thể sử dụng công cụ phân tích tĩnh veridex để biết loại cách sử dụng (liên kết hoặc phản ánh), mức độ hạn chế và ngăn xếp cuộc gọi.

  • Cú pháp Veridex:

    ./art/tools/veridex/appcompat.sh --dex-file={apk file}
    
  • Ví dụ về kết quả veridex:

    #1: Linking greylist-max-o Landroid/animation/AnimationHandler;-><init>()V use(s):
           Lcom/android/systemui/pip/phone/PipMotionHelper;-><init>(Landroid/content/Context;Landroid/app/IActivityManager;Landroid/app/IActivityTaskManager;Lcom/android/systemui/pip/phone/PipMenuActivityController;Lcom/android/internal/policy/PipSnapAlgorithm;Lcom/android/systemui/statusbar/FlingAnimationUtils;)V
    
    #1332: Reflection greylist Landroid/app/Activity;->mMainThread use(s):
           Landroidx/core/app/ActivityRecreator;->getMainThreadField()Ljava/lang/reflect/Field;
    

Để biết chi tiết về cách sử dụng veridex, hãy tham khảo Kiểm tra bằng công cụ veridex .

Bước 6: Cập nhật device.mk

Sau khi sửa tất cả các lỗi xây dựng và thời gian chạy, đồng thời xác minh rằng các hành vi thời gian chạy như mong đợi, hãy đặt thông tin sau trong device.mk :

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true