वर्शन

HIDL के लिए आवश्यक है कि HIDL में लिखे गए प्रत्येक इंटरफ़ेस को संस्करणित किया जाए। एचएएल इंटरफ़ेस प्रकाशित होने के बाद, इसे फ़्रीज़ कर दिया जाता है और उस इंटरफ़ेस के नए संस्करण में कोई और बदलाव किया जाना चाहिए। हालाँकि किसी दिए गए प्रकाशित इंटरफ़ेस को संशोधित नहीं किया जा सकता है, इसे किसी अन्य इंटरफ़ेस द्वारा बढ़ाया जा सकता है।

एचआईडीएल कोड संरचना

HIDL कोड उपयोगकर्ता-परिभाषित प्रकारों, इंटरफेस और पैकेजों में व्यवस्थित है :

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

डेटा-प्रकार परिभाषा फ़ाइल types.hal केवल यूडीटी शामिल हैं (सभी पैकेज-स्तरीय यूडीटी एक ही फ़ाइल में रखे गए हैं)। लक्ष्य भाषा में प्रतिनिधित्व पैकेज के सभी इंटरफेस के लिए उपलब्ध हैं।

वर्जनिंग दर्शन

एक HIDL पैकेज (जैसे कि android.hardware.nfc ), किसी दिए गए संस्करण (जैसे 1.0 ) के लिए प्रकाशित होने के बाद, अपरिवर्तनीय है; इसे बदला नहीं जा सकता. पैकेज में इंटरफेस में संशोधन या इसके यूडीटी में कोई भी बदलाव केवल दूसरे पैकेज में ही हो सकता है।

एचआईडीएल में, वर्जनिंग पैकेज स्तर पर लागू होती है, इंटरफ़ेस स्तर पर नहीं, और एक पैकेज में सभी इंटरफेस और यूडीटी एक ही संस्करण साझा करते हैं। पैकेज संस्करण पैच स्तर और बिल्ड-मेटाडेटा घटकों के बिना सिमेंटिक संस्करण का पालन करते हैं। किसी दिए गए पैकेज के भीतर, एक लघु संस्करण बम्प का अर्थ है कि पैकेज का नया संस्करण पुराने पैकेज के साथ पीछे की ओर-संगत है और एक प्रमुख संस्करण बम्प का अर्थ है कि पैकेज का नया संस्करण पुराने पैकेज के साथ पीछे की ओर-संगत नहीं है।

वैचारिक रूप से, एक पैकेज दूसरे पैकेज से कई तरीकों से संबंधित हो सकता है:

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

इंटरफ़ेस की संरचना करना

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

ट्रेबल अलग-अलग संकलित विक्रेता और सिस्टम घटकों का समर्थन करता है जिसमें एक डिवाइस पर vendor.img और system.img अलग से संकलित किया जा सकता है। vendor.img और system.img के बीच सभी इंटरैक्शन को स्पष्ट रूप से और पूरी तरह से परिभाषित किया जाना चाहिए ताकि वे कई वर्षों तक काम करना जारी रख सकें। इसमें कई एपीआई सतहें शामिल हैं, लेकिन एक प्रमुख सतह आईपीसी तंत्र है जिसे एचआईडीएल system.img / vendor.img सीमा पर इंटरप्रोसेस संचार के लिए उपयोग करता है।

आवश्यकताएं

एचआईडीएल से पारित सभी डेटा को स्पष्ट रूप से परिभाषित किया जाना चाहिए। यह सुनिश्चित करने के लिए कि कार्यान्वयन और ग्राहक अलग-अलग संकलित या स्वतंत्र रूप से विकसित होने पर भी एक साथ काम करना जारी रख सकें, डेटा को निम्नलिखित आवश्यकताओं का पालन करना होगा:

  • अर्थ संबंधी नामों और अर्थ के साथ सीधे एचआईडीएल में वर्णित किया जा सकता है (स्ट्रक्चर्स एनम आदि का उपयोग करके)।
  • ISO/IEC 7816 जैसे सार्वजनिक मानक द्वारा वर्णित किया जा सकता है।
  • हार्डवेयर मानक या हार्डवेयर के भौतिक लेआउट द्वारा वर्णित किया जा सकता है।
  • यदि आवश्यक हो तो अपारदर्शी डेटा (जैसे सार्वजनिक कुंजी, आईडी, आदि) हो सकता है।

यदि अपारदर्शी डेटा का उपयोग किया जाता है, तो इसे HIDL इंटरफ़ेस के केवल एक तरफ से पढ़ा जाना चाहिए। उदाहरण के लिए, यदि vendor.img कोड system.img पर एक घटक को एक स्ट्रिंग संदेश या vec<uint8_t> डेटा देता है, तो उस डेटा को system.img द्वारा स्वयं पार्स नहीं किया जा सकता है; इसे व्याख्या करने के लिए केवल vendor.img को वापस भेजा जा सकता है। system.img पर या किसी अन्य डिवाइस पर vendor.img से वेंडर कोड में एक मान पास करते समय, डेटा का प्रारूप और इसकी व्याख्या कैसे की जानी है, इसका सटीक वर्णन किया जाना चाहिए और यह अभी भी इंटरफ़ेस का हिस्सा है।

दिशा-निर्देश

आपको केवल .hal फ़ाइलों का उपयोग करके HAL का कार्यान्वयन या क्लाइंट लिखने में सक्षम होना चाहिए (यानी आपको Android स्रोत या सार्वजनिक मानकों को देखने की आवश्यकता नहीं होनी चाहिए)। हम सटीक आवश्यक व्यवहार निर्दिष्ट करने की अनुशंसा करते हैं. "एक कार्यान्वयन ए या बी कर सकता है" जैसे कथन कार्यान्वयन को उन ग्राहकों के साथ जुड़ने के लिए प्रोत्साहित करते हैं जिनके साथ वे विकसित किए गए हैं।

एचआईडीएल कोड लेआउट

HIDL में कोर और विक्रेता पैकेज शामिल हैं।

कोर HIDL इंटरफ़ेस Google द्वारा निर्दिष्ट हैं। वे जिस पैकेज से संबंधित हैं वह android.hardware. और उपप्रणाली द्वारा नामित किए गए हैं, संभावित रूप से नामकरण के नेस्टेड स्तरों के साथ। उदाहरण के लिए, NFC पैकेज का नाम android.hardware.nfc है और कैमरा पैकेज का नाम android.hardware.camera है। सामान्य तौर पर, एक कोर पैकेज का नाम android.hardware. [ name1 ].[ name2 ]... HIDL पैकेज में उनके नाम के अतिरिक्त एक संस्करण होता है। उदाहरण के लिए, पैकेज android.hardware.camera संस्करण 3.4 पर हो सकता है; यह महत्वपूर्ण है, क्योंकि पैकेज का संस्करण स्रोत ट्री में उसके प्लेसमेंट को प्रभावित करता है।

सभी कोर पैकेज बिल्ड सिस्टम में hardware/interfaces/ के अंतर्गत रखे गए हैं। पैकेज android.hardware. [ name1 ].[ name2 ]… संस्करण $m.$n hardware/interfaces/name1/name2//$m.$n/ के अंतर्गत है; पैकेज android.hardware.camera संस्करण 3.4 निर्देशिका hardware/interfaces/camera/3.4/. पैकेज उपसर्ग android.hardware. और पथ hardware/interfaces/

गैर-कोर (विक्रेता) पैकेज वे हैं जो SoC विक्रेता या ODM द्वारा उत्पादित किए जाते हैं। गैर-कोर पैकेजों के लिए उपसर्ग vendor.$(VENDOR).hardware. जहां $(VENDOR) एक SoC विक्रेता या OEM/ODM को संदर्भित करता है। यह पेड़ में पथ vendor/$(VENDOR)/interfaces को मैप करता है (यह मैपिंग भी हार्ड-कोडेड है)।

पूरी तरह से योग्य उपयोगकर्ता-परिभाषित-प्रकार के नाम

एचआईडीएल में, प्रत्येक यूडीटी का एक पूरी तरह से योग्य नाम होता है जिसमें यूडीटी नाम, पैकेज का नाम जहां यूडीटी परिभाषित होता है, और पैकेज संस्करण शामिल होता है। पूर्ण-योग्य नाम का उपयोग केवल तभी किया जाता है जब प्रकार के उदाहरण घोषित किए जाते हैं, न कि जहां प्रकार को परिभाषित किया जाता है। उदाहरण के लिए, मान लें कि पैकेज android.hardware.nfc, संस्करण 1.0 NfcData नामक संरचना को परिभाषित करता है। घोषणा स्थल पर (चाहे types.hal में या इंटरफ़ेस की घोषणा के भीतर), घोषणा में बस इतना कहा गया है:

struct NfcData {
    vec<uint8_t> data;
};

इस प्रकार का उदाहरण घोषित करते समय (चाहे डेटा संरचना के भीतर या विधि पैरामीटर के रूप में), पूरी तरह से योग्य प्रकार के नाम का उपयोग करें:

android.hardware.nfc@1.0::NfcData

सामान्य सिंटैक्स PACKAGE @ VERSION :: UDT है, जहां:

  • PACKAGE एक HIDL पैकेज का डॉट-पृथक नाम है (उदाहरण के लिए, android.hardware.nfc )।
  • VERSION पैकेज का डॉट-सेपरेटेड मेजर.माइनर-संस्करण प्रारूप है (उदाहरण के लिए, 1.0 )।
  • UDT , एचआईडीएल यूडीटी का बिंदु-पृथक नाम है। चूंकि एचआईडीएल नेस्टेड यूडीटी का समर्थन करता है और एचआईडीएल इंटरफेस में यूडीटी (एक प्रकार का नेस्टेड डिक्लेरेशन) हो सकता है, नामों तक पहुंचने के लिए डॉट्स का उपयोग किया जाता है।

उदाहरण के लिए, यदि निम्नलिखित नेस्टेड घोषणा को पैकेज android.hardware.example संस्करण 1.0 में सामान्य प्रकार की फ़ाइल में परिभाषित किया गया था:

// types.hal
package android.hardware.example@1.0;
struct Foo {
    struct Bar {
        // …
    };
    Bar cheers;
};

Bar के लिए पूर्णतः योग्य नाम android.hardware.example@1.0::Foo.Bar है। यदि, उपरोक्त पैकेज में होने के अलावा, नेस्टेड घोषणा IQuux नामक इंटरफ़ेस में थी:

// IQuux.hal
package android.hardware.example@1.0;
interface IQuux {
    struct Foo {
        struct Bar {
            // …
        };
        Bar cheers;
    };
    doSomething(Foo f) generates (Foo.Bar fb);
};

Bar के लिए पूर्णतः योग्य नाम android.hardware.example@1.0::IQuux.Foo.Bar है।

दोनों मामलों में, Bar केवल Foo की घोषणा के दायरे में Bar के रूप में संदर्भित किया जा सकता है। पैकेज या इंटरफ़ेस स्तर पर, आपको Foo : Foo.Bar के माध्यम से Bar को संदर्भित करना होगा, जैसा कि ऊपर doSomething विधि की घोषणा में है। वैकल्पिक रूप से, आप विधि को अधिक क्रियात्मक रूप से इस प्रकार घोषित कर सकते हैं:

// IQuux.hal
doSomething(android.hardware.example@1.0::IQuux.Foo f) generates (android.hardware.example@1.0::IQuux.Foo.Bar fb);

पूर्णतः योग्य गणना मान

यदि यूडीटी एक एनम प्रकार है, तो एनम प्रकार के प्रत्येक मान में एक पूर्ण-योग्य नाम होता है जो एनम प्रकार के पूर्ण-योग्य नाम से शुरू होता है, उसके बाद एक कोलन होता है, उसके बाद एनम मान का नाम होता है। उदाहरण के लिए, मान लें कि पैकेज android.hardware.nfc, संस्करण 1.0 एक एनम प्रकार NfcStatus परिभाषित करता है:

enum NfcStatus {
    STATUS_OK,
    STATUS_FAILED
};

STATUS_OK का संदर्भ देते समय, पूर्णतः योग्य नाम है:

android.hardware.nfc@1.0::NfcStatus:STATUS_OK

सामान्य सिंटैक्स PACKAGE @ VERSION :: UDT : VALUE , जहां:

  • PACKAGE @ VERSION :: UDT एनम प्रकार के लिए बिल्कुल वही पूर्णतः योग्य नाम है।
  • VALUE मान का नाम है.

स्वत: अनुमान नियम

पूर्णतः योग्य यूडीटी नाम निर्दिष्ट करने की आवश्यकता नहीं है। एक यूडीटी नाम निम्नलिखित को सुरक्षित रूप से छोड़ सकता है:

  • पैकेज, उदाहरण के लिए @1.0::IFoo.Type
  • पैकेज और संस्करण दोनों, उदाहरण के लिए IFoo.Type

HIDL ऑटो-हस्तक्षेप नियमों (कम नियम संख्या का मतलब उच्च प्राथमिकता) का उपयोग करके नाम को पूरा करने का प्रयास करता है।

नियम 1

यदि कोई पैकेज और संस्करण उपलब्ध नहीं कराया गया है, तो स्थानीय नाम खोजने का प्रयास किया जाता है। उदाहरण:

interface Nfc {
    typedef string NfcErrorMessage;
    send(NfcData d) generates (@1.0::NfcStatus s, NfcErrorMessage m);
};

NfcErrorMessage को स्थानीय रूप से देखा जाता है, और इसके ऊपर typedef पाया जाता है। NfcData स्थानीय रूप से भी देखा जाता है, लेकिन चूंकि इसे स्थानीय रूप से परिभाषित नहीं किया गया है, इसलिए नियम 2 और 3 का उपयोग किया जाता है। @1.0::NfcStatus एक संस्करण प्रदान करता है, इसलिए नियम 1 लागू नहीं होता है।

नियम 2

यदि नियम 1 विफल हो जाता है और पूर्ण-योग्य नाम का एक घटक गायब है (पैकेज, संस्करण, या पैकेज और संस्करण), तो घटक वर्तमान पैकेज से जानकारी के साथ स्वत: भर जाता है। इसके बाद एचआईडीएल कंपाइलर स्वचालित रूप से भरे गए पूर्ण-योग्य नाम को खोजने के लिए वर्तमान फ़ाइल (और सभी आयात) को देखता है। ऊपर दिए गए उदाहरण का उपयोग करते हुए, मान लें कि ExtendedNfcData की घोषणा उसी पैकेज ( android.hardware.nfc ) में उसी संस्करण ( 1.0 ) में NfcData के रूप में की गई थी, जो इस प्रकार है:

struct ExtendedNfcData {
    NfcData base;
    // … additional members
};

HIDL कंपाइलर पूरी तरह से योग्य UDT नाम android.hardware.nfc@1.0::NfcData उत्पन्न करने के लिए वर्तमान पैकेज से पैकेज नाम और संस्करण नाम भरता है। चूँकि नाम वर्तमान पैकेज में मौजूद है (यह मानते हुए कि इसे ठीक से आयात किया गया है), इसका उपयोग घोषणा के लिए किया जाता है।

वर्तमान पैकेज में कोई नाम तभी आयात किया जाता है जब निम्न में से कोई एक सत्य हो:

  • इसे import विवरण के साथ स्पष्ट रूप से आयात किया जाता है।
  • इसे वर्तमान पैकेज में types.hal में परिभाषित किया गया है

यदि NfcData केवल संस्करण संख्या द्वारा योग्य था तो उसी प्रक्रिया का पालन किया जाता है:

struct ExtendedNfcData {
    // autofill the current package name (android.hardware.nfc)
    @1.0::NfcData base;
    // … additional members
};

नियम 3

यदि नियम 2 एक मिलान उत्पन्न करने में विफल रहता है (यूडीटी को वर्तमान पैकेज में परिभाषित नहीं किया गया है), तो एचआईडीएल कंपाइलर सभी आयातित पैकेजों के भीतर एक मिलान के लिए स्कैन करता है। उपरोक्त उदाहरण का उपयोग करते हुए, मान लें कि ExtendedNfcData पैकेज android.hardware.nfc के संस्करण 1.1 में घोषित किया गया है, 1.1 1.0 को आयात करता है जैसा कि इसे करना चाहिए ( पैकेज-स्तर एक्सटेंशन देखें), और परिभाषा केवल UDT नाम निर्दिष्ट करती है:

struct ExtendedNfcData {
    NfcData base;
    // … additional members
};

कंपाइलर NfcData नाम के किसी भी UDT को ढूंढता है और संस्करण 1.0 पर android.hardware.nfc में एक ढूंढता है, जिसके परिणामस्वरूप android.hardware.nfc@1.0::NfcData का पूर्णतः योग्य UDT प्राप्त होता है। यदि किसी दिए गए आंशिक रूप से योग्य यूडीटी के लिए एक से अधिक मिलान पाए जाते हैं, तो एचआईडीएल कंपाइलर एक त्रुटि उत्पन्न करता है।

उदाहरण

नियम 2 का उपयोग करते हुए, वर्तमान पैकेज में परिभाषित एक आयातित प्रकार को दूसरे पैकेज से आयातित प्रकार पर प्राथमिकता दी जाती है:

// hardware/interfaces/foo/1.0/types.hal
package android.hardware.foo@1.0;
struct S {};

// hardware/interfaces/foo/1.0/IFooCallback.hal
package android.hardware.foo@1.0;
interface IFooCallback {};

// hardware/interfaces/bar/1.0/types.hal
package android.hardware.bar@1.0;
typedef string S;

// hardware/interfaces/bar/1.0/IFooCallback.hal
package android.hardware.bar@1.0;
interface IFooCallback {};

// hardware/interfaces/bar/1.0/IBar.hal
package android.hardware.bar@1.0;
import android.hardware.foo@1.0;
interface IBar {
    baz1(S s); // android.hardware.bar@1.0::S
    baz2(IFooCallback s); // android.hardware.foo@1.0::IFooCallback
};
  • S android.hardware.bar@1.0::S के रूप में प्रक्षेपित किया गया है, और bar/1.0/types.hal में पाया जाता है (क्योंकि types.hal स्वचालित रूप से आयात किया जाता है)।
  • IFooCallback नियम 2 का उपयोग करके android.hardware.bar@1.0::IFooCallback के रूप में प्रक्षेपित किया गया है, लेकिन इसे नहीं पाया जा सकता क्योंकि bar/1.0/IFooCallback.hal स्वचालित रूप से आयात नहीं किया जाता है (जैसा कि types.hal है)। इस प्रकार, नियम 3 इसके बजाय इसे android.hardware.foo@1.0::IFooCallback पर हल करता है, जिसे import android.hardware.foo@1.0; ).

प्रकार.हाल

प्रत्येक एचआईडीएल पैकेज में यूडीटी युक्त एक types.hal फ़ाइल होती है जो उस पैकेज में भाग लेने वाले सभी इंटरफेस के बीच साझा की जाती है। एचआईडीएल प्रकार हमेशा सार्वजनिक होते हैं; इस बात की परवाह किए बिना कि यूडीटी को types.hal में घोषित किया गया है या इंटरफ़ेस घोषणा के भीतर, ये प्रकार उस दायरे के बाहर पहुंच योग्य हैं जहां उन्हें परिभाषित किया गया है। types.hal मतलब किसी पैकेज के सार्वजनिक एपीआई का वर्णन करना नहीं है, बल्कि पैकेज के भीतर सभी इंटरफेस द्वारा उपयोग किए जाने वाले यूडीटी को होस्ट करना है। एचआईडीएल की प्रकृति के कारण, सभी यूडीटी इंटरफ़ेस का हिस्सा हैं।

types.hal में यूडीटी और import विवरण शामिल हैं। क्योंकि types.hal पैकेज के प्रत्येक इंटरफ़ेस के लिए उपलब्ध कराया गया है (यह एक अंतर्निहित आयात है), ये import विवरण परिभाषा के अनुसार पैकेज-स्तर हैं। types.hal में यूडीटी में इस प्रकार आयातित यूडीटी और इंटरफेस भी शामिल हो सकते हैं।

उदाहरण के लिए, IFoo.hal के लिए:

package android.hardware.foo@1.0;
// whole package import
import android.hardware.bar@1.0;
// types only import
import android.hardware.baz@1.0::types;
// partial imports
import android.hardware.qux@1.0::IQux.Quux;
// partial imports
import android.hardware.quuz@1.0::Quuz;

निम्नलिखित आयात किए जाते हैं:

  • android.hidl.base@1.0::IBase (स्पष्ट रूप से)
  • android.hardware.foo@1.0::types (स्पष्ट रूप से)
  • android.hardware.bar@1.0 में सब कुछ (सभी इंटरफ़ेस और उसके types.hal सहित)
  • types.hal android.hardware.baz@1.0::types से ( android.hardware.baz@1.0 में इंटरफेस आयात नहीं किए जाते हैं)
  • android.hardware.qux@1.0 से IQux.hal और types.hal
  • android.hardware.quuz@1.0 से Quuz (यह मानते हुए कि Quuz types.hal में परिभाषित किया गया है, संपूर्ण types.hal फ़ाइल को पार्स किया गया है, लेकिन Quuz के अलावा अन्य प्रकार आयात नहीं किए जाते हैं)।

इंटरफ़ेस-स्तरीय संस्करण

पैकेज के भीतर प्रत्येक इंटरफ़ेस अपनी फ़ाइल में रहता है। इंटरफ़ेस जिस पैकेज से संबंधित है, उसे package स्टेटमेंट का उपयोग करके इंटरफ़ेस के शीर्ष पर घोषित किया जाता है। पैकेज घोषणा के बाद, शून्य या अधिक इंटरफ़ेस-स्तरीय आयात (आंशिक या संपूर्ण-पैकेज) सूचीबद्ध किया जा सकता है। उदाहरण के लिए:

package android.hardware.nfc@1.0;

एचआईडीएल में, इंटरफेस extends कीवर्ड का उपयोग करके अन्य इंटरफेस से इनहेरिट कर सकते हैं। एक इंटरफ़ेस के लिए दूसरे इंटरफ़ेस का विस्तार करने के लिए, उसे एक import विवरण के माध्यम से उस तक पहुंच होनी चाहिए। विस्तारित किए जा रहे इंटरफ़ेस का नाम (बेस इंटरफ़ेस) ऊपर बताए गए प्रकार-नाम योग्यता के नियमों का पालन करता है। एक इंटरफ़ेस केवल एक इंटरफ़ेस से प्राप्त हो सकता है; HIDL एकाधिक वंशानुक्रम का समर्थन नहीं करता.

नीचे दिए गए अपग्रेड संस्करण उदाहरण निम्नलिखित पैकेज का उपयोग करते हैं:

// types.hal
package android.hardware.example@1.0
struct Foo {
    struct Bar {
        vec<uint32_t> val;
    };
};

// IQuux.hal
package android.hardware.example@1.0
interface IQuux {
    fromFooToBar(Foo f) generates (Foo.Bar b);
}

उप्रेव नियम

पैकेज package@major.minor को परिभाषित करने के लिए, या तो A या सभी B सत्य होने चाहिए:

नियम ए "एक प्रारंभिक लघु संस्करण है": सभी पिछले लघु संस्करण, package@major.0 , package@major.1 , ..., package@major.(minor-1) परिभाषित नहीं किया जाना चाहिए।
या
नियम बी

निम्नलिखित सभी सत्य हैं:

  1. "पिछला लघु संस्करण मान्य है": package@major.(minor-1) परिभाषित किया जाना चाहिए और उसी नियम A का पालन करना चाहिए ( package@major.0 से package@major.(minor-2) में से कोई भी परिभाषित नहीं है) या नियम B (यदि यह @major.(minor-2) );

    और

  2. "समान नाम से कम से कम एक इंटरफ़ेस इनहेरिट करें": एक इंटरफ़ेस package@major.minor::IFoo मौजूद है जो package@major.(minor-1)::IFoo विस्तारित करता है (यदि पिछले पैकेज में एक इंटरफ़ेस है);

    और

  3. "किसी भिन्न नाम के साथ कोई विरासत में मिला इंटरफ़ेस नहीं": package@major.minor::IBar मौजूद नहीं होना चाहिए जो package@major.(minor-1)::IBaz विस्तारित करता है, जहां IBar और IBaz दो अलग-अलग नाम हैं। यदि समान नाम वाला कोई इंटरफ़ेस है, package@major.minor::IBar package@major.(minor-k)::IBar विस्तार करना होगा ताकि छोटे k के साथ कोई IBar मौजूद न हो।

नियम ए के कारण:

  • पैकेज किसी भी छोटे संस्करण संख्या से शुरू हो सकता है (उदाहरण के लिए, android.hardware.biometrics.fingerprint @2.1 से शुरू होता है।)
  • आवश्यकता " android.hardware.foo@1.0 परिभाषित नहीं है" का अर्थ है कि निर्देशिका hardware/interfaces/foo/1.0 मौजूद ही नहीं होनी चाहिए।

हालाँकि, नियम A समान पैकेज नाम वाले पैकेज को प्रभावित नहीं करता है, बल्कि एक अलग प्रमुख संस्करण को प्रभावित करता है (उदाहरण के लिए, android.hardware.camera.device में @1.0 और @3.2 दोनों परिभाषित हैं; @3.2 को @1.0 के साथ इंटरैक्ट करने की आवश्यकता नहीं है) .) इसलिए, @3.2::IExtFoo @1.0::IFoo विस्तार कर सकता है।

बशर्ते पैकेज का नाम अलग हो, package@major.minor::IBar एक अलग नाम वाले इंटरफ़ेस से विस्तारित हो सकता है (उदाहरण के लिए, android.hardware.bar@1.0::IBar android.hardware.baz@2.2::IBaz विस्तार कर सकता है) ). यदि कोई इंटरफ़ेस स्पष्ट रूप से extend कीवर्ड के साथ एक सुपर प्रकार घोषित नहीं करता है, तो यह android.hidl.base@1.0::IBase (स्वयं IBase को छोड़कर) का विस्तार करेगा।

B.2 और B.3 का एक ही समय में पालन किया जाना चाहिए। उदाहरण के लिए, भले ही android.hardware.foo@1.1::IFoo IFoo नियम B.2 को पारित करने के लिए android.hardware.foo@1.0::IFoo विस्तार करता है, यदि android.hardware.foo@1.1::IExtBar android.hardware.foo@1.0::IBar , यह अभी भी वैध अपग्रेड नहीं है।

इंटरफ़ेस को ऊपर उठाना

android.hardware.example@1.0 (ऊपर परिभाषित) को @1.1 तक अपग्रेड करने के लिए:

// types.hal
package android.hardware.example@1.1;
import android.hardware.example@1.0;

// IQuux.hal
package android.hardware.example@1.1
interface IQuux extends @1.0::IQuux {
    fromBarToFoo(Foo.Bar b) generates (Foo f);
}

यह types.hal में android.hardware.example के संस्करण 1.0 का पैकेज-स्तरीय import है। हालाँकि पैकेज के संस्करण 1.1 में कोई नया यूडीटी नहीं जोड़ा गया है, संस्करण 1.0 में यूडीटी के संदर्भ अभी भी आवश्यक हैं, इसलिए types.hal में पैकेज-स्तरीय आयात। (समान प्रभाव IQuux.hal में इंटरफ़ेस-स्तरीय आयात के साथ प्राप्त किया जा सकता था।)

IQuux की घोषणा में extends @1.0::IQuux में, हमने IQuux के उस संस्करण को निर्दिष्ट किया है जो विरासत में मिला है (बहुविकल्पी आवश्यक है क्योंकि IQuux का उपयोग इंटरफ़ेस घोषित करने और इंटरफ़ेस से प्राप्त करने के लिए किया जाता है)। चूँकि घोषणाएँ केवल वे नाम हैं जो घोषणा स्थल पर सभी पैकेज और संस्करण विशेषताओं को प्राप्त करते हैं, असंबद्धता आधार इंटरफ़ेस के नाम पर होनी चाहिए; हम पूरी तरह से योग्य यूडीटी का भी उपयोग कर सकते थे, लेकिन वह अनावश्यक होता।

नया इंटरफ़ेस IQuux विधि fromFooToBar() पुनः घोषित नहीं करता है, यह @1.0::IQuux से प्राप्त होता है; यह बस उस नई विधि को सूचीबद्ध करता है जिसे वह fromBarToFoo() जोड़ता है। HIDL में, विरासत में मिली विधियों को चाइल्ड इंटरफ़ेस में दोबारा घोषित नहीं किया जा सकता है, इसलिए IQuux इंटरफ़ेस fromFooToBar() विधि को स्पष्ट रूप से घोषित नहीं कर सकता है।

उप्रेव सम्मेलन

कभी-कभी इंटरफ़ेस नामों को विस्तारित इंटरफ़ेस का नाम बदलना होगा। हम अनुशंसा करते हैं कि एनम एक्सटेंशन, स्ट्रक्चर्स और यूनियनों का वही नाम हो जो वे विस्तारित करते हैं जब तक कि वे एक नए नाम की गारंटी देने के लिए पर्याप्त रूप से भिन्न न हों। उदाहरण:

// in parent hal file
enum Brightness : uint32_t { NONE, WHITE };

// in child hal file extending the existing set with additional similar values
enum Brightness : @1.0::Brightness { AUTOMATIC };

// extending the existing set with values that require a new, more descriptive name:
enum Color : @1.0::Brightness { HW_GREEN, RAINBOW };

यदि किसी विधि में एक नया अर्थ संबंधी नाम हो सकता है (उदाहरण के लिए fooWithLocation ) तो उसे प्राथमिकता दी जाती है। अन्यथा, इसका नाम उसी के समान रखा जाना चाहिए जिसका यह विस्तार कर रहा है। उदाहरण के लिए, यदि कोई बेहतर वैकल्पिक नाम नहीं है, तो @1.1::IFoo में विधि foo_1_1 @1.0::IFoo में foo विधि की कार्यक्षमता को प्रतिस्थापित कर सकती है।

पैकेज-स्तरीय संस्करण

HIDL संस्करण पैकेज स्तर पर होता है; एक पैकेज प्रकाशित होने के बाद, यह अपरिवर्तनीय है (इसके इंटरफेस और यूडीटी का सेट बदला नहीं जा सकता है)। पैकेज कई तरीकों से एक-दूसरे से संबंधित हो सकते हैं, जिनमें से सभी इंटरफ़ेस-स्तरीय विरासत और संरचना द्वारा यूडीटी के निर्माण के संयोजन के माध्यम से व्यक्त किए जा सकते हैं।

हालाँकि, एक प्रकार का संबंध सख्ती से परिभाषित है और इसे लागू किया जाना चाहिए: पैकेज-स्तर बैकवर्ड-संगत विरासत । इस परिदृश्य में, पैरेंट पैकेज वह पैकेज है जो विरासत में मिला है और चाइल्ड पैकेज वह है जो पैरेंट का विस्तार करता है। पैकेज-स्तरीय पश्चगामी-संगत वंशानुक्रम नियम इस प्रकार हैं:

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

इन नियमों को एचआईडीएल इंटरफ़ेस-स्तरीय विरासत और यूडीटी संरचना का उपयोग करके कार्यान्वित किया जा सकता है, लेकिन इन संबंधों को बैकवर्ड-संगत पैकेज एक्सटेंशन बनाने के लिए मेटा-स्तरीय ज्ञान की आवश्यकता होती है। इस ज्ञान का अनुमान इस प्रकार लगाया जाता है:

यदि कोई पैकेज इस आवश्यकता को पूरा करता है, hidl-gen पश्चगामी-संगतता नियमों को लागू करता है।