एचएएल के लिए एआईडीएल

Android 11 वर्शन में, Android में एचएएल के लिए एआईडीएल का इस्तेमाल करने की सुविधा लॉन्च की गई है. इससे एचआईडीएल के बिना, Android के हिस्सों को लागू किया जा सकता है. जहां मुमकिन हो वहां एआईडीएल का इस्तेमाल करने के लिए ट्रांज़िशन एचएएल (जब अपस्ट्रीम एचएएल, एचआईडीएल का इस्तेमाल करते हों, तो एचएएल का इस्तेमाल करना ज़रूरी है).

फ़्रेमवर्क कॉम्पोनेंट के बीच संपर्क करने के लिए एआईडीएल का इस्तेमाल करने वाले एचएएल, जैसे कि system.img में मौजूद एचएएल और हार्डवेयर कॉम्पोनेंट, जैसे कि vendor.img में मौजूद एचएएल को स्टेबल एआईडीएल का इस्तेमाल करना चाहिए. हालांकि, किसी बंटवारे के दौरान आईपीसी सिस्टम पर कोई पाबंदी नहीं होती, जैसे कि एक एचएएल से दूसरे एचएएल तक.

वजह

एआईडीएल का इस्तेमाल एचआईडीएल से ज़्यादा होता है और कई दूसरी जगहों पर भी इसका इस्तेमाल किया जाता है. जैसे, Android फ़्रेमवर्क के कॉम्पोनेंट के बीच या ऐप्लिकेशन में. एआईडीएल को स्थिरता से जुड़ी सुविधा मिलती है, इसलिए अब एक आईपीसी रनटाइम के साथ पूरे स्टैक को लागू किया जा सकता है. HIDL के मुकाबले AIDL में बेहतर वर्शनिंग सिस्टम भी है.

  • एक ही आईपीसी भाषा का इस्तेमाल करने का मतलब है कि आपके पास सीखने, डीबग करने, ऑप्टिमाइज़ करने, और सुरक्षित रखने के लिए एक ही चीज़ है.
  • एआईडीएल, इंटरफ़ेस के मालिकों के लिए उसी जगह पर वर्शन तैयार करने की सुविधा देते हैं:
    • मालिक, इंटरफ़ेस के आखिर में तरीके जोड़ सकते हैं या पार्स किए जा सकने वाले फ़ील्ड में फ़ील्ड जोड़ सकते हैं. इसका मतलब यह है कि साल-दर-साल वर्शन कोड इस्तेमाल करना आसान होता है. साथ ही, साल-दर-साल कीमत कम होती है. टाइप में बदलाव किए जा सकते हैं और हर इंटरफ़ेस वर्शन के लिए अलग लाइब्रेरी की ज़रूरत नहीं होती.
    • एक्सटेंशन इंटरफ़ेस, टाइप सिस्टम के बजाय रनटाइम के दौरान अटैच किए जा सकते हैं. इसलिए, इंटरफ़ेस के नए वर्शन पर डाउनस्ट्रीम एक्सटेंशन को फिर से बनाने की ज़रूरत नहीं है.
  • किसी मौजूदा एआईडीएल इंटरफ़ेस का इस्तेमाल तब ही किया जा सकता है, जब उसका मालिक उसे स्टेबलाइज़ करने का विकल्प चुनता है. पहले, इंटरफ़ेस की एक पूरी कॉपी HIDL में बनानी होगी.

एआईडीएल रनटाइम के मुताबिक बनाएं

AIDL के तीन अलग-अलग बैकएंड होते हैं: Java, NDK, और CPP. स्टेबल एआईडीएल का इस्तेमाल करने के लिए, आपको system/lib*/libbinder.so पर libbinder की सिस्टम कॉपी का हमेशा इस्तेमाल करना होगा और /dev/binder पर बात करनी होगी. वेंडर इमेज पर मौजूद कोड के लिए, इसका मतलब यह है कि libbinder (VNDK से) का इस्तेमाल नहीं किया जा सकता: इस लाइब्रेरी में अस्थिर C++ API है और अंदरूनी काम नहीं कर सकता है. इसके बजाय, नेटिव वेंडर कोड को एआईडीएल के एनडीके बैकएंड का इस्तेमाल करना चाहिए और libbinder_ndk (जो सिस्टम libbinder.so पर आधारित है) से लिंक करना चाहिए. साथ ही, इसे aidl_interface एंट्री से बनाई गई एनडीके लाइब्रेरी से लिंक करना चाहिए. मॉड्यूल के सटीक नामों के लिए, मॉड्यूल का नाम रखने के नियम देखें.

AIDL HAL इंटरफ़ेस लिखना

सिस्टम और वेंडर के बीच AIDL इंटरफ़ेस इस्तेमाल करने के लिए, इंटरफ़ेस में दो बदलाव करने होंगे:

  • हर टाइप की परिभाषा के बारे में @VintfStability के साथ एनोटेट किया जाना चाहिए.
  • aidl_interface के एलान में stability: "vintf", शामिल होना चाहिए.

केवल इंटरफ़ेस का स्वामी ही ये बदलाव कर सकता है.

जब आप ये बदलाव करते हैं, तो इंटरफ़ेस VINTF मेनिफ़ेस्ट में होना चाहिए, ताकि यह काम कर सके. वीटीएस टेस्ट vts_treble_vintf_vendor_test का इस्तेमाल करके, इसे (और इससे जुड़ी ज़रूरी शर्तें, जैसे कि रिलीज़ किए गए इंटरफ़ेस रुके हुए हैं या नहीं) की जांच करें. इन ज़रूरी शर्तों के बिना @VintfStability इंटरफ़ेस का इस्तेमाल करने के लिए, एनडीके बैकएंड में AIBinder_forceDowngradeToLocalStability, C++ बैकएंड में android::Stability::forceDowngradeToLocalStability या बाइंडर ऑब्जेक्ट पर Java बैकएंड में android.os.Binder#forceDowngradeToSystemStability को कॉल करें. इसके बाद ही उसे किसी अन्य प्रोसेस में भेजा जा सकता है. Java में किसी सेवा को वेंडर के काम करने के लिए डाउनग्रेड नहीं किया जा सकता, क्योंकि सभी ऐप्लिकेशन, सिस्टम के हिसाब से चलते हैं.

इसके अलावा, कोड को ज़्यादा से ज़्यादा पोर्ट करने की सुविधा और गै़र-ज़रूरी अतिरिक्त लाइब्रेरी जैसी समस्याओं से बचने के लिए, सीपीपी बैकएंड को बंद करें.

ध्यान दें कि कोड के उदाहरण में, backends का इस्तेमाल सही है. ऐसा इसलिए, क्योंकि इसमें तीन बैकएंड (Java, NDK, और CPP) हैं. नीचे दिया गया कोड, खास तौर पर सीपीपी बैकएंड को बंद करने का तरीका बताता है.

    aidl_interface: {
        ...
        backends: {
            cpp: {
                enabled: false,
            },
        },
    }

AIDL HAL इंटरफ़ेस ढूंढें

aidl फ़ोल्डर में, HAL के लिए AOSP स्टेबल AIDL इंटरफ़ेस, HIDL इंटरफ़ेस की तरह एक ही बेस डायरेक्ट्री में होता है.

  • हार्डवेयर/इंटरफ़ेस
  • फ़्रेमवर्क/हार्डवेयर/इंटरफ़ेस
  • सिस्टम/हार्डवेयर/इंटरफ़ेस

आपको एक्सटेंशन इंटरफ़ेस को vendor या hardware में, hardware/interfaces की अन्य सबडायरेक्ट्री में रखना चाहिए.

एक्सटेंशन इंटरफ़ेस

Android में हर रिलीज़ के साथ आधिकारिक AOSP इंटरफ़ेस का एक सेट मौजूद है. अगर Android पार्टनर इन इंटरफ़ेस में फ़ंक्शन जोड़ना चाहते हैं, तो उन्हें सीधे तौर पर इन्हें नहीं बदलना चाहिए. ऐसा इसलिए, क्योंकि इसका मतलब यह होगा कि उनका Android रनटाइम, एओएसपी Android रनटाइम के साथ काम नहीं करता है. GMS डिवाइसों के लिए, इन इंटरफ़ेस को बदलने से बचने से भी यह पक्का होता है कि जीएसआई इमेज काम करती रहेगी.

एक्सटेंशन दो अलग-अलग तरीकों से रजिस्टर किए जा सकते हैं:

  • रनटाइम पर, अटैच किए गए एक्सटेंशन देखें.
  • यह सुविधा अलग से उपलब्ध होती है और दुनिया भर में रजिस्टर होती है. साथ ही, इसे VINTF में भी रजिस्टर किया जाता है.

हालांकि, वेंडर के हिसाब से (अपस्ट्रीम एओएसपी का हिस्सा नहीं) कॉम्पोनेंट, इंटरफ़ेस का इस्तेमाल करने पर एक्सटेंशन रजिस्टर होता है, तो मर्ज करने पर कोई समस्या नहीं होती. हालांकि, जब अपस्ट्रीम एओएसपी कॉम्पोनेंट में डाउनस्ट्रीम बदलाव किए जाते हैं, तो मर्ज करने के विवाद हो सकते हैं. इसके लिए, इन रणनीतियों का सुझाव दिया जाता है:

  • अगली रिलीज़ में जोड़े गए इंटरफ़ेस एओएसपी में अप-स्ट्रीम किए जा सकते हैं
  • नए इंटरफ़ेस में मर्ज किए गए विरोधाभासों के बिना अतिरिक्त इंटरफ़ेस उपलब्ध कराने के लिए, उसे अगली रिलीज़ में अपस्ट्रीम किया जा सकता है.

पार्स किए जा सकने वाले एक्सटेंशन: Parcelable Holder

ParcelableHolder एक Parcelable है, जिसमें एक और Parcelable हो सकता है. ParcelableHolder का मुख्य इस्तेमाल उदाहरण, Parcelable को एक्सटेंसिबल बनाना है. उदाहरण के लिए, ऐसी इमेज जिसकी मदद से डिवाइस लागू करने वाले, एओएसपी के बनाए हुए Parcelable, AospDefinedParcelable को बढ़ा सकते हैं. इससे, वैल्यू बढ़ाने वाली सुविधाएं शामिल करने में मदद मिलती है.

पहले ParcelableHolder के बिना, डिवाइस लागू करने वाले लोग एओएसपी-तय स्थिर एआईडीएल इंटरफ़ेस में बदलाव नहीं कर सकते थे. ऐसा इसलिए था, क्योंकि ज़्यादा फ़ील्ड जोड़ना गड़बड़ी की वजह से होगा:

parcelable AospDefinedParcelable {
  int a;
  String b;
  String x; // ERROR: added by a device implementer
  int[] y; // added by a device implementer
}

जैसा कि पिछले कोड में दिखाया गया है, यह तरीका काम नहीं करता. ऐसा इसलिए है, क्योंकि Android की अगली रिलीज़ में पार्स किए जा सकने वाले एलिमेंट में बदलाव करते समय, डिवाइस लागू करने वाले के जोड़े गए फ़ील्ड में कॉन्फ़्लिक्ट हो सकता है.

ParcelableHolder का इस्तेमाल करके, पार्सल किए जा सकने वाले एलिमेंट का मालिक, Parcelable में एक्सटेंशन पॉइंट तय कर सकता है.

parcelable AospDefinedParcelable {
  int a;
  String b;
  ParcelableHolder extension;
}

इसके बाद, डिवाइस लागू करने वाले लोग अपने एक्सटेंशन के लिए, अपना Parcelable तय कर सकते हैं.

parcelable OemDefinedParcelable {
  String x;
  int[] y;
}

आखिर में, ParcelableHolder फ़ील्ड की मदद से नए Parcelable को ओरिजनल Parcelable के साथ अटैच किया जा सकता है.


// Java
AospDefinedParcelable ap = ...;
OemDefinedParcelable op = new OemDefinedParcelable();
op.x = ...;
op.y = ...;

ap.extension.setParcelable(op);

...

OemDefinedParcelable op = ap.extension.getParcelable(OemDefinedParcelable.class);

// C++
AospDefinedParcelable ap;
OemDefinedParcelable op;
std::shared_ptr<OemDefinedParcelable> op_ptr = make_shared<OemDefinedParcelable>();

ap.extension.setParcelable(op);
ap.extension.setParcelable(op_ptr);

...

std::shared_ptr<OemDefinedParcelable> op_ptr;

ap.extension.getParcelable(&op_ptr);

// NDK
AospDefinedParcelable ap;
OemDefinedParcelable op;
ap.extension.setParcelable(op);

...

std::optional<OemDefinedParcelable> op;
ap.extension.getParcelable(&op);

// Rust
let mut ap = AospDefinedParcelable { .. };
let op = Rc::new(OemDefinedParcelable { .. });

ap.extension.set_parcelable(Rc::clone(&op));

...

let op = ap.extension.get_parcelable::<OemDefinedParcelable>();

AIDL HAL सर्वर इंस्टेंस के नाम

आम तौर पर, एआईडीएल एचएएल सेवाओं का एक इंस्टेंस नाम $package.$type/$instance फ़ॉर्मैट में होता है. उदाहरण के लिए, वाइब्रेटर एचएएल के एक इंस्टेंस को android.hardware.vibrator.IVibrator/default के तौर पर रजिस्टर किया गया है.

AIDL HAL सर्वर लिखना

@VintfStability एआईडीएल सर्वर के बारे में VINTF मेनिफ़ेस्ट में बताया जाना चाहिए. उदाहरण के लिए, यह इस तरह का है:

    <hal format="aidl">
        <name>android.hardware.vibrator</name>
        <version>1</version>
        <fqname>IVibrator/default</fqname>
    </hal>

अगर ऐसा नहीं है, तो उन्हें एआईडीएल सेवा को सामान्य रूप से रजिस्टर करना चाहिए. वीटीएस टेस्ट चलाते समय, हो सकता है कि एलान किए गए सभी एआईडीएल एचएएल उपलब्ध हों.

एआईडीएल क्लाइंट लिखना

एआईडीएल क्लाइंट को कोड के साथ काम करने वाले मैट्रिक्स में खुद के बारे में जानकारी देनी चाहिए. उदाहरण के लिए, ऐसा करने के लिए:

    <hal format="aidl" optional="true">
        <name>android.hardware.vibrator</name>
        <version>1-2</version>
        <interface>
            <name>IVibrator</name>
            <instance>default</instance>
        </interface>
    </hal>

मौजूदा HAL को HIDL से एआईडीएल में बदलें

HIDL इंटरफ़ेस को एआईडीएल में बदलने के लिए, hidl2aidl टूल का इस्तेमाल करें.

hidl2aidl की सुविधाएं:

  • दिए गए पैकेज के लिए .hal फ़ाइलों के आधार पर .aidl फ़ाइलें बनाएं
  • नए बनाए गए एआईडीएल पैकेज के लिए, सभी बैकएंड चालू होने पर बिल्ड नियम बनाएं
  • Java, CPP, और NDK बैकएंड में अनुवाद के तरीके बनाएं, ताकि HIDL टाइप से AIDL टाइप में अनुवाद किया जा सके
  • ज़रूरी डिपेंडेंसी के साथ लाइब्रेरी का अनुवाद करने के लिए बिल्ड रूल बनाएं
  • स्टैटिक दावा बनाएं, ताकि यह पक्का किया जा सके कि सीपीपी और एनडीके बैकएंड में HIDL और AIDL

.hal फ़ाइलों के पैकेज को .aidl फ़ाइलों में बदलने के लिए, यह तरीका अपनाएं:

  1. system/tools/hidl/hidl2aidl में मौजूद टूल बनाएं.

    नए सोर्स से इस टूल को बनाने से आपको बेहतरीन अनुभव मिलता है. पिछली रिलीज़ से पुरानी ब्रांच पर इंटरफ़ेस बदलने के लिए, नए वर्शन का इस्तेमाल किया जा सकता है.

    m hidl2aidl
    
  2. टूल को एक आउटपुट डायरेक्ट्री के साथ एक्ज़ीक्यूट करें. इसके बाद, वह पैकेज डालें जिसे बदलना है.

    इसके अलावा, नई लाइसेंस फ़ाइल के कॉन्टेंट को जनरेट की गई सभी फ़ाइलों में सबसे ऊपर जोड़ने के लिए, -l आर्ग्युमेंट का इस्तेमाल करें. सही लाइसेंस और तारीख का इस्तेमाल करें.

    hidl2aidl -o <output directory> -l <file with license> <package>
    

    उदाहरण के लिए:

    hidl2aidl -o . -l my_license.txt android.hardware.nfc@1.2
    
  3. जनरेट की गई फ़ाइलों को पढ़ें और कन्वर्ज़न से जुड़ी समस्याओं को ठीक करें.

    • conversion.log में ऐसी समस्याएं मौजूद हैं जिन्हें हल नहीं किया गया है. इस समस्या को पहले ठीक करना ज़रूरी है.
    • जनरेट की गई .aidl फ़ाइलों में चेतावनियां और सुझाव हो सकते हैं, जिन पर कार्रवाई करने की ज़रूरत है. ये टिप्पणियां // से शुरू होती हैं.
    • अब पैकेज का स्टोरेज खाली करें और उसमें सुधार करें.
    • ज़रूरी सुविधाओं के बारे में जानने के लिए, @JavaDerive की जानकारी देखें. जैसे, toString या equals.
  4. सिर्फ़ अपनी ज़रूरत के हिसाब से टारगेट बनाएं.

    • इस्तेमाल नहीं किए जाने वाले बैकएंड बंद करें. सीपीपी बैकएंड के बजाय, एनडीके बैकएंड को प्राथमिकता दें, रनटाइम चुनना लेख पढ़ें.
    • अनुवाद वाली लाइब्रेरी या उनका जनरेट किया गया ऐसा कोई भी कोड हटाएं जिसका इस्तेमाल नहीं किया जाएगा.
  5. बड़े एआईडीएल/एचआईडीएल का अंतर देखें.

    • आम तौर पर, एआईडीएल के बिल्ट-इन Status और अपवादों का इस्तेमाल करने से इंटरफ़ेस बेहतर होता है. साथ ही, अलग-अलग स्टेटस टाइप की ज़रूरत नहीं पड़ती.
    • तरीकों में एआईडीएल इंटरफ़ेस के आर्ग्युमेंट, डिफ़ॉल्ट रूप से @nullable नहीं होते हैं, जैसे कि वे HIDL में थे.

एआईडीएल एचएएल के लिए एसईनीति

वेंडर कोड को दिखने वाली एआईडीएल सेवा के टाइप में hal_service_type एट्रिब्यूट होना ज़रूरी है. अन्य मामलों में, नीति का कॉन्फ़िगरेशन किसी भी दूसरी एआईडीएल सेवा की तरह ही होता है. हालांकि, एचएएल के लिए कुछ खास एट्रिब्यूट होते हैं. यहां एचएएल सेवा के कॉन्टेक्स्ट की परिभाषा का एक उदाहरण दिया गया है:

    type hal_foo_service, service_manager_type, hal_service_type;

प्लैटफ़ॉर्म के मुताबिक तय की जाने वाली ज़्यादातर सेवाओं के लिए, सेवा का सही टाइप पहले से ही जोड़ा जाता है. उदाहरण के लिए, android.hardware.foo.IFoo/default को पहले से ही hal_foo_service के तौर पर मार्क किया जाएगा. हालांकि, अगर किसी फ़्रेमवर्क क्लाइंट में एक से ज़्यादा इंस्टेंस के नाम इस्तेमाल किए जा सकते हैं, तो खास डिवाइस से जुड़ी service_contexts फ़ाइलों में अतिरिक्त इंस्टेंस के नाम जोड़ने होंगे.

    android.hardware.foo.IFoo/custom_instance u:object_r:hal_foo_service:s0

जब हम नए तरह का एचएएल बनाते हैं, तब एचएएल एट्रिब्यूट जोड़ने ज़रूरी हैं. कोई खास एचएएल एट्रिब्यूट, कई तरह की सेवाओं से जुड़ा हो सकता है. इनमें से हर टाइप के कई इंस्टेंस हो सकते हैं, जैसा कि हमने अभी चर्चा की है. foo एचएएल के लिए, हमारे पास hal_attribute(foo) हैं. यह मैक्रो hal_foo_client और hal_foo_server एट्रिब्यूट की जानकारी देता है. किसी दिए गए डोमेन के लिए, hal_client_domain और hal_server_domain मैक्रो, किसी डोमेन को दिए गए एचएएल एट्रिब्यूट से जोड़ते हैं. उदाहरण के लिए, अगर सिस्टम सर्वर इस एचएएल का क्लाइंट है, तो वह hal_client_domain(system_server, hal_foo) नीति के मुताबिक है. इसी तरह, एक HAL सर्वर में hal_server_domain(my_hal_domain, hal_foo) शामिल होता है. आम तौर पर, दिए गए एचएएल एट्रिब्यूट के लिए, हम रेफ़रंस के तौर पर hal_foo_default या एचएएल के उदाहरण जैसा डोमेन भी बनाते हैं. हालांकि, कुछ डिवाइस अपने सर्वर के लिए इन डोमेन का इस्तेमाल करते हैं. एक से ज़्यादा सर्वर के लिए डोमेन के बीच अंतर सिर्फ़ तब करना ज़रूरी है, जब हमारे पास एक ही इंटरफ़ेस वाले कई सर्वर हों और उन्हें लागू करने के लिए अलग-अलग अनुमतियों की ज़रूरत हो. इन सभी मैक्रो में, hal_foo वास्तव में एक से-नीति ऑब्जेक्ट नहीं है. इसके बजाय, ये मैक्रो इस टोकन का इस्तेमाल क्लाइंट सर्वर के जोड़े से जुड़े एट्रिब्यूट के ग्रुप की जानकारी देने के लिए करते हैं.

हालांकि, अब तक हमने hal_foo_service और hal_foo (hal_attribute(foo) का एट्रिब्यूट पेयर) नहीं जोड़े हैं. एचएएल एट्रिब्यूट, hal_attribute_service मैक्रो का इस्तेमाल करके AIDL HAL सेवाओं से जुड़ा है (HIDL HAL, hal_attribute_hwservice मैक्रो का इस्तेमाल करते हैं). उदाहरण के लिए, hal_attribute_service(hal_foo, hal_foo_service). इसका मतलब है कि hal_foo_client प्रोसेस को एचएएल से रिकॉर्ड किया जा सकता है और hal_foo_server प्रोसेस, एचएएल को रजिस्टर कर सकती हैं. इन रजिस्ट्रेशन नियमों को लागू करने का काम, कॉन्टेक्स्ट मैनेजर (servicemanager) करता है. ध्यान दें, ऐसा हो सकता है कि सेवा के नाम हमेशा एचएएल एट्रिब्यूट से मेल न खाते हों. उदाहरण के लिए, हमें hal_attribute_service(hal_foo, hal_foo2_service) दिख सकता है. आम तौर पर, इसका मतलब है कि सेवाओं को हमेशा एक साथ इस्तेमाल किया जाता है. इसलिए, हम hal_foo2_service को हटाकर और अपनी सभी सेवा के लिए hal_foo_service का इस्तेमाल करने पर विचार कर सकते हैं. ज़्यादातर एचएएल, जो कई hal_attribute_service को सेट करते हैं, क्योंकि मूल एचएएल एट्रिब्यूट का नाम उतना सामान्य नहीं होता है और न ही उसे बदला जा सकता है.

इन सभी को एक साथ मिलाकर देखें, तो उदाहरण के तौर पर दिया गया HAL कुछ ऐसा दिखता है:

    public/attributes:
    // define hal_foo, hal_foo_client, hal_foo_server
    hal_attribute(foo)

    public/service.te
    // define hal_foo_service
    type hal_foo_service, hal_service_type, protected_service, service_manager_type

    public/hal_foo.te:
    // allow binder connection from client to server
    binder_call(hal_foo_client, hal_foo_server)
    // allow client to find the service, allow server to register the service
    hal_attribute_service(hal_foo, hal_foo_service)
    // allow binder communication from server to service_manager
    binder_use(hal_foo_server)

    private/service_contexts:
    // bind an AIDL service name to the selinux type
    android.hardware.foo.IFooXxxx/default u:object_r:hal_foo_service:s0

    private/<some_domain>.te:
    // let this domain use the hal service
    binder_use(some_domain)
    hal_client_domain(some_domain, hal_foo)

    vendor/<some_hal_server_domain>.te
    // let this domain serve the hal service
    hal_server_domain(some_hal_server_domain, hal_foo)

अटैच किए गए एक्सटेंशन इंटरफ़ेस

एक्सटेंशन को किसी भी बाइंडर इंटरफ़ेस में अटैच किया जा सकता है. भले ही, वह टॉप-लेवल का ऐसा इंटरफ़ेस हो जिसे सीधे सेवा मैनेजर पर रजिस्टर किया गया हो या वह कोई सब-इंटरफ़ेस हो. एक्सटेंशन मिलते समय, आपको इस बात की पुष्टि करनी होगी कि एक्सटेंशन का टाइप उम्मीद के मुताबिक है. एक्सटेंशन को सिर्फ़ बाइंडर उपलब्ध कराने वाली प्रोसेस से सेट किया जा सकता है.

जब भी कोई एक्सटेंशन किसी मौजूदा एचएएल के काम करने के तरीके में बदलाव करता है, तो अटैच किए गए एक्सटेंशन का इस्तेमाल किया जाना चाहिए. पूरी तरह से नए फ़ंक्शन की ज़रूरत होने पर, इस तरीके का इस्तेमाल करने की ज़रूरत नहीं होती. साथ ही, एक्सटेंशन इंटरफ़ेस को सेवा मैनेजर से सीधे तौर पर रजिस्टर किया जा सकता है. अटैच किए गए एक्सटेंशन इंटरफ़ेस तब सबसे सही होते हैं, जब वे सब-इंटरफ़ेस से जुड़े होते हैं, क्योंकि ये हैरारकी ज़्यादा या एक से ज़्यादा बार हो सकते हैं. किसी अन्य सेवा के बाइंडर इंटरफ़ेस की हैरारकी को मिरर करने के लिए, ग्लोबल एक्सटेंशन का इस्तेमाल करने के लिए, बड़े पैमाने पर हिसाब-किताब की ज़रूरत होगी, ताकि सीधे तौर पर अटैच किए गए एक्सटेंशन के जैसे फ़ंक्शन दिए जा सकें.

बाइंडर पर एक्सटेंशन सेट करने के लिए, इन एपीआई का इस्तेमाल करें:

  • एनडीके बैकएंड में: AIBinder_setExtension
  • Java बैकएंड में: android.os.Binder.setExtension
  • सीपीपी बैकएंड में: android::Binder::setExtension
  • Rust बैकएंड में: binder::Binder::set_extension

बाइंडर पर एक्सटेंशन पाने के लिए, इन एपीआई का इस्तेमाल करें:

  • एनडीके बैकएंड में: AIBinder_getExtension
  • Java बैकएंड में: android.os.IBinder.getExtension
  • सीपीपी बैकएंड में: android::IBinder::getExtension
  • Rust बैकएंड में: binder::Binder::get_extension

इन एपीआई के बारे में ज़्यादा जानकारी पाने के लिए, उससे जुड़े बैकएंड में getExtension फ़ंक्शन से जुड़े दस्तावेज़ में जाएं. एक्सटेंशन को इस्तेमाल करने के तरीके का उदाहरण हार्डवेयर/इंटरफ़ेस/टेस्ट/एक्सटेंशन/वाइब्रेटर में मिल सकता है.

अहम एआईडीएल और एचआईडीएल में अंतर

एआईडीएल एचएएल या एआईडीएल एचएएल इंटरफ़ेस का इस्तेमाल करते समय, एचआईडीएल एचएएल लिखने और लिखने के बीच के अंतर का ध्यान रखें.

  • एआईडीएल भाषा का सिंटैक्स Java के काफ़ी करीब है. HIDL सिंटैक्स, C++ की तरह है.
  • सभी एआईडीएल इंटरफ़ेस में गड़बड़ी की स्थितियां पहले से मौजूद होती हैं. कस्टम स्टेटस टाइप बनाने के बजाय, इंटरफ़ेस फ़ाइलों में कॉन्स्टेंट स्टेटस इंस्टेंस बनाएं. साथ ही, सीपीपी/एनडीके बैकएंड में EX_SERVICE_SPECIFIC और Java बैकएंड में ServiceSpecificException का इस्तेमाल करें. गड़बड़ी को मैनेज करना लेख देखें.
  • बाइंडर ऑब्जेक्ट भेजे जाने पर, एआईडीएल, थ्रेडपूल अपने-आप शुरू नहीं करता है. इन्हें मैन्युअल तरीके से शुरू किया जाना चाहिए (थ्रेड मैनेजमेंट देखें).
  • एआईडीएल, ट्रांसपोर्ट वाली ऐसी गड़बड़ियों को रद्द नहीं करता है जिनके सही का निशान नहीं लगाया गया है. हालांकि, HIDL Return, सही का निशान न होने पर होने वाली गड़बड़ियों को रद्द करता है.
  • एआईडीएल हर फ़ाइल के लिए सिर्फ़ एक टाइप के बारे में जानकारी दे सकता है.
  • एआईडीएल आर्ग्युमेंट को आउटपुट पैरामीटर के साथ-साथ "इन/आउट/इनआउट" के तौर पर भी सेट किया जा सकता है. "सिंक्रोनस कॉलबैक नहीं होते".
  • एआईडीएल, हैंडल के बजाय प्रिमिटिव टाइप के तौर पर fd का इस्तेमाल करता है.
  • HIDL, काम न करने वाले बदलावों के लिए मेजर वर्शन का इस्तेमाल करता है. साथ ही, काम करने वाले बदलावों के लिए, माइनर वर्शन का इस्तेमाल करता है. एआईडीएल में पुराने सिस्टम के साथ काम करने की सुविधा वाले बदलाव अपने-आप लागू होते हैं. एआईडीएल में मेजर वर्शन का कोई कॉन्सेप्ट नहीं है. इसके बजाय, इसे पैकेज के नामों में शामिल किया जाता है. उदाहरण के लिए, एआईडीएल पैकेज नाम bluetooth2 का इस्तेमाल कर सकता है.
  • एआईडीएल, डिफ़ॉल्ट रूप से रीयलटाइम प्राथमिकता इनहेरिट नहीं करता. रीयलटाइम प्रायॉरिटी इनहेरिटेंस को चालू करने के लिए, setInheritRt फ़ंक्शन को हर बाइंडर के हिसाब से इस्तेमाल करना चाहिए.