إنشاء واجهة HAL

يجب استخدام HIDL لوصف جميع علامات الإصدار المستخدمة بشكل مشروط وتجميع إطار العمل. يجب تجميع علامات الإصدار ذات الصلة وتضمينها في ملف .hal واحد. استخدام HIDL لتحديد عناصر الإعداد المزايا التالية:

  • (لإضافة عناصر إعداد جديدة، على المورّدين/المصنّعين الأصليين للأجهزة توسيع نطاق طبقة تجريد الأجهزة (HAL)
  • موثَّق بالكامل
  • التحكم في الوصول باستخدام SELinux
  • يتم فحص سلامة عناصر الإعداد من خلال اختبار المورّد Suite (التحقّق من النطاق والتحقق من التبعية بين العناصر وما إلى ذلك)
  • واجهات برمجة التطبيقات التي تم إنشاؤها تلقائيًا في كل من C++ وJava

تحديد علامات التصميم التي يستخدمها إطار العمل

ابدأ بتحديد تهيئات الإصدار المستخدمة لتجميع إطار عمل، ثم التخلي عن الإعدادات القديمة لتصغير المجموعة. على سبيل المثال: يتم تحديد المجموعة التالية من علامات الإصدار الخاصة بـ surfaceflinger:

  • TARGET_USES_HWC2
  • TARGET_BOARD_PLATFORM
  • TARGET_DISABLE_TRIPLE_BUFFERING
  • TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
  • NUM_FRAMEBUFFER_SURFACE_BUFFERS
  • TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK
  • VSYNC_EVENT_PHASE_OFFSET_NS
  • SF_VSYNC_EVENT_PHASE_OFFSET_NS
  • PRESENT_TIME_OFFSET_FROM_VSYNC_NS
  • MAX_VIRTUAL_DISPLAY_DIMENSION

إنشاء واجهة HAL

يتم الوصول إلى تكوينات التصميم للنظام الفرعي من خلال واجهة HAL، بينما الواجهات المخصصة لتوفير قيم التهيئة مجمّعة في حزمة HAL android.hardware.configstore (إصدار 1.0 حاليًا). على سبيل المثال، لإنشاء ملف واجهة HAL لـ surfaceflinger، في hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal:

package android.hardware.configstore@1.0;

interface ISurfaceFlingerConfigs {
    // TO-BE-FILLED-BELOW
};

بعد إنشاء ملف .hal، شغِّل hardware/interfaces/update-makefiles.sh لإضافة العنصر الجديد ملف .hal إلى Android.bp Android.mk ملف.

إضافة دوال لعلامات الإصدار

أضِف دالة جديدة إلى الواجهة لكل علامة إصدار. على سبيل المثال، في hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal:

interface ISurfaceFlingerConfigs {
    disableTripleBuffering() generates(OptionalBool ret);
    forceHwcForVirtualDisplays() generates(OptionalBool ret);
    enum NumBuffers: uint8_t {
        USE_DEFAULT = 0,
        TWO = 2,
        THREE = 3,
    };
    numFramebufferSurfaceBuffers() generates(NumBuffers ret);
    runWithoutSyncFramework() generates(OptionalBool ret);
    vsyncEventPhaseOffsetNs generates (OptionalUInt64 ret);
    presentTimeOffsetFromSyncNs generates (OptionalUInt64 ret);
    maxVirtualDisplayDimension() generates(OptionalInt32 ret);
};

عند إضافة دالة:

  • استخدام الأسماء المختصرة: تجنُّب تحويل متغيّر makefile الأسماء إلى أسماء دوال وتذكر أن TARGET_ و لم تعُد بادئات BOARD_ ضرورية.
  • إضافة تعليقات ساعد المطوّرين في فهم الغرض من config، وكيف يغير سلوك إطار العمل، والقيم الصالحة، وغير ذلك من المعلومات.

يمكن أن تكون أنواع إرجاع الدوال Optional[Bool|String|Int32|UInt32|Int64|UInt64] يتم تحديد الأنواع. في types.hal في الدليل نفسه مع إحاطة القيم الأساسية باستخدام الذي يشير إلى ما إذا كان يتم تحديد القيمة بواسطة HAL؛ وإذا لم يكن كذلك، فإن الإعداد الافتراضي استخدام القيمة.

struct OptionalString {
    bool specified;
    string value;
};

عند الاقتضاء، حدد التعداد الذي يمثل نوع عنصر الضبط واستخدام هذا التعداد كنوع الإرجاع. في المثال أعلاه، يتم تحديد تعداد NumBuffers للحد من عدد القيم. عند تحديد أنواع البيانات المخصصة هذه، أضف حقلاً أو قيمة تعداد (مع مثال، USE_DEFAULT) للإشارة إلى ما إذا كانت القيمة محددة أو لم يتم تحديدها بواسطة HAL.

ليس من الضروري أن تصبح علامة إصدار واحدة دالة مفردة في HIDL. يمكن لمالكي الوحدات بدلاً من ذلك تجميع علامات إصدار وثيقة الصلة ببعضها في هيكل ولها دالة تقوم بإرجاع هذه البنية (يمكن أن يؤدي القيام بذلك إلى تقليل عدد استدعاءات الدوال).

على سبيل المثال، خيار لتجميع علامتي إنشاء في هيكل واحد في "hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal" :

 interface ISurfaceFlingerConfigs {
    // other functions here
    struct SyncConfigs {
        OptionalInt64 vsyncEventPhaseoffsetNs;
        OptionalInt64 presentTimeoffsetFromSyncNs;
    };
    getSyncConfigs() generates (SyncConfigs ret);
    // other functions here
};

بدائل لدالة HAL واحدة

كبديل لاستخدام دالة HAL واحدة لجميع علامات الإصدار، يمكن أن تحدد دالة HAL دوال بسيطة مثل getBoolean(string key) وgetInteger(string key). القيمة الفعلية يتم تخزين key=value أزواج في ملفات منفصلة وخدمة HAL. ويوفر القيم من خلال قراءة/تحليل هذه الملفات.

في حين أن هذا النهج سهل التعريف، إلا أنه لا يتضمن مزايا مقدَّمة من HIDL (فرض الإصدارات، وسهولة التوثيق، والتحكم في الوصول) وبالتالي لا يُنصح به

الواجهات الفردية والمتعددة

يعرض تصميم واجهة HAL لعناصر التهيئة اثنين الخيارات:

  • واجهة واحدة تشمل جميع عناصر الضبط
  • واجهات متعددة، تغطي كل منها مجموعة من الإعدادات ذات الصلة العناصر

الواجهة الواحدة أسهل ولكن قد يتعذّر الحفاظ عليها كلما ازدادت إضافة عناصر التهيئة إلى الملف الفردي. بالإضافة إلى ذلك، يمكن للتحكم في الوصول ليست دقيقة، لذا يمكن للعملية التي تم منحها إذن الوصول إلى الواجهة قراءة كل عناصر التهيئة (لا يمكن الوصول إلى مجموعة جزئية من عناصر التهيئة ). بدلاً من ذلك، في حال عدم منح إذن الوصول، لا يمكن منح عناصر الضبط تَقْرَأ

بسبب هذه المشاكل، يستخدم Android واجهات متعددة مع طبقة تجريد الأجهزة (HAL) واحدة. لمجموعة من عناصر الإعداد ذات الصلة. على سبيل المثال: ISurfaceflingerConfigs ذات الصلة بـ surfaceflinger عناصر الضبط، وIBluetoothConfigs المتعلقة بالبلوتوث عناصر التهيئة.