Dinamik olarak kullanılabilir HAL'ler

Android 9, kullanılmadıkları veya ihtiyaç duyulmadıkları zaman Android donanım alt sistemlerinin dinamik olarak kapatılmasını destekler. Örneğin, kullanıcı kablosuz ağ kullanmıyorsa kablosuz ağ alt sistemleri bellek, güç veya başka sistem kaynaklarını kullanmamalıdır. Android'in önceki sürümlerinde, HAL'ler/sürücüler Android telefon açıldığı sürece Android cihazlarda açık tutuluyordu.

Dinamik kapatma işlemini uygulamak, aşağıdaki bölümlerde ayrıntılı olarak açıklandığı şekilde veri akışlarını bağlamayı ve dinamik işlemleri yürütmeyi içerir.

HAL tanımlarında yapılan değişiklikler

Dinamik kapatma, hangi HAL arayüzlerinin hangi işlemlere hizmet ettiğine dair bilgi (bu bilgiler daha sonra başka bağlamlarda da yararlı olabilir) gerektirir. Ayrıca, süreçlerin önyüklemede başlatılmaması ve çıktıklarında (yeniden istenene kadar) yeniden başlatılmaması gerekir.

# some init.rc script associated with the HAL
service vendor.some-service-name /vendor/bin/hw/some-binary-service
    # init language extension, provides information of what service is served
    # if multiple interfaces are served, they can be specified one on each line
    interface android.hardware.light@2.0::ILight default
    # restarted if hwservicemanager dies
    # would also cause the hal to start early during boot if disabled wasn't set
    class hal
    # will not be restarted if it exits until it is requested to be restarted
    oneshot
    # will only be started when requested
    disabled
    # ... other properties

init ve hwservicemanager'da yapılan değişiklikler

Dinamik kapatma işlemi için hwservicemanager'ün, init'a istenen hizmetleri başlatmasını söylemesi de gerekir. Android 9'da init, ctl.interface_start, ctl.interface_stop ve ctl.interface_restart olmak üzere üç ek kontrol mesajı (ör. ctl.start) içerir. Bu mesajlar, belirli donanım arayüzlerini açmak ve kapatmak için init'e sinyal göndermek amacıyla kullanılabilir. Bir hizmet istendiğinde ve kaydedilmediğinde hwservicemanager, hizmetin başlatılmasını ister. Ancak dinamik HAL'ler için bunların hiçbirini kullanmanız gerekmez.

HAL çıkışını belirleme

Android 9'da HAL çıkışının manuel olarak belirlenmesi gerekir. Android 10 ve sonraki sürümlerde bu, otomatik yaşam döngüleri ile de belirlenebilir.

Dinamik kapatma, HAL'in ne zaman başlatılacağına ve ne zaman kapatılacağına karar vermek için birden fazla politika gerektirir. Bir HAL herhangi bir nedenle çıkmaya karar verirse HAL tanımında sağlanan bilgiler ve init ile hwservicemanager'te yapılan değişiklikler tarafından sağlanan altyapı kullanılarak tekrar ihtiyaç duyulduğunda otomatik olarak yeniden başlatılır. Bu, aşağıdakiler dahil olmak üzere birkaç farklı stratejiyi içerebilir:

  • Bir HAL, üzerinde yakın veya benzer bir API çağrısı yapan kullanıcılar varsa kendi üzerinde exit çağrısı yapabilir. Bu davranış, ilgili HAL arayüzünde belirtilmelidir.
  • HAL'ler, görevleri tamamlandığında kapanabilir (HAL dosyasında belirtilmiştir).

Otomatik yaşam döngüleri

Android 10, çekirdeğe ve hwservicemanager'e daha fazla destek ekleyerek HAL'lerin istemcileri olmadığında otomatik olarak kapanmasına olanak tanır. Bu özelliği kullanmak için HAL tanımlarında yapılan değişiklikler bölümündeki tüm adımları uygulayın ve aşağıdakileri yapın:

  • Hizmeti C++'da üye işlevi registerAsService yerine LazyServiceRegistrar ile kaydedin. Örneğin:
    // only one instance of LazyServiceRegistrar per process
    LazyServiceRegistrar registrar;
    registrar.registerAsService(myHidlService /* , "default" */);
  • HAL istemcisinin, yalnızca kullanımdayken üst düzey HAL'e (hwservicemanager ile kayıtlı arayüz) referans tuttuğunu doğrulayın. Bu referans, çalışmaya devam eden bir hwbinder iş parçacığına bırakılırsa gecikmeleri önlemek için istemci, referansı bıraktıktan sonra IPCThreadState::self()->flushCommands() işlevini de çağırarak bağlayıcı sürücüsünün ilişkili referans sayısı değişikliklerinden haberdar olmasını sağlamalıdır.