APEX của nhà cung cấp

Bạn có thể sử dụng định dạng tệpAPEX để đóng gói và cài đặt các mô-đun Hệ điều hành Android cấp thấp hơn. Giải pháp này cho phép bạn xây dựng và cài đặt các thành phần như dịch vụ và thư viện gốc, HAL chương trình triển khai, chương trình cơ sở, tệp cấu hình, v.v.

APEX của nhà cung cấp được hệ thống xây dựng cài đặt tự động trong /vendor được apexd kích hoạt trong thời gian chạy, giống như các APEX trong phân vùng.

Trường hợp sử dụng

Mô-đun hoá hình ảnh của nhà cung cấp

APEX hỗ trợ việc gói và mô-đun hoá tính năng một cách tự nhiên triển khai hình ảnh của nhà cung cấp.

Khi hình ảnh của nhà cung cấp được tạo bằng cách kết hợp các nhà cung cấp được tạo độc lập APEX, nhà sản xuất thiết bị có thể dễ dàng chọn cách triển khai của nhà cung cấp mà họ muốn trên thiết bị của họ. Các nhà sản xuất thậm chí có thể tạo một APEX của nhà cung cấp mới nếu không có APEX được cung cấp nào phù hợp với nhu cầu của họ hoặc họ có phần cứng tuỳ chỉnh hoàn toàn mới.

Ví dụ: OEM có thể chọn thiết lập thiết bị của họ bằng AOSP wifi APEX triển khai, APEX triển khai Bluetooth SoC và OEM tuỳ chỉnh APEX triển khai điện thoại.

Không có APEX của nhà cung cấp, quá trình triển khai có quá nhiều phần phụ thuộc giữa các thành phần của nhà cung cấp đòi hỏi sự phối hợp và theo dõi cẩn thận. Bằng cách gói tất cả các thành phần (bao gồm cả tệp cấu hình và thư viện bổ sung) trong APEX có các giao diện được xác định rõ ràng tại bất kỳ điểm giao tiếp giữa nhiều tính năng, các thành phần khác nhau có thể thay thế cho nhau.

Lặp lại dành cho nhà phát triển

Các APEX của nhà cung cấp giúp nhà phát triển lặp lại nhanh hơn trong khi vẫn phát triển các mô-đun nhà cung cấp bằng cách nhóm toàn bộ việc triển khai tính năng, chẳng hạn như HAL (Lớp trừu tượng phần cứng) cho Wi-Fi, bên trong một nhà cung cấp Hàm APEX. Sau đó, nhà phát triển có thể tạo và đẩy APEX của nhà cung cấp theo cách riêng lẻ để kiểm thử thay vì xây dựng lại toàn bộ hình ảnh nhà cung cấp.

Điều này giúp đơn giản hoá và đẩy nhanh chu kỳ lặp lại của nhà phát triển cho những nhà phát triển đang chủ yếu hoạt động trong một lĩnh vực tính năng và muốn lặp lại chỉ tính năng đó .

Việc gói tự nhiên một vùng đối tượng vào một APEX cũng giúp đơn giản hoá quá trình về việc xây dựng, phát hành và thử nghiệm những thay đổi cho mảng tính năng đó. Ví dụ: Việc cài đặt lại APEX sẽ tự động cập nhật mọi tệp cấu hình hoặc thư viện đi kèm APEX bao gồm.

Việc nhóm một vùng đối tượng vào một APEX cũng giúp đơn giản hoá việc gỡ lỗi hoặc hoàn nguyên khi phát hiện thấy hành vi xấu trên thiết bị. Ví dụ: nếu điện thoại hoạt động kém ở một bản dựng mới, thì nhà phát triển có thể thử cài đặt phiên bản điện thoại APEX triển khai trên thiết bị (mà không cần cài đặt ROM bản dựng đầy đủ) và xem hành vi tốt có được khôi phục hay không.

Ví dụ về quy trình làm việc:

# Build the entire device and flash. OR, obtain an already-flashed device.
source build/envsetup.sh && lunch oem_device-userdebug
m
fastboot flashall -w

# Test the device.
... testing ...

# Check previous behavior using a vendor APEX from one week ago, downloaded from
# your continuous integration build.
... download command ...
adb install <path to downloaded APEX>
adb reboot
... testing ...

# Edit and rebuild just the APEX to change and test behavior.
... edit APEX source contents ...
m <apex module name>
adb install out/<path to built APEX>
adb reboot
... testing ...

Ví dụ

Thông tin cơ bản

Xem trang Định dạng tệpAPEX chính để biết APEX chung thông tin, bao gồm yêu cầu về thiết bị, chi tiết định dạng tệp và các bước cài đặt.

Trong Android.bp, việc đặt thuộc tính vendor: true sẽ khiến mô-đun APEX trở thành APEX của nhà cung cấp.

apex {
  ..
  vendor: true,
  ..
}

Tệp nhị phân và thư viện dùng chung

APEX bao gồm các phần phụ thuộc bắc cầu bên trong tải trọng APEX, trừ phi các phần phụ thuộc đó có giao diện ổn định.

Giao diện gốc ổn định cho các phần phụ thuộc APEX của nhà cung cấp bao gồm cc_library với stubs, ndk_library hoặc llndk_library. Các phần phụ thuộc này bị loại trừ khỏi việc đóng gói và phần phụ thuộc đều được ghi lại trong tệp kê khai APEX. Tệp kê khai là được linkerconfig xử lý để các phần phụ thuộc gốc bên ngoài có sẵn trong thời gian chạy.

Không giống như APEX trong phân vùng /system, APEX của nhà cung cấp thường liên kết với một phiên bản VNDK cụ thể. Thư viện VNDK đảm bảo tính ổn định của ABI trong để có thể coi các thư viện VNDK là ổn định và giảm quy mô của nhà cung cấp APEX bằng cách loại trừ chúng khỏi APEX bằng cách sử dụng use_vndk_as_stable thuộc tính này.

Trong đoạn mã dưới đây, APEX sẽ chứa cả tệp nhị phân (my_service) và phần phụ thuộc không ổn định (tệp *.so). Không chứa các thư viện VNDK, ngay cả khi my_service được tạo bằng các thư viện VNDK như libbase. Thay vào đó, lúc thời gian chạy my_service sẽ dùng libbase từ các thư viện VNDK do hệ thống.

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  binaries: ["my_service"],
  ..
}

Trong đoạn mã dưới đây, APEX sẽ chứa thư viện chia sẻ my_standalone_libvà mọi phần phụ thuộc không ổn định (như mô tả ở trên).

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  native_shared_libs: ["my_standalone_lib"],
  ..
}

Triển khai HAL

Để xác định cách triển khai HAL, hãy cung cấp các tệp nhị phân và thư viện tương ứng bên trong APEX của nhà cung cấp, tương tự như các ví dụ sau:

Để đóng gói hoàn toàn việc triển khai HAL, APEX cũng phải chỉ định bất kỳ các mảnh VINTF và tập lệnh init có liên quan.

Mảnh VINTF

Mảnh VINTF có thể được phân phát qua APEX của nhà cung cấp khi các mảnh nằm trong etc/vintf của APEX.

Dùng thuộc tính prebuilts để nhúng các mảnh VINTF vào APEX.

apex {
  ..
  vendor: true,
  prebuilts: ["fragment.xml"],
  ..
}

prebuilt_etc {
  name: "fragment.xml",
  src: "fragment.xml",
  sub_dir: "vintf",
}

Tập lệnh khởi tạo

APEX có thể chứa các tập lệnh khởi tạo theo 2 cách: (A) một tệp văn bản tạo sẵn trong tải trọng APEX hoặc (B) một tập lệnh init thông thường trong /vendor/etc. Bạn có thể đặt cả hai cho cùng một APEX.

Khởi tạo tập lệnh trong APEX:

prebuilt_etc {
  name: "myinit.rc",
  src: "myinit.rc"
}

apex {
  ..
  vendor: true,
  prebuilts: ["myinit.rc"],
  ..
}

Các tập lệnh khởi tạo trong APEX chỉ có thể có định nghĩa service. Tập lệnh khởi tạo trong APEX của nhà cung cấp cũng có thể có lệnh on <property>.

Hãy thận trọng khi sử dụng lệnh on. Vì các tập lệnh init trong APEX được phân tích cú pháp và thực thi sau khi APEX được kích hoạt, một số sự kiện hoặc thuộc tính không thể sử dụng. Sử dụng apex.all.ready=true để kích hoạt các hành động càng sớm càng tốt.

Chương trình cơ sở

Ví dụ:

Nhúng chương trình cơ sở vào APEX của nhà cung cấp bằng loại mô-đun prebuilt_firmware, như theo dõi.

prebuilt_firmware {
  name: "my.bin",
  src: "path_to_prebuilt_firmware",
  vendor: true,
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.bin"],  // installed inside APEX as /etc/firmware/my.bin
  ..
}

prebuilt_firmware mô-đun được cài đặt trong <apex name>/etc/firmware của APEX. ueventd quét /apex/*/etc/firmware thư mục để tìm mô-đun chương trình cơ sở.

file_contexts của APEX phải gắn nhãn mọi mục trong phần tải trọng của chương trình cơ sở đúng cách để đảm bảo rằng ueventd có thể truy cập vào các tệp này trong thời gian chạy; thường, chỉ cần nhãn vendor_file là đủ. Ví dụ:

(/.*)? u:object_r:vendor_file:s0

Mô-đun kernel

Nhúng mô-đun nhân hệ điều hành trong APEX của nhà cung cấp dưới dạng mô-đun tạo sẵn như sau.

prebuilt_etc {
  name: "my.ko",
  src: "my.ko",
  vendor: true,
  sub_dir: "modules"
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.ko"],  // installed inside APEX as /etc/modules/my.ko
  ..
}

file_contexts của APEX phải gắn nhãn cho mọi mục nhập tải trọng mô-đun nhân đúng cách. Ví dụ:

/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0

Bạn phải cài đặt các mô-đun hạt nhân một cách rõ ràng. Tập lệnh init mẫu sau trong phân vùng nhà cung cấp hiển thị bản cài đặt qua insmod:

my_init.rc:

on early-boot
  insmod /apex/myapex/etc/modules/my.ko
  ..

Lớp phủ tài nguyên trong thời gian chạy

Ví dụ:

Nhúng lớp phủ tài nguyên thời gian chạy vào APEX của nhà cung cấp bằng cách sử dụng thuộc tính rros.

runtime_resource_overlay {
    name: "my_rro",
    soc_specific: true,
}


apex {
  ..
  vendor: true,
  rros: ["my_rro"],  // installed inside APEX as /overlay/my_rro.apk
  ..
}

Các tệp cấu hình khác

APEX của nhà cung cấp hỗ trợ nhiều tệp cấu hình khác thường có trên nhà cung cấp phân vùng dưới dạng được tạo sẵn bên trong các APEX của nhà cung cấp và nhiều cấu hình khác đang được thêm vào.

Ví dụ:

Các tính năng phát triển bổ sung

Lựa chọn APEX khi khởi động

Ví dụ:

Nhà phát triển cũng có thể cài đặt nhiều phiên bản APEX của nhà cung cấp dùng chung cùng tên và khoá APEX, sau đó chọn phiên bản sẽ được kích hoạt trong mỗi lần khởi động bằng sysprops liên tục. Đối với một số trường hợp sử dụng nhất định của nhà phát triển, đơn giản hơn so với việc cài đặt một bản sao của APEX mới bằng adb install.

Ví dụ về trường hợp sử dụng:

  • Cài đặt 3 phiên bản APEX của nhà cung cấp Wi-Fi HAL: Nhóm đảm bảo chất lượng có thể chạy hướng dẫn hoặc kiểm thử tự động bằng một phiên bản, sau đó khởi động lại để chuyển sang một phiên bản khác và chạy lại kiểm thử, sau đó so sánh kết quả cuối cùng.
  • Cài đặt 2 phiên bản APEX của nhà cung cấp lớp trừu tượng phần cứng (HAL) cho máy ảnh, hiện tạithử nghiệm: Nhân viên thử nghiệm có thể sử dụng phiên bản thử nghiệm mà không cần tải xuống và cài đặt một tệp bổ sung để chúng có thể dễ dàng hoán đổi lại.

Trong khi khởi động, apexd tìm các sysprops theo một định dạng cụ thể để kích hoạt đúng phiên bản APEX.

Các định dạng dự kiến cho khoá thuộc tính là:

  • Cấu hình khởi động
    • Dùng để đặt giá trị mặc định trong BoardConfig.mk.
    • androidboot.vendor.apex.<apex name>
  • sysprop ổn định
    • Dùng để thay đổi giá trị mặc định, được đặt trên một thiết bị đã khởi động.
    • Ghi đè giá trị bootconfig nếu có.
    • persist.vendor.apex.<apex name>

Giá trị của thuộc tính này phải là tên tệp của APEX đã kích hoạt.

// Default version.
apex {
  name: "com.oem.camera.hal.my_apex_default",
  vendor: true,
  ..
}

// Non-default version.
apex {
  name: "com.oem.camera.hal.my_apex_experimental",
  vendor: true,
  ..
}

Phiên bản mặc định cũng phải được định cấu hình bằng cách sử dụng bootconfig trong BoardConfig.mk:

# Example for APEX "com.oem.camera.hal" with the default above:
BOARD_BOOTCONFIG += \
    androidboot.vendor.apex.com.oem.camera.hal=com.oem.camera.hal.my_apex_default

Sau khi khởi động thiết bị, hãy thay đổi phiên bản đã kích hoạt bằng cách đặt sysprop ổn định:

$ adb root;
$ adb shell setprop \
    persist.vendor.apex.com.oem.camera.hal \
    com.oem.camera.hal.my_apex_experimental;
$ adb reboot;

Nếu thiết bị hỗ trợ cập nhật cấu hình khởi động sau khi cài đặt ROM (chẳng hạn như qua lệnh fastboot oem), hãy thay đổi thuộc tính khởi động cho cấu hình được cài đặt APEX cũng thay đổi phiên bản được kích hoạt khi khởi động.

Đối với các thiết bị tham chiếu ảo dựa trên Cuttlefish, bạn có thể dùng lệnh --extra_bootconfig_args để đặt thuộc tính bootconfig ngay trong khi khởi chạy. Ví dụ:

launch_cvd --noresume \
  --extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";