AIDL برای HAL ها

اندروید 11 قابلیت استفاده از AIDL برای HAL ها را در اندروید معرفی می کند و امکان پیاده سازی بخش هایی از اندروید را بدون HIDL فراهم می کند. HAL های انتقالی را به استفاده انحصاری از AIDL در صورت امکان تغییر دهید (زمانی که HAL های بالادست از HIDL استفاده می کنند، HIDL باید استفاده شود).

HAL هایی که از AIDL برای برقراری ارتباط بین اجزای چارچوب، مانند اجزای موجود در system.img و اجزای سخت افزاری، مانند آنهایی که در vendor.img استفاده می کنند، باید از AIDL پایدار استفاده کنند. با این حال، برای برقراری ارتباط در یک پارتیشن، به عنوان مثال، از یک HAL به دیگری، هیچ محدودیتی در مکانیسم IPC برای استفاده وجود ندارد.

انگیزه

AIDL طولانی‌تر از HIDL بوده است و در بسیاری از مکان‌های دیگر مانند بین اجزای چارچوب Android یا در برنامه‌ها استفاده می‌شود. اکنون که AIDL از پشتیبانی پایداری برخوردار است، امکان پیاده‌سازی کل پشته با یک زمان اجرا IPC وجود دارد. AIDL همچنین سیستم نسخه سازی بهتری نسبت به HIDL دارد. در اینجا برخی از مزایای AIDL وجود دارد:

  • استفاده از یک زبان IPC به معنای داشتن تنها یک چیز برای یادگیری است، اشکال زدایی، بهینه سازی و ایمن سازی.
  • AIDL از نسخه سازی در محل برای صاحبان یک رابط پشتیبانی می کند:
    • مالکان می‌توانند روش‌هایی را به انتهای رابط‌ها یا فیلدهایی را به بسته‌بندی‌ها اضافه کنند. این بدان معناست که در طول سال‌ها کدگذاری نسخه آسان‌تر است، و همچنین هزینه سال به سال کمتر است (انواع را می‌توان در جای خود اصلاح کرد و نیازی به کتابخانه‌های اضافی برای هر نسخه رابط نیست).
    • رابط های برنامه افزودنی را می توان در زمان اجرا به جای سیستم نوع متصل کرد، بنابراین نیازی به تغییر برنامه های افزودنی پایین دستی به نسخه های جدیدتر اینترفیس ها نیست.
  • یک رابط AIDL موجود می‌تواند مستقیماً زمانی استفاده شود که صاحب آن بخواهد آن را تثبیت کند. قبل از این، یک نسخه کامل از رابط باید در HIDL ایجاد شود.

ساخت در برابر زمان اجرا AIDL

AIDL دارای سه باطن مختلف است: جاوا، NDK و CPP. برای استفاده از AIDL پایدار، همیشه از نسخه سیستمی libbinder در system/lib*/libbinder.so استفاده کنید و در /dev/binder صحبت کنید. برای کد روی تصویر vendor ، این به این معنی است که از libbinder (از VNDK) نمی توان استفاده کرد: این کتابخانه دارای یک C++ API ناپایدار و داخلی های ناپایدار است. در عوض، کد فروشنده بومی باید از پشتیبان NDK AIDL، پیوند در برابر libbinder_ndk (که توسط system libbinder.so پشتیبانی می‌شود) و در برابر کتابخانه‌های NDK ایجاد شده توسط ورودی‌های aidl_interface استفاده کند. برای نام‌های دقیق ماژول، قوانین نام‌گذاری ماژول را ببینید.

یک رابط AIDL HAL بنویسید

برای استفاده از رابط AIDL بین سیستم و فروشنده، این رابط به دو تغییر نیاز دارد:

  • هر نوع تعریف باید با @VintfStability حاشیه نویسی شود.
  • اعلان aidl_interface باید شامل stability: "vintf", .

فقط صاحب یک رابط می تواند این تغییرات را انجام دهد.

وقتی این تغییرات را انجام می دهید، رابط باید در مانیفست VINTF باشد تا کار کند. با استفاده از آزمون VTS vts_treble_vintf_vendor_test این (و الزامات مربوطه، مانند تأیید اینکه رابط های منتشر شده ثابت هستند) را آزمایش کنید. می‌توانید با فراخوانی AIBinder_forceDowngradeToLocalStability در باطن NDK، android::Stability::forceDowngradeToLocalStability در بک‌اند C++، یا android.os.Binder#forceDowngradeToSystemStability قبل از ارسال یک فرآیند دیگر در جاوای backend در یک شیء دیگر، از یک واسط @VintfStability بدون این الزامات استفاده کنید.

علاوه بر این، برای حداکثر قابلیت حمل کد و برای جلوگیری از مشکلات احتمالی مانند کتابخانه های اضافی غیر ضروری، پشتیبان CPP را غیرفعال کنید.

توجه داشته باشید که استفاده از backends در مثال کد زیر صحیح است، زیرا سه Backend وجود دارد (جاوا، NDK و CPP). کد نحوه غیرفعال کردن پشتیبان CPP را نشان می دهد:

    aidl_interface: {
        ...
        backends: {
            cpp: {
                enabled: false,
            },
        },
    }

رابط های AIDL HAL را پیدا کنید

رابط های AIDL پایدار AOSP برای HALS در پوشه های aidl در همان دایرکتوری های پایه رابط های HIDL قرار دارند:

  • hardware/interfaces برای رابط هایی است که معمولاً توسط سخت افزار ارائه می شود.
  • frameworks/hardware/interfaces برای رابط های سطح بالا ارائه شده به سخت افزار است.
  • system/hardware/interfaces برای رابط های سطح پایین ارائه شده به سخت افزار است.

رابط های افزونه را در سایر زیر شاخه های hardware/interfaces موجود در vendor یا hardware قرار دهید.

رابط های برنامه افزودنی

اندروید با هر نسخه دارای مجموعه ای از رابط های رسمی AOSP است. وقتی شرکای اندرویدی می‌خواهند قابلیت‌هایی را به این رابط‌ها اضافه کنند، نباید مستقیماً آن‌ها را تغییر دهند، زیرا این باعث می‌شود زمان اجرا اندروید آن‌ها با زمان اجرا اندروید AOSP ناسازگار باشد. از تغییر این رابط ها اجتناب کنید تا تصویر GSI بتواند به کار خود ادامه دهد.

برنامه های افزودنی می توانند به دو روش مختلف ثبت شوند:

با این حال، یک برنامه افزودنی ثبت شده است، زمانی که مؤلفه‌های خاص فروشنده (به این معنی که بخشی از AOSP بالادستی نیست) از رابط استفاده می‌کنند، تداخل ادغام امکان‌پذیر نیست، با این حال، وقتی تغییرات پایین‌دستی برای مؤلفه‌های AOSP بالادست انجام می‌شود، تداخل ادغام می‌تواند منجر شود، و استراتژی‌های زیر توصیه می‌شوند:

  • در نسخه بعدی رابط اضافه شده به AOSP در بالادست.
  • افزودنی‌های رابط بالادستی که در نسخه بعدی انعطاف‌پذیری بیشتری (بدون تداخل ادغام) می‌دهد.

بسته های الحاقی: ParcelableHolder

ParcelableHolder نمونه ای از واسط Parcelable است که می تواند شامل نمونه دیگری از Parcelable باشد.

مورد اصلی استفاده از ParcelableHolder این است که Parcelable را قابل توسعه می کند. به عنوان مثال، تصویری که پیاده‌کننده‌های دستگاه انتظار دارند بتوانند یک Parcelable تعریف‌شده توسط AOSP، AospDefinedParcelable را گسترش دهند تا ویژگی‌های ارزش افزوده آن‌ها را در بر گیرد.

از رابط ParcelableHolder برای گسترش Parcelable با ویژگی های ارزش افزوده خود استفاده کنید. رابط ParcelableHolder شامل یک نمونه از Parcelable است. اگر بخواهید مستقیماً فیلدهایی را به Parcelable اضافه کنید، باعث ایجاد خطا می شود:

parcelable AospDefinedParcelable {
  int a;
  String b;
  String x; // ERROR: added by a device implementer
  int[] y; // added by a device implementer
}

همانطور که در کد قبلی مشاهده شد، این عمل شکسته شده است زیرا ممکن است فیلدهای اضافه شده توسط پیاده‌کننده دستگاه در هنگام بازبینی Parcelable در نسخه‌های بعدی اندروید دچار تداخل شوند.

با استفاده از ParcelableHolder ، صاحب یک parcelable می تواند یک نقطه توسعه را در یک نمونه از Parcelable تعریف کند:

parcelable AospDefinedParcelable {
  int a;
  String b;
  ParcelableHolder extension;
}

سپس پیاده‌کننده‌های دستگاه می‌توانند نمونه Parcelable خود را برای پسوند خود تعریف کنند:

parcelable OemDefinedParcelable {
  String x;
  int[] y;
}

نمونه Parcelable جدید را می توان با قسمت ParcelableHolder به Parcelable اصلی متصل کرد:


// Java
AospDefinedParcelable ap = ...;
OemDefinedParcelable op = new OemDefinedParcelable();
op.x = ...;
op.y = ...;

ap.extension.setParcelable(op);

...

OemDefinedParcelable op = ap.extension.getParcelable(OemDefinedParcelable.class);

// C++
AospDefinedParcelable ap;
OemDefinedParcelable op;
std::shared_ptr<OemDefinedParcelable> op_ptr = make_shared<OemDefinedParcelable>();

ap.extension.setParcelable(op);
ap.extension.setParcelable(op_ptr);

...

std::shared_ptr<OemDefinedParcelable> op_ptr;

ap.extension.getParcelable(&op_ptr);

// NDK
AospDefinedParcelable ap;
OemDefinedParcelable op;
ap.extension.setParcelable(op);

...

std::optional<OemDefinedParcelable> op;
ap.extension.getParcelable(&op);

// Rust
let mut ap = AospDefinedParcelable { .. };
let op = Rc::new(OemDefinedParcelable { .. });

ap.extension.set_parcelable(Rc::clone(&op));

...

let op = ap.extension.get_parcelable::<OemDefinedParcelable>();

نام های نمونه سرور AIDL HAL

طبق قرارداد، خدمات AIDL HAL یک نام نمونه با فرمت $package.$type/$instance دارند. به عنوان مثال، یک نمونه از لرزاننده HAL به عنوان android.hardware.vibrator.IVibrator/default ثبت شده است.

یک سرور AIDL HAL بنویسید

سرورهای AIDL @VintfStability باید در مانیفست VINTF اعلام شوند، برای مثال:

    <hal format="aidl">
        <name>android.hardware.vibrator</name>
        <version>1</version>
        <fqname>IVibrator/default</fqname>
    </hal>

در غیر این صورت باید خدمات AIDL را به طور معمول ثبت کنند. هنگام اجرای تست های VTS ، انتظار می رود که همه HAL های AIDL اعلام شده در دسترس باشند.

یک مشتری AIDL بنویسید

مشتریان AIDL باید خود را در ماتریس سازگاری اعلام کنند، به عنوان مثال:

    <hal format="aidl" optional="true">
        <name>android.hardware.vibrator</name>
        <version>1-2</version>
        <interface>
            <name>IVibrator</name>
            <instance>default</instance>
        </interface>
    </hal>

HAL موجود را از HIDL به AIDL تبدیل کنید

از ابزار hidl2aidl برای تبدیل رابط HIDL به AIDL استفاده کنید.

ویژگی های hidl2aidl :

  • فایل های AIDL ( .aidl ) را بر اساس فایل های HAL ( .hal ) برای بسته داده شده ایجاد کنید.
  • قوانین ساخت بسته AIDL تازه ایجاد شده را با فعال بودن تمام backendها ایجاد کنید.
  • برای ترجمه از انواع HIDL به انواع AIDL، متدهای ترجمه را در پشتیبان‌های جاوا، CPP و NDK ایجاد کنید.
  • قوانین ساخت را برای کتابخانه های ترجمه با وابستگی های مورد نیاز ایجاد کنید.
  • برای اطمینان از اینکه شمارشگرهای HIDL و AIDL دارای مقادیر یکسانی در backendهای CPP و NDK هستند، اظهارات ثابت ایجاد کنید.

برای تبدیل بسته ای از فایل های HAL به فایل های AIDL مراحل زیر را دنبال کنید:

  1. ابزار واقع در system/tools/hidl/hidl2aidl را بسازید.

    ساخت این ابزار از آخرین منبع کامل ترین تجربه را ارائه می دهد. می توانید از آخرین نسخه برای تبدیل رابط ها در شاخه های قدیمی تر از نسخه های قبلی استفاده کنید:

    m hidl2aidl
  2. ابزار را با دایرکتوری خروجی و به دنبال آن بسته ای که قرار است تبدیل شود اجرا کنید.

    به صورت اختیاری، از آرگومان -l برای افزودن محتویات یک فایل مجوز جدید به بالای همه فایل های تولید شده استفاده کنید. حتما از مجوز و تاریخ صحیح استفاده کنید:

    hidl2aidl -o <output directory> -l <file with license> <package>

    به عنوان مثال:

    hidl2aidl -o . -l my_license.txt android.hardware.nfc@1.2
  3. فایل های تولید شده را بخوانید و مشکلات مربوط به تبدیل را برطرف کنید:

    • conversion.log حاوی هر گونه مشکل کنترل نشده است که ابتدا باید برطرف شود.
    • فایل های AIDL ایجاد شده ممکن است هشدارها و پیشنهاداتی داشته باشند که نیاز به اقدام دارند. این نظرات با // شروع می شود.
    • پاکسازی و بهبود در بسته.
    • حاشیه‌نویسی @JavaDerive را برای ویژگی‌هایی که ممکن است مورد نیاز باشد، مانند toString یا equals بررسی کنید.
  4. فقط اهداف مورد نیاز خود را بسازید:

    • پشتیبان هایی که استفاده نمی شوند را غیرفعال کنید. باطن NDK را به باطن CPP ترجیح دهید. به ساخت در مقابل زمان اجرا AIDL مراجعه کنید.
    • کتابخانه‌های ترجمه یا هر کد تولید شده‌ای که استفاده نمی‌شود را حذف کنید.
  5. تفاوت های عمده AIDL و HIDL را ببینید:

    • استفاده از Status داخلی AIDL و استثناها معمولاً رابط را بهبود می بخشد و نیاز به نوع وضعیت خاص رابط دیگر را برطرف می کند.
    • آرگومان‌های واسط AIDL در متدها به‌طور پیش‌فرض مانند HIDL @nullable نیستند.

SEPolicy برای AIDL HAL

یک نوع سرویس AIDL که برای کد فروشنده قابل مشاهده است باید دارای ویژگی hal_service_type باشد. در غیر این صورت، پیکربندی sepolicy مانند هر سرویس AIDL دیگری است (اگرچه ویژگی های خاصی برای HAL ها وجود دارد). در اینجا یک تعریف مثال از زمینه خدمات HAL آورده شده است:

    type hal_foo_service, service_manager_type, hal_service_type;

برای اکثر سرویس‌های تعریف‌شده توسط پلتفرم، یک زمینه سرویس با نوع صحیح از قبل اضافه شده است (به عنوان مثال، android.hardware.foo.IFoo/default قبلاً به عنوان hal_foo_service علامت‌گذاری شده است). با این حال، اگر یک کلاینت فریمورک از چندین نام نمونه پشتیبانی می‌کند، نام‌های نمونه اضافی باید در فایل‌های service_contexts مخصوص دستگاه اضافه شوند:

    android.hardware.foo.IFoo/custom_instance u:object_r:hal_foo_service:s0

هنگامی که نوع جدیدی از HAL ایجاد می کنید، باید ویژگی های HAL را اضافه کنید. یک ویژگی HAL خاص ممکن است با چندین نوع سرویس مرتبط باشد (که هر کدام می‌توانند نمونه‌های متعددی داشته باشند، همانطور که قبلاً بحث شد). برای یک HAL، foo ، hal_attribute(foo) وجود دارد. این ماکرو ویژگی های hal_foo_client و hal_foo_server را تعریف می کند. برای یک دامنه معین، ماکروهای hal_client_domain و hal_server_domain یک دامنه را با ویژگی HAL معین مرتبط می‌کنند. به عنوان مثال، سرور سیستم که مشتری این HAL است با خط مشی hal_client_domain(system_server, hal_foo) مطابقت دارد. یک سرور HAL به طور مشابه شامل hal_server_domain(my_hal_domain, hal_foo) است.

به طور معمول، برای یک ویژگی HAL داده شده، یک دامنه مانند hal_foo_default برای مرجع یا نمونه HAL نیز ایجاد کنید. با این حال، برخی از دستگاه ها از این دامنه ها برای سرورهای خود استفاده می کنند. تمایز بین دامنه‌ها برای چندین سرور فقط در صورتی مهم است که چندین سرور وجود داشته باشد که یک رابط را ارائه می‌دهند و به مجموعه مجوزهای متفاوتی در پیاده‌سازی‌های خود نیاز دارند. در همه این ماکروها، hal_foo یک شیء sepolicy نیست. در عوض، این توکن توسط این ماکروها برای اشاره به گروهی از ویژگی های مرتبط با یک جفت سرور مشتری استفاده می شود.

با این حال، تا کنون، hal_foo_service و hal_foo (جفت ویژگی از hal_attribute(foo) ) مرتبط نیستند. یک ویژگی HAL با خدمات AIDL HAL با استفاده از ماکرو hal_attribute_service مرتبط است (HIDL HAL ها از ماکرو hal_attribute_hwservice استفاده می کنند)، برای مثال، hal_attribute_service(hal_foo, hal_foo_service) . این بدان معنی است که فرآیندهای hal_foo_client می توانند HAL را به دست آورند و فرآیندهای hal_foo_server می توانند HAL را ثبت کنند. اجرای این قوانین ثبت نام توسط مدیر زمینه ( servicemanager ) انجام می شود.

نام سرویس‌ها ممکن است همیشه با ویژگی‌های HAL مطابقت نداشته باشند، برای مثال، hal_attribute_service(hal_foo, hal_foo2_service) . به طور کلی، از آنجایی که این نشان می‌دهد که سرویس‌ها همیشه با هم استفاده می‌شوند، می‌توانید hal_foo2_service حذف کنید و hal_foo_service برای همه زمینه‌های سرویس استفاده کنید. وقتی HAL ها چندین نمونه hal_attribute_service تنظیم می کنند، به این دلیل است که نام اصلی ویژگی HAL به اندازه کافی عمومی نیست و نمی توان آن را تغییر داد.

با کنار هم قرار دادن همه اینها، یک نمونه HAL به این شکل است:

    public/attributes:
    // define hal_foo, hal_foo_client, hal_foo_server
    hal_attribute(foo)

    public/service.te
    // define hal_foo_service
    type hal_foo_service, hal_service_type, protected_service, service_manager_type

    public/hal_foo.te:
    // allow binder connection from client to server
    binder_call(hal_foo_client, hal_foo_server)
    // allow client to find the service, allow server to register the service
    hal_attribute_service(hal_foo, hal_foo_service)
    // allow binder communication from server to service_manager
    binder_use(hal_foo_server)

    private/service_contexts:
    // bind an AIDL service name to the selinux type
    android.hardware.foo.IFooXxxx/default u:object_r:hal_foo_service:s0

    private/<some_domain>.te:
    // let this domain use the hal service
    binder_use(some_domain)
    hal_client_domain(some_domain, hal_foo)

    vendor/<some_hal_server_domain>.te
    // let this domain serve the hal service
    hal_server_domain(some_hal_server_domain, hal_foo)

رابط های افزودنی پیوست شده

یک برنامه افزودنی را می توان به هر رابط بایندر وصل کرد، خواه این رابط سطح بالا باشد که مستقیماً در سرویس مدیر ثبت شده باشد یا یک رابط فرعی. هنگام دریافت برنامه افزودنی، باید تأیید کنید که نوع پسوند مطابق انتظار است. می‌توانید برنامه‌های افزودنی را فقط از فرآیندی که یک کلاسور را ارائه می‌کند تنظیم کنید.

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

برای تنظیم یک افزونه بر روی یک کلاسور، از API های زیر استفاده کنید:

  • باطن NDK: AIBinder_setExtension
  • باطن جاوا: android.os.Binder.setExtension
  • باطن CPP: android::Binder::setExtension
  • Rust backend: binder::Binder::set_extension

برای دریافت پسوند بر روی بایندر، از API های زیر استفاده کنید:

  • باطن NDK: AIBinder_getExtension
  • باطن جاوا: android.os.IBinder.getExtension
  • باطن CPP: android::IBinder::getExtension
  • Rust backend: binder::Binder::get_extension

می‌توانید اطلاعات بیشتری برای این APIها در مستندات تابع getExtension در باطن مربوطه پیدا کنید. نمونه‌ای از نحوه استفاده از برنامه‌های افزودنی در hardware/interfaces/tests/extension/vibrator است.

تفاوت های عمده AIDL و HIDL

هنگام استفاده از AIDL HAL یا استفاده از رابط های AIDL HAL، از تفاوت ها در مقایسه با نوشتن HIDL HAL آگاه باشید.

  • نحو زبان AIDL به جاوا نزدیکتر است. نحو HIDL شبیه به C++ است.
  • همه رابط های AIDL دارای وضعیت خطای داخلی هستند. به جای ایجاد انواع وضعیت سفارشی، ints وضعیت ثابت را در فایل های رابط ایجاد کنید و EX_SERVICE_SPECIFIC در پشتیبان های CPP و NDK و ServiceSpecificException در باطن جاوا استفاده کنید. رسیدگی به خطا را ببینید.
  • AIDL به طور خودکار thread pool ها را هنگام ارسال اشیاء binder راه اندازی نمی کند. شما باید آنها را به صورت دستی شروع کنید (به مدیریت موضوع مراجعه کنید).
  • AIDL در خطاهای حمل و نقل بررسی نشده سقط نمی شود (HIDL Return در خطاهای بررسی نشده سقط می شود).
  • AIDL می تواند تنها یک نوع را در هر فایل اعلام کند.
  • آرگومان های AIDL را می توان علاوه بر پارامتر خروجی به صورت in ، out یا inout مشخص کرد (هیچ پاسخ تماس همزمان وجود ندارد).
  • AIDL از fd به عنوان نوع اولیه به جای handle استفاده می کند.
  • HIDL از نسخه های اصلی برای تغییرات ناسازگار و از نسخه های جزئی برای تغییرات سازگار استفاده می کند. در AIDL، تغییرات سازگار با عقب در جای خود انجام می شود. AIDL هیچ مفهوم صریحی از نسخه های اصلی ندارد. در عوض، این در نام بسته گنجانده شده است. به عنوان مثال، AIDL ممکن است از نام بسته bluetooth2 استفاده کند.
  • AIDL به طور پیش فرض اولویت بلادرنگ را به ارث نمی برد. تابع setInheritRt باید در هر بایندر برای فعال کردن وراثت اولویت بلادرنگ استفاده شود.

تست های مجموعه تست فروشنده (VTS) برای HAL ها

Android برای تأیید اجرای HAL مورد انتظار به مجموعه تست فروشنده (VTS) متکی است. VTS کمک می کند تا اطمینان حاصل شود که Android می تواند با پیاده سازی های فروشنده قدیمی سازگار باشد. پیاده سازی هایی که VTS ناموفق هستند مشکلات سازگاری شناخته شده ای دارند که می تواند مانع از کار آنها با نسخه های بعدی سیستم عامل شود.

دو بخش عمده از VTS برای HAL ها وجود دارد.

1. بررسی کنید که HAL های موجود در دستگاه توسط Android شناخته شده و مورد انتظار هستند

این مجموعه از تست ها را می توان در test/vts-testcase/hal/treble/vintf یافت. این آزمایش ها مسئول تأیید هستند:

  • هر رابط @VintfStability که در یک مانیفست VINTF اعلام شده است در نسخه منتشر شده شناخته شده ثابت می شود. این تضمین می کند که هر دو طرف رابط بر روی تعریف دقیق آن نسخه از رابط توافق دارند. این برای عملیات اساسی ضروری است.
  • تمام HAL هایی که در مانیفست VINTF اعلام شده اند در آن دستگاه در دسترس هستند. هر مشتری با مجوزهای کافی برای استفاده از سرویس HAL اعلام شده باید بتواند آن خدمات را در هر زمانی دریافت کند و از آن استفاده کند.
  • تمام HAL هایی که در مانیفست VINTF اعلان می شوند، نسخه رابطی را که در مانیفست اعلام می کنند، ارائه می کنند.
  • هیچ HAL منسوخ شده ای در دستگاهی ارائه نمی شود. Android پشتیبانی از نسخه‌های پایین‌تر رابط‌های HAL را همانطور که در چرخه عمر FCM توضیح داده شده است، متوقف می‌کند.
  • HAL های مورد نیاز روی دستگاه موجود است. برای اینکه اندروید به درستی کار کند به برخی از HAL ها نیاز است.

2. رفتار مورد انتظار هر HAL را بررسی کنید

هر رابط HAL دارای تست های VTS مخصوص به خود است تا رفتار مورد انتظار مشتریان خود را تأیید کند. موارد تست در برابر هر نمونه ای از رابط HAL اعلام شده اجرا می شوند و رفتار خاصی را بر اساس نسخه رابط پیاده سازی شده اعمال می کنند.

این تست‌ها سعی می‌کنند هر جنبه‌ای از اجرای HAL را که چارچوب اندروید بر آن تکیه می‌کند یا ممکن است در آینده بر آن تکیه کند، پوشش دهد.

این آزمایش‌ها شامل تأیید پشتیبانی از ویژگی‌ها، مدیریت خطا و هر رفتار دیگری است که مشتری ممکن است از سرویس انتظار داشته باشد.

نقاط عطف VTS برای توسعه HAL

انتظار می رود تست های VTS هنگام ایجاد یا اصلاح رابط های HAL اندروید به روز نگه داشته شوند.

تست‌های VTS باید تمام شده و آماده باشند تا پیاده‌سازی‌های فروشنده را قبل از اینکه برای نسخه‌های Android Vendor API ثابت شوند، تأیید کنند. آنها باید قبل از ثابت شدن اینترفیس ها آماده باشند تا توسعه دهندگان بتوانند پیاده سازی های خود را ایجاد کنند، آنها را تأیید کنند و بازخوردی را برای توسعه دهندگان رابط HAL ارائه دهند.

VTS در Cattlefish

زمانی که سخت افزار در دسترس نباشد، اندروید از Cuttlefish به عنوان وسیله ای برای توسعه رابط های HAL استفاده می کند. این امکان VTS مقیاس پذیر و تست یکپارچه سازی اندروید را فراهم می کند.

hal_implementation_test آزمایش می‌کند که Cuttlefish آخرین نسخه‌های رابط HAL را اجرا می‌کند تا مطمئن شود اندروید برای مدیریت رابط‌های جدید آماده است و تست‌های VTS آماده هستند تا پیاده‌سازی‌های فروشنده جدید را به محض در دسترس قرار گرفتن سخت‌افزار و دستگاه‌های جدید آزمایش کنند.