HIDL

HAL arabirim tanımlama dili veya HIDL ("hide-l" olarak telaffuz edilir), bir HAL ile kullanıcıları arasındaki arabirimi belirtmek için bir arabirim açıklama dilidir (IDL). Arayüzlerde ve paketlerde toplanan türlerin ve yöntem çağrılarının belirlenmesine izin verir. Daha geniş olarak, HIDL, bağımsız olarak derlenebilen kod tabanları arasında iletişim için bir sistemdir. Android 10'dan itibaren, HIDL kullanımdan kaldırılmıştır ve Android, AIDL'yi her yerde kullanmak için geçiş yapmaktadır.

HIDL, süreçler arası iletişim (IPC) için kullanılmak üzere tasarlanmıştır. Süreçler arasındaki iletişim olarak adlandırılır Binderized . Bir süreç bağlantılı olmalıdır kütüphaneler için bir passthrough mod (Java desteklenmemektedir) de mevcuttur.

HIDL, paketler halinde toplanan arabirimlerde (bir sınıfa benzer) düzenlenen veri yapılarını ve yöntem imzalarını belirtir. HIDL'nin sözdizimi C++ ve Java programcılarına farklı bir anahtar sözcük kümesiyle tanıdık gelecektir. HIDL ayrıca Java tarzı ek açıklamalar kullanır.

HIDL tasarımı

HIDL'nin amacı, çerçevenin HAL'leri yeniden oluşturmaya gerek kalmadan değiştirilebilmesidir. HAL'lere satıcıları veya SOC yapımcıları tarafından inşa edilmiş ve bir konacaktır /vendor HAL'lerin derlemeye olmadan bir OTA ile değiştirilmesi, kendi bölümüne, çerçeve sağlayan cihazda bölüm.

HIDL tasarımı aşağıdaki endişeleri dengeler:

  • Birlikte çalışabilirlik. Çeşitli mimariler, araç zincirleri ve yapı yapılandırmalarıyla derlenebilen süreçler arasında güvenilir şekilde birlikte çalışabilir arabirimler oluşturun. HIDL arayüzleri versiyonlanmıştır ve yayınlandıktan sonra değiştirilemez.
  • Verimlilik. HIDL, kopyalama işlemlerinin sayısını en aza indirmeye çalışır. HIDL tanımlı veriler, paketi açmadan kullanılabilen C++ standart yerleşim veri yapılarında C++ koduna teslim edilir. HIDL ayrıca paylaşılan bellek arabirimleri sağlar ve RPC'ler doğal olarak biraz yavaş olduğundan, HIDL bir RPC çağrısı kullanmadan veri aktarmanın iki yolunu destekler: paylaşılan bellek ve Hızlı Mesaj Kuyruğu (FMQ).
  • Sezgisel. HIDL önler dikenli sadece kullanılarak bellek mülkiyet sorunları in RPC (bkz parametreleri Android Arayüz Tanımlama Dili (AIDL) ); yöntemlerden verimli bir şekilde döndürülemeyen değerler, geri arama işlevleri aracılığıyla döndürülür. Ne aktarım için HIDL'ye veri iletmek ne de HIDL'den veri almak verinin sahipliğini değiştirmez; sahiplik her zaman arama işlevinde kalır. Verilerin yalnızca çağrılan işlev süresince kalıcı olması gerekir ve çağrılan işlev geri döndükten hemen sonra yok edilebilir.

Geçiş modunu kullanma

Android'in önceki sürümlerini çalıştıran cihazları Android O'ya güncellemek için, hem geleneksel (ve eski) HAL'leri, HAL'a ciltlenmiş ve aynı işlem (geçiş) modlarında hizmet veren yeni bir HIDL arabirimine sarabilirsiniz. Bu sarma, hem HAL hem de Android çerçevesi için şeffaftır.

Geçiş modu yalnızca C++ istemcileri ve uygulamaları için kullanılabilir. Android'in önceki sürümlerini çalıştıran cihazlarda Java ile yazılmış HAL'ler yoktur, bu nedenle Java HAL'leri doğal olarak ciltlenir.

Bir zaman .hal dosya derlenmiş, hidl-gen bir ilave geçidi başlık dosyası üretir BsFoo.h bağlayıcı iletişim için kullanılan başlıklarına ilave olarak; Bu başlık tanımlar fonksiyonları olduğu dlopen ed. Geçişli HAL'ler çağrıldıkları aynı işlemde çalıştığından, çoğu durumda geçiş yöntemleri doğrudan işlev çağrısı (aynı iş parçacığı) tarafından çağrılır. oneway onlar (bu vasıta kullandığı herhangi HAL bunları işlemek için HAL beklemek amaçlanmamıştır gibi yöntemler kendi iplik çalıştırmak oneway geçişi modundadır yöntemlerle parçacığı güvenli olmalıdır).

Verilen bir IFoo.hal , BsFoo.h yaratmak (örneğin, ek özellikleri sağlamak için HIDL yaratılan yöntemler sarar oneway başka bir iş parçacığı çalıştırmak işlemleri). Bu dosya benzer BpFoo.h ancak bunun yerine bağlayıcı yapılan aramalar IPC bulaştırma, istenen fonksiyonları doğrudan çağrılır. HAL'lere gelecek uygulamalar gibi FooFast HAL ve FooAccurate HAL gibi birden çok uygulamaları, sağlayabilir. Bu gibi durumlarda, her bir ek uygulama için bir dosya (örneğin, yaratılmış olacaktır PTFooFast.cpp ve PTFooAccurate.cpp ).

Geçiş HAL'lerini bağlama

Geçiş modunu destekleyen HAL uygulamalarını ciltleyebilirsiniz. Verilen bir HAL arayüzü abcd@MN::IFoo , iki paket oluşturulur:

  • abcd@MN::IFoo-impl . HAL uygulanmasını içerir ve İFŞA işlev IFoo* HIDL_FETCH_IFoo(const char* name) . Eski cihazlarda, bu pakettir dlopen ed ve uygulama kullanarak örneği HIDL_FETCH_IFoo . Sen kullanarak taban kodu oluşturabilirsiniz hidl-gen ve -Lc++-impl ve -Landroidbp-impl .
  • abcd@MN::IFoo-service . HAL geçişini açar ve kendisini ciltlenmiş bir hizmet olarak kaydederek, aynı HAL uygulamasının hem geçiş hem de ciltlenmiş olarak kullanılmasını sağlar.

Tipi göz önüne alındığında IFoo , Arayabileceğin sp<IFoo> IFoo::getService(string name, bool getStub) örneğine erişmek için IFoo . Eğer getStub doğrudur, getService girişimleri sadece geçişi modundadır HAL açın. Eğer getStub yanlıştır, getService girişimleri bir binderized hizmeti bulmak için; bu başarısız olursa, geçiş hizmetini bulmaya çalışır. getStub parametresi haricinde asla kullanılmamalıdır defaultPassthroughServiceImplementation . (Android O ile başlatılan cihazlar tamamen ciltlenmiş cihazlardır, bu nedenle bir hizmetin geçiş modunda açılmasına izin verilmez.)

HIDL dilbilgisi

Tasarım gereği, HIDL dili C'ye benzer (ancak C önişlemcisini kullanmaz). Tüm noktalama işaretleri (bariz kullanılmasından kenara aşağıda açıklanmayan = ve | ) dilbilgisi parçasıdır.

Not: HIDL kod tarzı hakkında ayrıntılı bilgi için bkz Kod Stil Kılavuzu'na .

  • /** */ bir dokümantasyon açıklama belirtir. Bunlar yalnızca tür, yöntem, alan ve enum değeri bildirimlerine uygulanabilir.
  • /* */ A satırlı açıklama belirtir.
  • // satırın sonuna kadar bir açıklama belirtir. Kenara gelen // , yeni satırlar başka boşluk aynıdır.
  • Aşağıdaki örnek gramer olarak, metin // satırın sonuna kadar dilbilgisi parçası değildir ancak bunun yerine dilbilgisi üzerinde bir yorumdur.
  • [empty] terimi, boş olabilir anlamına gelir.
  • ? bir hazır bilgi veya terimin ardından isteğe bağlı olduğu anlamına gelir.
  • ... sekansı belirtildiği gibi noktalama ayırma sıfır ya da daha fazla öğe içeren gösterir. HIDL'de değişken argümanlar yoktur.
  • Virgüller sıra öğelerini ayırır.
  • Noktalı virgül, son öğe de dahil olmak üzere her öğeyi sonlandırır.
  • BÜYÜK HARF bir terminal dışıdır.
  • italics gibi bir belirteç aile integer veya identifier (standart Cı ayrıştırma kuralları).
  • constexpr C tarzı sabit ifadesidir (örneğin 1 + 1 ve 1L << 3 ).
  • import_name tarif edildiği gibi, nitelikli bir paket veya arayüz adı HIDL Versioning .
  • Küçük harflerle words değişmez jetonladır.

Örnek:

ROOT =
    PACKAGE IMPORTS PREAMBLE { ITEM ITEM ... }  // not for types.hal
  | PACKAGE IMPORTS ITEM ITEM...  // only for types.hal; no method definitions

ITEM =
    ANNOTATIONS? oneway? identifier(FIELD, FIELD ...) GENERATES?;
  |  safe_union identifier { UFIELD; UFIELD; ...};
  |  struct identifier { SFIELD; SFIELD; ...};  // Note - no forward declarations
  |  union identifier { UFIELD; UFIELD; ...};
  |  enum identifier: TYPE { ENUM_ENTRY, ENUM_ENTRY ... }; // TYPE = enum or scalar
  |  typedef TYPE identifier;

VERSION = integer.integer;

PACKAGE = package android.hardware.identifier[.identifier[...]]@VERSION;

PREAMBLE = interface identifier EXTENDS

EXTENDS = <empty> | extends import_name  // must be interface, not package

GENERATES = generates (FIELD, FIELD ...)

// allows the Binder interface to be used as a type
// (similar to typedef'ing the final identifier)
IMPORTS =
   [empty]
  |  IMPORTS import import_name;

TYPE =
  uint8_t | int8_t | uint16_t | int16_t | uint32_t | int32_t | uint64_t | int64_t |
 float | double | bool | string
|  identifier  // must be defined as a typedef, struct, union, enum or import
               // including those defined later in the file
|  memory
|  pointer
|  vec<TYPE>
|  bitfield<TYPE>  // TYPE is user-defined enum
|  fmq_sync<TYPE>
|  fmq_unsync<TYPE>
|  TYPE[SIZE]

FIELD =
   TYPE identifier

UFIELD =
   TYPE identifier
  |  safe_union identifier { FIELD; FIELD; ...} identifier;
  |  struct identifier { FIELD; FIELD; ...} identifier;
  |  union identifier { FIELD; FIELD; ...} identifier;

SFIELD =
   TYPE identifier
  |  safe_union identifier { FIELD; FIELD; ...};
  |  struct identifier { FIELD; FIELD; ...};
  |  union identifier { FIELD; FIELD; ...};
  |  safe_union identifier { FIELD; FIELD; ...} identifier;
  |  struct identifier { FIELD; FIELD; ...} identifier;
  |  union identifier { FIELD; FIELD; ...} identifier;

SIZE =  // Must be greater than zero
     constexpr

ANNOTATIONS =
     [empty]
  |  ANNOTATIONS ANNOTATION

ANNOTATION =
  |  @identifier
  |  @identifier(VALUE)
  |  @identifier(ANNO_ENTRY, ANNO_ENTRY  ...)

ANNO_ENTRY =
     identifier=VALUE

VALUE =
     "any text including \" and other escapes"
  |  constexpr
  |  {VALUE, VALUE ...}  // only in annotations

ENUM_ENTRY =
     identifier
  |  identifier = constexpr

terminoloji

Bu bölüm, aşağıdaki HIDL ile ilgili terimleri kullanır:

ciltlenmiş HIDL'nin, Binder benzeri bir mekanizma üzerinden uygulanan işlemler arasındaki uzak prosedür çağrıları için kullanıldığını gösterir. Passthrough Ayrıca bkz.
geri arama, asenkron Bir HAL kullanıcısı tarafından sunulan, HAL'e geçirilen (bir HIDL yöntemi aracılığıyla) ve herhangi bir zamanda veri döndürmek için HAL tarafından çağrılan arabirim.
geri arama, senkron Bir sunucunun HIDL yöntemi uygulamasından istemciye veri döndürür. Void veya tek bir ilkel değer döndüren yöntemler için kullanılmaz.
müşteri Belirli bir arabirimin yöntemlerini çağıran işlem. Bir HAL veya çerçeve işlemi, bir arabirimin istemcisi ve diğerinin sunucusu olabilir. Passthrough Ayrıca bkz.
uzanır Başka bir arabirime yöntemler ve/veya türler ekleyen bir arabirimi belirtir. Bir arabirim yalnızca bir başka arabirimi genişletebilir. Aynı paket adında küçük bir sürüm artışı için veya daha eski bir paket üzerine inşa edilecek yeni bir paket (örneğin bir satıcı uzantısı) için kullanılabilir.
üretir İstemciye değer döndüren bir arabirim yöntemini belirtir. İlkel olmayan bir değer veya birden fazla değer döndürmek için eşzamanlı bir geri arama işlevi oluşturulur.
arayüz Yöntem ve türlerin toplanması. C++ veya Java'da bir sınıfa çevrildi. Bir arabirimdeki tüm yöntemler aynı yönde çağrılır: bir istemci süreci, bir sunucu süreci tarafından uygulanan yöntemleri çağırır.
tek yön Bir HIDL yöntemine uygulandığında, yöntemin hiçbir değer döndürmediğini ve engellemediğini belirtir.
paket Bir sürümü paylaşan arayüzlerin ve veri türlerinin toplanması.
geçit HIDL şekli olan sunucu paylaşılan kütüphanesi, dlopen istemci tarafından ed. Geçiş modunda, istemci ve sunucu aynı işlemdir ancak ayrı kod tabanlarıdır. Yalnızca eski kod tabanlarını HIDL modeline getirmek için kullanılır. Ayrıca bakınız Binderized.
sunucu Bir arabirimin yöntemlerini uygulayan işlem. Passthrough Ayrıca bkz.
Ulaşım Sunucu ve istemci arasında veri taşıyan HIDL altyapısı.
versiyon Bir paketin sürümü. Majör ve minör olmak üzere iki tam sayıdan oluşur. Küçük sürüm artışları, türler ve yöntemler ekleyebilir (ancak değiştirmez).