Android 11 tách riêng phân vùng product
, giúp phân vùng này độc lập với các phân vùng system
và vendor
. Trong số 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 giao diện gốc và Java (tương tự như cách thực thi giao diện cho 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 này được tự động đặt thành current
khi cấp độ API vận chuyển của mục tiêu lớn hơn 29.) Biện pháp thực thi cho phép:
- Các mô-đun gốc trong phân vùng
product
để liên kết:- Tĩnh hoặc động đến các mô-đun khác trong phân vùng
product
bao gồm thư viện tĩnh, thư viện dùng chung hoặc thư viện tiêu đề. - Tự động chuyển sang các thư viện VNDK trong phân vùng
system
.
- Tĩnh hoặc động đến các mô-đun khác trong phân vùng
- Thư viện JNI trong các tệp APK chưa đóng gói trong phân vùng
product
để liên kết với các thư viện trong/product/lib
hoặc/product/lib64
(ngoài các thư viện NDK).
Việc thực thi không cho phép các đường liên kết khác đến các phân vùng ngoài phân vùng product
.
Thực thi thời gian xây dựng (Android.bp)
Trong Android 11, các mô-đun hệ thống có thể tạo ra một biến thể hình ảnh sản phẩm ngoài các biến thể hình ảnh chính và hình ảnh của nhà cung cấp. Khi tính năng thực thi giao diện gốc được bật (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ể chính.Các mô-đun có
product_available: true
trong tệpAndroid.bp
sẽ 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ỉ địnhproduct_specific: true
hoặcproduct_available: true
trong tệpAndroid.bp
.Thư viện VNDK phải có
product_available: true
trong tệpAndroid.bp
để tệp nhị phânproduct
có thể liên kết với thư viện VNDK.
Bảng sau đây tóm tắt các thuộc tính Android.bp
dùng để tạo biến thể hình ảnh.
Thuộc tính trong Android.bp | Số biến thể đã tạo | |
---|---|---|
Trước khi thực thi | Sau khi thực thi | |
mặc định (không có) | chính (bao gồm /system , /system_ext và /product ) |
chính (bao gồm /system và /system_ext nhưng không bao gồm /product ) |
system_ext_specific: true |
core | core |
product_specific: true |
core | sản phẩm |
vendor: true |
nhà cung cấp | nhà cung cấp |
vendor_available: true |
core, vendor | core, vendor |
product_available: true |
Không áp dụng | cốt lõi, sản phẩm |
vendor_available: true VÀ product_available:
true |
Không áp dụng | cốt lõi, sản phẩm, nhà cung cấp |
system_ext_specific: true VÀ vendor_available:
true |
core, vendor | core, vendor |
product_specific: true VÀ vendor_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
sẽ 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. Nếu bạn cố gắng liên kết với bất kỳ mô-đun nào khác ngoài các mô-đun này, hệ thống xây dựng sẽ tạo lỗi kiểm tra loại đường liên kết.
Thực thi trong thời gian chạy
Khi bạn 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 sẽ 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 với thư viện bên ngoài phân vùng product
(tuy nhiên, các quy trình như vậy có thể liên kết với thư viện VNDK). Việc cố gắng vi phạm cấu hình đường liên kết thời gian chạy sẽ khiến quá trình này 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ị này được tự động đặt 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, chế độ thực thi sẽ cho phép hoặc không cho phép các quyền truy cập sau:
API | /system | /system_ext | /product | /vendor | /data |
---|---|---|---|---|---|
API công khai | |||||
@SystemApi | |||||
@hide API |
Giống như trong phân vùng vendor
, ứng dụng hoặc thư viện Java trong phân vùng product
chỉ được phép sử dụng API công khai và API hệ thống; không được phép liên kết đến thư viện sử dụng API ẩn. Quy định hạn chế này bao gồm việc liên kết tại thời điểm tạo bản dựng và phản chiếu trong thời gian chạy.
Thực thi thời gian tạo bản dựng
Tại thời điểm tạo bản 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 các API ẩn bằng cách kiểm tra các trường platform_apis
và sdk_version
. Bạn phải điền current
, system_current
hoặc phiên bản số của API vào sdk_version
của ứng dụng trong phân vùng product
và trường platform_apis
phải trống.
Thực thi trong thời gian chạy
Môi trường 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 thông tin chi tiết, hãy tham khảo phần Hạn chế đối với giao diện không phải SDK.
Bật tính năng thực thi giao diện sản phẩm
Hãy làm theo các bước trong phần này để bật tính năng thực thi giao diện sản phẩm.
Bước | Việc cần làm | Bắt buộc |
---|---|---|
1 | Xác định tệp makefile hệ thống của riêng bạn, chỉ định các gói cho phân vùng system , sau đó đặt chế độ kiểm tra yêu cầu về đường dẫn cấu phần phần mềm trong device.mk (để ngăn các mô-đun không phải hệ thống cài đặt vào phân vùng system ). |
Không |
2 | Dọn dẹp danh sách được phép. | Không |
3 | Thực thi 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 việc thực thi Java). | Có |
4 | Thực thi giao diện Java và xác minh hành vi trong thời gian chạy (có thể chạy song song với quá trình thực thi gốc). | Có |
5 | Kiểm tra hành vi trong thời gian chạy. | Có |
6 | Cập nhật device.mk để thực thi giao diện sản phẩm. |
Có |
Bước 1: Tạo tệp makefile và bật tính năng kiểm tra đường dẫn cấu phần phần mềm
Trong bước này, bạn xác định tệp makefile system
.
Tạo một tệp makefile xác định các gói cho phân vùng
system
. Ví dụ: tạo tệpoem_system.mk
bằng 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),)
Trong tệp
device.mk
, kế thừa tệp makefile chung cho phân vùngsystem
và bật tính năng kiểm tra yêu cầu về đường dẫn cấu phần phần mềm. 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 cấu phần phần mềm
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 makefile khác cài đặt vào các đường dẫn được xác định trong require-artifacts-in-path
và ngăn các gói được xác định trong tệp makefile hiện tại cài đặt cấu phần phần mề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 system
. Để đưa các mô-đun này vào, bạn phải xác định các mô-đun đó trong chính tệp oem_system.mk
hoặc trong một tệp makefile đi kèm.
Việc cố gắng 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 các điểm ngắt, hãy làm theo một trong những cách sau:
Cách 1: Đưa mô-đun hệ thống vào tệp makefile có trong
oem_system.mk
. Điều này giúp đáp ứng yêu cầu về đường dẫn cấu phần phần mềm (vì các mô-đun hiện tồn tại trong một tệp makefile đi kèm) và do đó cho phép cài đặt vào tập hợp đường dẫn trong "require-artifacts-in-path".Lựa chọn 2: Cài đặt mô-đun vào phân vùng
system_ext
hoặcproduct
(và không cài đặt mô-đun vào phân vùngsystem
).Cách 3: Thêm mô-đun vào
PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
. Danh sách này liệt kê các mô-đun được phép cài đặt.
Bước 2: Xoá danh sách cho phép
Ở bước này, bạn làm cho PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST
trống để tất cả các thiết bị dùng chung oem_system.mk
cũng có thể chia sẻ một hình ảnh system
duy nhất. Để làm trống danh sách được phép, hãy di chuyển mọi mô-đun trong danh sách sang phân vùng system_ext
hoặc product
hoặc thêm các mô-đun đó vào tệp tạo system
. Bước này không bắt buộc vì bạn không cần xác định hình ảnh system
phổ biến để bật tính năng 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ẽ giúp xác định ranh giới system
bằng system_ext
.
Bước 3: Thực thi giao diện gốc
Trong 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 khắc phục các lỗi đó. Cách kiểm tra nhật ký và quá trình khởi động thiết bị, cũng như tìm và khắc phục lỗi liên kết trong thời gian chạy:
Đặt
PRODUCT_PRODUCT_VNDK_VERSION := current
.Tạo thiết bị và tìm lỗi bản dựng. Bạn có thể sẽ thấy một vài lỗi xây dựng đối với các biến thể sản phẩm bị thiếu hoặc các biến thể chính. Sau đây là một số điểm chèn quảng cáo phổ biến:
- Mọi mô-đun
hidl_interface
cóproduct_specific: true
sẽ không sử dụng được cho các mô-đun hệ thống. Để khắc phục, hãy thay thếproduct_specific: true
bằngsystem_ext_specific: true
. - Các mô-đun có thể thiếu biến thể sản phẩm bắt buộc đối với 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 đặtproduct_available: true
hoặc di chuyển mô-đun sang phân vùngproduct
bằng cách đặtproduct_specific: true
.
- Mọi mô-đun
Giải quyết lỗi bản dựng và đảm bảo rằng thiết bị được tạo thành công.
Truyền hình ảnh và tì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ẻ
linker
trong nhật ký trường hợp kiểm thử hiển thị thông báoCANNOT LINK EXECUTABLE
, thì tệp make 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 thư viện này từ hệ thống xây dựng, hãy thêm thư viện bắt buộc vào trường
shared_libs:
hoặcrequired:
.
- Nếu thẻ
Giải quyết các phần phụ thuộc bị thiếu theo hướng dẫn ở trên.
Bước 4: Thực thi giao diện Java
Trong bước này, bạn thiết lập PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true
, sau đó tìm và khắc phục các lỗi bản dựng phát sinh. Hãy tìm hai loại lỗi cụ thể:
Lỗi về loại đường liên kết. Lỗi này cho biết 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ộngsdk_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 ký hiệu. 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 một API ẩn. Để khắc phục, hãy sử dụng API hiển thị (không ẩn) hoặc tìm một API 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 trong thời gian chạy
Ở bước này, bạn xác minh các hành vi trong thời gian chạy như dự kiến. Đối với các ứng dụng có thể gỡ lỗi, bạn có thể theo dõi mức sử dụng API ẩn bằng nhật ký bằng cách sử dụ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 hình sử dụng (liên kết hoặc phản chiếu), cấp độ hạn chế và ngăn xếp lệnh 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 thông tin chi tiết về cách sử dụng veridex, hãy tham khảo bài viết Kiểm thử bằng công cụ veridex.
Bước 6: Cập nhật device.mk
Sau khi khắc phục tất cả lỗi bản 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 diễn ra như mong đợi, hãy thiết lập nội dung sau trong device.mk
:
PRODUCT_PRODUCT_VNDK_VERSION := current
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true