واجهات وأمبير. الحزم

تم بناء 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/* هال
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 في Java.) تعلن واجهة IBase، المستوردة ضمنيًا، عن العديد من الأساليب المحجوزة التي لا ينبغي ولا يمكن إعادة تعريفها في الواجهات المعرفة من قبل المستخدم أو استخدامها بطريقة أخرى. وتشمل هذه الأساليب:

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

استيراد

بيان import هو آلية HIDL للوصول إلى واجهات الحزمة وأنواعها في حزمة أخرى. بيان import يتعلق بكيانين:

  • كيان الاستيراد ، والذي يمكن أن يكون إما حزمة أو واجهة؛ و
  • كيان الاستيراد ، والذي يمكن أيضًا أن يكون حزمة أو واجهة.

يتم تحديد الكيان المستورد حسب موقع بيان import . عندما تكون العبارة داخل حزمة types.hal ، فإن ما يتم استيراده يكون مرئيًا للحزمة بأكملها؛ هذا استيراد على مستوى الحزمة . عندما تكون العبارة داخل ملف واجهة، فإن الكيان المستورد هو الواجهة نفسها؛ هذا استيراد على مستوى الواجهة .

يتم تحديد الكيان المستورد بالقيمة التي تلي الكلمة الأساسية import . لا يلزم أن تكون القيمة اسمًا مؤهلاً بالكامل؛ إذا تم حذف أحد المكونات، فسيتم ملؤه تلقائيًا بالمعلومات من الحزمة الحالية. بالنسبة للقيم المؤهلة بالكامل، يتم دعم حالات الاستيراد التالية:

  • واردات الحزمة الكاملة . إذا كانت القيمة عبارة عن اسم حزمة وإصدار (بناء الجملة الموضح أدناه)، فسيتم استيراد الحزمة بأكملها إلى الكيان المستورد.
  • الواردات الجزئية إذا كانت القيمة:
    • يتم استيراد الواجهة types.hal الحزمة.hal وتلك الواجهة إلى الكيان المستورد.
    • UDT المحدد في types.hal ، عندها فقط يتم استيراد UDT إلى الكيان المستورد (لا يتم استيراد الأنواع الأخرى في types.hal ).
  • أنواع الواردات فقط . إذا كانت القيمة تستخدم بناء جملة الاستيراد الجزئي الموضح أعلاه، ولكن مع types الكلمات الأساسية بدلاً من اسم الواجهة، فسيتم استيراد UDTs الموجودة في types.hal للحزمة المعينة فقط.

يحصل الكيان المستورد على حق الوصول إلى مجموعة من:

  • UDTs الشائعة للحزمة المستوردة والمحددة في types.hal ؛
  • واجهات الحزمة المستوردة (لاستيراد الحزمة الكاملة) أو الواجهة المحددة (للاستيراد الجزئي) لأغراض استدعائها وتمرير المقابض إليها و/أو الوراثة منها.

تستخدم عبارة الاستيراد صيغة اسم النوع المؤهل بالكامل لتوفير اسم وإصدار الحزمة أو الواجهة التي يتم استيرادها:

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 . بدلاً من ذلك، يجب أن يقوم الإصدار 4.1 IBar بتوسيع الإصدار 4.0 IBar ، المرتبط بـ IFoo الإصدار 1.2. يمكن أن يقوم الإصدار 5.0 IBar بتوسيع الإصدار 1.3 من IFoo ، إذا رغبت في ذلك.

لا تعني امتدادات الواجهة اعتماد المكتبة أو تضمين HAL المتقاطع في التعليمات البرمجية التي تم إنشاؤها - فهي ببساطة تستورد بنية البيانات وتعريفات الأسلوب على مستوى HIDL. يجب تنفيذ كل أسلوب في طبقة تجريد سطح الأرض (HAL) في ذلك الجزء.

امتدادات البائع

في بعض الحالات، سيتم تنفيذ ملحقات البائعين كفئة فرعية للكائن الأساسي الذي يمثل الواجهة الأساسية التي يقومون بتوسيعها. سيتم تسجيل نفس الكائن تحت اسم HAL الأساسي وإصداره، وتحت اسم HAL (البائع) وإصداره.

الإصدار

يتم إصدار الحزم، وتحتوي الواجهات على إصدار الحزمة الخاصة بها. يتم التعبير عن الإصدارات في عددين صحيحين، رئيسي . صغير .

  • الإصدارات الرئيسية غير متوافقة مع الإصدارات السابقة. تؤدي زيادة رقم الإصدار الرئيسي إلى إعادة تعيين رقم الإصدار الثانوي إلى 0.
  • الإصدارات الثانوية متوافقة مع الإصدارات السابقة. تشير زيادة الرقم الثانوي إلى أن الإصدار الأحدث متوافق تمامًا مع الإصدار السابق. يمكن إضافة بنيات وأساليب بيانات جديدة، ولكن لا يجوز تغيير أي بنيات بيانات أو توقيعات أسلوب موجودة.

يمكن أن تكون هناك إصدارات رئيسية أو ثانوية متعددة من HAL موجودة على الجهاز في وقت واحد. ومع ذلك، يجب تفضيل الإصدار الثانوي على الإصدار الرئيسي لأن تعليمات برمجية العميل التي تعمل مع واجهة الإصدار الثانوي السابقة ستعمل أيضًا مع الإصدارات الثانوية الأحدث من نفس الواجهة. للحصول على مزيد من التفاصيل حول إصدار الإصدارات وملحقات الموردين، راجع إصدار HIDL .

ملخص تخطيط الواجهة

يلخص هذا القسم كيفية إدارة حزمة واجهة HIDL (مثل hardware/interfaces ) ويدمج المعلومات المقدمة في قسم HIDL. قبل القراءة، تأكد من أنك على دراية بإصدار HIDL ، ومفاهيم التجزئة في التجزئة باستخدام hidl-gen ، وتفاصيل العمل مع HIDL بشكل عام ، والتعريفات التالية:

شرط تعريف
واجهة التطبيق الثنائية (ABI) واجهة برمجة التطبيقات + أي روابط ثنائية مطلوبة.
الاسم المؤهل بالكامل (fqName) اسم لتمييز نوع hidl. مثال: android.hardware.foo@1.0::IFoo .
طَرد حزمة تحتوي على واجهة HIDL وأنواعها. مثال: android.hardware.foo@1.0 .
جذر الحزمة الحزمة الجذرية التي تحتوي على واجهات HIDL. مثال: واجهة android.hardware لـ HIDL موجودة في جذر الحزمة 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 .

من الناحية العملية، من المستحسن أن يقوم البائع أو صانع المعدات الأصلية المسمى 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 with hidl-gen ).

تنتقل الواجهات إلى مواقع مستقلة عن الجهاز

ومن الناحية العملية، يوصى بمشاركة الواجهات بين الفروع. يسمح ذلك بأقصى قدر من إعادة استخدام التعليمات البرمجية والحد الأقصى من اختبار التعليمات البرمجية عبر الأجهزة وحالات الاستخدام المختلفة.