एचआईडीएल सी++,एचआईडीएल सी++,एचआईडीएल सी++

एंड्रॉइड ओ डिवाइस-स्वतंत्र एंड्रॉइड प्लेटफ़ॉर्म और डिवाइस- और विक्रेता-विशिष्ट कोड के बीच स्पष्ट इंटरफेस को परिभाषित करने के लिए एंड्रॉइड ओएस को फिर से आर्किटेक्ट करता है। एंड्रॉइड पहले से ही ऐसे कई इंटरफेस को एचएएल इंटरफेस के रूप में परिभाषित करता है, जिन्हें hardware/libhardware में सी हेडर के रूप में परिभाषित किया गया है। HIDL इन HAL इंटरफेस को स्थिर, संस्करणित इंटरफेस से बदल देता है, जो C++ (नीचे वर्णित) या Java में क्लाइंट- और सर्वर-साइड HIDL इंटरफेस हो सकता है।

इस अनुभाग के पृष्ठ HIDL इंटरफेस के C++ कार्यान्वयन का वर्णन करते हैं, जिसमें hidl-gen कंपाइलर द्वारा HIDL .hal फ़ाइलों से स्वचालित रूप से जेनरेट की गई फ़ाइलों के बारे में विवरण शामिल हैं, इन फ़ाइलों को कैसे पैक किया जाता है, और इन फ़ाइलों को C++ कोड के साथ कैसे एकीकृत किया जाए उनका उपयोग करता है.

क्लाइंट और सर्वर कार्यान्वयन

HIDL इंटरफ़ेस में क्लाइंट और सर्वर कार्यान्वयन हैं:

  • HIDL इंटरफ़ेस का क्लाइंट वह कोड होता है जो इंटरफ़ेस पर विधियों को कॉल करके उसका उपयोग करता है।
  • एक सर्वर एक HIDL इंटरफ़ेस का कार्यान्वयन है जो ग्राहकों से कॉल प्राप्त करता है और परिणाम लौटाता है (यदि आवश्यक हो)।

libhardware एचएएल से एचआईडीएल एचएएल में संक्रमण में, एचएएल कार्यान्वयन सर्वर बन जाता है और एचएएल में कॉल करने की प्रक्रिया क्लाइंट बन जाती है। डिफ़ॉल्ट कार्यान्वयन पासथ्रू और बाइंडराइज्ड एचएएल दोनों की सेवा कर सकता है, और समय के साथ बदल सकता है:

चित्र 1. विरासती एचएएल के लिए विकास की प्रगति।

एचएएल क्लाइंट बनाना

मेकफ़ाइल में एचएएल लाइब्रेरीज़ को शामिल करके प्रारंभ करें:

  • बनाएं: LOCAL_SHARED_LIBRARIES += android.hardware.nfc@1.0
  • जल्द ही: shared_libs: [ …, android.hardware.nfc@1.0 ]

इसके बाद, HAL हेडर फ़ाइलें शामिल करें:

#include <android/hardware/nfc/1.0/IFoo.h>
…
// in code:
sp<IFoo> client = IFoo::getService();
client->doThing();

एचएएल सर्वर बनाना

एचएएल कार्यान्वयन बनाने के लिए, आपके पास .hal फ़ाइलें होनी चाहिए जो आपके एचएएल का प्रतिनिधित्व करती हैं और पहले से ही आपके एचएएल के लिए -Lmakefile या -Landroidbp का उपयोग करके hidl-gen ( ./hardware/interfaces/update-makefiles.sh ) पर मेकफ़ाइलें जेनरेट कर चुकी हैं। आंतरिक एचएएल फ़ाइलें और एक अच्छा संदर्भ है)। libhardware से एचएएल पर स्थानांतरित करते समय, आप सी2एचएएल का उपयोग करके यह काम आसानी से कर सकते हैं।

अपने HAL को लागू करने के लिए आवश्यक फ़ाइलें बनाने के लिए:

PACKAGE=android.hardware.nfc@1.0
LOC=hardware/interfaces/nfc/1.0/default/
m -j hidl-gen
hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \
    -randroid.hidl:system/libhidl/transport $PACKAGE
hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \
    -randroid.hidl:system/libhidl/transport $PACKAGE

एचएएल को पासथ्रू मोड में काम करने के लिए, आपके /(system|vendor|...)/lib(64)?/hw/android.hardware.package@3.0-impl( OPTIONAL_IDENTIFIER ).so में रहने वाला फ़ंक्शन HIDL_FETCH_IModuleName होना चाहिए। जहां OPTIONAL_IDENTIFIER पासथ्रू कार्यान्वयन की पहचान करने वाली एक स्ट्रिंग है। पासथ्रू मोड आवश्यकताओं को उपरोक्त आदेशों द्वारा स्वचालित रूप से पूरा किया जाता है, जो android.hardware.nfc@1.0-impl लक्ष्य भी बनाता है, लेकिन किसी भी एक्सटेंशन का उपयोग किया जा सकता है। उदाहरण के लिए android.hardware.nfc@1.0-impl-foo खुद को अलग करने के लिए -foo उपयोग करता है।

यदि कोई एचएएल किसी अन्य एचएएल का लघु संस्करण या विस्तार है, तो इस बाइनरी को नाम देने के लिए आधार एचएएल का उपयोग किया जाना चाहिए। उदाहरण के लिए, android.hardware.graphics.mapper@2.1 कार्यान्वयन अभी भी android.hardware.graphics.mapper@2.0-impl( OPTIONAL_IDENTIFIER ) नामक बाइनरी में होना चाहिए। आमतौर पर, यहां OPTIONAL_IDENTIFIER में वास्तविक HAL संस्करण शामिल होगा। इस तरह बाइनरी का नामकरण करके, 2.0 क्लाइंट इसे सीधे पुनर्प्राप्त कर सकते हैं, और 2.1 क्लाइंट कार्यान्वयन को अपकास्ट कर सकते हैं।

इसके बाद, स्टब्स को कार्यक्षमता से भरें और एक डेमॉन सेटअप करें। उदाहरण डेमॉन कोड (पासथ्रू का समर्थन):

#include <hidl/LegacySupport.h>

int main(int /* argc */, char* /* argv */ []) {
    return defaultPassthroughServiceImplementation<INfc>("nfc");
}

defaultPassthroughServiceImplementation प्रदत्त -impl लाइब्रेरी को dlopen() करेगा और इसे बाइंडराइज़्ड सेवा के रूप में प्रदान करेगा। उदाहरण डेमॉन कोड (शुद्ध बाइंडरीकृत सेवा के लिए):

int main(int /* argc */, char* /* argv */ []) {
    // This function must be called before you join to ensure the proper
    // number of threads are created. The threadpool will never exceed
    // size one because of this call.
    ::android::hardware::configureRpcThreadpool(1 /*threads*/, true /*willJoin*/);

    sp<INfc> nfc = new Nfc();
    const status_t status = nfc->registerAsService();
    if (status != ::android::OK) {
        return 1; // or handle error
    }

    // Adds this thread to the threadpool, resulting in one total
    // thread in the threadpool. We could also do other things, but
    // would have to specify 'false' to willJoin in configureRpcThreadpool.
    ::android::hardware::joinRpcThreadpool();
    return 1; // joinRpcThreadpool should never return
}

यह डेमॉन आमतौर पर $PACKAGE + "-service-suffix" (उदाहरण के लिए, android.hardware.nfc@1.0-service ) में रहता है, लेकिन यह कहीं भी हो सकता है। एचएएल के एक विशिष्ट वर्ग के लिए सेपॉलिसी विशेषता hal_<module> (उदाहरण के लिए, hal_nfc) है। यह विशेषता उस डेमॉन पर लागू होनी चाहिए जो एक विशेष HAL को चलाता है (यदि एक ही प्रक्रिया कई HAL को सेवा प्रदान करती है, तो उस पर कई विशेषताएँ लागू की जा सकती हैं)।