يتطلب HIDL إصدار نُسخ من كل واجهة مكتوبة بـ HIDL. بعد HAL نشر واجهة المستخدم، وتم تجميدها، ويجب إجراء أي تغييرات أخرى على بإصدار جديد من تلك الواجهة. وعلى الرغم من أنه لا يمكن ربط واجهة منشورة يمكن توسيعه باستخدام واجهة أخرى.
بنية رمز HIDL
يتم تنظيم رمز HIDL في صورة يحددها المستخدم الأنواع والواجهات والحزم:
- الأنواع من تحديد المستخدم (UDTs): يوفر HIDL الوصول إلى مجموعة من أنواع البيانات الأولية التي يمكن استخدامها لإنشاء أنواع أكثر تعقيدًا من خلال الهياكل والاتحادات والتعدادات. يتم تمرير رموز UDT إلى طرق ويمكن تحديدها على مستوى الحزمة (شائعة لجميع الواجهات) أو محليًا على إحدى الواجهات.
- الواجهات: وهي وحدة أساسية في HIDL، وهي واجهة من UDT وإعلانات الطريقة. يمكن أن تكتسب الواجهات أيضًا من واجهة أخرى.
- الحِزم: تنظِّم واجهات HIDL ذات الصلة والبيانات.
في الأنواع التي تعمل عليها. يتم تحديد الحزمة بواسطة اسم وإصدار
ما يلي:
- ملف تعريف من نوع بيانات باسم
types.hal
. - لا تتوفّر واجهات أو أكثر، كلٌّ منها في ملف
.hal
الخاص بها.
- ملف تعريف من نوع بيانات باسم
يحتوي ملف تعريف نوع البيانات types.hal
على الأحرف UDT فقط (جميع
UDT على مستوى الحزمة في ملف واحد). التمثيلات في الهدف
متاحة لجميع الواجهات في الحزمة.
فلسفة تحديد الإصدارات
حزمة HIDL (مثل android.hardware.nfc
)، بعد أن يتم
منشور لنسخة معيَّنة (مثل 1.0
)، غير قابل للتغيير. هو/هي
ولا يمكن تغييره. التعديلات على الواجهات في الحزمة أو أي
لا يمكن أن تحدث التغييرات في المعرِّفات الموحدة (UDT) إلا في حزمة أخرى.
في HIDL، ينطبق تحديد الإصدارات على مستوى الحزمة، وليس على مستوى الواجهة، وجميع الواجهات والواجهات UDT في الحزمة تشترك في الإصدار نفسه. طرد تتبع النُسخ الدلالية الإصدارات بدون مستوى التصحيح ومكوّنات البيانات الوصفية للإصدار. في حزمة معينة، يشير الاصطدام الثانوي إلى الإصدار الجديد من تتوافق الحزمة مع الإصدارات القديمة مع الحزمة القديمة و الإصدار من الاصطدام إلى أن الإصدار الجديد من الحزمة ليس التوافق مع الإصدارات القديمة مع الحزمة القديمة.
من الناحية النظرية، يمكن أن ترتبط الحزمة بحزمة أخرى بإحدى الطرق التالية:
- على الإطلاق:
- قابلية التوسّع المتوافقة مع الإصدارات القديمة على مستوى الحزمة: هذا النمط
يحدث في عمليات الأعلى الجديدة ذات الإصدار الثانوي (المراجعة اللاحقة) لحزمة؛
فإن الحزمة الجديدة لها نفس الاسم وإصدار رئيسي كالحزمة القديمة، ولكن
رقم الإصدار الثانوي الأعلى. من الناحية الوظيفية، تعد الحزمة الجديدة أفضل من الحزمة القديمة
حزمة، المعنى:
- توجد واجهات ذات مستوى أعلى للحزمة الرئيسية في الحزمة الجديدة،
على الرغم من أن الواجهات قد تتضمن طرقًا جديدة، إلا أن UDT الجديدة المحلية للواجهة (
امتداد على مستوى الواجهة الموضح أدناه)، وواجهات UDT جديدة في
types.hal
- يمكن أيضًا إضافة واجهات جديدة إلى الحزمة الجديدة.
- جميع أنواع البيانات الخاصة بالحزمة الرئيسية موجودة في الحزمة الجديدة يمكن التعامل معها من خلال الطرق (التي ربما أعيد تنفيذها) من الحزمة القديمة.
- يمكن أيضًا إضافة أنواع بيانات جديدة لاستخدامها من خلال أي من الطريقتين الجديدتين لتحسين الأداء. الواجهات الحالية أو حسب الواجهات الجديدة.
- توجد واجهات ذات مستوى أعلى للحزمة الرئيسية في الحزمة الجديدة،
على الرغم من أن الواجهات قد تتضمن طرقًا جديدة، إلا أن UDT الجديدة المحلية للواجهة (
امتداد على مستوى الواجهة الموضح أدناه)، وواجهات UDT جديدة في
- قابلية التوسّع المتوافقة مع الإصدارات القديمة على مستوى الواجهة:
يمكن أيضًا لحزمة توسيع الحزمة الأصلية أن تتكون من وحدات منفصلة منطقيًا
الواجهات التي توفّر ببساطة وظائف إضافية، وليس الوظائف الأساسية
لهذا الغرض، قد يكون ما يلي مرغوبًا فيه:
- تلجأ الواجهات في الحزمة الجديدة إلى أنواع بيانات طرد.
- يمكن أن تعمل الواجهات في الحزمة الجديدة على تمديد الواجهات القديمة لواحد أو أكثر حزم.
- توسيع نطاق عدم التوافق الأصلي مع الأنظمة القديمة. هذا هو وارتفاع الإصدار الرئيسي للحزمة، وليست هناك حاجة إلى أي ارتباط بين الاثنين. وبقدر ما يوجد، يمكن التعبير عنه بمجموعة من من الإصدار الأقدم للحزمة، واكتساب مجموعة فرعية من وواجهات الحزمة القديمة.
هيكلة الواجهة
للحصول على واجهة منظمة بشكل جيد، يمكن إضافة أنواع جديدة من الوظائف ليست جزءًا من التصميم الأصلي يجب أن تتطلب تعديلاً لرخصة HIDL من واجهة pyplot. وعلى العكس، إذا كنت تستطيع أو تتوقع إجراء تغيير من كلا جانبي الواجهة التي تقدّم وظائف جديدة بدون تغيير الواجهة نفسها، فإن الواجهة ليست مهيكلة.
يدعم Treble مكونات النظام والمورِّد التي تم تجميعها بشكل منفصل والتي
vendor.img
على أحد الأجهزة وsystem.img
يمكن
مجمعة بشكل منفصل. كل التفاعلات بين vendor.img
و
يجب تحديد system.img
بشكل صريح ودقيق حتى تتمكّن من
واستمروا في العمل لسنوات عديدة. ويشمل ذلك العديد من مساحات عرض واجهة برمجة التطبيقات، ولكن
هو آلية IPC التي يستخدمها HIDL للاتصال البيني للعمليات على
الحد system.img
/vendor.img
المتطلبات
يجب تحديد جميع البيانات التي يتم تمريرها من خلال HIDL بشكل صريح. لضمان والتنفيذ والعميل من مواصلة العمل معًا حتى عند تجميع بشكل منفصل أو إذا تم تطويره بشكل مستقل، فيجب أن تلتزم البيانات بما يلي المتطلبات:
- يمكن وصفها في HIDL مباشرةً (باستخدام تعدادات structs، وما إلى ذلك) مع والأسماء الدلالية والمعنى.
- يمكن وصفه وفقًا لمعيار عام مثل ISO/IEC 7816.
- يمكن وصفه بواسطة تخطيط الأجهزة القياسية أو الفعلية.
- يمكن أن تكون بيانات مبهمة (مثل المفاتيح العامة وأرقام التعريف وما إلى ذلك) إذا لزم الأمر.
في حال استخدام بيانات مبهمة، يجب قراءتها فقط على جانب واحد من شهادة HIDL
من واجهة pyplot. على سبيل المثال، إذا أعطى الرمز vendor.img
مكوّنًا على
system.img
رسالة سلسلة أو vec<uint8_t>
البيانات التي لا يمكن تحليلها باستخدام system.img
نفسه مُمْكِنْ
يتم إرسالها مرة أخرى إلى vendor.img
فقط لتفسيرها. متى
تمرير قيمة من vendor.img
إلى رمز البائع في
system.img
أو إلى جهاز آخر، تنسيق البيانات وكيفية ذلك
إلى أن يُفسَّر يجب وصفه بدقة ويظل جزءًا من
من واجهة pyplot.
الإرشادات
ينبغي أن تكون قادرًا على كتابة تنفيذ أو عميل لـ HAL باستخدام ملفات .hal (أي لن تحتاج إلى إلقاء نظرة على مصدر Android أو إلى والمعايير القياسية). ننصح بتحديد السلوك المطلوب بدقة. عبارات مثل لأنّ "التطبيق قد يكون A أو B" بتشجيع عمليات التنفيذ لتصبح متشابكة مع العملاء الذين تم تطويرهم معهم.
تنسيق رمز HIDL
تشمل HIDL الحزم الأساسية وحزم البائع.
واجهات HIDL الأساسية هي تلك التي تحدّدها Google. الطرود التي ينتمي إليها
التي تبدأ بـ android.hardware.
وتسميتها من قبل النظام الفرعي،
مع مستويات متداخلة من التسمية. على سبيل المثال، تتم تسمية حزمة NFC
android.hardware.nfc
وحزمة الكاميرا هي
android.hardware.camera
بشكل عام، الحزمة الأساسية لها اسم
android.hardware.
[name1
].[name2
]...
حزم HIDL لها إصدار بالإضافة إلى اسمها. على سبيل المثال، تتضمن الحزمة
قد يكون الإصدار android.hardware.camera
متوفرًا في الإصدار 3.4
. هذا هو
مهم، حيث يؤثر إصدار الحزمة في موضعها في شجرة المصدر.
يتم وضع جميع الحِزم الأساسية ضمن hardware/interfaces/
في
نظام التصميم. الطرد
android.hardware.
[name1
].[name2
]...
في الإصدار $m.$n
أقل من
hardware/interfaces/name1/name2/
.../$m.$n/
؛ طرد
الإصدار 3.4
من android.hardware.camera
متوفّر في الدليل.
hardware/interfaces/camera/3.4/.
يوجد تعيين غير قابل للتغيير
بين بادئة الحزمة android.hardware.
والمسار
hardware/interfaces/
.
الحزم غير الأساسية (المورِّدون) هي تلك التي ينتجها مورّد المنظومة على الرقاقة (SoC) أو ODM. تشير رسالة الأشكال البيانية
للحزم غير الأساسية هي بادئة vendor.$(VENDOR).hardware.
حيث
$(VENDOR)
تشير إلى مورّد منظومة على الرقاقة (SoC) أو المصنّع الأصلي للجهاز أو المصنّع الأصلي للجهاز. يؤدي هذا إلى ربط المسار
vendor/$(VENDOR)/interfaces
في الشجرة (عملية الربط هذه أيضًا
غير قابل للتغيير).
أسماء أنواع محدّدة من قِبل المستخدم مؤهلة بالكامل
في HIDL، يكون لكل UDT اسم مؤهل بالكامل يتكون من اسم UDT،
اسم الحزمة حيث يتم تعريف UDT وإصدار الحزمة. تشير رسالة الأشكال البيانية
لا يتم استخدام اسم مؤهل بالكامل إلا عندما يتم الإعلان عن الحالات من النوع
وليس حيث يتم تعريف النوع نفسه. على سبيل المثال، لنفترض أن الحزمة
تحدِّد النسخة 1.0
من android.hardware.nfc,
بنية.
باسم NfcData
. في موقع البيان (سواء في
types.hal
أو ضمن بيان واجهة)، فإن البيان
ينص ببساطة على:
struct NfcData { vec<uint8_t> data; };
عند الإعلان عن مثيل من هذا النوع (سواء داخل بنية بيانات أو كمعلمة طريقة)، فاستخدم اسم النوع المؤهل بالكامل:
android.hardware.nfc@1.0::NfcData
الصيغة العامة هي
PACKAGE@VERSION::UDT
، حيث:
PACKAGE
هو الاسم المفصول بالنقاط لحزمة HIDL. (مثال:android.hardware.nfc
).VERSION
هو الإصدارMajor.minor-version المفصول بالنقاط تنسيق الحزمة (على سبيل المثال،1.0
).UDT
هو الاسم المفصول بالنقاط لـ HIDL UDT. نظرًا لأن HIDL تدعم واجهات UDT وHIDL المدمجة، يمكن أن تحتوي على UDT (نوع من إعلان متداخل)، تُستخدم النقاط للوصول إلى الأسماء.
على سبيل المثال، إذا تم تحديد التعريف المتداخل التالي في علامة
أنواع الملف في إصدار الحزمة android.hardware.example
1.0
:
// types.hal package android.hardware.example@1.0; struct Foo { struct Bar { // … }; Bar cheers; };
اسم Bar
المؤهل بالكامل هو
android.hardware.example@1.0::Foo.Bar
إذا، بالإضافة إلى التواجد في
للحزمة أعلاه، كان الإعلان المتداخل في واجهة تسمى
IQuux
:
// IQuux.hal package android.hardware.example@1.0; interface IQuux { struct Foo { struct Bar { // … }; Bar cheers; }; doSomething(Foo f) generates (Foo.Bar fb); };
اسم Bar
المؤهل بالكامل هو
android.hardware.example@1.0::IQuux.Foo.Bar
وفي كلتا الحالتين، يمكن الإشارة إلى Bar
على أنّه Bar
فقط.
في نطاق بيان Foo
في الطرد أو
مستوى الواجهة، يجب الرجوع إلى Bar
من خلال Foo
:
Foo.Bar
، كما في إعلان الطريقة doSomething
أعلاه. بدلاً من ذلك، يمكنك الإعلان عن الطريقة بشكل مطول على النحو التالي:
// IQuux.hal doSomething(android.hardware.example@1.0::IQuux.Foo f) generates (android.hardware.example@1.0::IQuux.Foo.Bar fb);
قيم تعداد مؤهَّلة بالكامل
إذا كان UDT نوع تعداد، فإن كل قيمة من نوع التعداد يكون لها
اسم مؤهل بالكامل يبدأ بالاسم المؤهل بالكامل لنوع التعداد،
متبوعة بعلامة النقطتين، ثم متبوعة باسم قيمة التعداد. على سبيل المثال:
افتراض الحزمة android.hardware.nfc,
الإصدار 1.0
إلى تحديد نوع التعداد NfcStatus
:
enum NfcStatus { STATUS_OK, STATUS_FAILED };
عند الإشارة إلى STATUS_OK
، يكون الاسم المؤهّل بالكامل هو:
android.hardware.nfc@1.0::NfcStatus:STATUS_OK
الصيغة العامة هي
PACKAGE@VERSION::UDT:VALUE
,
حيث:
PACKAGE@VERSION::UDT
هو نفس الاسم المؤهل بالكامل لنوع التعداد.VALUE
هو اسم القيمة.
قواعد الاستنتاج التلقائي
لا يلزم تحديد اسم UDT مؤهل بالكامل. يمكن لاسم UDT احذف ما يلي بأمان:
- الحزمة، مثل
@1.0::IFoo.Type
- كلاً من الحزمة والإصدار، مثلاً
IFoo.Type
يحاول HIDL إكمال الاسم باستخدام قواعد التداخل التلقائي (القاعدة الأدنى الرقم يعني أولوية أعلى).
القاعدة 1
في حال عدم توفير حزمة وإصدار، تتم محاولة البحث عن اسم محلي. مثال:
interface Nfc { typedef string NfcErrorMessage; send(NfcData d) generates (@1.0::NfcStatus s, NfcErrorMessage m); };
تم البحث عن NfcErrorMessage
محليًا وtypedef
فوقه. تم البحث عن NfcData
أيضًا محليًا، ولكن كما هو
غير محدد محليًا، يتم استخدام القاعدة 2 و3. @1.0::NfcStatus
نسخة، لذا لا تنطبق القاعدة 1.
القاعدة 2
في حال فشل القاعدة 1 وفقدان أحد مكونات الاسم المؤهل بالكامل
(الحزمة أو الإصدار أو الحزمة والإصدار)، يتم ملء المكون تلقائيًا
ومعلومات من الحزمة الحالية. ثم يبحث محول HIDL في
الملف الحالي (وجميع عمليات الاستيراد) للعثور على الاسم المؤهّل بالكامل الذي تم ملؤه تلقائيًا.
باستخدام المثال أعلاه، يجب افتراض أنّ بيان ExtendedNfcData
تم التحويل في نفس الطرد (android.hardware.nfc
)
الإصدار (1.0
) على النحو التالي: NfcData
:
struct ExtendedNfcData { NfcData base; // … additional members };
يملأ المحول البرمجي لـ HIDL اسم الحزمة واسم الإصدار من
الحزمة الحالية لإنتاج اسم UDT المؤهل بالكامل
android.hardware.nfc@1.0::NfcData
ونظرًا لأن الاسم موجود في
الحزمة الحالية (على افتراض استيرادها بشكل صحيح)، فسيتم استخدامها
.
يتم استيراد اسم في الحزمة الحالية فقط إذا كان أي مما يلي: صواب:
- ويتم استيرادها بشكل صريح باستخدام عبارة
import
. - تم تحديده في
types.hal
في الحزمة الحالية.
يتم اتباع العملية نفسها إذا كان NfcData
مؤهلاً من خلال
رقم الإصدار:
struct ExtendedNfcData { // autofill the current package name (android.hardware.nfc) @1.0::NfcData base; // … additional members };
القاعدة 3
إذا فشلت القاعدة 2 في الحصول على تطابق (لم يتم تحديد UDT في
)، يقوم المحول البرمجي HIDL بالبحث عن تطابق ضمن جميع الحزم المستوردة.
باستخدام المثال أعلاه، لنفترض أنّه قد تم تعريف السمة ExtendedNfcData
في
الإصدار 1.1
من الحزمة android.hardware.nfc
،
تستورد 1.1
1.0
كما يجب (انظر
الإضافات على مستوى الحزمة)، والتعريف
تحدد فقط اسم UDT:
struct ExtendedNfcData { NfcData base; // … additional members };
يبحث المحول البرمجي عن أي UDT يسمى NfcData
ويجد واحدًا في
android.hardware.nfc
في الإصدار 1.0
، ما أدى إلى
UDT مؤهلة بالكامل من android.hardware.nfc@1.0::NfcData
. إذا كانت أكثر
تم العثور على أكثر من مطابقة واحدة لـ UDT مؤهل جزئيًا، وهو برنامج تجميع HIDL
إلى حدوث خطأ.
مثال
باستخدام القاعدة 2، يتم تفضيل نوع مستورد محدد في الحزمة الحالية على نوع تم استيراده من حزمة أخرى:
// hardware/interfaces/foo/1.0/types.hal package android.hardware.foo@1.0; struct S {}; // hardware/interfaces/foo/1.0/IFooCallback.hal package android.hardware.foo@1.0; interface IFooCallback {}; // hardware/interfaces/bar/1.0/types.hal package android.hardware.bar@1.0; typedef string S; // hardware/interfaces/bar/1.0/IFooCallback.hal package android.hardware.bar@1.0; interface IFooCallback {}; // hardware/interfaces/bar/1.0/IBar.hal package android.hardware.bar@1.0; import android.hardware.foo@1.0; interface IBar { baz1(S s); // android.hardware.bar@1.0::S baz2(IFooCallback s); // android.hardware.foo@1.0::IFooCallback };
- يتم استيفاء
S
كـandroid.hardware.bar@1.0::S
، وهي متوفرة فيbar/1.0/types.hal
(لأنّtypes.hal
يتم تلقائيًا ). - يتم استيفاء
IFooCallback
كـandroid.hardware.bar@1.0::IFooCallback
باستخدام القاعدة 2، لكنها لا يمكن العثور عليه لأنه لم يتم استيرادbar/1.0/IFooCallback.hal
تلقائيًا (كما هوtypes.hal
). وبالتالي، تحل القاعدة 3android.hardware.foo@1.0::IFooCallback
بدلاً من ذلك، والتي تم استيرادها عبرimport android.hardware.foo@1.0;
).
type.hal
تحتوي كل حزمة HIDL على ملف types.hal
يحتوي على أرقام UDT.
التي تتم مشاركتها بين جميع الواجهات المشاركة في الحزمة. أنواع HIDL
تكون دائمًا عامة؛ بغض النظر عما إذا تم الإعلان عن UDT في
types.hal
أو ضمن بيان واجهة، تكون هذه الأنواع
ويمكن الوصول إليها خارج النطاق الذي تم تعريفها فيه. types.hal
لا يعني وصف واجهة برمجة التطبيقات العامة للحزمة، بل لاستضافة لغات UDT
تستخدمها جميع الواجهات ضمن الحزمة. نظرًا لطبيعة HIDL، يمكن لجميع
تشكل جزءًا من الواجهة.
تتكوّن الدالة types.hal
من عبارتَي UDT وimport
.
بما أنّ types.hal
متاحة لكل واجهة من
حزمة (استيراد ضمني)، تكون عبارات import
هذه
على مستوى الحزمة حسب التعريف. يمكن أيضًا أن تتضمّن الأسماء الموجّهة (UDT) في types.hal
واجهات UDT والواجهات التي تم استيرادها.
على سبيل المثال، لـ IFoo.hal
:
package android.hardware.foo@1.0; // whole package import import android.hardware.bar@1.0; // types only import import android.hardware.baz@1.0::types; // partial imports import android.hardware.qux@1.0::IQux.Quux; // partial imports import android.hardware.quuz@1.0::Quuz;
يتم استيراد ما يلي:
android.hidl.base@1.0::IBase
(ضمنيًا)android.hardware.foo@1.0::types
(ضمنيًا)- كل شيء في
android.hardware.bar@1.0
(بما في ذلك الكل الواجهات وtypes.hal
) types.hal
منandroid.hardware.baz@1.0::types
(لا يتم استيراد الواجهات فيandroid.hardware.baz@1.0
)IQux.hal
وtypes.hal
منandroid.hardware.qux@1.0
Quuz
منandroid.hardware.quuz@1.0
(بافتراض يتم تحديدQuuz
فيtypes.hal
، حيث تم تحليل ملفtypes.hal
، ولكن بأنواع أخرى غيرQuuz
. ).
تحديد الإصدارات على مستوى الواجهة
تكمن كل واجهة ضمن الحزمة في ملفها الخاص. حزمة
التي تنتمي إليها هذه الواجهة في أعلى الواجهة باستخدام
عبارة package
. بعد بيان الحزمة، صفر أو أكثر
قد يتم سرد عمليات استيراد على مستوى الواجهة (حزمة جزئية أو كاملة). مثلاً:
package android.hardware.nfc@1.0;
في HIDL، يمكن أن تكتسب الواجهات من الواجهات الأخرى باستخدام
كلمة رئيسية واحدة (extends
). لكي تقوم الواجهة بتوسيع واجهة أخرى،
يجب أن يكون لدى المستخدم إذن بالوصول إليها من خلال عبارة import
. اسم
الواجهة التي يتم توسيعها (الواجهة الأساسية) يتبع القواعد الخاصة بـ type-name
أو مؤهلات الشركة المذكورة أعلاه. لا يجوز أن تكتسِب الواجهة إلّا من واجهة واحدة.
لا يدعم HIDL الوراثة المتعددة.
تستخدم أمثلة الترقية أدناه الحزمة التالية:
// types.hal package android.hardware.example@1.0 struct Foo { struct Bar { vec<uint32_t> val; }; }; // IQuux.hal package android.hardware.example@1.0 interface IQuux { fromFooToBar(Foo f) generates (Foo.Bar b); }
قواعد Uprev
لتعريف حزمة package@major.minor
، تكون إما A أو كل B
يجب أن تكون true:
القاعدة أ | "هو إصدار ثانوي للبداية": جميع الإصدارات الثانوية السابقة
"package@major.0 " و"package@major.1 " و...،
يجب عدم تحديد package@major.(minor-1) .
|
---|
القاعدة "ب" | ينطبق كل ما يلي:
|
---|
بسبب القاعدة "أ":
- يمكن أن تبدأ الحزمة بأي رقم إصدار ثانوي (على سبيل المثال،
android.hardware.biometrics.fingerprint
يبدأ في@2.1
). - الشرط "
android.hardware.foo@1.0
غير محدّد" يعني فيجب ألا يكون الدليلhardware/interfaces/foo/1.0
موجودًا أصلاً.
ومع ذلك، لا تؤثر القاعدة A على حزمة لها نفس اسم الحزمة ولكن
إصدار رئيسي مختلف (على سبيل المثال،
android.hardware.camera.device
تحتوي على كل من @1.0
تم تحديد @3.2
؛ لا يحتاج "@3.2
" إلى التفاعل مع.
@1.0
.) وبالتالي، يمكن لـ @3.2::IExtFoo
تمديد
@1.0::IFoo
شريطة أن يكون اسم الحزمة مختلفًا،
يمكن توسيع نطاق package@major.minor::IBar
من واجهة ذات
اسم مختلف (على سبيل المثال، android.hardware.bar@1.0::IBar
يمكن
التمديد android.hardware.baz@2.2::IBaz
). إذا لم تكن هناك واجهة
أن تعلن بشكلٍ صريح عن نوع فائق باستخدام الكلمة الرئيسية extend
، فإنه
يمتد إلى android.hidl.base@1.0::IBase
(باستثناء IBase
نفسها).
يجب اتباع B.2 وB.3 في نفس الوقت. على سبيل المثال، حتى إذا
تمديدات "android.hardware.foo@1.1::IFoo
"
android.hardware.foo@1.0::IFoo
لتمرير القاعدة B.2، إذا كانت
امتداد android.hardware.foo@1.1::IExtBar
android.hardware.foo@1.0::IBar
، لا تزال هذه الزيادة غير صالحة.
واجهات Uprev
لرفع قيمة android.hardware.example@1.0
(الموضحة أعلاه) إلى
@1.1
:
// types.hal package android.hardware.example@1.1; import android.hardware.example@1.0; // IQuux.hal package android.hardware.example@1.1 interface IQuux extends @1.0::IQuux { fromBarToFoo(Foo.Bar b) generates (Foo f); }
هذا import
على مستوى الحزمة من الإصدار "1.0
" من
android.hardware.example
في types.hal
. بدون إضافة معلومات جديدة
تمت إضافة الأحرف UDT في الإصدار 1.1
من الحزمة، ويشير هذا المصطلح إلى الأحرف UDT في
لا تزال هناك حاجة إلى الإصدار 1.0
، وبالتالي يجب إجراء الاستيراد على مستوى الحزمة
في types.hal
. (كان من الممكن تحقيق نفس التأثير باستخدام
استيراد على مستوى الواجهة في IQuux.hal
).
في extends @1.0::IQuux
في بيان
IQuux
، حدّدنا إصدار IQuux
الذي يجري استخدامه
مكتسب (يجب توضيح الغموض نظرًا لاستخدام IQuux
إعلان واجهة واكتسابها من واجهة). نظرًا لأن التعريفات هي
أسماءً تكتسب جميع سمات الحزمة والإصدار على موقع الويب
يجب أن يكون التوضيح في اسم الواجهة الأساسية. نحن
كان بإمكان المستخدم استخدام لغة UDT المؤهلة بالكامل أيضًا، ولكن كان من الممكن
متكرر.
لم تعرض الواجهة الجديدة IQuux
طريقة إعادة تعريف
fromFooToBar()
المكتسَب من @1.0::IQuux
ببساطة
الطريقة الجديدة التي تتم إضافتها fromBarToFoo()
. مُكتسَب في HIDL
لا يمكن تعريفها مرة أخرى في الواجهات الفرعية، لذا
لا يمكن لواجهة IQuux
الإعلان عن fromFooToBar()
بشكل صريح.
اصطلاحات Uprev
في بعض الأحيان، يجب أن تعيد أسماء الواجهات تسمية الواجهة الموسّعة. ننصحك بما يلي: أن إضافات التعداد والتركيبات والاتحادات تحمل الاسم نفسه الذي تُوسِّعه ما لم تكن مختلفة بما يكفي لتبرير اسم جديد. أمثلة:
// in parent hal file enum Brightness : uint32_t { NONE, WHITE }; // in child hal file extending the existing set with additional similar values enum Brightness : @1.0::Brightness { AUTOMATIC }; // extending the existing set with values that require a new, more descriptive name: enum Color : @1.0::Brightness { HW_GREEN, RAINBOW };
فإذا كان لإحدى الطرق اسم دلالي جديد (على سبيل المثال،
fooWithLocation
) إذًا هو الخيار المفضّل. بخلاف ذلك، يجب أن يكون
على غرار ما يمده. على سبيل المثال، الطريقة
يمكن استخدام foo_1_1
في @1.1::IFoo
بدلاً من الوظيفة
من طريقة foo
في @1.0::IFoo
إذا لم تكن هناك طريقة
اسم بديل.
تحديد الإصدارات على مستوى الحزمة
يحدث إصدار HIDL على مستوى الحزمة؛ بعد نشر الحزمة، فإنه غير قابل للتغيير (لا يمكن تغيير مجموعة واجهاته ولا يمكن تغيير UDT). يمكن للحزم وترتبط ببعضها البعض بعدة طرق، وكلها يمكن التعبير عنها من خلال الجمع بين التوريث على مستوى الواجهة وإنشاء معرّفات UDT حسب التركيب.
ومع ذلك، هناك نوع واحد من العلاقات محدد بدقة ويجب تنفيذه: اكتساب متوافق مع الإصدارات القديمة على مستوى الحزمة: في هذا السيناريو، الحزمة parent هي الحزمة التي يتم اكتسابها منها حزمة child هي التي تُوسّع نطاق العنصر الرئيسي. على مستوى الحزمة تكون قواعد الاكتساب المتوافقة مع الإصدارات القديمة على النحو التالي:
- يتم اكتساب جميع واجهات المستوى الأعلى للحزمة الرئيسية من الواجهات في حزمة فرعية.
- يمكن أيضًا إضافة الواجهات الجديدة إلى الحزمة الجديدة (لا توجد قيود حول العلاقات بالواجهات الأخرى في الحزم الأخرى).
- يمكن أيضًا إضافة أنواع بيانات جديدة لاستخدامها من خلال أي من الطريقتين الجديدتين لتحسين الأداء. الواجهات الحالية أو حسب الواجهات الجديدة.
يمكن تنفيذ هذه القواعد باستخدام الاكتساب على مستوى واجهة HIDL لكنّها تتطلب معرفة على مستوى البيانات الوصفية للتعرّف على هذه العلاقات لتشكيل امتداد حزمة متوافق مع الإصدارات القديمة. يتم استنتاج هذه المعلومات. على النحو التالي:
في حال استيفاء الحزمة هذا الشرط، يتم فرض سياسة hidl-gen
.
قواعد التوافق مع الأنظمة القديمة.