رابط ها & بسته ها

HIDL حول رابط ها ساخته شده است، یک نوع انتزاعی که در زبان های شی گرا برای تعریف رفتارها استفاده می شود. هر رابط بخشی از یک بسته است.

بسته ها

نام بسته ها می تواند دارای سطوح فرعی مانند package.subpackage باشد. دایرکتوری ریشه برای بسته های HIDL منتشر شده hardware/interfaces یا vendor/vendorName است (مثلاً vendor/google برای دستگاه های Pixel). نام بسته یک یا چند زیردایرکتوری را در زیر شاخه اصلی تشکیل می دهد. تمام فایل هایی که یک بسته را تعریف می کنند در یک دایرکتوری قرار دارند. به عنوان مثال، package android.hardware.example.extension.light@2.0 را می توان در قسمت hardware/interfaces/example/extension/light/2.0 یافت.

جدول زیر پیشوندها و مکان های بسته را فهرست می کند:

پیشوند بسته محل انواع رابط
android.hardware.* hardware/interfaces/* HAL
android.frameworks.* frameworks/hardware/interfaces/* چارچوب/ مرتبط
android.system.* system/hardware/interfaces/* سیستم/ مرتبط
android.hidl.* system/libhidl/transport/* هسته

دایرکتوری بسته حاوی فایل هایی با پسوند .hal است. هر فایل باید حاوی یک دستور package باشد که بسته و نسخه ای که فایل بخشی از آن است نامگذاری کند. فایل types.hal ، در صورت وجود، یک رابط تعریف نمی کند، بلکه انواع داده های قابل دسترسی برای هر رابط در بسته را تعریف می کند.

تعریف رابط

به غیر از types.hal ، هر فایل .hal دیگری یک رابط را تعریف می کند. یک رابط معمولاً به صورت زیر تعریف می شود:

interface IBar extends IFoo { // IFoo is another interface
    // embedded types
    struct MyStruct {/*...*/};

    // interface methods
    create(int32_t id) generates (MyStruct s);
    close();
};

یک رابط بدون اعلان extends صریح به طور ضمنی از android.hidl.base@1.0::IBase (شبیه به java.lang.Object در جاوا.) اینترفیس IBase، که به طور ضمنی وارد شده است، چندین روش رزرو شده را اعلام می کند که نباید و نمی توانند مجدداً اعلام شوند. در واسط های تعریف شده توسط کاربر یا به صورت دیگری استفاده می شود. این روش ها عبارتند از:

  • ping
  • interfaceChain
  • interfaceDescriptor
  • notifySyspropsChanged
  • linkToDeath
  • unlinkToDeath
  • setHALInstrumentation
  • getDebugInfo
  • debug
  • getHashChain

واردات

دستور import مکانیزم HIDL برای دسترسی به واسط‌ها و انواع بسته‌ها در بسته دیگر است. یک بیانیه import به دو نهاد مربوط می شود:

  • موجودیت واردکننده ، که می تواند بسته یا رابط باشد. و
  • موجودیت ویرایش واردات، که می تواند یک بسته یا یک رابط باشد.

نهاد واردکننده بر اساس محل اظهارنامه import تعیین می شود. هنگامی که عبارت در داخل یک بسته types.hal باشد، آنچه وارد می شود توسط کل بسته قابل مشاهده است. این یک واردات در سطح بسته است. هنگامی که عبارت داخل یک فایل واسط است، نهاد واردکننده، خود رابط است. این یک واردات در سطح رابط است.

موجودیت وارد شده با مقدار بعد از کلمه کلیدی import تعیین می شود. مقدار لازم نیست یک نام کاملاً واجد شرایط باشد. اگر یک جزء حذف شود، به طور خودکار با اطلاعات بسته فعلی پر می شود. برای مقادیر کاملاً واجد شرایط، موارد واردات زیر پشتیبانی می‌شوند:

  • واردات بسته بندی کامل اگر مقدار یک نام بسته و یک نسخه باشد (سیستکس شرح داده شده در زیر)، پس کل بسته به نهاد واردکننده وارد می شود.
  • واردات جزئی اگر مقدار:
    • یک اینترفیس، بسته به types.hal و آن واسط به نهاد واردکننده وارد می‌شوند.
    • یک UDT در types.hal تعریف شده است، سپس فقط آن UDT به نهاد واردکننده وارد می شود (سایر انواع در types.hal وارد نمی شوند).
  • واردات فقط انواع اگر مقدار از نحو یک واردات جزئی که در بالا توضیح داده شد استفاده کند، اما به جای نام رابط، از types کلمه کلیدی استفاده کند، فقط UDTها در types.hal بسته تعیین‌شده وارد می‌شوند.

نهاد واردکننده به ترکیبی از موارد زیر دسترسی دارد:

  • UDTهای رایج بسته وارداتی که در types.hal تعریف شده است.
  • واسط های بسته وارداتی (برای واردات کل بسته) یا رابط مشخص (برای واردات جزئی) به منظور فراخوانی آنها، انتقال دسته ها به آنها و/یا ارث بردن از آنها.

دستور import از نحو کاملاً واجد شرایط نوع نام برای ارائه نام و نسخه بسته یا واسط وارد شده استفاده می کند:

import android.hardware.nfc@1.0;            // import a whole package
import android.hardware.example@1.0::IQuux; // import an interface and types.hal
import android.hardware.example@1.0::types; // import just types.hal

وراثت رابط

یک اینترفیس می‌تواند پسوند یک رابط از قبل تعریف شده باشد. پسوندها می توانند یکی از سه نوع زیر باشند:

  • اینترفیس می‌تواند عملکردی را به یکی دیگر اضافه کند و API آن را بدون تغییر بگنجاند.
  • بسته می‌تواند عملکردی را به یکی دیگر اضافه کند و API خود را بدون تغییر اضافه کند.
  • رابط می تواند انواع را از یک بسته یا از یک رابط خاص وارد کند.

یک رابط می تواند تنها یک رابط دیگر را گسترش دهد (بدون وراثت چندگانه). هر رابط در یک بسته با شماره نسخه جزئی غیر صفر باید یک رابط در نسخه قبلی بسته گسترش دهد. به عنوان مثال، اگر یک رابط IBar در نسخه 4.0 derivative مبتنی بر یک رابط IFoo در نسخه 1.2 بسته original (بسط) باشد، و یک نسخه 1.3 از بسته original ایجاد شود، IBar نسخه 4.1 نمی‌تواند نسخه 1.3 IFoo را گسترش دهد. در عوض، نسخه IBar 4.1 باید نسخه IBar 4.0 را که به IFoo نسخه 1.2 مرتبط است، گسترش دهد. در صورت تمایل، نسخه IBar 5.0 می تواند نسخه IFoo 1.3 را گسترش دهد.

پسوندهای رابط دلالت بر وابستگی کتابخانه یا گنجاندن متقاطع HAL در کد تولید شده ندارند - آنها به سادگی ساختار داده و تعاریف روش را در سطح HIDL وارد می کنند. هر متد در یک HAL باید در آن HAL پیاده سازی شود.

پسوند فروشنده

در برخی موارد، افزونه‌های فروشنده به‌عنوان یک زیر کلاس از شی پایه که نمایانگر رابط اصلی آن‌ها است، پیاده‌سازی می‌شوند. همان شیء تحت نام و نسخه پایه HAL و نام و نسخه HAL پسوند (فروشنده) ثبت می شود.

نسخه سازی

بسته ها نسخه بندی شده اند و رابط ها نسخه بسته خود را دارند. نسخه ها در دو عدد صحیح بیان می شوند. جزئی .

  • نسخه های اصلی با نسخه های قبلی سازگار نیستند. با افزایش شماره نسخه اصلی، شماره نسخه فرعی به 0 بازنشانی می شود.
  • نسخه های کوچک با عقب سازگار هستند. افزایش عدد جزئی نشان می دهد که نسخه جدیدتر کاملاً با نسخه قبلی سازگار است. ساختارها و روش های داده جدید را می توان اضافه کرد، اما هیچ ساختار داده یا امضای روش موجود را نمی توان تغییر داد.

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

خلاصه طرح رابط

این بخش نحوه مدیریت بسته رابط HIDL (مانند hardware/interfaces ) را خلاصه می کند و اطلاعات ارائه شده در سراسر بخش HIDL را ادغام می کند. قبل از مطالعه، مطمئن شوید که با نسخه HIDL ، مفاهیم هش در Hashing با hidl-gen ، جزئیات کار با HIDL به طور کلی و تعاریف زیر آشنا هستید:

مدت، اصطلاح تعریف
رابط باینری برنامه (ABI) رابط برنامه نویسی برنامه + هر گونه پیوند باینری مورد نیاز.
نام کاملاً واجد شرایط (fqName) نام برای تشخیص نوع hidl. مثال: android.hardware.foo@1.0::IFoo .
بسته بسته حاوی رابط HIDL و انواع. مثال: android.hardware.foo@1.0 .
ریشه پکیج بسته ریشه که شامل رابط های HIDL است. مثال: رابط HIDL android.hardware در بسته ریشه android.hardware.foo@1.0 قرار دارد.
مسیر ریشه بسته مکان در درخت منبع Android که در آن یک بسته ریشه به آن نقشه می‌دهد.

برای تعاریف بیشتر، اصطلاحات HIDL را ببینید.

هر فایل را می توان از نقشه ریشه بسته و نام کاملاً واجد شرایط آن پیدا کرد

ریشه های بسته به hidl-gen به عنوان آرگومان -r android.hardware:hardware/interfaces . برای مثال، اگر بسته vendor.awesome.foo@1.0::IFoo است و hidl-gen -r vendor.awesome:some/device/independent/path/interfaces ارسال می شود، فایل رابط باید در $ANDROID_BUILD_TOP/some/device/independent/path/interfaces/foo/1.0/IFoo.hal قرار گیرد. $ANDROID_BUILD_TOP/some/device/independent/path/interfaces/foo/1.0/IFoo.hal .

در عمل، به یک فروشنده یا OEM با نام awesome توصیه می شود که رابط های استاندارد خود را در vendor.awesome قرار دهد. پس از انتخاب یک مسیر بسته، نباید آن را تغییر داد زیرا در ABI رابط ساخته شده است.

نگاشت مسیر بسته باید منحصر به فرد باشد

به عنوان مثال، اگر -rsome.package:$PATH_A و -rsome.package:$PATH_B دارید، $PATH_A باید برابر با $PATH_B برای یک فهرست رابط ثابت باشد (این کار نسخه‌سازی رابط‌ها را بسیار آسان‌تر می‌کند).

ریشه بسته باید دارای یک فایل نسخه سازی باشد

اگر یک مسیر بسته مانند -r vendor.awesome:vendor/awesome/interfaces ایجاد می کنید، باید فایل $ANDROID_BUILD_TOP/vendor/awesome/interfaces/current.txt نیز ایجاد کنید، که باید حاوی هش های رابط های ساخته شده با استفاده از -Lhash باشد. گزینه در hidl-gen (این مورد به طور گسترده در Hashing با hidl-gen مورد بحث قرار گرفته است).

رابط ها در مکان های مستقل از دستگاه قرار می گیرند

در عمل توصیه می‌شود که رابط‌ها را بین شاخه‌ها به اشتراک بگذارید. این اجازه می دهد تا حداکثر استفاده مجدد از کد و حداکثر آزمایش کد در دستگاه های مختلف و موارد استفاده انجام شود.