Anda dapat menggunakan format file APEX untuk memaketkan dan menginstal modul Android OS tingkat rendah. Hal ini memungkinkan pembuatan dan penginstalan komponen secara independen seperti layanan dan library native, implementasi HAL, firmware, file konfigurasi, dll.
APEX vendor diinstal secara otomatis oleh sistem build dalam partisi /vendor
dan diaktifkan saat runtime oleh apexd
seperti APEX di partisi
lain.
Kasus penggunaan
Modularisasi gambar vendor
APEX memfasilitasi pengelompokan dan modularisasi alami dari penerapan fitur pada image vendor.
Saat image vendor dibuat sebagai kombinasi APEX vendor yang dibuat secara independen, produsen perangkat dapat dengan mudah memilih dan menentukan implementasi vendor tertentu yang diinginkan di perangkat mereka. Produsen bahkan dapat membuat APEX vendor baru jika tidak ada APEX yang disediakan yang sesuai dengan kebutuhan mereka, atau mereka memiliki hardware kustom baru.
Misalnya, OEM dapat memilih untuk mengomposisi perangkatnya dengan APEX implementasi wifi AOSP, APEX implementasi bluetooth SoC, dan APEX implementasi telepon OEM kustom.
Tanpa APEX vendor, implementasi dengan begitu banyak dependensi di antara komponen vendor memerlukan koordinasi dan pelacakan yang cermat. Dengan menggabungkan semua komponen (termasuk file konfigurasi dan library tambahan) di APEX dengan antarmuka yang ditentukan dengan jelas pada setiap titik komunikasi lintas fitur, komponen yang berbeda menjadi dapat dipertukarkan.
Iterasi developer
APEX vendor membantu developer melakukan iterasi lebih cepat saat mengembangkan modul vendor dengan menggabungkan seluruh implementasi fitur, seperti HAL wifi, di dalam APEX vendor. Kemudian, developer dapat mem-build dan mengirim APEX vendor satu per satu untuk menguji perubahan, bukan membangun ulang seluruh image vendor.
Hal ini menyederhanakan dan mempercepat siklus iterasi developer untuk developer yang terutama bekerja di satu area fitur dan ingin melakukan iterasi hanya pada area fitur tersebut.
Penggabungan alami area fitur ke dalam APEX juga menyederhanakan proses mem-build, mendorong, dan menguji perubahan untuk area fitur tersebut. Misalnya, menginstal ulang APEX akan otomatis mengupdate library atau file konfigurasi yang dipaketkan APEX.
Memaketkan area fitur ke dalam APEX juga menyederhanakan proses debug atau pengembalian jika perilaku perangkat yang buruk diamati. Misalnya, jika telepon tidak berfungsi dengan baik pada build baru, developer dapat mencoba menginstal APEX implementasi telepon lama di perangkat (tanpa perlu mem-flash build penuh) dan melihat apakah perilaku yang baik telah dipulihkan.
Contoh alur kerja:
# 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 ...
Contoh
Dasar-dasar
Lihat halaman Format File APEX utama untuk mengetahui informasi APEX umum, termasuk persyaratan perangkat, detail format file, dan langkah-langkah penginstalan.
Di Android.bp
, menetapkan properti vendor: true
akan membuat modul APEX menjadi
APEX vendor.
apex {
..
vendor: true,
..
}
Biner dan library bersama
APEX menyertakan dependensi transitif di dalam payload APEX kecuali jika memiliki antarmuka yang stabil.
Antarmuka native yang stabil untuk dependensi APEX vendor mencakup cc_library
dengan
library stubs
dan LLNDK. Dependensi ini dikecualikan dari
paket, dan dependensi dicatat dalam manifes APEX. Manifes diproses oleh linkerconfig
agar dependensi native eksternal tersedia saat runtime.
Dalam cuplikan berikut, APEX berisi biner (my_service
) dan
dependensi yang tidak stabil (file *.so
).
apex {
..
vendor: true,
binaries: ["my_service"],
..
}
Dalam cuplikan berikut, APEX berisi library bersama
my_standalone_lib
dan dependensi non-stabilnya (seperti yang dijelaskan di atas).
apex {
..
vendor: true,
native_shared_libs: ["my_standalone_lib"],
..
}
Membuat APEX lebih kecil
APEX dapat menjadi lebih besar karena membundel dependensi yang tidak stabil. Sebaiknya
gunakan penautan statis. Library umum seperti libc++.so
dan libbase.so
dapat
ditautkan secara statis ke biner HAL. Membuat dependensi untuk menyediakan antarmuka
yang stabil dapat menjadi opsi lain. Dependensi tidak akan dipaketkan dalam APEX.
Implementasi HAL
Untuk mendefinisikan implementasi HAL, sediakan biner dan library yang sesuai dalam APEX vendor seperti contoh berikut:
Untuk mengenkapsulasi implementasi HAL sepenuhnya, APEX juga harus menentukan fragmen VINTF dan skrip init yang relevan.
Fragmen VINTF
Fragmen VINTF dapat ditayangkan dari APEX vendor saat fragmen berada di
etc/vintf
APEX.
Gunakan properti prebuilts
untuk menyematkan fragmen VINTF di APEX.
apex {
..
vendor: true,
prebuilts: ["fragment.xml"],
..
}
prebuilt_etc {
name: "fragment.xml",
src: "fragment.xml",
sub_dir: "vintf",
}
API Kueri
Saat fragmen VINTF ditambahkan ke APEX, gunakan libbinder_ndk
API untuk mendapatkan
pemetaan antarmuka HAL dan nama APEX.
AServiceManager_isUpdatableViaApex("com.android.foo.IFoo/default")
:true
jika instance HAL ditentukan di APEX.AServiceManager_getUpdatableApexName("com.android.foo.IFoo/default", ...)
: mendapatkan nama APEX yang menentukan instance HAL.AServiceManager_openDeclaredPassthroughHal("mapper", "instance", ...)
: gunakan ini untuk membuka HAL passthrough.
Skrip init
APEX dapat menyertakan skrip init dengan dua cara: (A) file teks bawaan dalam
payload APEX, atau (B) skrip init reguler di /vendor/etc
. Anda dapat menetapkan keduanya
untuk APEX yang sama.
Skrip init di APEX:
prebuilt_etc {
name: "myinit.rc",
src: "myinit.rc"
}
apex {
..
vendor: true,
prebuilts: ["myinit.rc"],
..
}
Skrip init di APEX vendor dapat memiliki definisi service
dan
perintah on <property or event>
.
Pastikan definisi service
mengarah ke biner di APEX yang sama.
Misalnya, com.android.foo
APEX dapat menentukan layanan bernama foo-service
.
on foo-service /apex/com.android.foo/bin/foo
...
Berhati-hatilah saat menggunakan perintah on
. Karena skrip init dalam APEX
diurai dan dieksekusi setelah APEX diaktifkan, beberapa peristiwa atau properti
tidak dapat digunakan. Gunakan apex.all.ready=true
untuk mengaktifkan tindakan sedini mungkin.
APEX Bootstrap dapat menggunakan on init
, tetapi tidak
on early-init
.
Firmware
Contoh:
Sematkan firmware di APEX vendor dengan jenis modul prebuilt_firmware
, seperti
berikut.
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
..
}
Modul prebuilt_firmware
diinstal di direktori <apex name>/etc/firmware
APEX. ueventd
memindai direktori /apex/*/etc/firmware
untuk
menemukan modul firmware.
file_contexts
APEX harus memberi label entri payload firmware
dengan benar untuk memastikan bahwa file ini dapat diakses oleh ueventd
saat runtime;
biasanya, label vendor_file
sudah memadai. Contoh:
(/.*)? u:object_r:vendor_file:s0
Modul kernel
Sematkan modul kernel di APEX vendor sebagai modul bawaan, sebagai berikut.
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
APEX harus memberi label entri payload modul kernel
dengan benar. Contoh:
/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0
Modul kernel harus diinstal secara eksplisit. Contoh skrip init berikut
di partisi vendor menunjukkan penginstalan melalui insmod
:
my_init.rc
:
on early-boot
insmod /apex/myapex/etc/modules/my.ko
..
Overlay resource runtime
Contoh:
Sematkan overlay resource runtime di APEX vendor
menggunakan properti rros
.
runtime_resource_overlay {
name: "my_rro",
soc_specific: true,
}
apex {
..
vendor: true,
rros: ["my_rro"], // installed inside APEX as /overlay/my_rro.apk
..
}
File konfigurasi lainnya
APEX vendor mendukung berbagai file konfigurasi lain yang biasanya ditemukan di partisi vendor sebagai bawaan di dalam APEX vendor, dan lainnya sedang ditambahkan.
Contoh:
- XML pernyataan fitur
- Sensor menampilkan XML sebagai pra-build di APEX vendor HAL sensor
- File konfigurasi input
- Konfigurasi layar sentuh sebagai bawaan di APEX vendor khusus konfigurasi
Bootstrap APEX Vendor
Beberapa layanan HAL seperti keymint
harus tersedia sebelum APEX
diaktifkan. HAL tersebut biasanya menetapkan early_hal
dalam definisi layanannya dalam
skrip init. Contoh lainnya adalah class animation
yang biasanya dimulai
lebih awal daripada peristiwa post-fs-data
. Saat layanan HAL awal tersebut
dikemas dalam APEX vendor, buat "vendorBootstrap": true
apex dalam Manifes
APEX-nya agar dapat diaktifkan lebih awal. Perhatikan bahwa APEX bootstrap hanya dapat diaktifkan dari lokasi bawaan seperti /vendor/apex
, bukan dari /data/apex
.
Properti sistem
Berikut adalah properti sistem yang dibaca framework untuk mendukung APEX vendor:
input_device.config_file.apex=<apex name>
- jika ditetapkan, file konfigurasi input (*.idc
,*.kl
, dan*.kcm
) akan ditelusuri dari direktori/etc/usr
APEX.ro.vulkan.apex=<apex name>
- jika ditetapkan, driver Vulkan akan dimuat dari APEX. Karena driver Vulkan digunakan oleh HAL awal, buat APEX Bootstrap APEX dan konfigurasikan namespace penaut tersebut agar terlihat.
Tetapkan properti sistem di skrip init menggunakan perintah
setprop
.
Fitur pengembangan tambahan
Pemilihan APEX saat booting
Contoh:
Developer juga dapat menginstal beberapa versi APEX vendor yang memiliki
nama dan kunci APEX yang sama, lalu memilih versi mana yang diaktifkan selama setiap
bootup menggunakan sysprop persisten. Untuk kasus penggunaan developer tertentu, hal ini mungkin
lebih sederhana daripada menginstal salinan APEX baru menggunakan adb install
.
Contoh kasus penggunaan:
- Instal 3 versi APEX vendor HAL wifi: Tim QA dapat menjalankan pengujian manual atau otomatis menggunakan satu versi, lalu memulai ulang ke versi lain dan menjalankan ulang pengujian, lalu membandingkan hasil akhir.
- Instal 2 versi APEX vendor HAL kamera, saat ini dan eksperimental: Dogfooder dapat menggunakan versi eksperimental tanpa mendownload dan menginstal file tambahan, sehingga mereka dapat dengan mudah beralih kembali.
Selama booting, apexd
mencari sysprops yang mengikuti format tertentu untuk
mengaktifkan versi APEX yang tepat.
Format yang diharapkan untuk kunci properti adalah:
- Bootconfig
- Digunakan untuk menetapkan nilai default, di
BoardConfig.mk
. androidboot.vendor.apex.<apex name>
- Digunakan untuk menetapkan nilai default, di
- Sysprop persisten
- Digunakan untuk mengubah nilai default, disetel pada perangkat yang sudah di-booting.
- Mengganti nilai bootconfig jika ada.
persist.vendor.apex.<apex name>
Nilai properti harus berupa nama file APEX yang harus diaktifkan.
// 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,
..
}
Versi default juga harus dikonfigurasi menggunakan bootconfig di
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
Setelah perangkat di-booting, ubah versi yang diaktifkan dengan menetapkan sysprop persisten:
$ adb root;
$ adb shell setprop \
persist.vendor.apex.com.oem.camera.hal \
com.oem.camera.hal.my_apex_experimental;
$ adb reboot;
Jika perangkat mendukung update bootconfig setelah melakukan flash (seperti melalui perintah fastboot
oem
), mengubah properti bootconfig untuk APEX
yang multi-instal juga akan mengubah versi yang diaktifkan saat booting.
Untuk perangkat referensi virtual berdasarkan Cuttlefish,
Anda dapat menggunakan perintah --extra_bootconfig_args
untuk menetapkan properti bootconfig
secara langsung saat peluncuran. Contoh:
launch_cvd --noresume \
--extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";