एचएएल इंटरफेस बनाना

ढांचे को सशर्त रूप से संकलित करने के लिए उपयोग किए जाने वाले सभी बिल्ड फ़्लैग का वर्णन करने के लिए आपको HIDL का उपयोग करना चाहिए। प्रासंगिक बिल्ड फ़्लैग को समूहीकृत किया जाना चाहिए और एक .hal फ़ाइल में शामिल किया जाना चाहिए। कॉन्फ़िगरेशन आइटम निर्दिष्ट करने के लिए HIDL का उपयोग करने में निम्नलिखित लाभ शामिल हैं:

  • संस्करणित (नए कॉन्फिग आइटम जोड़ने के लिए, विक्रेताओं/ओईएम को स्पष्ट रूप से एचएएल का विस्तार करना चाहिए)
  • अच्छी तरह से प्रलेखित
  • SELinux का उपयोग करके अभिगम नियंत्रण
  • विक्रेता परीक्षण सूट (श्रेणी की जांच, वस्तुओं के बीच अंतर-निर्भरता जांच, आदि) के माध्यम से कॉन्फ़िगरेशन आइटम के लिए विवेक जांच।
  • सी ++ और जावा दोनों में ऑटो-जेनरेटेड एपीआई

ढांचे द्वारा उपयोग किए जाने वाले निर्माण झंडे की पहचान करना

सशर्त रूप से ढांचे को संकलित करने के लिए उपयोग की जाने वाली बिल्ड कॉन्फ़िगरेशन की पहचान करके प्रारंभ करें, फिर सेट को छोटा बनाने के लिए अप्रचलित कॉन्फ़िगरेशन को छोड़ दें। उदाहरण के लिए, 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

एचएएल इंटरफ़ेस बनाना

एक सबसिस्टम के लिए बिल्ड कॉन्फिग को एचएएल इंटरफेस के माध्यम से एक्सेस किया जाता है, जबकि कॉन्फ़िगरेशन वैल्यू देने के लिए इंटरफेस को एचएएल पैकेज android.hardware.configstore (वर्तमान में संस्करण 1.0 पर) में समूहीकृत किया जाता है। उदाहरण के लिए, hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal में, surfaceflinger के लिए एक HAL इंटरफ़ेस फ़ाइल बनाने के लिए:

package android.hardware.configstore@1.0;

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

.hal फ़ाइल बनाने के बाद, Android.bp और Android.mk फ़ाइलों में नई .hal फ़ाइल जोड़ने के लिए hardware/interfaces/update-makefiles.sh चलाएँ।

झंडे बनाने के लिए कार्य जोड़ना

प्रत्येक बिल्ड फ़्लैग के लिए, इंटरफ़ेस में एक नया फ़ंक्शन जोड़ें। उदाहरण के लिए, 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);
};

फ़ंक्शन जोड़ते समय:

  • नामों के साथ संक्षिप्त रहें। मेकफ़ाइल वैरिएबल नामों को फ़ंक्शन नामों में बदलने से बचें और ध्यान रखें कि TARGET_ और BOARD_ उपसर्ग अब आवश्यक नहीं हैं।
  • टिप्पणी करें। डेवलपर्स को कॉन्फ़िगरेशन आइटम के उद्देश्य को समझने में सहायता करें, यह कैसे फ्रेमवर्क व्यवहार, मान्य मान और अन्य प्रासंगिक जानकारी बदलता है।

फ़ंक्शन रिटर्न प्रकार Optional[Bool|String|Int32|UInt32|Int64|UInt64] । प्रकार को उसी निर्देशिका में types.hal में परिभाषित किया गया है और एक फ़ील्ड के साथ आदिम मानों को लपेटता है जो इंगित करता है कि मान एचएएल द्वारा निर्दिष्ट किया गया है; यदि नहीं, तो डिफ़ॉल्ट मान का उपयोग किया जाता है।

struct OptionalString {
    bool specified;
    string value;
};

जब उपयुक्त हो, उस एनम को परिभाषित करें जो कॉन्फ़िगरेशन आइटम के प्रकार का सबसे अच्छा प्रतिनिधित्व करता है और उस एनम को रिटर्न प्रकार के रूप में उपयोग करता है। ऊपर के उदाहरण में, NumBuffers enum को मान्य मानों की संख्या को सीमित करने के लिए परिभाषित किया गया है। इस तरह के कस्टम डेटा प्रकारों को परिभाषित करते समय, एक फ़ील्ड या एक एनम मान जोड़ें (उदाहरण के लिए, USE_DEFAULT ) यह दर्शाने के लिए कि क्या मान एचएएल द्वारा निर्दिष्ट नहीं है।

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 इंटरफ़ेस सरल कार्य भी प्रदान करता है जैसे getBoolean(string key) और getInteger(string key) । वास्तविक key=value जोड़े अलग-अलग फाइलों में संग्रहीत होते हैं और एचएएल सेवा उन फाइलों को पढ़/पार्स करके मान प्रदान करती है।

हालांकि इस दृष्टिकोण को परिभाषित करना आसान है, इसमें एचआईडीएल (प्रवर्तित संस्करण, दस्तावेज़ीकरण में आसानी, अभिगम नियंत्रण) द्वारा प्रदान किए गए लाभ शामिल नहीं हैं और इसलिए इसकी अनुशंसा नहीं की जाती है।

सिंगल और मल्टीपल इंटरफेस

कॉन्फ़िगरेशन आइटम के लिए HAL इंटरफ़ेस का डिज़ाइन दो विकल्प प्रस्तुत करता है:

  • एक एकल इंटरफ़ेस जो सभी कॉन्फ़िगरेशन आइटम को कवर करता है
  • एकाधिक इंटरफेस, जिनमें से प्रत्येक में संबंधित कॉन्फ़िगरेशन आइटम का एक सेट शामिल है

एक एकल इंटरफ़ेस आसान है, लेकिन यह अप्राप्य हो सकता है क्योंकि एकल फ़ाइल में अधिक कॉन्फ़िगरेशन आइटम जोड़े जाते हैं। इसके अलावा, अभिगम नियंत्रण ठीक-ठाक नहीं है, इसलिए एक प्रक्रिया जिसे इंटरफ़ेस तक पहुंच प्रदान की गई है, सभी कॉन्फ़िगरेशन आइटम पढ़ सकती है (कॉन्फ़िगरेशन आइटम के आंशिक सेट तक पहुंच प्रदान नहीं की जा सकती है)। वैकल्पिक रूप से, यदि पहुंच प्रदान नहीं की जाती है, तो कॉन्फ़िगरेशन आइटम को पढ़ा नहीं जा सकता है।

इन मुद्दों के कारण, एंड्रॉइड संबंधित कॉन्फ़िगरेशन आइटम के समूह के लिए एकल एचएएल इंटरफ़ेस के साथ कई इंटरफेस का उपयोग करता है। उदाहरण के लिए, ISurfaceflingerConfigs -संबंधित कॉन्फ़िगरेशन आइटम के लिए surfaceflinger , और ब्लूटूथ-संबंधित कॉन्फ़िगरेशन आइटम के लिए IBluetoothConfigs