Google is committed to advancing racial equity for Black communities. See how.
Bu sayfa, Cloud Translation API ile çevrilmiştir.
Switch to English

HIDL

HAL arayüz tanımlama dili veya HIDL ("hide-l" olarak okunur), bir HAL ve kullanıcıları arasındaki arayüzü belirtmek için bir arayüz tanımlama dilidir (IDL). Arabirimler ve paketler halinde toplanan türlerin ve yöntem çağrılarının belirlenmesine izin verir. Daha genel olarak HIDL, bağımsız olarak derlenebilen kod tabanları arasında iletişim kurmak için bir sistemdir.

HIDL, süreçler arası iletişim (IPC) için kullanılmak üzere tasarlanmıştır. Süreçler arasındaki iletişim, Bağlayıcı olarak adlandırılır . Bir işleme bağlanması gereken kitaplıklar için, bir geçiş modu da mevcuttur (Java'da desteklenmez).

HIDL, paketler halinde toplanan arayüzlerde (bir sınıfa benzer) organize edilmiş veri yapılarını ve yöntem imzalarını belirtir. HIDL'nin sözdizimi, farklı bir anahtar kelime kümesi olsa da, C ++ ve Java programcılarına tanıdık gelecektir. HIDL ayrıca Java tarzı açıklamalar kullanır.

HIDL tasarımı

HIDL'nin amacı, çerçevenin HAL'leri yeniden oluşturmak zorunda kalmadan değiştirilebilmesidir. HAL'ler, satıcılar veya SOC üreticileri tarafından oluşturulacak ve cihaza bir /vendor bölümü yerleştirilerek çerçevenin kendi bölümünde HAL'leri yeniden derlemeden bir OTA ile değiştirilmesini sağlayacaktır.

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

  • Birlikte çalışabilirlik . Çeşitli mimariler, araç zincirleri ve yapı konfigürasyonları ile derlenebilen süreçler arasında güvenilir şekilde birlikte çalışabilir arayüzler oluşturun. HIDL arayüzleri sürümlendirilir 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, paket açılmadan kullanılabilen C ++ standart yerleşim veri yapılarında C ++ koduna gönderilir. HIDL ayrıca paylaşılan bellek arabirimleri sağlar ve RPC'ler doğası gereği yavaş olduğundan HIDL, bir RPC çağrısı kullanmadan iki veri aktarımı 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. Verilerin aktarımı için HIDL'ye aktarılması veya HIDL'den veri alınması verilerin sahipliğini değiştirmez - sahiplik her zaman arayan işlevde kalır. Verilerin yalnızca çağrılan işlevin süresi boyunca kalması gerekir ve çağrılan işlev 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 (hem de eski) HAL'leri, HAL'ye ciltlenmiş ve aynı işlem (geçiş) modlarında hizmet veren yeni bir HIDL arayüzüne sarabilirsiniz. Bu kaplama 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 bağlayıcıdır.

Bir .hal dosyası derlendiğinde, hidl-gen , ciltleyici iletişimi için kullanılan başlıklara ek olarak fazladan bir passthrough başlık dosyası BsFoo.h üretir; Bu başlık tanımlar fonksiyonları olduğu dlopen ed. Geçiş HAL'leri çağrıldıkları aynı işlemde çalıştıkları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 yöntemler, HAL'ın onları işlemesini beklemedikleri için kendi iş parçacığında çalışır (bu, geçiş modunda oneway yöntemleri kullanan tüm oneway iş parçacığı açısından güvenli olması gerektiği anlamına gelir).

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 BpFoo.h benzer, ancak IPC çağrılarını bağlayıcı kullanarak iletmek yerine, istenen işlevler doğrudan çağrılır. HAL'lerin gelecekteki uygulamaları, FooFast HAL ve bir FooAccurate HAL gibi birden çok uygulama sağlayabilir . Bu tür durumlarda, her ek uygulama için bir dosya oluşturulacaktır (örneğin, PTFooFast.cpp ve PTFooAccurate.cpp ).

Doğrudan geçiş HAL'lerini birleştirmek

Geçiş modunu destekleyen HAL uygulamalarını birleştirebilirsiniz. Bir HAL arayüzü verildiğinde abcd@MN::IFoo , iki paket oluşturulur:

  • abcd@MN::IFoo-impl . HAL uygulamasını içerir ve IFoo* HIDL_FETCH_IFoo(const char* name) işlevini IFoo* HIDL_FETCH_IFoo(const char* name) . Eski cihazlarda, bu pakettir dlopen ed ve uygulama kullanarak örneği HIDL_FETCH_IFoo . Temel kodu hidl-gen ve -Lc++-impl -Landroidbp-impl ve -Landroidbp-impl -Lc++-impl kullanarak hidl-gen .
  • abcd@MN::IFoo-service . Geçiş HAL'yi açar ve kendisini ciltlenmiş bir hizmet olarak kaydederek aynı HAL uygulamasının hem geçiş hem de bağlayıcı olarak kullanılmasını sağlar.

IFoo türü IFoo , sp<IFoo> IFoo::getService(string name, bool getStub) bir örneğine erişmek için sp<IFoo> IFoo::getService(string name, bool getStub) IFoo . getStub doğruysa getService , getService yalnızca geçiş modunda açmaya çalışır. getStub yanlışsa, getService ciltlenmiş bir hizmet bulmaya çalışır; bu başarısız olursa, geçiş hizmetini bulmaya çalışır. getStub parametresi, defaultPassthroughServiceImplementation dışında hiçbir zaman kullanılmamalıdır. (Android O ile başlatılan cihazlar tamamen bağlayıcı hale getirilmiş cihazlardır, bu nedenle geçiş modunda bir hizmetin açılmasına izin verilmez.)

HIDL dilbilgisi

Tasarım gereği, HIDL dili C'ye benzer (ancak C ön işlemcisini kullanmaz). Aşağıda açıklanmayan tüm noktalama işaretleri ( = ve | ifadelerinin bariz kullanımı dışında) dilbilgisinin bir parçasıdır.

Not: HIDL kod stili hakkında ayrıntılar için Kod Stili Kılavuzuna bakın .

  • /** */ bir belge açıklamasını belirtir. Bunlar yalnızca tür, yöntem, alan ve enum değer bildirimlerine uygulanabilir.
  • /* */ çok satırlı bir açıklamayı belirtir.
  • // satırın sonuna bir açıklamayı belirtir. // dışında, satırsonları diğer boşluklarla aynıdır.
  • Aşağıdaki örnek gramerde, // ile satırın sonuna kadar olan metin, dilbilgisinin bir parçası değildir, bunun yerine dilbilgisi üzerine bir yorumdur.
  • [empty] , terimin boş olabileceği anlamına gelir.
  • ? bir harfi veya terimi takip etmek, isteğe bağlı olduğu anlamına gelir.
  • ... belirtildiği gibi ayıran noktalama işaretleriyle sıfır veya daha fazla öğe içeren diziyi gösterir. HIDL'de çeşitli 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, terminal dışıdır.
  • italics , integer veya identifier gibi bir belirteç ailesidir (standart C ayrıştırma kuralları).
  • constexpr , C tarzı sabit bir ifadedir ( 1 + 1 ve 1L << 3 ).
  • import_name , HIDL Versioning'de açıklandığı gibi nitelendirilen bir paket veya arayüz adıdır.
  • Küçük harfli words değişmez simgelerdir.

Misal:

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ında uzaktan prosedür çağrıları için kullanıldığını gösterir. Ayrıca geçişe bakın.
geri arama, eşzamansız Bir HAL kullanıcısı tarafından sunulan, HAL'ye geçen (bir HIDL yöntemi aracılığıyla) ve herhangi bir zamanda verileri döndürmek için HAL tarafından çağrılan arayüz.
geri arama, eşzamanlı Bir sunucunun HIDL yöntemi uygulamasından istemciye verileri döndürür. Void veya tek bir ilkel değer döndüren yöntemler için kullanılmaz.
müşteri Belirli bir arayüzün yöntemlerini çağıran işlem. Bir HAL veya çerçeve süreci, bir arayüzün istemcisi ve diğerinin sunucusu olabilir. Ayrıca geçişe bakın.
genişler Başka bir arabirime yöntemler ve / veya türler ekleyen bir arabirimi gösterir. 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 etmek için yeni bir paket (örneğin bir satıcı uzantısı) için kullanılabilir.
üretir İstemciye değerler döndüren bir arabirim yöntemini gösterir. İlkel olmayan bir değeri veya birden fazla değeri döndürmek için, senkronize bir geri çağırma 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 işlemi, bir sunucu işlemi 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 gösterir.
paket Bir sürümü paylaşan arayüzlerin ve veri türlerinin toplanması.
geçiş HIDL şekli olan sunucu paylaşılan kütüphanesi, dlopen istemci tarafından ed. Geçiş modunda, istemci ve sunucu aynı süreçtir ancak ayrı kod tabanlarıdır. Yalnızca eski kod tabanlarını HIDL modeline getirmek için kullanılır. Ayrıca bkz . Binderized .
sunucu Bir arayüzün yöntemlerini uygulayan süreç. Ayrıca geçişe bakın.
Ulaşım Verileri sunucu ve istemci arasında taşıyan HIDL altyapısı.
versiyon Bir paketin sürümü. Büyük ve küçük olmak üzere iki tam sayıdan oluşur. Küçük sürüm artışları, türleri ve yöntemleri ekleyebilir (ancak değiştiremez).