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

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

फ्रेमवर्क घटकों, जैसे कि system.img , और हार्डवेयर घटकों, जैसे vendor.img , के बीच संचार करने के लिए AIDL का उपयोग करने वाले HAL को स्थिर AIDL का उपयोग करना चाहिए। हालाँकि, किसी विभाजन के भीतर संचार करने के लिए, उदाहरण के लिए एक एचएएल से दूसरे तक, आईपीसी तंत्र के उपयोग पर कोई प्रतिबंध नहीं है।

प्रेरणा

एआईडीएल एचआईडीएल से अधिक समय से अस्तित्व में है, और इसका उपयोग कई अन्य स्थानों पर किया जाता है, जैसे कि एंड्रॉइड फ्रेमवर्क घटकों के बीच या ऐप्स में। अब जब एआईडीएल के पास स्थिरता समर्थन है, तो एकल आईपीसी रनटाइम के साथ संपूर्ण स्टैक को लागू करना संभव है। एआईडीएल के पास एचआईडीएल की तुलना में बेहतर संस्करण प्रणाली भी है।

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

एआईडीएल एचएएल इंटरफ़ेस लिखना

सिस्टम और विक्रेता के बीच एआईडीएल इंटरफ़ेस का उपयोग करने के लिए, इंटरफ़ेस को दो परिवर्तनों की आवश्यकता है:

  • प्रत्येक प्रकार की परिभाषा को @VintfStability के साथ एनोटेट किया जाना चाहिए।
  • aidl_interface घोषणा में stability: "vintf", .

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

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

इसके अतिरिक्त, अधिकतम कोड पोर्टेबिलिटी के लिए और अनावश्यक अतिरिक्त लाइब्रेरी जैसी संभावित समस्याओं से बचने के लिए, सीपीपी बैकएंड को अक्षम करें।

ध्यान दें कि नीचे दिए गए कोड उदाहरण में backends का उपयोग सही है, क्योंकि तीन बैकएंड (जावा, एनडीके और सीपीपी) हैं। नीचे दिया गया कोड बताता है कि इसे अक्षम करने के लिए विशेष रूप से सीपीपी बैकएंड का चयन कैसे करें।

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

एआईडीएल एचएएल इंटरफेस ढूँढना

एचएएल के लिए एओएसपी स्थिर एआईडीएल इंटरफेस aidl फ़ोल्डरों में एचआईडीएल इंटरफेस के समान आधार निर्देशिकाओं में हैं।

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

आपको vendor या hardware में अन्य hardware/interfaces उपनिर्देशिकाओं में एक्सटेंशन इंटरफ़ेस डालना चाहिए।

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

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

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

हालाँकि एक एक्सटेंशन पंजीकृत है, जब विक्रेता-विशिष्ट (अर्थात् अपस्ट्रीम एओएसपी का हिस्सा नहीं) घटक इंटरफ़ेस का उपयोग करते हैं, तो मर्ज संघर्ष की कोई संभावना नहीं होती है। हालाँकि, जब अपस्ट्रीम AOSP घटकों में डाउनस्ट्रीम संशोधन किए जाते हैं, तो मर्ज विरोध उत्पन्न हो सकता है, और निम्नलिखित रणनीतियों की सिफारिश की जाती है:

  • इंटरफ़ेस परिवर्धन को अगली रिलीज़ में AOSP पर अपस्ट्रीम किया जा सकता है
  • इंटरफ़ेस परिवर्धन जो मर्ज विवादों के बिना और लचीलेपन की अनुमति देते हैं, उन्हें अगली रिलीज़ में अपस्ट्रीम किया जा सकता है

एक्सटेंशन पार्सलेबल्स: पार्सलेबलहोल्डर

ParcelableHolder एक Parcelable है जिसमें एक और Parcelable शामिल हो सकता है। ParcelableHolder का मुख्य उपयोग Parcelable एक्स्टेंसिबल बनाना है। उदाहरण के लिए, छवि जो डिवाइस कार्यान्वयनकर्ता अपने मूल्य-वर्धित सुविधाओं को शामिल करने के लिए AOSP-परिभाषित Parcelable , AospDefinedParcelable का विस्तार करने में सक्षम होने की उम्मीद करते हैं।

पहले ParcelableHolder के बिना, डिवाइस कार्यान्वयनकर्ता AOSP-परिभाषित स्थिर AIDL इंटरफ़ेस को संशोधित नहीं कर सकते थे क्योंकि अधिक फ़ील्ड जोड़ने में त्रुटि होगी:

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

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

ParcelableHolder उपयोग करके, पार्सल करने योग्य का मालिक Parcelable में एक विस्तार बिंदु को परिभाषित कर सकता है।

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

फिर डिवाइस कार्यान्वयनकर्ता अपने एक्सटेंशन के लिए अपने स्वयं के Parcelable परिभाषित कर सकते हैं।

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

अंत में, नए Parcelable ParcelableHolder फ़ील्ड के माध्यम से मूल 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 रनटाइम के विरुद्ध निर्माण

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

एआईडीएल एचएएल सर्वर इंस्टेंस नाम

परंपरा के अनुसार, एआईडीएल एचएएल सेवाओं का प्रारूप $package.$type/$instance का एक इंस्टेंस नाम होता है। उदाहरण के लिए, वाइब्रेटर HAL का एक उदाहरण android.hardware.vibrator.IVibrator/default के रूप में पंजीकृत है।

एआईडीएल एचएएल सर्वर लिखना

@VintfStability AIDL सर्वर को 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 से AIDL में परिवर्तित करना

HIDL इंटरफ़ेस को AIDL में बदलने के लिए hidl2aidl टूल का उपयोग करें।

hidl2aidl विशेषताएं:

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

.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 नहीं हैं जैसे कि वे एचआईडीएल में थे।

एआईडीएल एचएएल के लिए सेपॉलिसी

एक एआईडीएल सेवा प्रकार जो विक्रेता कोड को दिखाई देता है उसमें 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

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

हालाँकि, अब तक, हमने hal_foo_service और hal_foo ( hal_attribute(foo) से विशेषता जोड़ी) को संबद्ध नहीं किया है। एक HAL विशेषता hal_attribute_service मैक्रो का उपयोग करके AIDL HAL सेवाओं से जुड़ी है (HIDL HALs hal_attribute_hwservice मैक्रो का उपयोग करते हैं)। उदाहरण के लिए, hal_attribute_service(hal_foo, hal_foo_service) । इसका मतलब यह है कि hal_foo_client प्रक्रियाएं HAL पर पकड़ बना सकती हैं, और hal_foo_server प्रक्रियाएं HAL को पंजीकृत कर सकती हैं। इन पंजीकरण नियमों का प्रवर्तन संदर्भ प्रबंधक ( servicemanager ) द्वारा किया जाता है। ध्यान दें, सेवा नाम हमेशा एचएएल विशेषताओं के अनुरूप नहीं हो सकते हैं। उदाहरण के लिए, हम hal_attribute_service(hal_foo, hal_foo2_service) देख सकते हैं। हालांकि आम तौर पर, चूंकि इसका तात्पर्य यह है कि सेवाओं का उपयोग हमेशा एक साथ किया जाता है, हम hal_foo2_service हटाने और हमारे सभी सेवा संदर्भों के लिए hal_foo_service उपयोग करने पर विचार कर सकते हैं। अधिकांश HAL जो एकाधिक 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
  • जावा बैकएंड में: android.os.Binder.setExtension
  • सीपीपी बैकएंड में: android::Binder::setExtension
  • रस्ट बैकएंड में: binder::Binder::set_extension

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

  • एनडीके बैकएंड में: AIBinder_getExtension
  • जावा बैकएंड में: android.os.IBinder.getExtension
  • सीपीपी बैकएंड में: android::IBinder::getExtension
  • रस्ट बैकएंड में: binder::Binder::get_extension

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

प्रमुख एआईडीएल/एचआईडीएल अंतर

एआईडीएल एचएएल का उपयोग करते समय या एआईडीएल एचएएल इंटरफेस का उपयोग करते समय, एचआईडीएल एचएएल लिखने की तुलना में अंतर से अवगत रहें।

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