Tedarikçi firma APEX

Alt düzey 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 derlenmesine 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 firma görüntülerinin modülerleştirilmesi

APEX'ler, tedarikçi firma resimlerinde özellik uygulamalarının doğal bir şekilde gruplandırılmasını ve modülerleştirilmesini sağlar.

Tedarikçi firma resimleri, bağımsız olarak oluşturulmuş tedarikçi firma APEX'lerinin bir kombinasyonu olarak oluşturulduğunda cihaz üreticileri, cihazlarında istedikleri tedarikçi firma uygulamalarını kolayca seçebilir. Üreticiler, sağlanan APEX'lerden hiçbiri ihtiyaçlarına uymuyorsa veya yepyeni özel donanımlara sahiplerse yeni bir tedarikçi APEX'i bile oluşturabilirler.

Örneğin, bir OEM, cihazını AOSP kablosuz ağ uygulaması APEX, SoC Bluetooth uygulama APEX ve özel bir OEM telefon uygulaması APEX ile oluşturmayı tercih edebilir.

Tedarikçi APEX'leri olmadığında, tedarikçi bileşenleri arasında çok fazla bağımlılığın bulunduğu bir uygulama için dikkatli bir koordinasyon ve izleme gerekir. Tüm bileşenler (yapılandırma dosyaları ve ek kitaplıklar dahil) APEX'lere, özellikler arası iletişim noktasında açıkça tanımlanmış arayüzlerle sarmalandığında farklı bileşenler birbirinin yerine kullanılabilir.

Geliştirici iterasyonu

Tedarikçi APEX'leri, bir tedarikçi APEX'inin içine WiFi HAL gibi bir özellik uygulamasının tamamını paketleyerek tedarikçi modülleri geliştirirken geliştiricilerin daha hızlı iterasyon yapmasına yardımcı olur. Geliştiriciler daha sonra tedarikçi firma imajının tamamını yeniden oluşturmak yerine değişiklikleri test etmek için tedarikçi firma APEX'ini oluşturup tek tek gönderebilir.

Bu, esas olarak tek bir özellik alanında çalışan ve yalnızca bu özellik alanında iterasyon yapmak isteyen geliştiriciler için geliştirici yineleme döngüsünü basitleştirip hızlandırır.

Bir özellik alanının APEX'te doğal olarak gruplandırılması, söz konusu özellik alanındaki değişiklikleri oluşturma, yayınlama ve test etme sürecini de basitleştirir. Örneğin, bir APEX'i yeniden yüklediğinizde APEX'in içerdiği tüm paketlenmiş kitaplıklar veya yapılandırma dosyaları otomatik olarak güncellenir.

Bir özellik alanını APEX'te gruplandırmak, kötü cihaz davranışı gözlemlendiğinde hata ayıklamayı veya geri almayı da kolaylaştırır. Örneğin, yeni bir derlemede telefon işlevi düzgün çalışmıyorsa geliştiriciler, cihaza eski bir telefon işlevi APEX'i yüklemeyi (tam derlemeyi yüklemeye gerek kalmadan) deneyip düzgün çalışma durumunun geri dönüp dönmediğ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 gereksinimleri, 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ına bakın.

Android.bp içinde vendor: true mülkünün ayarlanması, APEX modülünü tedarikçi APEX'e dönüştürür.

apex {
  ..
  vendor: true,
  ..
}

İkili programlar ve paylaşılan kitaplıklar

APEX, kararlı arayüzleri olmadığı 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 arasında cc_library ile stubs ve LLNDK kitaplıkları bulunur. Bu bağımlılıklar pakete 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 ikili dosyayı (my_service) hem de kararlı olmayan bağımlılıkları (*.so dosyaları) içerir.

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

Aşağıdaki snippet'te APEX, paylaşılan kitaplığı my_standalone_libve yukarıda açıklandığı gibi kararlı olmayan tüm bağımlılıklarını içerir.

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 ikili dosyalarına statik olarak bağlanabilir. İstikrarlı bir arayüz sağlamak için bağımlılık kurmak başka bir seçenek olabilir. Bağımlılık APEX'e dahil edilmez.

HAL uygulamaları

HAL uygulamasını tanımlamak için aşağıdaki örneklere benzer şekilde bir tedarikçi APEX'inde ilgili ikili dosyaları ve kitaplıkları sağlayın:

HAL uygulamasını tamamen kapsayacak şekilde APEX, ilgili tüm VINTF parçalarını ve başlatma komut dosyalarını da belirtmelidir.

VINTF parçaları

VINTF parçaları, APEX'in etc/vintf bölümünde bulunduğunda tedarikçi APEX'inden yayınlanabilir.

VINTF parçalarını APEX'e yerleştirmek için prebuilts mülkünü kullanın.

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

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

Sorgu 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", ...) : Geçiş HAL'i açmak için bunu kullanın.

İlklendirme komut dosyaları

APEX'ler, başlatma komut dosyalarını iki şekilde içerebilir: (A) APEX yükü içinde önceden oluşturulmuş bir metin dosyası veya (B) /vendor/etc içinde normal bir başlatma komut dosyası. Her ikisini de aynı APEX için ayarlayabilirsiniz.

APEX'te ilklendirme komut dosyası:

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

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

Tedarikçi APEX'lerindeki ilklendirme komut dosyalarında service tanımları ve on <property or event> yönergeleri bulunabilir.

service tanımının aynı APEX'teki bir ikili programı işaret ettiğinden emin olun. Örneğin, com.android.foo APEX, foo-service adlı bir hizmeti tanımlayabilir.

on foo-service /apex/com.android.foo/bin/foo
  ...

on yönergelerini kullanırken dikkatli olun. APEX'lerdeki başlangıç komut dosyaları ayrıştırıldığından ve APEX'ler etkinleştirildikten sonra yürütüldüğünden bazı etkinlikler veya özellikler kullanılamaz. İşlemleri mümkün olduğunca erken başlatmak için apex.all.ready=true öğesini kullanın. Bootstrap APEX'leri on init kullanabilir ancak on early-init kullanamaz.

Donanım Yazılımı

Örnek:

Aşağıdaki gibi prebuilt_firmware modül türüyle tedarikçi firma APEX'e donanım yazılımı 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
  ..
}

prebuilt_firmware modülü, APEX'in <apex name>/etc/firmware dizinine yüklenir. ueventd, donanım yazılımı modüllerini bulmak için /apex/*/etc/firmware dizinlerini tarar.

APEX'in file_contexts, bu dosyaların çalışma zamanında ueventd tarafından erişilebilmesini sağlamak için tüm donanım yazılımı yükü girişlerini uygun şekilde etiketlemelidir. Genellikle vendor_file etiketi yeterlidir. Örnek:

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

Çekirdek modülleri

Çekirdek modüllerini, aşağıdaki gibi önceden oluşturulmuş modüller olarak bir tedarikçi APEX'e 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 doğru şekilde etiketlemelidir. Örnek:

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

Çekirdek modülleri açık şekilde yüklenmelidir. Tedarikçi firma bölümündeki aşağıdaki örnek ilk ayarlama komut dosyası, insmod üzerinden yüklemeyi gösterir:

my_init.rc:

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

Çalışma zamanında kaynak yer paylaşımları

Örnek:

rros özelliğini kullanarak tedarikçi firma APEX'e ç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ı

Satıcı APEX'leri, genellikle satıcı bölümünde bulunan diğer çeşitli yapılandırma dosyalarını satıcı APEX'leri içinde önceden oluşturulmuş olarak destekler. Daha fazlası da eklenmektedir.

Örnekler:

Tedarikçi APEX'lerini önyükleme

keymint gibi bazı HAL hizmetleri, APEX'ler etkinleştirilmeden önce kullanılabilir olmalıdır. Bu HAL'ler genellikle init komut dosyasında hizmet tanımlarında early_hal değerini ayarlar. Başka bir örnek de genellikle post-fs-data etkinliğinden daha önce başlatılan animation sınıfıdır. Bu tür erken bir HAL hizmeti tedarikçi APEX'te paketlendiğinde, daha erken etkinleştirilebilmesi için APEX manifest dosyasında apex'i "vendorBootstrap": true yapın. Önyükleme APEX'lerinin /data/apex yerine yalnızca /vendor/apex gibi önceden oluşturulmuş konumdan etkinleştirilebileceğini unutmayın.

Sistem özellikleri

Çerçeve, tedarikçi APEX'lerini desteklemek için okuduğu sistem özellikleri şunlardır:

  • 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ü eski HAL'ler tarafından kullanıldığı için APEX'i Bootstrap APEX yapın ve bu bağlayıcı ad alanını görünür olarak yapılandırın.

setprop komutunu kullanarak init komut dosyalarında sistem özelliklerini ayarlayın.

Ekstra geliştirme özellikleri

APEX'i başlatma

Örnek:

Geliştiriciler ayrıca, aynı APEX adını ve anahtarını paylaşan birden fazla tedarikçi firma APEX sürümünü yükleyebilir ve ardından kalıcı sysprops kullanarak her başlatma sırasında hangi sürümün etkinleştirileceğini seçebilir. Bu, belirli geliştirici kullanım alanları için adb install kullanarak APEX'in yeni bir kopyasını yüklemekten daha basit olabilir.

Örnek kullanım alanları:

  • Kablosuz HAL tedarikçi APEX'in 3 sürümünü yükleyin: KG ekipleri, bir sürümü kullanarak manuel veya otomatik test çalıştırabilir, ardından başka bir sürüme yeniden başlayıp testleri yeniden çalıştırabilir ve nihai sonuçları karşılaştırabilir.
  • Kamera HAL tedarikçi APEX'in 2 sürümünü yükleyin: Mevcut ve deneysel: Dogfooders, ek bir dosya indirip yüklemeden deneysel sürümü kullanabilir. Böylece kolayca geri dönebilirler.

apexd, başlatma sırasında doğru APEX sürümünü etkinleştirmek için belirli bir biçim kullanarak sysprops'u arar.

Mülk anahtarı için beklenen biçimler şunlardır:

  • Bootconfig
    • BoardConfig.mk içinde varsayılan değeri ayarlamak için kullanılır.
    • androidboot.vendor.apex.<apex name>
  • Kalıcı sysprop
    • Zaten başlatılmış bir cihazda ayarlanan varsayılan değeri değiştirmek için kullanılır.
    • Varsa bootconfig değerini geçersiz kılar.
    • persist.vendor.apex.<apex name>

Özelliğin değeri, etkinleştirilmesi gereken APEX dosyasının adı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, BoardConfig.mk içinde bootconfig kullanılarak da 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, kalıcı sysprop'u ayarlayarak etkin sürümü 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, önyükleme işleminin ardından bootconfig'in güncellenmesini destekliyorsa (fastboot oem komutları aracılığıyla gibi) çoklu yüklenen APEX için bootconfig özelliği değiştirildiğinde, önyüklemede etkinleştirilen sürüm de değişir.

Cuttlefish tabanlı sanal referans cihazlarında, başlatma sırasında doğrudan bootconfig özelliğini ayarlamak için --extra_bootconfig_args komutunu kullanabilirsiniz. Örnek:

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