Bir HIDL paketinde tanımlanan her arayüzün otomatik olarak oluşturulmuş kendi C++ sınıfı vardır inceleyebilirsiniz. İstemciler ve sunucular, arayüzlerle farklı şekillerde kullanabilirsiniz:
- Sunucular arayüzleri uygular.
- İstemciler, arayüzlerde yöntemleri çağırır.
Arayüzler sunucu tarafından ada göre kaydedilebilir veya ve HIDL'nin tanımladığı yöntemlere uygulanır. Örneğin çerçeve kodu, HAL'den eşzamansız mesajları almak ve bu arayüzü aktarmak için kullanılan arayüz doğrudan HAL'ye gönderebilirsiniz.
Sunucu uygulaması
IFoo
arayüzünü uygulayan bir sunucu,
Otomatik olarak oluşturulan IFoo
başlık dosyası:
#include <android/hardware/samples/1.0/IFoo.h>
Başlık, dosyanın paylaşılan kitaplığı tarafından otomatik olarak dışa aktarılır
Bağlantı oluşturulacak IFoo
arayüzü. Örnek IFoo.hal
:
// IFoo.hal interface IFoo { someMethod() generates (vec<uint32_t>); ... }
IFoo arayüzünün sunucu uygulaması için örnek iskelet:
// From the IFoo.h header using android::hardware::samples::V1_0::IFoo; class FooImpl : public IFoo { Return<void> someMethod(foo my_foo, someMethod_cb _cb) { vec<uint32_t> return_data; // Compute return_data _cb(return_data); return Void(); } ... };
Sunucu arayüzü uygulamasını bir istemcinin kullanımına sunmak için şunları yapabilir:
- Arayüz uygulamasını
hwservicemanager
(aşağıdaki ayrıntılara bakın),
VEYA
- Arayüz uygulamasını etkileyerek arayüz yöntemi (detaller için, bkz. Eşzamansız geri çağırma).
Arayüz uygulamasını kaydederken,
hwservicemanager
işlemi, kayıtlı HIDL arayüzlerini takip eder.
adı ve sürümüne göre
cihazda çalıştırılıyor. Sunucular HIDL arayüzü kaydedebilir
ada göre uygulama ve müşteriler ada göre hizmet uygulamaları isteyebilir
ve sürümünü seçin. Bu işlem HIDL arayüzüne sunar
android.hidl.manager@1.0::IServiceManager
Otomatik olarak oluşturulan her HIDL arayüzü başlık dosyası (IFoo.h
gibi)
işlevi kaydetmek için kullanılabilecek bir registerAsService()
yöntemi vardır
hwservicemanager
ile arayüzün nasıl uygulandığını öğrenin. Tek
gerekli bağımsız değişken, istemciler olarak arayüz uygulamalarının adıdır.
hwservicemanager
uygulamasından arayüzü almak için bu adı kullanın
daha sonra:
::android::sp<IFoo> myFoo = new FooImpl(); ::android::sp<IFoo> mySecondFoo = new FooAnotherImpl(); status_t status = myFoo->registerAsService(); status_t anotherStatus = mySecondFoo->registerAsService("another_foo");
hwservicemanager
,
Etkinleştirmek için [package@version::interface, instance_name]
benzersiz
farklı arayüzleri (veya aynı arayüzün farklı sürümlerini)
aynı örnek adlarına sahip olur ve bunların çakışma
olmasını sağlar. Arama yaptığınızda
registerAsService()
ile tamamen aynı paket sürümünü, arayüzünü ve
belirtirse hwservicemanager
,
yenisini kullanır.
İstemci uygulaması
Sunucunun yaptığı gibi, istemcinin de her arayüzde #include
işlemi yapması gerekir
şu anlama gelir:
#include <android/hardware/samples/1.0/IFoo.h>
Müşteriler, arayüze iki şekilde ulaşabilir:
I<InterfaceName>::getService
üzerinden (hwservicemanager
)- Bir arayüz yöntemiyle
Otomatik olarak oluşturulan her arayüz başlığı dosyasının statik bir getService
öğesi vardır
web sitesinden bir hizmet örneği almak için kullanılabilecek bir yöntem
hwservicemanager
:
// getService returns nullptr if the service can't be found sp<IFoo> myFoo = IFoo::getService(); sp<IFoo> myAlternateFoo = IFoo::getService("another_foo");
Böylece istemcinin bir IFoo
arayüzü vardır ve müşterinin
bunu sanki yerel bir sınıf uygulamasıymış gibi ele alacağız. Gerçekte ise uygulama,
Aynı işlemde, farklı bir işlemde, hatta başka bir cihazda çalışabilir
(HAL uzaktan erişimli). Çünkü müşteri getService
adlı kullanıcıyı
Paketin 1.0
sürümünden IFoo
nesne dahil edildi,
hwservicemanager
, yalnızca
uygulama 1.0
istemcileriyle uyumludur. Pratikte bu
yalnızca 1.n
sürümüne (sürüm 1.n
) sahip sunucu uygulamaları anlamına gelir
Bir arayüzün x.(y+1)
kadarı genişletilmelidir (devralınacak kaynak)
x.y
).
Ayrıca, uygulamalar arasında yayın yapmak için castFrom
yöntemi sağlanır.
farklı arayüzler. Bu yöntem, uzaktan kumandaya bir IPC çağrısı yapılarak çalışır
kullanılan türle aynı olduğundan emin olmak için yeni arayüze
istendi. İstenen tür kullanılamıyorsa nullptr
geri döndü.
sp<V1_0::IFoo> foo1_0 = V1_0::IFoo::getService(); sp<V1_1::IFoo> foo1_1 = V1_1::IFoo::castFrom(foo1_0);
Eşzamansız geri çağırma işlevleri
Mevcut HAL uygulamalarının çoğunda eşzamansız donanımlar kullanılıyor. etkinlikleri hakkında müşterileri bilgilendirmek için eşzamansız bir yönteme meydana geldi. HIDL, eşzamansız geri çağırma olarak HIDL arayüzü kullanılabilir. arayüz işlevleri, HIDL arayüz nesnelerini parametre olarak alabilir.
Örnek arayüz dosyası IFooCallback.hal
:
package android.hardware.samples@1.0; interface IFooCallback { sendEvent(uint32_t event_id); sendData(vec<uint8_t> data); }
IFoo
ürününde
IFooCallback
parametresi:
package android.hardware.samples@1.0; interface IFoo { struct Foo { int64_t someValue; handle myHandle; }; someMethod(Foo foo) generates (int32_t ret); anotherMethod() generates (vec<uint32_t>); registerCallback(IFooCallback callback); };
IFoo
arayüzünü kullanan istemci,
IFooCallback
arayüzünün sunucusu; sağladığı
IFooCallback
uygulaması:
class FooCallback : public IFooCallback { Return<void> sendEvent(uint32_t event_id) { // process the event from the HAL } Return<void> sendData(const hidl_vec<uint8_t>& data) { // process data from the HAL } };
Ayrıca bunu, istemcinin mevcut bir örneği üzerinden de
IFoo
arayüzü:
sp<IFooCallback> myFooCallback = new FooCallback(); myFoo.registerCallback(myFooCallback);
IFoo
öğesini uygulayan sunucu bunu
sp<IFooCallback>
nesne algılandı. Geri çağırmayı depolayabilir ve
bu arayüzü kullanmak istediğinde istemciye geri bildirim gönderir.
Vefat edenler
Hizmet uygulamaları farklı bir süreçte çalışabileceğinden,
kullanıcı hayatta kaldığında, arayüzü uygulama işleminin kapanacağını hatırlatır.
Ölen bir işlemde barındırılan arayüz nesnesine yapılan tüm çağrılar başarısız oluyor
(isOK()
, false
değerini döndürür). Projenizi yönetmenin
bir hatadan kurtulmak için, hizmetin yeni bir örneğini
I<InterfaceName>::getService()
aranıyor. Bu yalnızca aşağıdaki durumlarda çalışır:
kilitlenen işlem yeniden başlatılmış ve hizmetleri
servicemanager
(HAL uygulamaları için genellikle geçerlidir).
Bir arayüzün müşterileri bununla reaktif şekilde uğraşmak yerine,
Bir hizmet öldüğünde bildirim almak için ölüm alıcısı kaydedin.
Alınan IFoo
arayüzünde bu tür bildirimlere kaydolmak için
şunları yapabilir:
foo->linkToDeath(recipient, 1481 /* cookie */);
recipient
parametresi,
HIDL tarafından sağlanan android::hardware::hidl_death_recipient
arayüzü,
Bu yöntem, adı verilen tek bir serviceDied()
yöntemini içerir.
arayüzü barındıran işlem öldüğünde, RPC iş parçacığındaki bir iş parçacığından:
class MyDeathRecipient : public android::hardware::hidl_death_recipient { virtual void serviceDied(uint64_t cookie, const android::wp<::android::hidl::base::V1_0::IBase>& who) { // Deal with the fact that the service died } }
cookie
parametresi,
linkToDeath()
ise who
parametresi bir
istemcide hizmeti temsil eden nesneye yönelik zayıf işaretçi. Şununla
yukarıda verilen örnek çağrı, cookie
eşittir 1481 ve who
foo
değerine eşit.
Ayrıca, ölen bir alıcıyı kaydettirdikten sonra kaydı iptal edebilirsiniz:
foo->unlinkToDeath(recipient);