Daha düşük seviyeli Android OS modüllerini paketlemek ve yüklemek için APEX dosya biçimini kullanabilirsiniz. Yerel hizmetler ve kitaplıklar, HAL uygulamaları, donanım yazılımı, yapılandırma dosyaları gibi bileşenlerin bağımsız olarak oluşturulmasına ve yüklenmesine olanak tanır.
Tedarikçi APEX'leri, derleme sistemi tarafından /vendor
bölümüne otomatik olarak yüklenir ve diğer bölümlerdeki APEX'ler gibi apexd
tarafından çalışma zamanında etkinleştirilir.
Kullanım örnekleri
Tedarikçi resimlerinin modülerleştirilmesi
APEX'ler, satıcı resimlerindeki özellik uygulamalarının doğal olarak paketlenmesini ve modülerleştirilmesini kolaylaştırır.
Tedarikçi resimleri, bağımsız olarak oluşturulmuş tedarikçi APEX'lerinin bir kombinasyonu olarak oluşturulduğunda cihaz üreticileri, cihazlarında istedikleri belirli tedarikçi uygulamalarını kolayca seçebilir. Üreticiler, sağlanan APEX'lerden hiçbiri ihtiyaçlarına uygun değilse veya yepyeni bir özel donanımları varsa yeni bir satıcı APEX'i bile oluşturabilir.
Örneğin, bir OEM, cihazını AOSP kablosuz uygulama APEX'i, SoC bluetooth uygulama APEX'i ve özel bir OEM telefon uygulama APEX'i ile oluşturmayı seçebilir.
Tedarikçi APEX'leri olmadan, tedarikçi bileşenleri arasında bu kadar çok bağımlılığın olduğu bir uygulamanın dikkatli bir şekilde koordine edilmesi ve izlenmesi gerekir. Tüm bileşenler (yapılandırma dosyaları ve ek kitaplıklar dahil) özellikler arası iletişimin herhangi bir noktasında net bir şekilde tanımlanmış arayüzlere sahip APEX'lere yerleştirilerek farklı bileşenler birbirinin yerine kullanılabilir hale gelir.
Geliştirici yinelemesi
Tedarikçi APEX'leri, geliştiricilerin tedarikçi modüllerini geliştirirken daha hızlı yineleme yapmasına yardımcı olur. Bunu, WiFi HAL gibi tüm özellik uygulamalarını bir tedarikçi APEX'i içinde paketleyerek yapar. Böylece geliştiriciler, satıcı APEX'ini test değişikliklerine göre ayrı ayrı oluşturup gönderebilir ve satıcı imajının tamamını yeniden oluşturmak zorunda kalmaz.
Bu, öncelikli olarak tek bir özellik alanında çalışan ve yalnızca bu özellik alanında yineleme yapmak isteyen geliştiriciler için geliştirici yineleme döngüsünü basitleştirir ve hızlandırır.
Bir özellik alanının APEX'e doğal olarak paketlenmesi, bu özellik alanıyla ilgili değişikliklerin oluşturulması, gönderilmesi ve test edilmesi sürecini de basitleştirir. Örneğin, bir APEX'in yeniden yüklenmesi, APEX'in içerdiği tüm paketlenmiş kitaplık veya yapılandırma dosyalarını otomatik olarak günceller.
Bir özellik alanını APEX'e dahil etmek, kötü cihaz davranışı gözlemlendiğinde hata ayıklamayı veya geri döndürmeyi de kolaylaştırır. Örneğin, yeni bir derlemede telefon özelliği düzgün çalışmıyorsa geliştiriciler, cihaza daha eski bir telefon özelliği uygulaması APEX'i yükleyip (tam derleme flaşlamaya gerek kalmadan) iyi davranışın geri gelip gelmediğini görebilir.
Örnek iş akışı:
# 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 ...
Örnekler
Temel Bilgiler
Cihaz koşulları, dosya biçimi ayrıntıları ve yükleme adımları dahil olmak üzere genel APEX bilgileri için ana APEX Dosya Biçimi sayfasını inceleyin.
Android.bp
içinde vendor: true
özelliğinin ayarlanması, APEX modülünü satıcı APEX'i yapar.
apex {
..
vendor: true,
..
}
İkili dosyalar ve paylaşılan kitaplıklar
APEX'ler, kararlı arayüzlere sahip olmadıkları sürece APEX yükü içinde geçişli bağımlılıklar içerir.
Satıcı APEX bağımlılıkları için kararlı yerel arayüzler, cc_library
ile stubs
ve LLNDK kitaplıklarını içerir. Bu bağımlılıklar paketlemeye dahil edilmez ve bağımlılıklar APEX manifestine kaydedilir. Manifest, linkerconfig
tarafından işlenir. Böylece, harici yerel bağımlılıklar çalışma zamanında kullanılabilir.
Aşağıdaki snippet'te APEX hem ikiliyi (my_service
) hem de kararlı olmayan bağımlılıklarını (*.so
dosyaları) içerir.
apex {
..
vendor: true,
binaries: ["my_service"],
..
}
Aşağıdaki snippet'te APEX, paylaşılan kitaplığı ve kararlı olmayan bağımlılıklarını (yukarıda açıklandığı gibi) içerir.my_standalone_lib
apex {
..
vendor: true,
native_shared_libs: ["my_standalone_lib"],
..
}
APEX'i küçültme
APEX, kararlı olmayan bağımlılıkları paketlediği için daha büyük olabilir. Statik bağlantı kullanmanızı öneririz. libc++.so
ve libbase.so
gibi yaygın kitaplıklar, HAL ikililerine statik olarak bağlanabilir. Kararlı bir arayüz sağlamak için bağımlılık oluşturmak da başka bir seçenek olabilir. Bağımlılık, APEX'e dahil edilmez.
HAL uygulamaları
Bir HAL uygulaması tanımlamak için aşağıdaki örneklere benzer şekilde, satıcı APEX'i içinde ilgili ikili dosyaları ve kitaplıkları sağlayın:
HAL uygulamasını tam olarak kapsamak için APEX, ilgili VINTF parçalarını ve init komut dosyalarını da belirtmelidir.
VINTF parçaları
VINTF parçaları, APEX'in etc/vintf
bölümünde bulunduğunda bir tedarikçi APEX'inden sunulabilir.
VINTF parçalarını APEX'e yerleştirmek için prebuilts
özelliğini kullanın.
apex {
..
vendor: true,
prebuilts: ["fragment.xml"],
..
}
prebuilt_etc {
name: "fragment.xml",
src: "fragment.xml",
sub_dir: "vintf",
}
Query API'leri
VINTF parçaları APEX'e eklendiğinde HAL arayüzlerinin ve APEX adlarının eşlemelerini almak için libbinder_ndk
API'lerini kullanın.
AServiceManager_isUpdatableViaApex("com.android.foo.IFoo/default")
:true
HAL örneği APEX'te tanımlanmışsa.AServiceManager_getUpdatableApexName("com.android.foo.IFoo/default", ...)
: HAL örneğini tanımlayan APEX adını alır.AServiceManager_openDeclaredPassthroughHal("mapper", "instance", ...)
: Bu komut, doğrudan geçişli bir HAL'ı açmak için kullanılır.
Init komut dosyaları
APEX'ler, başlatma komut dosyalarını iki şekilde içerebilir: (A) APEX yükünde önceden oluşturulmuş bir metin dosyası veya (B) /vendor/etc
içinde normal bir başlatma komut dosyası. Aynı APEX için her ikisini de ayarlayabilirsiniz.
APEX'teki başlatma komut dosyası:
prebuilt_etc {
name: "myinit.rc",
src: "myinit.rc"
}
apex {
..
vendor: true,
prebuilts: ["myinit.rc"],
..
}
Tedarikçi APEX'lerindeki başlatma komut dosyaları service
tanımlarına ve on <property or event>
yönergelerine sahip olabilir.
Bir service
tanımının aynı APEX'teki bir ikiliye işaret ettiğinden emin olun.
Örneğin, com.android.foo
APEX, foo-service
adlı bir hizmet tanımlayabilir.
on foo-service /apex/com.android.foo/bin/foo
...
on
yönergelerini kullanırken dikkatli olun. APEX'lerdeki başlatma komut dosyaları, APEX'ler etkinleştirildikten sonra ayrıştırılıp yürütüldüğünden bazı etkinlikler veya özellikler kullanılamaz. İşlemleri mümkün olduğunca erken tetiklemek için apex.all.ready=true
kullanın.
Bootstrap APEX'leri on init
kullanabilir ancak on early-init
kullanamaz.
Donanım yazılımı
Örnek:
Donanım yazılımını, aşağıdaki gibi prebuilt_firmware
modül türüyle bir tedarikçi APEX'ine yerleştirin.
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
..
}
APEX'in <apex name>/etc/firmware
dizinine prebuilt_firmware
modül yüklenir. ueventd
, donanım yazılımı modüllerini bulmak için /apex/*/etc/firmware
dizinlerini tarar.
on early-init
APEX'in file_contexts
, bu dosyaların çalışma zamanında ueventd
tarafından erişilebilir olmasını sağlamak için tüm donanım yazılımı yükü girişlerini düzgün şekilde etiketlemelidir. Genellikle vendor_file
etiketi yeterlidir. Örneğin:
(/.*)? u:object_r:vendor_file:s0
Çekirdek modülleri
Çekirdek modüllerini, aşağıdaki şekilde önceden oluşturulmuş modüller olarak bir satıcı APEX'ine yerleştirin.
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
..
}
APEX'in file_contexts
, tüm çekirdek modülü yükü girişlerini düzgün şekilde etiketlemelidir. Örneğin:
/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0
Çekirdek modülleri açıkça yüklenmelidir. Aşağıdaki örnekte, satıcı bölümündeki bir başlatma komut dosyası, insmod
üzerinden yüklemeyi göstermektedir:
my_init.rc
:
on early-boot
insmod /apex/myapex/etc/modules/my.ko
..
Çalışma zamanında kaynak eşlemeleri
Örnek:
rros
özelliğini kullanarak bir satıcı APEX'ine çalışma zamanı kaynak yer paylaşımları yerleştirin.
runtime_resource_overlay {
name: "my_rro",
soc_specific: true,
}
apex {
..
vendor: true,
rros: ["my_rro"], // installed inside APEX as /overlay/my_rro.apk
..
}
Diğer yapılandırma dosyaları
Tedarikçi APEX'leri, genellikle tedarikçi bölümünde bulunan çeşitli yapılandırma dosyalarını tedarikçi APEX'lerinde önceden oluşturulmuş olarak destekler ve daha fazlası eklenmektedir.
Örnekler:
- Özellik beyanı XML'leri
- Sensörler, sensör HAL satıcısı APEX'inde önceden oluşturulmuş olarak XML'leri içerir.
- Giriş yapılandırma dosyaları
- Dokunmatik ekran yapılandırmaları, yalnızca yapılandırma içeren bir satıcı APEX'inde önceden oluşturulmuş olarak
Bootstrap Vendor APEXes
keymint
gibi bazı HAL hizmetleri, APEX'ler etkinleştirilmeden önce kullanılabilir olmalıdır. Bu HAL'ler genellikle başlatma komut dosyasındaki hizmet tanımlarında early_hal
değerini ayarlar. Başka bir örnek de post-fs-data
etkinliğinden genellikle daha önce başlayan animation
sınıfıdır. Bu tür erken HAL hizmetleri, satıcı APEX'inde paketlendiğinde, APEX Manifest'inde "vendorBootstrap": true
olarak işaretleyin. Böylece daha erken etkinleştirilebilir. Başlangıç APEX'lerinin yalnızca /vendor/apex
gibi önceden oluşturulmuş konumdan etkinleştirilebileceğini, /data/apex
konumundan etkinleştirilemeyeceğini unutmayın.
Sistem özellikleri
Çerçeve, satıcı APEX'lerini desteklemek için aşağıdaki sistem özelliklerini okur:
input_device.config_file.apex=<apex name>
: Ayarlandığında giriş yapılandırma dosyaları (*.idc
,*.kl
ve*.kcm
), APEX'in/etc/usr
dizininde aranır.ro.vulkan.apex=<apex name>
- Ayarlandığında Vulkan sürücüsü APEX'ten yüklenir. Vulkan sürücüsü erken HAL'ler tarafından kullanıldığından APEX'i Bootstrap APEX olarak ayarlayın ve bağlayıcı ad alanını görünür olacak şekilde yapılandırın.
setprop
komutunu kullanarak init komut dosyalarında sistem özelliklerini ayarlayın.
Ek özellikler
Başlatma sırasında APEX seçimi
Örnek:
Tedarikçi APEX'leri, başlatma sırasında isteğe bağlı olarak etkinleştirilebilir.
Sistem özelliğini kullanarak bir dosya adı belirtirseniz
ro.vendor.apex.<apex name>
, yalnızca dosya adıyla eşleşen APEX, belirli <apex name>
için etkinleştirilir.
Bu sistem özelliği none
olarak ayarlanırsa <apex name>
içeren APEX yoksayılır (etkinleştirilmez). Bu özelliği, aynı ada sahip bir APEX'in birden fazla kopyasını yüklemek için kullanabilirsiniz. Aynı APEX'in birden fazla sürümü varsa aynı anahtarı paylaşmalıdırlar.
Kullanım alanı örnekleri:
- Kablosuz HAL sağlayıcı APEX'in 3 sürümünü yükleyin: KG ekipleri, bir sürümü kullanarak manuel veya otomatik testler çalıştırabilir, ardından başka bir sürümde yeniden başlatıp testleri tekrar çalıştırabilir ve son olarak sonuçları karşılaştırabilir.
- Kamera HAL satıcısı APEX'in 2 sürümünü (mevcut ve deneysel) yükleyin: Dogfood kullanıcıları, ek bir dosya indirmeden ve yüklemeden deneysel sürümü kullanabilir. Böylece kolayca geri dönebilirler.
Başlatma sırasında apexd
, doğru APEX sürümünü etkinleştirmek için belirli bir biçime sahip sysprop'ları arar.
Özellik anahtarı için beklenen biçimler şunlardır:
- Bootconfig
- Varsayılan değeri
BoardConfig.mk
cinsinden ayarlamak için kullanılır. androidboot.vendor.apex.<apex name>
- Varsayılan değeri
- Kalıcı sysprop
- Zaten başlatılmış bir cihazda ayarlanan varsayılan değeri değiştirmek için kullanılır.
- Mevcutsa bootconfig değerini geçersiz kılar.
persist.vendor.apex.<apex name>
Özelliğin değeri, etkinleştirilmesi gereken APEX'in dosya adı veya APEX'i devre dışı bırakmak için none
olmalıdır.
// 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,
..
}
Varsayılan sürüm de BoardConfig.mk
içinde bootconfig kullanılarak yapılandırılmalıdır:
# 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
Cihaz başlatıldıktan sonra, etkinleştirilen sürümü kalıcı sysprop'u ayarlayarak değiştirin:
$ adb root;
$ adb shell setprop \
persist.vendor.apex.com.oem.camera.hal \
com.oem.camera.hal.my_apex_experimental;
$ adb reboot;
Cihaz, yanıp sönme işleminden sonra bootconfig'in güncellenmesini destekliyorsa (ör. fastboot
oem
komutları aracılığıyla) çoklu yüklenmiş APEX'in bootconfig özelliğinin değiştirilmesi, başlatma sırasında etkinleştirilen sürümü de değiştirir.
Cuttlefish'e dayalı sanal referans cihazlarda, başlatma sırasında bootconfig özelliğini doğrudan ayarlamak için --extra_bootconfig_args
komutunu kullanabilirsiniz. Örneğin:
launch_cvd --noresume \
--extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";