Android 11 में, Android में एचएएल के लिए एआईडीएल का इस्तेमाल करने की सुविधा जोड़ी गई है. इससे, HIDL के बिना Android के कुछ हिस्सों को लागू किया जा सकता है. जहां भी हो सके, एचएएल को सिर्फ़ एआईडीएल का इस्तेमाल करने के लिए ट्रांज़िशन करें. जब अपस्ट्रीम एचएएल, एचआईडीएल का इस्तेमाल करते हैं, तो एचआईडीएल का इस्तेमाल करना ज़रूरी है.
system.img
जैसे फ़्रेमवर्क कॉम्पोनेंट और vendor.img
जैसे हार्डवेयर कॉम्पोनेंट के बीच कम्यूनिकेट करने के लिए, AIDL का इस्तेमाल करने वाले एचएएल को स्थिर AIDL का इस्तेमाल करना चाहिए. हालांकि, अगर आईपीसी के एक हिस्से से दूसरे एचएएल का इस्तेमाल किया जाता है, तो आईपीसी सिस्टम पर कोई पाबंदी नहीं है.
वजह
AIDL, HIDL से पहले से मौजूद है. इसका इस्तेमाल कई जगहों पर किया जाता है, जैसे कि Android फ़्रेमवर्क कॉम्पोनेंट के बीच या ऐप्लिकेशन में. अब AIDL में स्थिरता की सुविधा उपलब्ध है. इसलिए, एक ही आईपीसी रनटाइम की मदद से पूरे स्टैक को लागू किया जा सकता है. HIDL के मुकाबले AIDL में बेहतर वर्शनिंग सिस्टम भी है.
- एक ही आईपीसी भाषा का इस्तेमाल करने का मतलब है कि आपको सिर्फ़ एक चीज़ सीखनी है, डीबग करनी है, ऑप्टिमाइज़ करनी है, और सुरक्षित करनी है.
- AIDL, इंटरफ़ेस के मालिकों के लिए, इन-प्लेस वर्शनिंग की सुविधा देता है:
- मालिक, इंटरफ़ेस के आखिर में तरीके या पार्सल किए जा सकने वाले आइटम में फ़ील्ड जोड़ सकते हैं. इसका मतलब है कि साल दर साल वर्शन कोड इस्तेमाल करना आसान होता है और साल दर साल लागत भी कम होती है. टाइप में बदलाव किए जा सकते हैं और हर इंटरफ़ेस वर्शन के लिए अलग लाइब्रेरी की ज़रूरत नहीं होती.
- एक्सटेंशन इंटरफ़ेस, टाइप सिस्टम के बजाय रनटाइम पर अटैच किए जा सकते हैं. इसलिए, डाउनस्ट्रीम एक्सटेंशन को इंटरफ़ेस के नए वर्शन पर फिर से आधार बनाने की ज़रूरत नहीं है.
- जब कोई डेवलपर अपने मौजूदा AIDL इंटरफ़ेस को स्थिर करने का विकल्प चुनता है, तो उसका इस्तेमाल सीधे तौर पर किया जा सकता है. पहले, इंटरफ़ेस की पूरी कॉपी को HIDL में बनाना पड़ता था.
AIDL रनटाइम के हिसाब से बनाना
AIDL के तीन अलग-अलग बैकएंड होते हैं: Java, NDK, और CPP. Stable AIDL का इस्तेमाल करने के लिए, आपको system/lib*/libbinder.so
पर libbinder की सिस्टम कॉपी का इस्तेमाल करना होगा और /dev/binder
पर बातचीत करनी होगी. वेंडर इमेज पर मौजूद कोड के लिए, इसका मतलब है कि libbinder
(VNDK से) का इस्तेमाल नहीं किया जा सकता: इस लाइब्रेरी में अस्थिर C++ एपीआई और अस्थिर इंटरनल हैं. इसके बजाय, नेटिव वेंडर कोड को एआईडीएल के एनडीके बैकएंड का इस्तेमाल करना चाहिए. साथ ही, libbinder_ndk
(जो सिस्टम libbinder.so
के साथ काम करता है) और aidl_interface
एंट्री से बनाई गई एनडीके लाइब्रेरी से लिंक करना चाहिए. मॉड्यूल के सटीक नामों के लिए, मॉड्यूल के नाम तय करने के नियम देखें.
AIDL HAL इंटरफ़ेस लिखना
सिस्टम और वेंडर के बीच AIDL इंटरफ़ेस इस्तेमाल करने के लिए, इंटरफ़ेस में दो बदलाव करने होंगे:
- हर टाइप की परिभाषा के बारे में
@VintfStability
के साथ एनोटेट किया जाना चाहिए. aidl_interface
एलान मेंstability: "vintf",
शामिल होना चाहिए.
सिर्फ़ इंटरफ़ेस का मालिक ही इनमें बदलाव कर सकता है.
ये बदलाव करने के बाद, इंटरफ़ेस को VINTF मेनिफ़ेस्ट में शामिल करना ज़रूरी है, ताकि यह काम कर सके. वीटीएस टेस्ट vts_treble_vintf_vendor_test
का इस्तेमाल करके, इस और इससे जुड़ी ज़रूरी शर्तों की जांच करें. जैसे, यह पुष्टि करना कि रिलीज़ किए गए इंटरफ़ेस फ़्रीज़ हैं. @VintfStability
इंटरफ़ेस का इस्तेमाल, इन ज़रूरी शर्तों के बिना भी किया जा सकता है. इसके लिए, किसी बाइंडर ऑब्जेक्ट को किसी दूसरी प्रोसेस पर भेजने से पहले, NDK बैकएंड में AIBinder_forceDowngradeToLocalStability
, C++ बैकएंड में android::Stability::forceDowngradeToLocalStability
या Java बैकएंड में android.os.Binder#forceDowngradeToSystemStability
को कॉल करें. Java में, किसी सेवा को वेंडर के स्टेबिलिटी लेवल पर डाउनग्रेड करने की सुविधा उपलब्ध नहीं है. इसकी वजह यह है कि सभी ऐप्लिकेशन, सिस्टम के कॉन्टेक्स्ट में चलते हैं.
इसके अलावा, ज़्यादा से ज़्यादा कोड को एक प्लैटफ़ॉर्म से दूसरे प्लैटफ़ॉर्म पर ले जाने के लिए और ग़ैर-ज़रूरी अतिरिक्त लाइब्रेरी जैसी संभावित समस्याओं से बचने के लिए, सीपीपी बैकएंड को बंद करें.
ध्यान दें कि नीचे दिए गए कोड के उदाहरण में backends
का इस्तेमाल सही है, क्योंकि इसमें तीन बैकएंड (Java, NDK, और CPP) हैं. नीचे दिए गए कोड में, सीपीपी बैकएंड को चुनने और उसे बंद करने का तरीका बताया गया है.
aidl_interface: {
...
backends: {
cpp: {
enabled: false,
},
},
}
AIDL HAL इंटरफ़ेस ढूंढें
एचएएल के लिए AOSP के स्टेबल एआईडीएल इंटरफ़ेस, aidl
फ़ोल्डर में मौजूद एचआईडीएल इंटरफ़ेस की ही बेस डायरेक्ट्री में होते हैं.
- hardware/interfaces: आम तौर पर, हार्डवेयर से मिलने वाले इंटरफ़ेस के लिए
- frameworks/hardware/interfaces: हार्डवेयर के लिए उपलब्ध कराए गए हाई-लेवल इंटरफ़ेस के लिए
- सिस्टम/हार्डवेयर/इंटरफ़ेस: हार्डवेयर को दिए गए निम्न-स्तरीय इंटरफ़ेस के लिए
आपको एक्सटेंशन इंटरफ़ेस को vendor
या hardware
में मौजूद अन्य hardware/interfaces
सबडायरेक्ट्री में डालना चाहिए.
एक्सटेंशन इंटरफ़ेस
Android के हर रिलीज़ में, आधिकारिक AOSP इंटरफ़ेस का एक सेट होता है. अगर Android पार्टनर इन इंटरफ़ेस में फ़ंक्शन जोड़ना चाहते हैं, तो उन्हें सीधे तौर पर इन्हें नहीं बदलना चाहिए. ऐसा इसलिए, क्योंकि इसका मतलब यह होगा कि उनका Android रनटाइम, एओएसपी Android रनटाइम के साथ काम नहीं करता है. GMS डिवाइसों के लिए, इन इंटरफ़ेस में बदलाव न करने से यह भी पक्का होता है कि GSI इमेज काम करती रहे.
एक्सटेंशन दो अलग-अलग तरीकों से रजिस्टर किए जा सकते हैं:
- रनटाइम के दौरान, अटैच किए गए एक्सटेंशन देखें.
- स्टैंडअलोन, दुनिया भर में और VINTF में रजिस्टर किया गया हो.
हालांकि, जब वेंडर के हिसाब से (यानी अपस्ट्रीम AOSP का हिस्सा नहीं) कॉम्पोनेंट इंटरफ़ेस का इस्तेमाल करते हैं, तो मर्ज करने से जुड़ी कोई समस्या नहीं होती. हालांकि, जब अपस्ट्रीम एओएसपी कॉम्पोनेंट में डाउनस्ट्रीम बदलाव किए जाते हैं, तो मर्ज करने के विवाद हो सकते हैं. इसके लिए, इन रणनीतियों का सुझाव दिया जाता है:
- अगली रिलीज़ में जोड़े गए इंटरफ़ेस एओएसपी में अप-स्ट्रीम किए जा सकते हैं
- इंटरफ़ेस में जोड़े गए ऐसे बदलाव जिन्हें मर्ज करने में कोई समस्या नहीं आती और जो ज़्यादा सुविधाएं देते हैं, उन्हें अगले रिलीज़ में अपस्ट्रीम किया जा सकता है
पार्स किए जा सकने वाले एक्सटेंशन: Parcelable Holder
ParcelableHolder
एक Parcelable
है, जिसमें कोई दूसरा Parcelable
शामिल हो सकता है.
ParcelableHolder
का मुख्य इस्तेमाल उदाहरण, Parcelable
को एक्सटेंसिबल बनाना है.
उदाहरण के लिए, डिवाइस लागू करने वाले लोग, अपनी वैल्यू-ऐड करने वाली सुविधाओं को शामिल करने के लिए, AOSP के तय किए गए 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 के अगले रिलीज़ में Parcelable में बदलाव होने पर, डिवाइस को लागू करने वाले के जोड़े गए फ़ील्ड में कोई विरोध हो सकता है.
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 HAL सर्वर इंस्टेंस के नाम
आम तौर पर, एआईडीएल एचएएल सेवाओं का एक इंस्टेंस नाम $package.$type/$instance
फ़ॉर्मैट में होता है. उदाहरण के लिए, वाइब्रेटर HAL का एक इंस्टेंस, 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>
अगर ऐसा नहीं है, तो उन्हें एआईडीएल सेवा को सामान्य रूप से रजिस्टर करना चाहिए. VTS जांच करते समय, यह उम्मीद की जाती है कि एआईडीएल के सभी एचएएल उपलब्ध हों.
एआईडीएल क्लाइंट लिखना
AIDL क्लाइंट को, अपने बारे में संगतता मैट्रिक्स में बताना होगा. उदाहरण के लिए, इस तरह:
<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 इंटरफ़ेस को AIDL में बदलने के लिए, hidl2aidl
टूल का इस्तेमाल करें.
hidl2aidl
की सुविधाएं:
- दिए गए पैकेज के लिए,
.hal
फ़ाइलों के आधार पर.aidl
फ़ाइलें बनाएं - सभी बैकएंड चालू होने पर, बनाए गए नए AIDL पैकेज के लिए बिल्ड नियम बनाएं
- HIDL टाइप से AIDL टाइप में अनुवाद करने के लिए, Java, CPP, और NDK बैकएंड में अनुवाद करने के तरीके बनाएं
- ज़रूरी डिपेंडेंसी वाली Translate लाइब्रेरी के लिए, बिल्ड नियम बनाना
- स्टैटिक एसर्ट बनाएं, ताकि यह पक्का किया जा सके कि सीपीपी और एनडीके बैकएंड में, HIDL और एआईडीएल एनोमेरेटर की वैल्यू एक जैसी हों
.hal फ़ाइलों के पैकेज को .aidl फ़ाइलों में बदलने के लिए, यह तरीका अपनाएं:
system/tools/hidl/hidl2aidl
में मौजूद टूल बनाएं.इस टूल को नए सोर्स से बनाने पर, आपको सबसे बेहतर अनुभव मिलता है. पिछले रिलीज़ की पुरानी शाखाओं पर मौजूद इंटरफ़ेस को बदलने के लिए, नए वर्शन का इस्तेमाल किया जा सकता है.
m hidl2aidl
टूल को आउटपुट डायरेक्ट्री के साथ चलाएं. इसके बाद, उस पैकेज का नाम डालें जिसे बदलना है.
इसके अलावा, जनरेट की गई सभी फ़ाइलों में सबसे ऊपर, लाइसेंस की नई फ़ाइल का कॉन्टेंट जोड़ने के लिए,
-l
आर्ग्युमेंट का इस्तेमाल करें. सही लाइसेंस और तारीख का इस्तेमाल करें.hidl2aidl -o <output directory> -l <file with license> <package>
उदाहरण के लिए:
hidl2aidl -o . -l my_license.txt android.hardware.nfc@1.2
जनरेट की गई फ़ाइलें पढ़ें और कन्वर्ज़न से जुड़ी सभी समस्याओं को ठीक करें.
conversion.log
में ऐसी समस्याएं होती हैं जिन्हें पहले ठीक करना ज़रूरी है.- जनरेट की गई
.aidl
फ़ाइलों में ऐसी चेतावनियां और सुझाव हो सकते हैं जिन पर कार्रवाई की ज़रूरत हो. ये टिप्पणियां//
से शुरू होती हैं. - इस अवसर का इस्तेमाल करके, पैकेज को बेहतर बनाएं और उसमें मौजूद गड़बड़ियों को ठीक करें.
- ज़रूरी सुविधाओं के लिए,
@JavaDerive
एनोटेशन देखें. जैसे,toString
याequals
.
सिर्फ़ ज़रूरी टारगेट बनाएं.
- ऐसे बैकएंड बंद करें जिनका इस्तेमाल नहीं किया जाएगा. सीपीपी बैकएंड के बजाय, एनडीके बैकएंड का इस्तेमाल करें. रनटाइम चुनना देखें.
- अनुवाद करने वाली लाइब्रेरी या उनका जनरेट किया गया ऐसा कोड हटाएं जिसका इस्तेमाल नहीं किया जाएगा.
एआईडीएल/एचआईडीएल के बीच के मुख्य अंतर देखें.
- आम तौर पर, AIDL के पहले से मौजूद
Status
और अपवादों का इस्तेमाल करने से इंटरफ़ेस बेहतर होता है. साथ ही, इंटरफ़ेस के हिसाब से किसी दूसरे स्टेटस टाइप की ज़रूरत नहीं पड़ती. - मेथड में AIDL इंटरफ़ेस के आर्ग्युमेंट, डिफ़ॉल्ट रूप से
@nullable
नहीं होते, जैसे कि वे HIDL में होते थे.
- आम तौर पर, AIDL के पहले से मौजूद
एआईडीएल एचएएल के लिए SEPolicy
वेंडर कोड को दिखने वाली AIDL सेवा टाइप में, hal_service_type
एट्रिब्यूट होना चाहिए. अगर ऐसा नहीं है, तो sepolicy कॉन्फ़िगरेशन, किसी भी अन्य AIDL सेवा के जैसा ही होता है. हालांकि, एचएएल के लिए खास एट्रिब्यूट होते हैं. यहां HAL सेवा के संदर्भ की परिभाषा का उदाहरण दिया गया है:
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 को ऐक्सेस कर सकती हैं और hal_foo_server
प्रोसेस, HAL को रजिस्टर कर सकती हैं. रजिस्ट्रेशन से जुड़े इन नियमों को लागू करने का काम, कॉन्टेक्स्ट मैनेजर (servicemanager
) करता है. ध्यान दें कि सेवा के नाम, हमेशा एचएएल एट्रिब्यूट से मेल नहीं खा सकते. उदाहरण के लिए, हमें
hal_attribute_service(hal_foo, hal_foo2_service)
दिख सकता है. आम तौर पर, इससे यह पता चलता है कि सेवाओं का इस्तेमाल हमेशा एक साथ किया जाता है. इसलिए, हम hal_foo2_service
को हटाकर, अपनी सभी सेवाओं के लिए hal_foo_service
का इस्तेमाल कर सकते हैं. ज़्यादातर एचएएल, एक से ज़्यादा hal_attribute_service
सेट करते हैं, क्योंकि एचएएल के मूल एट्रिब्यूट का नाम सामान्य नहीं है और इसे बदला नहीं जा सकता.
इन सभी को मिलाकर, एचएएल का उदाहरण कुछ ऐसा दिखता है:
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
बाइंडर के लिए एक्सटेंशन पाने के लिए, इन एपीआई का इस्तेमाल करें:
- NDK बैकएंड में:
AIBinder_getExtension
- Java बैकएंड में:
android.os.IBinder.getExtension
- सीपीपी बैकएंड में:
android::IBinder::getExtension
- Rust बैकएंड में:
binder::Binder::get_extension
इन एपीआई के बारे में ज़्यादा जानकारी पाने के लिए, उससे जुड़े बैकएंड में getExtension
फ़ंक्शन से जुड़े दस्तावेज़ में जाएं. एक्सटेंशन इस्तेमाल करने का उदाहरण, hardware/interfaces/tests/extension/vibrator में देखा जा सकता है.
AIDL और HIDL के बीच के मुख्य अंतर
AIDL HALs या AIDL HAL इंटरफ़ेस का इस्तेमाल करते समय, HIDL HALs लिखने के मुकाबले अंतरों के बारे में पता होना चाहिए.
- AIDL भाषा का सिंटैक्स, Java से मिलता-जुलता है. HIDL सिंटैक्स, C++ की तरह है.
- सभी AIDL इंटरफ़ेस में, गड़बड़ी की स्थिति पहले से मौजूद होती है. कस्टम स्टेटस टाइप बनाने के बजाय, इंटरफ़ेस फ़ाइलों में कॉन्स्टेंट स्टेटस इंस्टेंस बनाएं. साथ ही, सीपीपी/एनडीके बैकएंड में
EX_SERVICE_SPECIFIC
और Java बैकएंड मेंServiceSpecificException
का इस्तेमाल करें. गड़बड़ी को मैनेज करना देखें. - बाइंडर ऑब्जेक्ट भेजे जाने पर, AIDL अपने-आप थ्रेडपूल शुरू नहीं करता. इन्हें मैन्युअल तरीके से शुरू करना होगा (थ्रेड मैनेजमेंट देखें).
- AIDL, ट्रांसपोर्ट से जुड़ी ऐसी गड़बड़ियों पर प्रोसेस को बंद नहीं करता जिनकी जांच नहीं की गई है. हालांकि, HIDL
Return
ऐसी गड़बड़ियों पर प्रोसेस को बंद कर देता है. - एआईडीएल हर फ़ाइल के लिए सिर्फ़ एक टाइप का एलान कर सकता है.
- एआईडीएल आर्ग्युमेंट को आउटपुट पैरामीटर के साथ-साथ, "इन/आउट/इनआउट" के तौर पर भी सेट किया जा सकता है. "सिंक्रोनस कॉलबैक नहीं होते".
- AIDL, हैंडल के बजाय प्राइमटिव टाइप के तौर पर fd का इस्तेमाल करता है.
- HIDL, काम न करने वाले बदलावों के लिए बड़े वर्शन और काम करने वाले बदलावों के लिए छोटे वर्शन का इस्तेमाल करता है. AIDL में, पुराने सिस्टम के साथ काम करने वाले बदलाव किए जाते हैं.
AIDL में, मुख्य वर्शन का कोई खास कॉन्सेप्ट नहीं है. इसके बजाय, इसे पैकेज के नामों में शामिल किया जाता है. उदाहरण के लिए, AIDL, पैकेज के नाम
bluetooth2
का इस्तेमाल कर सकता है. - AIDL, डिफ़ॉल्ट रूप से रीयल-टाइम प्राथमिकता को इनहेरिट नहीं करता. रीयलटाइम प्रायॉरिटी इनहेरिटेंस को चालू करने के लिए,
setInheritRt
फ़ंक्शन को हर बाइंडर के हिसाब से इस्तेमाल करना चाहिए.