توضّح هذه الصفحة كيفية تسجيل الخدمات واكتشافها وكيفية إرسالها.
نقل البيانات إلى خدمة من خلال استدعاء الطرق المحدّدة في الواجهات في .hal
الملفات.
خدمات التسجيل
يمكن تسجيل خوادم واجهة HIDL (الكائنات التي تنفِّذ الواجهة). كخدمات ذات تسمية. لا يلزم أن يكون الاسم المسجَّل مرتبطًا بالواجهة أو اسم الحزمة. إذا لم يتم تحديد أي اسم، يصبح الاسم "default" استخدام؛ هذا ينبغي تُستخدم لـ HALs التي لا تحتاج إلى تسجيل عمليتين تنفيذيتين من واجهة pyplot. على سبيل المثال، استدعاء C++ لتسجيل الخدمة المحدد في كل هي:
status_t status = myFoo->registerAsService(); status_t anotherStatus = anotherFoo->registerAsService("another_foo_service"); // if needed
وتتضمّن الواجهة نفسها إصدار واجهة HIDL. من المهم
ترتبط تلقائيًا بتسجيل الخدمة ويمكن استردادها عبر
طلب إجراء (android::hardware::IInterface::getInterfaceVersion()
)
على كل واجهة HIDL. لا يُشترَط تسجيل عناصر الخادم ويمكن تمريرها
عبر معلمات طريقة HIDL إلى عملية أخرى تقوم باستدعاء طريقة HIDL
إلى الخادم.
الاطّلاع على الخدمات
يتم تقديم الطلبات حسب رمز العميل لواجهة معيّنة حسب الاسم أو
، مما يؤدي إلى استدعاء getService
لفئة HAL المطلوبة:
// C++ sp<V1_1::IFooService> service = V1_1::IFooService::getService(); sp<V1_1::IFooService> alternateService = V1_1::IFooService::getService("another_foo_service"); // Java V1_1.IFooService service = V1_1.IFooService.getService(true /* retry */); V1_1.IFooService alternateService = V1_1.IFooService.getService("another", true /* retry */);
يتم التعامل مع كل إصدار من واجهة HIDL كواجهة منفصلة. وبالتالي،
الإصدار 1.1 من IFooService
والإصدار 2.2 من IFooService
يمكن تسجيل كل منهما باسم "foo_service" أو
يحصل getService("foo_service")
على أي من الواجهتين على التسجيل
الخاصة بهذه الواجهة. لهذا السبب، لا تحتاج مَعلمات الأسماء في معظم الحالات إلى
أن يتم توفيره للتسجيل أو الاكتشاف (أي الاسم "تلقائي").
كما يلعب كائن واجهة البائع دورًا في طريقة نقل
التي تم إرجاعها. بالنسبة إلى الواجهة IFoo
في الحزمة
android.hardware.foo@1.0
، الواجهة التي تم عرضها بواسطة
تستخدم IFoo::getService
دائمًا طريقة النقل المعرَّفة من أجل
android.hardware.foo
في بيان الجهاز إذا كان الإدخال متوفرًا؛
وإذا لم تكن طريقة النقل متاحة، يتم عرض nullptr.
في بعض الحالات، قد يكون من الضروري المتابعة فورًا حتى بدون
الحصول على الخدمة. يمكن أن يحدث هذا (على سبيل المثال) عندما يريد أحد العملاء
إدارة إشعارات الخدمة نفسها أو في أحد برامج التشخيص (مثل
atrace
) التي تحتاج إلى الحصول على جميع خدمات hwservices واستردادها. ضِمن
في هذه الحالة، يتم توفير واجهات برمجة تطبيقات إضافية مثل tryGetService
في لغة C++ أو
getService("instance-name", false)
في Java. واجهة برمجة التطبيقات القديمة
يجب استخدام getService
المتوفرة في Java أيضًا مع الخدمة
الإشعارات. لا يؤدي استخدام واجهة برمجة التطبيقات هذه إلى تجنُّب حالة السباق التي يفرض فيها الخادم
يقوم بتسجيل نفسه بعد أن يطلب العميل ذلك باستخدام إحدى واجهات برمجة التطبيقات هذه التي لا تحتاج إلى إعادة المحاولة.
إشعارات الوفاة في الخدمة
يمكن للعملاء الذين يريدون تلقّي إشعارات عند وفاة إحدى الخدمات أن يتعرّضوا للموت والإشعارات التي يقدِّمها إطار العمل لتلقي الإشعارات، يرغب العميل يجب:
- فئة فرعية لفئة/واجهة HIDL
hidl_death_recipient
(في C++ التعليمة البرمجية، وليس في HIDL). - إلغاء طريقة
serviceDied()
- إنشاء مثيل كائن من الفئة الفرعية
hidl_death_recipient
. - عليك استدعاء طريقة
linkToDeath()
في الخدمة لمراقبة ما يلي: تمرير كائن واجهةIDeathRecipient
. لاحظ أن هذا لا تأخذ هذه الطريقة ملكية مستلم الوفاة أو الخادم الوكيل الذي البيانات.
مثال على الكود الزائف (C++ وJava متشابهان):
class IMyDeathReceiver : hidl_death_recipient { virtual void serviceDied(uint64_t cookie, wp<IBase>& service) override { log("RIP service %d!", cookie); // Cookie should be 42 } }; .... IMyDeathReceiver deathReceiver = new IMyDeathReceiver(); m_importantService->linkToDeath(deathReceiver, 42);
يمكن تسجيل مستلم الوفاة نفسه في عدة خدمات مختلفة.
نقل البيانات
يمكن إرسال البيانات إلى خدمة من خلال استدعاء الطرق المحدّدة في الواجهات في
ملفان (.hal
). هناك نوعان من الطرق:
- تنتظر طرق الحظر حتى ينشئ الخادم نتيجته.
- ترسل الطرق اتجاه واحد البيانات في اتجاه واحد فقط ولا حظر. في حال تجاوز مقدار البيانات أثناء الطيران في طلبات استدعاء إجراء عن بُعد (RPC) التنفيذ فإن الاتصالات قد تمنع أو تعرض مؤشر خطأ (و غير محدد بعد).
طريقة لا تعرض قيمة ولكن لم يتم تعريفها على أنها
لا يزال تطبيق "oneway
" محظورًا.
يتم استدعاء جميع الطرق المعلنة في واجهة HIDL في اتجاه واحد، إما من HAL أو في HAL. لا تحدد الواجهة الاتجاه الذي يطلق عليه. البُنى التي تحتاج إلى مكالمات تنشأ منها يجب أن توفر قناة HAL واجهتين (أو أكثر) في حزمة HAL وأن تعرض الواجهة المناسبة من كل عملية. يمكن استخدام الكلمتين العميل تُستخدم server في ما يتعلق باتجاه استدعاء الواجهة (على سبيل المثال، يمكن أن يكون HAL خادمًا لواجهة واحدة وعميلًا لواجهة أخرى ).
طلبات معاودة الاتصال
تشير كلمة معاودة الاتصال إلى مفهومين مختلفين، يتم تمييزهما رد الاتصال المتزامن ومعاودة الاتصال غير المتزامنة.
تُستخدم عمليات الاستدعاء المتزامنة في بعض طرق HIDL التي تعرض البيانات. طريقة HIDL التي ترجع أكثر من قيمة واحدة (أو تُرجع قيمة واحدة غير أساسي) نتائجها عبر دالة استدعاء. إذا كانت هناك واحدة فقط وهي نوع أساسي، ولا يتم استخدام استدعاء يتم إرجاعها من الطريقة. ينفذ الخادم طرق HIDL ينفذ العميل عمليات الاستدعاء.
تسمح عمليات الاستدعاء غير المتزامنة لخادم واجهة HIDL
إنشاء المكالمات. ويتم ذلك من خلال تمرير مثيل لواجهة ثانية
من خلال الواجهة الأولى. يجب أن يعمل عميل الواجهة الأولى
الخادم الثاني. يمكن لخادم الواجهة الأولى استدعاء الطرق في
كائن الواجهة الثاني. على سبيل المثال، يمكن أن يؤدي تطبيق HAL إلى إرسال معلومات
بشكل غير متزامن إلى العملية التي تستخدمها عن طريق استدعاء طرق في
واجهة تم إنشاؤها وعرضها من خلال هذه العملية. الطرق في الواجهات المستخدمة
بالنسبة إلى رد الاتصال غير المتزامن الذي قد يكون محظورًا (وقد يعرض القيم للمتصل)
أو oneway
. على سبيل المثال، يُرجى الاطّلاع على "عمليات معاودة الاتصال غير المتزامنة" بوصة
HIDL C++.
لتبسيط ملكية الذاكرة، لا تستغرق عمليات استدعاء الطرق ومعاودة الاتصال سوى
مَعلمات in
ولا تتوافق مع out
أو
مَعلمات inout
الحدود القصوى المسموح بها لكل معاملة
لا يتم فرض حدود لكل معاملة على كمية البيانات المُرسلة في HIDL
والطرق وعمليات معاودة الاتصال. إلا أنه يتم تطبيق المكالمات التي تتجاوز 4 كيلوبايت لكل معاملة
تُعتبر زائدة عن الحد. في حال رصد ذلك، تتم إعادة تصميم واجهة HIDL المحدّدة.
الموصى به. هناك قيد آخر وهو الموارد المتاحة لرخصة HIDL
البنية الأساسية لمعالجة العديد من المعاملات المتزامنة. منتجات
يمكن إجراء المعاملات بشكل متزامن بسبب تعدد سلاسل المحادثات أو
عمليات إرسال استدعاءات إلى عملية أو عدة استدعاءات oneway
لا يتم التعامل معها بسرعة من خلال عملية التلقي. الحدّ الأقصى لإجمالي المساحة
حجم متاح لكل المعاملات المتزامنة هو 1 ميغابايت تلقائيًا.
في الواجهة المصممة جيدًا، لا ينبغي تجاوز هذه القيود على الموارد تحدث؛ وإذا تجاوزها، فيمكن إما حظر المكالمة التي تجاوزتها حتى توفر الموارد أو يشير إلى خطأ في النقل. كل موضع ورود تجاوز الحدود لكل معاملة أو تجاوز موارد تنفيذ شهادة HIDL يتم تسجيل المعاملات المجمَّعة أثناء الطيران لتسهيل تصحيح الأخطاء.
عمليات تنفيذ الطرق
ينشئ HIDL ملفات رأس توضح الأنواع والطرق عمليات الاستدعاء باللغة الهدف (C++ أو Java). النموذج الأولي لـ HIDL والاستدعاءات هي نفسها لكل من رمز العميل والخادم. أغنية HIDL عمليات تنفيذ خادم وكيل للطرق على جانب المتصل الذي ينظّم البيانات الخاصة بنقل IPC والكعب التعليمات البرمجية على جانب المتصل والتي تمرر البيانات إلى عمليات تنفيذ مطور البرامج الأساليب.
يمتلك المتصل بالدالة (طريقة HIDL أو معاودة الاتصال) ملكية البيانات الهياكل التي يتم تمريرها إلى الدالة وتحتفظ بالملكية بعد الاستدعاء بوصة جميع الحالات التي لا يحتاج فيها المتصل إلى تحرير سعة التخزين أو تحريرها.
- في لغة C++، قد تكون البيانات للقراءة فقط (يمكن أن تؤدي محاولات الكتابة إليها إلى خطأ في التصنيف) وأن تكون صالحة طوال مدة الاتصال. يمكن للعميل نسخ البيانات بشكل معمّق لنشرها خارج نطاق الاتصال.
- في Java، تتلقى التعليمات البرمجية نسخة محلية من البيانات (كائن Java عادي)، التي قد تحتفظ بها وتعدِّلها أو تسمح بجمعها من البيانات غير المرغوب فيها.
نقل البيانات بدون استدعاء إجراء عن بُعد (RPC)
تتوفّر طريقتان لنقل البيانات في بروتوكول HIDL بدون استخدام طلب استدعاء إجراء عن بُعد (RPC): مشترك ذاكرة وقائمة انتظار الرسائل السريعة (FMQ)، وكلاهما متوافقان فقط في C++.
- الذاكرة المشتركة نوع HIDL المدمَج هو
memory
. تُستخدم لتمرير كائن يمثل الذاكرة المشتركة التي تم تخصيصها. يمكن استخدامها في عملية الاستلام لربط الذكريات المشترَكة. - قائمة انتظار الرسائل السريعة (FMQ): يوفّر HIDL رسالة نموذجية.
قائمة انتظار ينفذ تمرير الرسائل بدون انتظار. وهو لا يستخدم النواة
أو أداة الجدولة في وضع العبور أو الربط بين الأجهزة (لا يكون الاتصال بين الأجهزة
على هذه الخصائص). عادةً ما تقوم HAL بإعداد نهاية قائمة الانتظار،
إنشاء كائن يمكن تمريره من خلال استدعاء إجراء عن بُعد (RPC) من خلال معلمة مدمجة
نوع HIDL
MQDescriptorSync
أوMQDescriptorUnsync
. هذا النمط قيد الاستلام من خلال عملية الاستلام لإعداد الطرف الآخر في قائمة الانتظار.- لا يُسمح بالتجاوز سعة قوائم الانتظار للمزامنة، ويمكن أن تحتوي على قائمة واحدة فقط قارئ البطاقات.
- يُسمح بإلغاء مزامنة قوائم الانتظار، ويمكن أن يكون لها العديد من القراء، حيث يجب أن يقرأ كل منها البيانات في وقتها أو يفقدها.
لمزيد من التفاصيل حول FMQ، راجع قائمة انتظار الرسائل السريعة (FMQ):