एचएएल इंटरफ़ेस परिभाषा भाषा या एचआईडीएल (उच्चारण "छिपाना-एल") एक एचएएल और उसके उपयोगकर्ताओं के बीच इंटरफ़ेस निर्दिष्ट करने के लिए एक इंटरफ़ेस विवरण भाषा (आईडीएल) है। यह इंटरफेस और पैकेज में एकत्रित प्रकार और विधि कॉल निर्दिष्ट करने की अनुमति देता है। मोटे तौर पर, एचआईडीएल कोडबेस के बीच संचार के लिए एक प्रणाली है जिसे स्वतंत्र रूप से संकलित किया जा सकता है। Android 10 के अनुसार, HIDL को हटा दिया गया है और Android हर जगह AIDL का उपयोग करने के लिए माइग्रेट कर रहा है।
HIDL का उपयोग इंटर-प्रोसेस कम्युनिकेशन (IPC) के लिए किया जाना है। प्रक्रियाओं के बीच संचार को बाइंडराइज्ड कहा जाता है। पुस्तकालयों के लिए जिन्हें एक प्रक्रिया से जोड़ा जाना चाहिए, एक पासथ्रू मोड भी उपलब्ध है (जावा में समर्थित नहीं)।
HIDL डेटा संरचनाओं और विधि हस्ताक्षरों को निर्दिष्ट करता है, जो इंटरफेस में व्यवस्थित होते हैं (एक वर्ग के समान) जो पैकेज में एकत्र किए जाते हैं। एचआईडीएल का सिंटैक्स सी ++ और जावा प्रोग्रामर के लिए परिचित लगेगा, हालांकि कीवर्ड के एक अलग सेट के साथ। HIDL जावा-शैली एनोटेशन का भी उपयोग करता है।
एचआईडीएल डिजाइन
एचआईडीएल का लक्ष्य यह है कि एचएएल के पुनर्निर्माण के बिना ढांचे को बदला जा सकता है। एचएएल को विक्रेताओं या एसओसी निर्माताओं द्वारा बनाया जाएगा और डिवाइस पर एक /vendor
विभाजन में डाल दिया जाएगा, जिससे एचएएल को फिर से संकलित किए बिना, अपने स्वयं के विभाजन में, एक ओटीए के साथ प्रतिस्थापित किया जा सकेगा।
एचआईडीएल डिजाइन निम्नलिखित चिंताओं को संतुलित करता है:
- इंटरऑपरेबिलिटी । विभिन्न आर्किटेक्चर, टूलचेन और बिल्ड कॉन्फ़िगरेशन के साथ संकलित की जा सकने वाली प्रक्रियाओं के बीच मज़बूती से इंटरऑपरेबल इंटरफेस बनाएं। HIDL इंटरफेस संस्करणबद्ध हैं और प्रकाशित होने के बाद इन्हें बदला नहीं जा सकता है।
- दक्षता । HIDL प्रतिलिपि संचालन की संख्या को कम करने का प्रयास करता है। एचआईडीएल-परिभाषित डेटा सी ++ मानक लेआउट डेटा संरचनाओं में सी ++ कोड में वितरित किया जाता है जिसे बिना पैकिंग के उपयोग किया जा सकता है। एचआईडीएल साझा मेमोरी इंटरफेस भी प्रदान करता है और, चूंकि आरपीसी स्वाभाविक रूप से कुछ हद तक धीमा है, एचआईडीएल आरपीसी कॉल का उपयोग किए बिना डेटा स्थानांतरित करने के दो तरीकों का समर्थन करता है: साझा स्मृति और एक तेज संदेश कतार (एफएमक्यू)।
- सहज ज्ञान युक्त । एचआईडीएल केवल आरपीसी के लिए मापदंडों
in
उपयोग करके स्मृति स्वामित्व के कांटेदार मुद्दों से बचा जाता है (देखें एंड्रॉइड इंटरफेस डेफिनिशन लैंग्वेज (एआईडीएल) ); वे मान जिन्हें विधियों से कुशलता से वापस नहीं किया जा सकता है, कॉलबैक फ़ंक्शंस के माध्यम से वापस कर दिए जाते हैं। ट्रांसफर के लिए न तो डेटा को HIDL में पास करना और न ही HIDL से डेटा प्राप्त करना डेटा के स्वामित्व को बदलता है-स्वामित्व हमेशा कॉलिंग फ़ंक्शन के पास रहता है। डेटा को केवल कॉल किए गए फ़ंक्शन की अवधि के लिए बने रहने की आवश्यकता होती है और कॉल किए गए फ़ंक्शन के वापस आने के तुरंत बाद नष्ट हो सकता है।
पासथ्रू मोड का उपयोग करना
Android के पुराने संस्करणों को चलाने वाले उपकरणों को Android O में अपडेट करने के लिए, आप पारंपरिक (और विरासत) दोनों HALs को एक नए HIDL इंटरफ़ेस में लपेट सकते हैं जो HAL को बाइंडराइज़्ड और समान-प्रक्रिया (पासथ्रू) मोड में कार्य करता है। यह रैपिंग एचएएल और एंड्रॉइड फ्रेमवर्क दोनों के लिए पारदर्शी है।
पासथ्रू मोड केवल C++ क्लाइंट और कार्यान्वयन के लिए उपलब्ध है। Android के पुराने संस्करणों को चलाने वाले उपकरणों में जावा में HAL नहीं लिखा होता है, इसलिए Java HALs स्वाभाविक रूप से बाइंडराइज़्ड होते हैं।
पासथ्रू हेडर फ़ाइलें
जब एक .hal
फ़ाइल संकलित की जाती है, hidl-gen
बाइंडर संचार के लिए उपयोग किए जाने वाले शीर्षलेखों के अतिरिक्त एक अतिरिक्त पासथ्रू हेडर फ़ाइल BsFoo.h
उत्पन्न करता है; यह हेडर फ़ंक्शन को dlopen
ed के रूप में परिभाषित करता है। चूंकि पासथ्रू एचएएल उसी प्रक्रिया में चलते हैं जिसमें उन्हें बुलाया जाता है, ज्यादातर मामलों में प्रत्यक्ष फ़ंक्शन कॉल (एक ही थ्रेड) द्वारा पासथ्रू विधियों को लागू किया जाता है। oneway
तरीके अपने स्वयं के धागे में चलते हैं क्योंकि उनका इरादा HAL को संसाधित करने के लिए प्रतीक्षा करने का नहीं है (इसका मतलब है कि कोई भी HAL जो पासथ्रू मोड में oneway
विधियों का उपयोग करता है वह थ्रेड-सुरक्षित होना चाहिए)।
IFoo.hal
को देखते हुए, BsFoo.h
अतिरिक्त सुविधाएँ प्रदान करने के लिए HIDL-जनित विधियों को लपेटता है (जैसे कि किसी अन्य थ्रेड में oneway
लेनदेन चलाना)। यह फ़ाइल BpFoo.h
के समान है, हालांकि बाइंडर का उपयोग करके IPC पर कॉल करने के बजाय, वांछित फ़ंक्शन सीधे लागू किए जाते हैं। HALs के भविष्य के कार्यान्वयन कई कार्यान्वयन प्रदान कर सकते हैं , जैसे कि FooFast HAL और एक FooAccurate HAL। ऐसे मामलों में, प्रत्येक अतिरिक्त कार्यान्वयन के लिए एक फ़ाइल बनाई जाएगी (उदाहरण के लिए, PTFooFast.cpp
और PTFooAccurate.cpp
)।
पासथ्रू HALs को बांधना
आप एचएएल कार्यान्वयन को बाँध सकते हैं जो पासथ्रू मोड का समर्थन करते हैं। HAL इंटरफ़ेस abcd@MN::IFoo
को देखते हुए, दो पैकेज बनाए जाते हैं:
-
abcd@MN::IFoo-impl
। एचएएल के कार्यान्वयन को शामिल करता है औरIFoo* HIDL_FETCH_IFoo(const char* name)
फ़ंक्शन को उजागर करता है। पुराने उपकरणों पर, यह पैकेजdlopen
ed है औरHIDL_FETCH_IFoo
का उपयोग करके कार्यान्वयन को तत्काल किया जाता है। आपhidl-gen
और-Lc++-impl
और-Landroidbp-impl
का उपयोग करके बेस कोड जेनरेट कर सकते हैं। -
abcd@MN::IFoo-service
. पासथ्रू एचएएल को खोलता है और खुद को एक बाइंडराइज्ड सेवा के रूप में पंजीकृत करता है, जिससे समान एचएएल कार्यान्वयन को पासथ्रू और बाइंडर दोनों के रूप में उपयोग किया जा सकता है।
IFoo
प्रकार को देखते हुए, आप IFoo
के उदाहरण तक पहुंच प्राप्त करने के लिए sp<IFoo> IFoo::getService(string name, bool getStub)
पर कॉल कर सकते हैं। यदि getStub
सत्य है, तो getService
केवल पासथ्रू मोड में HAL को खोलने का प्रयास करता है। यदि getStub
गलत है, तो getService
एक बाइंडरीकृत सेवा खोजने का प्रयास करता है; यदि वह विफल रहता है, तो वह पासथ्रू सेवा खोजने का प्रयास करता है। defaultPassthroughServiceImplementation
को छोड़कर getStub
पैरामीटर का कभी भी उपयोग नहीं किया जाना चाहिए। (एंड्रॉइड ओ के साथ लॉन्च होने वाले डिवाइस पूरी तरह से बाइंडर किए गए डिवाइस हैं, इसलिए पासथ्रू मोड में किसी सेवा को खोलने की अनुमति नहीं है।)
एचआईडीएल व्याकरण
डिज़ाइन के अनुसार, HIDL भाषा C के समान है (लेकिन C प्रीप्रोसेसर का उपयोग नहीं करती है)। नीचे वर्णित सभी विराम चिह्न ( =
और |
के स्पष्ट उपयोग के अलावा) व्याकरण का हिस्सा हैं।
नोट: HIDL कोड शैली के विवरण के लिए, कोड शैली मार्गदर्शिका देखें।
-
/** */
एक दस्तावेज़ीकरण टिप्पणी इंगित करता है। इन्हें केवल टाइप, मेथड, फील्ड और एनम वैल्यू डिक्लेरेशन पर लागू किया जा सकता है। -
/* */
एक बहुपंक्ति टिप्पणी को इंगित करता है। -
//
लाइन के अंत में एक टिप्पणी इंगित करता है।//
के अलावा, न्यूलाइन किसी अन्य व्हाइटस्पेस के समान ही हैं। - नीचे दिए गए उदाहरण व्याकरण में,
//
से पंक्ति के अंत तक का पाठ व्याकरण का हिस्सा नहीं है, बल्कि व्याकरण पर एक टिप्पणी है। -
[empty]
का अर्थ है कि शब्द खाली हो सकता है। -
?
शाब्दिक या शब्द का अनुसरण करने का अर्थ है कि यह वैकल्पिक है। -
...
संकेत के अनुसार अलग-अलग विराम चिह्नों के साथ शून्य या अधिक आइटम वाले अनुक्रम को इंगित करता है। HIDL में कोई भिन्न तर्क नहीं हैं। - अल्पविराम अलग अनुक्रम तत्व।
- अर्धविराम अंतिम तत्व सहित प्रत्येक तत्व को समाप्त करता है।
- अपरकेस एक नॉनटर्मिनल है।
-
italics
एक टोकन परिवार है जैसेinteger
याidentifier
(मानक सी पार्सिंग नियम)। -
constexpr
एक सी शैली स्थिर अभिव्यक्ति है (जैसे1 + 1
और1L << 3
)। -
import_name
एक पैकेज या इंटरफ़ेस नाम है, जो HIDL संस्करण में वर्णित के अनुसार योग्य है। - लोअरकेस
words
शाब्दिक टोकन हैं।
उदाहरण:
ROOT = PACKAGE IMPORTS PREAMBLE { ITEM ITEM ... } // not for types.hal | PACKAGE IMPORTS ITEM ITEM... // only for types.hal; no method definitions ITEM = ANNOTATIONS? oneway? identifier(FIELD, FIELD ...) GENERATES?; | safe_union identifier { UFIELD; UFIELD; ...}; | struct identifier { SFIELD; SFIELD; ...}; // Note - no forward declarations | union identifier { UFIELD; UFIELD; ...}; | enum identifier: TYPE { ENUM_ENTRY, ENUM_ENTRY ... }; // TYPE = enum or scalar | typedef TYPE identifier; VERSION = integer.integer; PACKAGE = package android.hardware.identifier[.identifier[...]]@VERSION; PREAMBLE = interface identifier EXTENDS EXTENDS = <empty> | extends import_name // must be interface, not package GENERATES = generates (FIELD, FIELD ...) // allows the Binder interface to be used as a type // (similar to typedef'ing the final identifier) IMPORTS = [empty] | IMPORTS import import_name; TYPE = uint8_t | int8_t | uint16_t | int16_t | uint32_t | int32_t | uint64_t | int64_t | float | double | bool | string | identifier // must be defined as a typedef, struct, union, enum or import // including those defined later in the file | memory | pointer | vec<TYPE> | bitfield<TYPE> // TYPE is user-defined enum | fmq_sync<TYPE> | fmq_unsync<TYPE> | TYPE[SIZE] FIELD = TYPE identifier UFIELD = TYPE identifier | safe_union identifier { FIELD; FIELD; ...} identifier; | struct identifier { FIELD; FIELD; ...} identifier; | union identifier { FIELD; FIELD; ...} identifier; SFIELD = TYPE identifier | safe_union identifier { FIELD; FIELD; ...}; | struct identifier { FIELD; FIELD; ...}; | union identifier { FIELD; FIELD; ...}; | safe_union identifier { FIELD; FIELD; ...} identifier; | struct identifier { FIELD; FIELD; ...} identifier; | union identifier { FIELD; FIELD; ...} identifier; SIZE = // Must be greater than zero constexpr ANNOTATIONS = [empty] | ANNOTATIONS ANNOTATION ANNOTATION = | @identifier | @identifier(VALUE) | @identifier(ANNO_ENTRY, ANNO_ENTRY ...) ANNO_ENTRY = identifier=VALUE VALUE = "any text including \" and other escapes" | constexpr | {VALUE, VALUE ...} // only in annotations ENUM_ENTRY = identifier | identifier = constexpr
शब्दावली
यह खंड निम्नलिखित एचआईडीएल-संबंधित शब्दों का उपयोग करता है:
बाँधना | इंगित करता है कि HIDL का उपयोग प्रक्रियाओं के बीच दूरस्थ प्रक्रिया कॉल के लिए किया जा रहा है, जिसे एक बाइंडर-जैसी तंत्र पर लागू किया गया है। पासथ्रू भी देखें। |
---|---|
कॉलबैक, अतुल्यकालिक | एक एचएएल उपयोगकर्ता द्वारा सेवा प्रदान किया गया इंटरफ़ेस, एचएएल (एक एचआईडीएल विधि के माध्यम से) को पास किया गया, और एचएएल द्वारा किसी भी समय डेटा वापस करने के लिए बुलाया गया। |
कॉलबैक, तुल्यकालिक | क्लाइंट को सर्वर के HIDL विधि कार्यान्वयन से डेटा लौटाता है। उन तरीकों के लिए उपयोग नहीं किया जाता है जो शून्य या एकल आदिम मान लौटाते हैं। |
ग्राहक | प्रक्रिया जो किसी विशेष इंटरफ़ेस के तरीकों को कॉल करती है। एक HAL या फ्रेमवर्क प्रक्रिया एक इंटरफ़ेस का क्लाइंट और दूसरे का सर्वर हो सकता है। पासथ्रू भी देखें। |
फैली | एक इंटरफ़ेस इंगित करता है जो किसी अन्य इंटरफ़ेस में विधियों और/या प्रकारों को जोड़ता है। एक इंटरफ़ेस केवल एक अन्य इंटरफ़ेस का विस्तार कर सकता है। एक ही पैकेज नाम में मामूली संस्करण वृद्धि के लिए या पुराने पैकेज पर निर्माण के लिए एक नए पैकेज (उदाहरण के लिए एक विक्रेता एक्सटेंशन) के लिए उपयोग किया जा सकता है। |
उत्पन्न करता है | एक इंटरफ़ेस विधि इंगित करता है जो क्लाइंट को मान लौटाता है। एक गैर-आदिम मान, या एक से अधिक मान वापस करने के लिए, एक सिंक्रोनस कॉलबैक फ़ंक्शन उत्पन्न होता है। |
इंटरफेस | विधियों और प्रकारों का संग्रह। सी ++ या जावा में कक्षा में अनुवादित। इंटरफ़ेस में सभी विधियों को एक ही दिशा में बुलाया जाता है: क्लाइंट प्रक्रिया सर्वर प्रक्रिया द्वारा कार्यान्वित विधियों को आमंत्रित करती है। |
एक तरफ़ा रास्ता | जब एक HIDL पद्धति पर लागू किया जाता है, तो यह इंगित करता है कि विधि कोई मान नहीं लौटाती है और अवरुद्ध नहीं करती है। |
पैकेज | एक संस्करण साझा करने वाले इंटरफेस और डेटा प्रकारों का संग्रह। |
निकासी | HIDL का तरीका जिसमें सर्वर एक साझा लाइब्रेरी है, क्लाइंट द्वारा dlopen एड। पासथ्रू मोड में, क्लाइंट और सर्वर एक ही प्रक्रिया हैं लेकिन अलग-अलग कोडबेस हैं। केवल HIDL मॉडल में लीगेसी कोडबेस लाने के लिए उपयोग किया जाता है। बाइंडराइज्ड भी देखें। |
सर्वर | प्रक्रिया जो एक इंटरफ़ेस के तरीकों को लागू करती है। पासथ्रू भी देखें। |
परिवहन | HIDL इन्फ्रास्ट्रक्चर जो सर्वर और क्लाइंट के बीच डेटा ले जाता है। |
संस्करण | पैकेज का संस्करण। दो पूर्णांकों से मिलकर बनता है, प्रमुख और लघु। मामूली संस्करण वृद्धि प्रकार और विधियों को जोड़ (लेकिन परिवर्तित नहीं) कर सकती है। |