एचएएल इंटरफ़ेस परिभाषा भाषा या एचआईडीएल एक एचएएल और उसके उपयोगकर्ताओं के बीच इंटरफ़ेस निर्दिष्ट करने के लिए एक इंटरफ़ेस विवरण भाषा (आईडीएल) है। एचआईडीएल इंटरफेस और पैकेज में एकत्रित प्रकार और विधि कॉल निर्दिष्ट करने की अनुमति देता है। अधिक व्यापक रूप से, HIDL कोडबेस के बीच संचार करने की एक प्रणाली है जिसे स्वतंत्र रूप से संकलित किया जा सकता है। Android 10 के अनुसार, HIDL को हटा दिया गया है और Android हर जगह AIDL का उपयोग करने के लिए स्थानांतरित हो रहा है।
एचआईडीएल का उपयोग अंतर-प्रक्रिया संचार (आईपीसी) के लिए किया जाना है। एचडीएल के साथ बनाए गए एचएएल को बाइंडराइज्ड एचएएल कहा जाता है क्योंकि वे बाइंडर इंटर-प्रोसेस कम्युनिकेशन (आईपीसी) कॉल का उपयोग करके अन्य आर्किटेक्चर परतों के साथ संचार कर सकते हैं। बाइंडराइज़्ड एचएएल उनका उपयोग करने वाले क्लाइंट से एक अलग प्रक्रिया में चलते हैं। उन पुस्तकालयों के लिए जिन्हें किसी प्रक्रिया से जोड़ा जाना चाहिए, एक पासथ्रू मोड भी उपलब्ध है (जावा में समर्थित नहीं)।
एचआईडीएल डेटा संरचनाओं और विधि हस्ताक्षरों को निर्दिष्ट करता है, जो इंटरफेस (एक वर्ग के समान) में व्यवस्थित होते हैं जिन्हें पैकेज में एकत्र किया जाता है। HIDL का सिंटैक्स C++ और Java प्रोग्रामर्स के लिए परिचित लगता है, लेकिन कीवर्ड के एक अलग सेट के साथ। HIDL जावा-शैली एनोटेशन का भी उपयोग करता है।
शब्दावली
यह अनुभाग निम्नलिखित HIDL-संबंधित शब्दों का उपयोग करता है:
जिल्दसाज़ | इंगित करता है कि HIDL का उपयोग प्रक्रियाओं के बीच दूरस्थ प्रक्रिया कॉल के लिए किया जा रहा है, जिसे बाइंडर-जैसी तंत्र पर लागू किया गया है। पासथ्रू भी देखें। |
---|---|
कॉलबैक, अतुल्यकालिक | एचएएल उपयोगकर्ता द्वारा परोसा गया इंटरफ़ेस, एचएएल को पास किया गया (एचआईडीएल विधि का उपयोग करके), और एचएएल द्वारा किसी भी समय डेटा वापस करने के लिए कॉल किया जाता है। |
कॉलबैक, सिंक्रोनस | सर्वर के HIDL विधि कार्यान्वयन से क्लाइंट को डेटा लौटाता है। उन तरीकों के लिए अप्रयुक्त जो शून्य या एकल आदिम मान लौटाते हैं। |
ग्राहक | वह प्रक्रिया जो किसी विशेष इंटरफ़ेस के तरीकों को कॉल करती है। एक एचएएल या एंड्रॉइड फ्रेमवर्क प्रक्रिया एक इंटरफ़ेस का क्लाइंट और दूसरे का सर्वर हो सकती है। पासथ्रू भी देखें। |
का विस्तार | एक इंटरफ़ेस को इंगित करता है जो किसी अन्य इंटरफ़ेस में विधियों और/या प्रकारों को जोड़ता है। एक इंटरफ़ेस केवल एक अन्य इंटरफ़ेस का विस्तार कर सकता है। समान पैकेज नाम में लघु संस्करण वृद्धि के लिए या पुराने पैकेज पर नया पैकेज (उदाहरण के लिए विक्रेता एक्सटेंशन) बनाने के लिए उपयोग किया जा सकता है। |
उत्पन्न करता है | एक इंटरफ़ेस विधि को इंगित करता है जो क्लाइंट को मान लौटाता है। एक गैर-आदिम मान, या एक से अधिक मान वापस करने के लिए, एक सिंक्रोनस कॉलबैक फ़ंक्शन उत्पन्न होता है। |
इंटरफेस | तरीकों और प्रकारों का संग्रह. C++ या Java में किसी कक्षा में अनुवादित। इंटरफ़ेस में सभी विधियों को एक ही दिशा में बुलाया जाता है: एक क्लाइंट प्रक्रिया सर्वर प्रक्रिया द्वारा कार्यान्वित विधियों को आमंत्रित करती है। |
एक तरफ़ा रास्ता | जब HIDL विधि पर लागू किया जाता है, तो यह इंगित करता है कि विधि कोई मान नहीं लौटाती है और ब्लॉक नहीं करती है। |
पैकेट | एक संस्करण साझा करने वाले इंटरफेस और डेटा प्रकारों का संग्रह। |
निकासी | HIDL का मोड जिसमें सर्वर एक साझा लाइब्रेरी है, क्लाइंट द्वारा dlopen एड। पासथ्रू मोड में, क्लाइंट और सर्वर एक ही प्रक्रिया हैं लेकिन अलग-अलग कोडबेस हैं। केवल लीगेसी कोडबेस को HIDL मॉडल में लाने के लिए उपयोग किया जाता है। बाइंडराइज़्ड भी देखें। |
सर्वर | वह प्रक्रिया जो इंटरफ़ेस के तरीकों को लागू करती है। पासथ्रू भी देखें। |
परिवहन | HIDL इन्फ्रास्ट्रक्चर जो सर्वर और क्लाइंट के बीच डेटा स्थानांतरित करता है। |
संस्करण | पैकेज का संस्करण. दो पूर्णांकों से मिलकर बना है, प्रमुख और लघु। लघु संस्करण वृद्धि प्रकार और विधियों को जोड़ सकती है (लेकिन परिवर्तित नहीं कर सकती)। |
एचआईडीएल डिजाइन
एचआईडीएल का लक्ष्य यह है कि एंड्रॉइड फ्रेमवर्क को एचएएल के पुनर्निर्माण के बिना बदला जा सकता है। एचएएल को विक्रेताओं या एसओसी निर्माताओं द्वारा बनाया जाएगा और डिवाइस पर /vendor
विभाजन में रखा जाएगा, जिससे एंड्रॉइड फ्रेमवर्क, अपने स्वयं के विभाजन में, एचएएल को पुन: संकलित किए बिना ओटीए के साथ प्रतिस्थापित किया जा सकेगा।
HIDL डिज़ाइन निम्नलिखित चिंताओं को संतुलित करता है:
- अंतरसंचालनीयता । प्रक्रियाओं के बीच विश्वसनीय रूप से इंटरऑपरेबल इंटरफेस बनाएं जिन्हें विभिन्न आर्किटेक्चर, टूलचेन और बिल्ड कॉन्फ़िगरेशन के साथ संकलित किया जा सकता है। HIDL इंटरफ़ेस संस्करणबद्ध हैं और प्रकाशित होने के बाद इन्हें बदला नहीं जा सकता।
- क्षमता । HIDL प्रतिलिपि संचालन की संख्या को न्यूनतम करने का प्रयास करता है। HIDL-परिभाषित डेटा को C++ मानक लेआउट डेटा संरचनाओं में C++ कोड में वितरित किया जाता है जिसका उपयोग बिना अनपॅकिंग के किया जा सकता है। एचआईडीएल साझा मेमोरी इंटरफेस भी प्रदान करता है और, चूंकि आरपीसी स्वाभाविक रूप से कुछ हद तक धीमी होती है, एचआईडीएल आरपीसी कॉल का उपयोग किए बिना डेटा स्थानांतरित करने के दो तरीकों का समर्थन करता है: साझा मेमोरी और एक फास्ट मैसेज क्यू (एफएमक्यू)।
- सहज ज्ञान युक्त । एचआईडीएल केवल आरपीसी के लिए मापदंडों
in
उपयोग करके मेमोरी स्वामित्व के कांटेदार मुद्दों से बचता है ( एंड्रॉइड इंटरफेस डेफिनिशन लैंग्वेज (एआईडीएल) देखें); वे मान जिन्हें विधियों से कुशलतापूर्वक वापस नहीं किया जा सकता, उन्हें कॉलबैक फ़ंक्शंस के माध्यम से लौटाया जाता है। स्थानांतरण के लिए न तो एचआईडीएल में डेटा पास करना और न ही एचआईडीएल से डेटा प्राप्त करने से डेटा का स्वामित्व बदलता है - स्वामित्व हमेशा कॉलिंग फ़ंक्शन के पास रहता है। डेटा को केवल कॉल किए गए फ़ंक्शन की अवधि के लिए बने रहने की आवश्यकता होती है और कॉल किए गए फ़ंक्शन के वापस आने के तुरंत बाद नष्ट किया जा सकता है।
पासथ्रू मोड का उपयोग करना
एंड्रॉइड के पुराने संस्करणों पर चलने वाले उपकरणों को एंड्रॉइड ओ में अपडेट करने के लिए, आप पारंपरिक (और विरासत) दोनों एचएएल को एक नए एचआईडीएल इंटरफ़ेस में लपेट सकते हैं जो एचएएल को बाइंडराइज्ड और समान-प्रक्रिया (पासथ्रू) मोड में कार्य करता है। यह रैपिंग एचएएल और एंड्रॉइड फ्रेमवर्क दोनों के लिए पारदर्शी है।
पासथ्रू मोड केवल C++ क्लाइंट और कार्यान्वयन के लिए उपलब्ध है। एंड्रॉइड के पुराने संस्करण चलाने वाले उपकरणों में जावा में एचएएल नहीं लिखा गया है, इसलिए जावा एचएएल स्वाभाविक रूप से बाइंडराइज्ड हैं।
पासथ्रू हेडर फ़ाइलें
जब एक .hal
फ़ाइल संकलित की जाती है, hidl-gen
बाइंडर संचार के लिए उपयोग किए जाने वाले हेडर के अलावा एक अतिरिक्त पासथ्रू हेडर फ़ाइल BsFoo.h
उत्पन्न करता है; यह हेडर dlopen
ed होने वाले फ़ंक्शंस को परिभाषित करता है। चूंकि पासथ्रू एचएएल उसी प्रक्रिया में चलते हैं जिसमें उन्हें बुलाया जाता है, ज्यादातर मामलों में पासथ्रू तरीकों को सीधे फ़ंक्शन कॉल (समान थ्रेड) द्वारा लागू किया जाता है। oneway
विधियाँ अपने स्वयं के थ्रेड में चलती हैं क्योंकि उनका उद्देश्य उन्हें संसाधित करने के लिए एचएएल की प्रतीक्षा करना नहीं है (इसका मतलब है कि कोई भी एचएएल जो पासथ्रू मोड में oneway
विधियों का उपयोग करता है उसे थ्रेड-सुरक्षित होना चाहिए)।
IFoo.hal
देखते हुए, BsFoo.h
अतिरिक्त सुविधाएं प्रदान करने के लिए HIDL-जनरेट किए गए तरीकों को लपेटता है (जैसे कि oneway
लेनदेन को दूसरे थ्रेड में चलाना)। यह फ़ाइल BpFoo.h
के समान है, हालांकि बाइंडर का उपयोग करके आईपीसी कॉल को पास करने के बजाय, वांछित फ़ंक्शन सीधे लागू किए जाते हैं। HAL के भविष्य के कार्यान्वयन कई कार्यान्वयन प्रदान कर सकते हैं , जैसे FooFast HAL और FooAccurate HAL। ऐसे मामलों में, प्रत्येक अतिरिक्त कार्यान्वयन के लिए एक फ़ाइल बनाई जाएगी (उदाहरण के लिए, PTFooFast.cpp
और PTFooAccurate.cpp
)।
बाइंडराइजिंग पासथ्रू एचएएल
आप एचएएल कार्यान्वयन को बाइंडराइज़ कर सकते हैं जो पासथ्रू मोड का समर्थन करते हैं। 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
पैरामीटर का उपयोग कभी नहीं किया जाना चाहिए। (एंड्रॉइड O के साथ लॉन्च होने वाले डिवाइस पूरी तरह से बाइंडराइज्ड डिवाइस हैं, इसलिए पासथ्रू मोड में किसी सेवा को खोलने की अनुमति नहीं है।)
एचआईडीएल व्याकरण
डिज़ाइन के अनुसार, HIDL भाषा C के समान है (लेकिन C प्रीप्रोसेसर का उपयोग नहीं करती है)। नीचे वर्णित सभी विराम चिह्न ( =
और |
के स्पष्ट उपयोग को छोड़कर) व्याकरण का हिस्सा हैं।
नोट: एचआईडीएल कोड शैली के विवरण के लिए, कोड स्टाइल गाइड देखें।
-
/** */
एक दस्तावेज़ीकरण टिप्पणी को इंगित करता है। इन्हें केवल प्रकार, विधि, फ़ील्ड और एनम मान घोषणाओं पर लागू किया जा सकता है। -
/* */
एक बहुपंक्ति टिप्पणी को इंगित करता है। -
//
पंक्ति के अंत में एक टिप्पणी इंगित करता है।//
के अलावा, नई लाइनें किसी भी अन्य रिक्त स्थान के समान ही हैं। - नीचे दिए गए उदाहरण व्याकरण में,
//
से पंक्ति के अंत तक का पाठ व्याकरण का हिस्सा नहीं है, बल्कि व्याकरण पर एक टिप्पणी है। -
[empty]
का मतलब है कि शब्द खाली हो सकता है। -
?
किसी शाब्दिक या पद का अनुसरण करने का अर्थ है कि यह वैकल्पिक है। -
...
संकेत के अनुसार अलग-अलग विराम चिह्न के साथ शून्य या अधिक आइटम वाले अनुक्रम को इंगित करता है। HIDL में कोई विविध तर्क नहीं हैं। - अनुक्रम तत्वों को अल्पविराम से अलग करें।
- अर्धविराम अंतिम तत्व सहित प्रत्येक तत्व को समाप्त करते हैं।
- अपरकेस एक नॉनटर्मिनल है।
-
italics
एक टोकन परिवार है जैसेinteger
याidentifier
(मानक सी पार्सिंग नियम)। -
constexpr
एक C शैली स्थिरांक अभिव्यक्ति है (जैसे1 + 1
और1L << 3
)। -
import_name
एक पैकेज या इंटरफ़ेस नाम है, जो एचआईडीएल वर्जनिंग में वर्णित अनुसार योग्य है। - छोटे अक्षर वाले
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