HIDL

زبان تعریف رابط HAL یا HIDL (تلفظ "hide-l") یک زبان توصیف رابط (IDL) است که رابط بین HAL و کاربران آن را مشخص می کند. این اجازه می دهد تا انواع و روش های تماس ، جمع آوری شده در رابط ها و بسته ها را مشخص کند. به طور گسترده تر ، HIDL سیستمی برای ارتباط بین پایگاه های کد است که ممکن است به طور مستقل کامپایل شود. از Android 10 ، HIDL منسوخ شده است و Android در حال مهاجرت به استفاده از AIDL در همه جا است.

HIDL برای ارتباط بین فرآیندی (IPC) استفاده می شود. ارتباط بین فرآیندهای به عنوان Binderized . برای کتابخانه هایی که باید به یک فرایند مرتبط می شود، یک حالت عبوری نیز موجود است (در جاوا پشتیبانی نمی شود).

HIDL ساختار داده ها و امضاهای متد را مشخص می کند که در رابط ها (شبیه به کلاس) سازماندهی شده و در بسته ها جمع آوری می شوند. نحو HIDL برای برنامه نویسان C ++ و جاوا آشنا به نظر می رسد ، هر چند با مجموعه ای از کلمات کلیدی متفاوت. HIDL همچنین از حاشیه نویسی به سبک جاوا استفاده می کند.

طراحی HIDL

هدف HIDL این است که می توان چارچوب را بدون نیاز به بازسازی HAL ها جایگزین کرد. HALS خواهد شد توسط فروشندگان یا سازندگان SOC ساخته شده و در یک قرار /vendor پارتیشن بر روی دستگاه، امکان چارچوب، در پارتیشن خود را دارد، با یک OTA جایگزین شود بدون کامپایل مجدد HALS.

طراحی HIDL نگرانی های زیر را متعادل می کند:

  • قابلیت همکاری. ایجاد واسط های قابل تعامل قابل اعتماد بین فرآیندهایی که ممکن است با معماری ها ، زنجیره ابزار مختلف ، و پیکربندی ایجاد شود. رابط های HIDL نسخه هستند و پس از انتشار قابل تغییر نیستند.
  • بهره وری. HIDL سعی می کند تعداد عملیات کپی را به حداقل برساند. داده های تعریف شده توسط HIDL به ساختار C ++ در ساختار داده های طرح بندی استاندارد C ++ تحویل داده می شود که می تواند بدون باز کردن بسته بندی مورد استفاده قرار گیرد. HIDL همچنین رابط های حافظه مشترک را ارائه می دهد و چون RPC ها ذاتاً کند هستند ، HIDL از دو روش انتقال داده بدون استفاده از تماس RPC پشتیبانی می کند: حافظه مشترک و صف پیام سریع (FMQ).
  • بصری. HIDL اجتناب خاردار مسائل مربوط به مالکیت حافظه با استفاده از تنها in پارامترهای برای RPC (نگاه کنید به رابط آندروید تعریف زبان (AIDL) )؛ مقادیری که نمی توانند به طور م fromثر از روش ها برگردانده شوند ، از طریق توابع فراخوانی بازگردانده می شوند. نه انتقال داده ها به HIDL برای انتقال و نه دریافت داده ها از HIDL مالکیت داده ها را تغییر نمی دهد - مالکیت همیشه در تابع فراخوانی باقی می ماند. داده ها فقط باید برای مدت زمان تابع فراخوانی شده باقی بمانند و ممکن است بلافاصله پس از بازگشت تابع فراخوانی شده ، از بین بروند.

استفاده از حالت passthrough

برای به روزرسانی دستگاه هایی که نسخه های قبلی Android را به اندروید O اجرا می کنند ، می توانید HAL های معمولی (و قدیمی) را در یک رابط HIDL جدید که HAL را در حالتهای اتصال دهنده و یکسان (passthrough) ارائه می دهد ، بپیچید. این بسته بندی برای HAL و چارچوب Android شفاف است.

حالت Passthrough فقط برای کلاینت های C ++ و پیاده سازی ها در دسترس است. دستگاه هایی که نسخه های قبلی اندروید را اجرا می کنند ، HAL به زبان جاوا نوشته نشده اند ، بنابراین HAL های جاوا ذاتاً محاسبه می شوند.

هنگامی که یک .hal فایل وارد شده است، hidl-gen تولید عبوری فایل هدر اضافی BsFoo.h علاوه بر هدر استفاده برای برقراری ارتباط چسب؛ این تعریف هدر توابع به dlopen اد. همانطور که HAL های passthrough در همان فرایندی که نامیده می شوند اجرا می شوند ، در اکثر موارد متدهای passthrough با فراخوانی تابع مستقیم (همان نخ) فراخوانی می شوند. oneway روش در موضوع خود را اجرا عنوان آنها در نظر گرفته شده برای HAL صبر کنید تا آنها را پردازش (این به معنی هر HAL که با استفاده از oneway روش در حالت عبوری باید موضوع امن باشد).

با توجه به IFoo.hal ، BsFoo.h کاری ادامه داده اند روش HIDL تولید به ارائه ویژگی های اضافی (مانند ساخت oneway معاملات در انجمن با کاربران دیگر اجرا). این فایل شبیه به BpFoo.h ، با این حال به جای عبور در تماس های IPC با استفاده از چسب، توابع مورد نظر به طور مستقیم استفاده نمود. پیاده سازی آینده از HALS ممکن است پیاده سازی های متعدد، مانند FooFast HAL و یک HAL FooAccurate فراهم می کند. در چنین مواردی، یک فایل برای هر اجرای اضافی به ایجاد (به عنوان مثال، PTFooFast.cpp و PTFooAccurate.cpp ).

اتصال بین HAL ها

می توانید پیاده سازی های HAL را که از حالت passthrough پشتیبانی می کنند ، متصل کنید. با توجه به HAL رابط abcd@MN::IFoo ، دو بسته را ایجاد می کند:

  • abcd@MN::IFoo-impl . شامل اجرای HAL و در معرض عمل IFoo* HIDL_FETCH_IFoo(const char* name) . در دستگاه های قدیمی، این بسته است dlopen اد و اجرای با استفاده از نمونه است HIDL_FETCH_IFoo . شما می توانید کد پایه با استفاده از تولید hidl-gen و -Lc++-impl و -Landroidbp-impl .
  • abcd@MN::IFoo-service . گذرگاه HAL را باز می کند و خود را به عنوان یک سرویس binderized ثبت می کند و باعث می شود از همان اجرای HAL به عنوان گذرنامه و binderized استفاده شود.

با توجه به نوع IFoo ، شما می توانید پاسخ sp<IFoo> IFoo::getService(string name, bool getStub) برای دسترسی به یک نمونه از IFoo . اگر getStub درست است، getService تلاش برای باز کردن HAL فقط در حالت عبوری. اگر getStub نادرست است، getService تلاش برای پیدا کردن یک سرویس binderized؛ در صورت عدم موفقیت ، سعی می کند سرویس passthrough را پیدا کند. getStub پارامتر هرگز نباید به جز در مورد استفاده قرار گیرد defaultPassthroughServiceImplementation . (دستگاههایی که با اندروید O راه اندازی می شوند ، دستگاههای کاملاً اتصال دهنده هستند ، بنابراین باز کردن سرویس در حالت passthrough ممنوع است.)

دستور زبان HIDL

از نظر طراحی ، زبان HIDL شبیه C است (اما از پیش پردازنده C استفاده نمی کند). همه علائم نگارشی در زیر توضیح داده (جدا از استفاده آشکار از نه = و | ) بخشی از دستور زبان است.

توجه: برای اطلاع از جزئیات سبک کد HIDL، نگاه کنید به کد راهنمای سبک .

  • /** */ نشان می دهد نظر اسناد و مدارک. اینها فقط برای اعلان های نوع ، روش ، فیلد و مقدار enum قابل استفاده هستند.
  • /* */ نشان می دهد یک توضیح چند خطی.
  • // نشان می دهد یک نظر به پایان خط. گذشته از // ، خط جدید مانند هر فضای خالی هستند.
  • در مثال دستور زبان زیر، متن از // به پایان خط است بخشی از دستور زبان نیست اما در عوض یک نظر در دستور زبان.
  • [empty] بدان معنی است که مدت ممکن است خالی باشد.
  • ? پیروی از واژه یا اصطلاح به معنی اختیاری است.
  • ... نشان می دهد دنباله حاوی صفر یا بیشتر موارد با جدا نقطه گذاری به عنوان نشان داد. هیچ استدلال متغیری در HIDL وجود ندارد.
  • کاما عناصر دنباله جداگانه
  • نقطه ویرگول هر عنصر ، از جمله آخرین عنصر را خاتمه می دهد.
  • UPPERCASE یک ترمینال نیست.
  • italics یک خانواده رمز مانند است integer یا identifier (قوانین C تجزیه استاندارد).
  • constexpr یک عبارت ثابت سبک C است (مانند 1 + 1 و 1L << 3 ).
  • import_name یک بسته یا رابط نام است، واجد شرایط به عنوان در توصیف HIDL نسخه .
  • با حروف کوچک words نشانه لفظی هستند.

مثال:

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

واژه شناسی

این بخش از اصطلاحات زیر مربوط به HIDL استفاده می کند:

چسبناک نشان می دهد که HIDL برای فراخوانی از راه دور بین فرآیندها که بر اساس مکانیزمی شبیه به Binder اجرا می شود ، استفاده می شود. همچنین نگاه عبوری.
تماس تلفنی ، ناهمزمان رابط توسط یک کاربر HAL ارائه می شود ، به HAL منتقل می شود (از طریق روش HIDL) ، و توسط HAL فراخوانی می شود تا داده ها را در هر زمان برگرداند.
تماس تلفنی ، همزمان داده های پیاده سازی روش HIDL سرور را به مشتری برمی گرداند. برای متدهایی که مقدار خالی یا یک مقدار اولیه را برمی گردانند استفاده نمی شود.
مشتری فرآیندی که متدهای یک رابط خاص را فراخوانی می کند. یک فرایند چارچوب یا HAL ممکن است مشتری یک رابط و سرور رابط دیگر باشد. همچنین نگاه عبوری.
گسترش می یابد نشان دهنده رابطی است که روش ها و/یا انواع را به رابط دیگر اضافه می کند. یک رابط می تواند فقط یک رابط دیگر را گسترش دهد. می تواند برای افزایش نسخه جزئی در همان نام بسته یا برای بسته جدیدی (به عنوان مثال افزونه فروشنده) برای ایجاد بسته قدیمی استفاده شود.
تولید می کند یک روش رابط را نشان می دهد که مقادیر را به مشتری برمی گرداند. برای بازگشت یک مقدار غیر اولیه یا بیش از یک مقدار ، یک تابع فراخوانی همزمان ایجاد می شود.
رابط مجموعه روشها و انواع. به یک کلاس در C ++ یا جاوا ترجمه شده است. همه روشهای موجود در یک رابط در یک جهت خوانده می شوند: یک فرایند سرویس گیرنده روش هایی را که توسط یک فرآیند سرور اجرا شده است فرا می خواند.
یک طرفه هنگامی که روی یک روش HIDL اعمال می شود ، نشان می دهد که این روش هیچ مقداری بر نمی گرداند و مسدود نمی کند.
بسته مجموعه ای از رابط ها و انواع داده ها که یک نسخه را به اشتراک می گذارند.
گذر نحوه HIDL که در آن سرور کتابخانه مشترک است، dlopen اد شده توسط مشتری. در حالت passthrough ، کلاینت و سرور یک فرایند یکسان هستند اما پایگاه کد جداگانه ای دارند. فقط برای آوردن کدهای قدیمی به مدل HIDL استفاده می شود. همچنین نگاه کنید به Binderized.
سرور فرآیندی که روش های یک رابط را پیاده سازی می کند. همچنین نگاه عبوری.
حمل و نقل زیرساخت HIDL که داده ها را بین سرور و سرویس گیرنده منتقل می کند.
نسخه نسخه یک بسته. شامل دو عدد صحیح عمده و جزئی است. افزایش نسخه های کوچک ممکن است انواع و روش ها را اضافه کند (اما تغییر نکند).