الواجهات والحزم

تم إنشاء HIDL حول الواجهات، وهي نوع تجريدي يُستخدم في الاتجاهات اللغات لتحديد السلوكيات. تعتبر كل واجهة جزءًا من حزمة.

الطرود

يمكن أن تحتوي أسماء الحِزم على مستويات فرعية مثل package.subpackage. تشير رسالة الأشكال البيانية الدليل الجذري لحِزم HIDL المنشورة هو hardware/interfaces. أو vendor/vendorName (مثلاً، vendor/google لهواتف Pixel الأجهزة). يشكّل اسم الحزمة دليلاً فرعيًا واحدًا أو أكثر ضمن الجذر. directory; جميع الملفات التي تحدد حزمة موجودة في الدليل نفسه. على سبيل المثال: يمكن العثور على جهاز "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 في Java). تستخدم واجهة IBase بشكل ضمني المستوردة، حيث تعلن عن العديد من الطرق المحجوزة التي يجب إعادة الإفصاح عنها في واجهات من تحديد المستخدم أو استخدامها بطريقة أخرى. هذه الطرق تشمل:

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

عملية الاستيراد

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

  • كيان الاستيرادing الذي يمكن أن يكون حزمة أو واحدة
  • الكيان المستورَد، الذي يمكن أن يكون حزمة أو واحدة

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

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

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

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

  • معرّفات UDT الشائعة للحزمة المستورَدة والمحددة في 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

اكتساب الأذونات من الواجهة

يمكن أن تكون الواجهة امتدادًا لواجهة سبق تحديدها. يمكن أن تكون الإضافات واحدة من الأنواع الثلاثة التالية:

  • يمكن أن تضيف الواجهة وظائف إلى واجهة أخرى، تدمج واجهة برمجة التطبيقات الخاصة بها دون تغيير.
  • يمكن للحزمة إضافة وظائف إلى حزمة أخرى، لدمج واجهة برمجة التطبيقات الخاصة بها دون تغيير.
  • يمكن للواجهة استيراد أنواع من حزمة أو من واجهة محددة.

يمكن للواجهة توسيع واجهة واحدة أخرى فقط (بدون اكتساب متعدد). يجب أن تُوسع كل واجهة في حزمة لها رقم إصدار ثانوي غير صفري واجهة المستخدم في الإصدار السابق من الحزمة. على سبيل المثال، إذا كانت هناك واجهة تستند IBar في الإصدار 4.0 من الحزمة derivative إلى (يوسّع) الواجهة IFoo في الإصدار 1.2 من الحزمة original، والإصدار 1.3 من الحزمة original هو تم الإنشاء، لا يمكن للإصدار 4.1 من IBar تمديد الإصدار 1.3 من IFoo بدلاً من ذلك، يجب تمديد الإصدار 4.1 من IBar الإصدار 4.0 من IBar، والمرتبط بالإصدار 1.2 من IFoo يمكن للإصدار 5.0 من IBar أن يعمل على تمديد الإصدار 1.3 من IFoo في حال ما يريده.

لا تشير إضافات الواجهة إلى الاعتماد على المكتبة أو تضمين HAL متعدد العناصر. في التعليمة البرمجية التي تم إنشاؤها، فإنها ببساطة تستورد بنية البيانات وطريقتها على مستوى HIDL. يجب تنفيذ كل طريقة في HAL في 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. مثال: واجهة 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

من الناحية العملية، يُنصح باستخدام هذا المنتج للمورّد أو المصنّع الأصلي للجهاز الذي يحمل الاسم 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 (تتم مناقشة هذا الأمر بشكل مكثف في التجزئة باستخدام hidl-gen).

تعمل الواجهات بشكل مستقل عن الأجهزة المواقع الجغرافية

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