İDL

HAL arayüz tanımlama dili veya HIDL, aşağıdakileri belirtmek için kullanılan bir arayüz açıklama dilidir (IDL) HAL ile HAL arasındaki arayüz teslim etmeye odaklandığı teslimatı öğrendiniz. HIDL, aşağıdaki gibi toplanan türlerin ve yöntem çağrılarının belirtilmesini sağlar: göz atabilirsiniz. HIDL daha genel olarak ifade etmek gerekirse arasında bağımsız olarak derlenebilir.

HIDL, süreçler arası iletişim (IPC) için kullanılmak üzere tasarlanmıştır. HDL ile oluşturulan HAL'ler: bağlayıcı kullanarak diğer mimari katmanlarıyla iletişim kurabilmeleri için "binderized HAL" olarak adlandırılır. işlemleri arası iletişim (IPC) çağrıları Binder HAL'ler, istemciden ayrı bir işlemde çalışır. çalışır. Örneğin, bir işleme, posta geçiş reklamı veya modu da kullanılabilir (Java'da desteklenmez).

HIDL, arayüzler halinde düzenlenmiş veri yapılarını ve yöntem imzalarını belirtir (bir sınıfa benzer şekilde) paket halinde toplanır. HIDL'nin söz dizimi C++ ve Java programcıları ama anahtar kelimeler. HIDL Java tarzı ek açıklamalar da kullanır.

Terminoloji

Bu bölümde HIDL ile ilgili aşağıdaki terimler kullanılmaktadır:

bağlı HIDL'nin işlemler arasında uzak prosedür çağrıları için kullanıldığını gösterir. ve Bağlayıcı benzeri bir mekanizma üzerinden uygulanır. Ayrıca posta geçiş konusuna da bakın.
geri çağırma, eşzamansız Bir HAL kullanıcısı tarafından sunulan, HAL'ye geçirilen (HIDL yöntemi kullanılarak) arayüz ve istediğiniz zaman veri döndürmesi için HAL tarafından çağrılacaktır.
geri çağırma, eşzamanlı Bir sunucunun HIDL yöntemi uygulamasındaki verileri istemciye döndürür. Boşluk veya tek bir temel değer döndüren yöntemler için kullanılmaz.
istemci Belirli bir arayüze ait yöntemleri çağıran işlem. HAL veya Android çerçevesi işlemi, bir arayüzün istemcisi ve diğerinin sunucusu olabilir. Şu kaynakları da inceleyin parantez.
uzatır Başka bir arayüze yöntem ve/veya tür ekleyen bir arayüzü belirtir. Bir arayüz yalnızca diğer bir arayüzü genişletebilir. Küçükler için kullanılabilir aynı paket adında veya yeni bir paket için (ör. tedarikçi firmanın uzantı) eski bir paketin üzerinde derlemek için kullanır.
oluşturur İstemciye değer döndüren bir arayüz yöntemini belirtir. Geri dönmek için primitif olmayan bir değer veya birden fazla değer, eşzamanlı bir geri çağırma işlevi oluşturulur.
arayüz Yöntem ve tür koleksiyonu. C++ veya Java sınıfa çevrilmişse. Tümü bir arayüzdeki yöntemler de aynı yönde çağrılır: 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 belirtir ve engellemez.
paket Bir sürümü paylaşan arayüzler ve veri türleri koleksiyonu.
geçiş Sunucunun paylaşılan bir kitaplık olduğu HIDL modu, dlopened teslim ederler. Geçiş modunda, istemci ve sunucu aynı süreçtir ancak ayrı kod tabanları kullanır. Yalnızca eski kod tabanlarını HIDL modeline taşımak için kullanılır. Bağlanmış bölümüne de bakın.
sunucu Bir arayüzdeki yöntemleri uygulayan işlem. Şu kaynakları da inceleyin parantez.
ulaşım Verileri sunucu ile istemci arasında taşıyan HIDL altyapısı.
sürüm Bir paketin sürümü. Büyük ve küçük olmak üzere iki tam sayıdan oluşur. Küçük yaştaki bir şahıs Sürüm artışları tür ve yöntemler ekleyebilir (ancak bunları değiştirmez).

HIDL tasarımı

HIDL'nin amacı Android çerçevesinin zahmetsizce değiştirilebilmesidir. yeniden oluşturmamız gerekir. HAL'ler tedarikçiler veya SOC üreticileri tarafından oluşturulur ve Cihazdaki /vendor bölümü, Android çerçevesini kendi başına etkinleştiriyor bölümü, HAL'ler yeniden derlemeden bir OTA ile değiştirilir.

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

  • Birlikte çalışabilirlik. Güvenilir bir şekilde birlikte çalışabilen arayüzler oluşturun farklı mimariler, araç zincirleriyle derlenebilecek süreçler arasında ve yapılandırmaları oluşturun. HIDL arayüzlerinin sürümü vardır ve değiştirilemez .
  • Verimlilik. HIDL, metinlerin kopya sayısını en aza operations. HIDL tarafından tanımlanan veriler C++ koduna C++ standart düzeninde iletilir veri yapıları oluşturun. HIDL ayrıca paylaşılan doğal olarak biraz yavaş olduğu için HIDL iki sunucuyu destekler. bir RPC çağrısı kullanmadan veri aktarmanın yolları: paylaşılan bellek ve Mesaj Sırası (FMQ).
  • Sezgiseldir. HIDL, bellek sahipliğiyle ilgili zorlu sorunları önlemek için RPC için yalnızca in parametrelerini kullanma (bkz. Android Arayüz Tanımlama Dili (AIDL)); değerleri etkili bir şekilde geri çağırma işlevleri aracılığıyla döndürülür. Veriler de iletilemiyor aktarım için HIDL'ye geçme veya HIDL'den veri alma ya da verileri: Sahiplik her zaman çağrı işlevinde kalır. Veri kullanımı yalnızca çağrılan işlev süresince devam eder ve yok edilebilir işlevi geri döndüğünden emin olun.

Geçiş modunu kullan

Android'in önceki sürümlerini çalıştıran cihazları Android O'ya güncellemek için şunları yapabilirsiniz: hem geleneksel (ve eski) HAL'leri hem de Birleştirilmiş ve aynı işlem (geçiş) modlarında HAL. Bu sarmalama hem HAL hem de Android çerçevesine göre şeffaf olması gerekir.

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

Bir .hal dosyası derlendiğinde, hidl-gen şunları üretir: başlıklara ek olarak BsFoo.h ek geçiş başlık dosyası bağlayıcı iletişim için kullanılır. bu başlık, dlopened. Geçiş HAL'leri her zaman olarak adlandırılırlar. Çoğu durumda, geçiş yöntemleri doğrudan işlev çağrısı (aynı iş parçacığı). oneway yöntem kendi iş parçacığında çalışıyor HAL'nin bunları işlemesini beklemek gibi olmadığından (bu, HAL (geçiş modunda oneway yöntemlerini kullanan) iş parçacığı açısından güvenli olmalıdır.

IFoo.hal ile BsFoo.h, HIDL tarafından oluşturulan HIDL'yi kapsar ek özellikler sağlamak için başka yöntemler de (oneway işlemler başka bir iş parçacığında çalıştırılır). Bu dosya şuna benzer: BpFoo.h, bununla birlikte bağlayıcı kullanarak IPC'yi iletmek yerine ve istenen işlevlerin doğrudan çağrılmasıdır. Gelecekteki HAL uygulamaları birden fazla uygulama sağlayabilir, örneğin FooFast HAL ve FooVerify HAL. Bu gibi durumlarda, her ek uygulama için (ör. PTFooFast.cpp ve PTFooAccurate.cpp) tıklayın.

Geçiş HAL'lerini bağlama

Geçiş modunu destekleyen HAL uygulamalarını bağlayabilirsiniz. Örneğin, HAL arayüzü a.b.c.d@M.N::IFoo, iki paket oluşturulur:

  • a.b.c.d@M.N::IFoo-impl HAL uygulamasını içerir ve IFoo* HIDL_FETCH_IFoo(const char* name) işlevini gösterir. Şu tarihte: eski cihazlarda, bu paket dlopen HIDL_FETCH_IFoo kullanılarak örneklendirilir. Temel kodu oluşturabilirsiniz. hidl-gen, -Lc++-impl ve -Landroidbp-impl.
  • a.b.c.d@M.N::IFoo-service Geçiş HAL'sini açar ve kendisini bağlayıcı bir hizmet olarak kaydederek, aynı HAL uygulamasını etkinleştirir. hem geçiş hem de bağlayıcı olarak kullanılmasını sağlar.

IFoo türünde, bir örneğe erişmek için sp<IFoo> IFoo::getService(string name, bool getStub) yöntemini çağırabilirsiniz / IFoo. getStub doğruysa getService HAL'yi yalnızca geçiş modunda açmaya çalışır. getStub ise false, getService bağlayıcı bir hizmet bulmaya çalışır; eğer başarısız olursa geçiş hizmetini bulmaya çalışır. getStub parametresi, defaultPassthroughServiceImplementation. ( Android O tamamen bağlı cihazlardır. Bu nedenle, bir hizmeti geçiş modunda açma izin verilmez.)

HIDL dil bilgisi

HIDL dili tasarımı gereği C'ye benzer (ancak C'yi kullanmaz) . Aşağıda açıklanmayan tüm noktalama işaretleri (bariz şekilde kullanılan kullanım (= ve |) dil bilgisinin bir parçası.

Not: HIDL kodu stiliyle ilgili ayrıntılar için şuraya bakın: Kod Stil Kılavuzu.

  • /** */, doküman açıklamasını gösterir. Bu düzenlemeler, yalnızca tür, yöntem, alan ve enum değer bildirimlerine izin verir.
  • /* */, çok satırlı bir yorumu gösterir.
  • //, satırın sonundaki yorumu gösterir. Şuralardan: //, yeni satırlar diğer tüm boşluklarla aynıdır.
  • Aşağıdaki örnek dilbilgisinde, // dilinden satırı, dilbilgisinin bir parçası değildir, bunun yerine dilbilgisi hakkında bir yorumdur.
  • [empty], terimin boş olabileceği anlamına gelir.
  • ? harfinin veya terimin ardından gelen kelime isteğe bağlı olduğu anlamına gelir.
  • ..., şununla sıfır veya daha fazla öğe içeren diziyi gösterir: noktalama işaretleri belirtilir. HIDL'de değişken argümanlar yoktur.
  • Sıra öğelerini virgülle ayırın.
  • Noktalı virgüller, son öğe de dahil olmak üzere her öğeyi sonlandırır.
  • BÜYÜK HARF, terminal olmayan bir ifadedir.
  • italics, şunun gibi bir jeton ailesidir: integer veya identifier (standart C) ayrıştırma kuralları) görürsünüz.
  • constexpr , C stili bir sabit ifadedir (örneğin, 1 + 1 ve 1L << 3).
  • import_name, nitelikli bir paket veya arayüz adıdır HIDL'de açıklandığı gibi Sürüm oluşturma.
  • Küçük words harfi, düz simgedir.

Ö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