सेवाएं और डेटा ट्रांसफ़र

इस पेज पर, सेवाओं को रजिस्टर करने, खोजने, और उन्हें भेजने का तरीका बताया गया है .hal में इंटरफ़ेस में बताए गए कॉल करने के तरीकों का इस्तेमाल करके, किसी सेवा को डेटा फ़ाइलें शामिल हैं.

सेवाओं को पंजीकृत करें

HIDL इंटरफ़ेस सर्वर (इंटरफ़ेस को लागू करने वाली ऑब्जेक्ट) रजिस्टर किए जा सकते हैं से संपर्क किया जा सकता है. रजिस्टर किया गया नाम इंटरफ़ेस से जुड़ा नहीं होना चाहिए या पैकेज का नाम. अगर कोई नाम तय नहीं किया गया है, तो नाम "डिफ़ॉल्ट" होगा इस्तेमाल किया गया है; इसे चाहिए का इस्तेमाल उन एचएएल के लिए किया जाता है जिन्हें एक ही लागू करने के दो तरीकों को रजिस्टर करने की ज़रूरत नहीं होती इंटरफ़ेस पर कॉपी करने की सुविधा मिलती है. उदाहरण के लिए, प्रत्येक इंटरफ़ेस:

status_t status = myFoo->registerAsService();
status_t anotherStatus = anotherFoo->registerAsService("another_foo_service");  // if needed

HIDL इंटरफ़ेस का वर्शन, इंटरफ़ेस में ही शामिल होता है. हां यह सेवा पंजीकरण के साथ स्वचालित रूप से संबद्ध होता है और इसके माध्यम से वापस हासिल किया जा सकता है तरीका कॉल (android::hardware::IInterface::getInterfaceVersion()) हर HIDL इंटरफ़ेस पर मौजूद है. सर्वर ऑब्जेक्ट को रजिस्टर करने की ज़रूरत नहीं होती है और उन्हें पास किया जा सकता है HIDL मेथड पैरामीटर के ज़रिए से किसी अन्य प्रोसेस में जाता है, जो HIDL मेथड कॉल करता है सर्वर में कॉपी हो जाता है.

सेवाएं खोजें

क्लाइंट कोड के ज़रिए दिए गए इंटरफ़ेस के लिए अनुरोध, नाम और वर्शन का इस्तेमाल करके, सही एचएएल क्लास पर getService को कॉल किया जा सकता है:

// C++
sp<V1_1::IFooService> service = V1_1::IFooService::getService();
sp<V1_1::IFooService> alternateService = V1_1::IFooService::getService("another_foo_service");
// Java
V1_1.IFooService service = V1_1.IFooService.getService(true /* retry */);
V1_1.IFooService alternateService = V1_1.IFooService.getService("another", true /* retry */);

HIDL इंटरफ़ेस के हर वर्शन को एक अलग इंटरफ़ेस माना जाता है. इसलिए, IFooService वर्शन 1.1 और IFooService वर्शन 2.2 दोनों को "foo_service" के रूप में रजिस्टर किया जा सकता है और दोनों में से किसी भी इंटरफ़ेस के getService("foo_service") को रजिस्टर किया जाता है उस इंटरफ़ेस के लिए सेवा. यही वजह है कि ज़्यादातर मामलों में, नाम पैरामीटर की ज़रूरत नहीं होती है रजिस्ट्रेशन या डिस्कवरी के लिए दिया जाना चाहिए (यानी नाम "डिफ़ॉल्ट").

वेंडर इंटरफ़ेस ऑब्जेक्ट, इंटरफ़ेस मिला. पैकेज में IFoo इंटरफ़ेस के लिए android.hardware.foo@1.0, इंटरफ़ेस को इसके ज़रिए दिखाया गया IFoo::getService हमेशा परिवहन के उस तरीके का इस्तेमाल करता है जिसके लिए एलान किया गया है अगर एंट्री मौजूद है, तो डिवाइस मेनिफ़ेस्ट में android.hardware.foo; और अगर ट्रांसपोर्ट का तरीका उपलब्ध नहीं है, तो nullptr दिखाया जाता है.

कुछ मामलों में, बिना किसी रुकावट के तुरंत जारी रखना ज़रूरी हो सकता है मुझे सेवाएं मिलती हैं. ऐसा तब हो सकता है, (उदाहरण के लिए), जब कोई क्लाइंट चाहता है कि सेवा सूचनाओं को खुद या किसी डाइग्नोस्टिक प्रोग्राम में मैनेज करना चाहिए (जैसे, atrace) को ऐक्सेस करना होता है, जिसे सभी hwservices को पाना और उन्हें फिर से हासिल करना होता है. तय सीमा में इस मामले में, अतिरिक्त एपीआई दिए गए हैं. जैसे, C++ में tryGetService या Java में getService("instance-name", false). लेगसी एपीआई Java में दिए गए getService को सेवा के साथ भी इस्तेमाल किया जाना चाहिए नोटिफ़िकेशन. इस एपीआई का इस्तेमाल करने पर, उस रेस कंडिशन से बचा नहीं जा सकता जिसमें सर्वर क्लाइंट की ओर से अनुरोध किए जाने पर, वह इन एपीआई की मदद से खुद को रजिस्टर करता है.

सेवा बंद होने की सूचनाएं

ऐसे क्लाइंट जो किसी सेवा की मौत होने पर सूचना पाना चाहते हैं, उनकी मौत हो सकती है नोटिफ़िकेशन फ़्रेमवर्क से डिलीवर किए जाएंगे. सूचनाएं पाने के लिए, क्लाइंट ज़रूरी है:

  1. HIDL क्लास/इंटरफ़ेस hidl_death_recipient को सब-क्लास करें (C++ में होना चाहिए, HIDL में नहीं).
  2. इसके serviceDied() तरीके को बदलें.
  3. hidl_death_recipient सब-क्लास का ऑब्जेक्ट इंस्टैंशिएट करें.
  4. निगरानी करने के लिए, सेवा में linkToDeath() तरीके को कॉल करें, IDeathRecipient के इंटरफ़ेस ऑब्जेक्ट में पास कर रहा है. ध्यान दें कि विधि मृत व्यक्ति का मालिकाना हक नहीं लेती है या उस प्रॉक्सी का इस्तेमाल नहीं करती जिस पर वह को कॉल किया जाता है.

स्यूडोकोड का उदाहरण (C++ और Java एक जैसे हैं):

class IMyDeathReceiver : hidl_death_recipient {
  virtual void serviceDied(uint64_t cookie,
                           wp<IBase>& service) override {
    log("RIP service %d!", cookie);  // Cookie should be 42
  }
};
....
IMyDeathReceiver deathReceiver = new IMyDeathReceiver();
m_importantService->linkToDeath(deathReceiver, 42);

मौत के एक ही व्यक्ति को कई अलग-अलग सेवाओं पर रजिस्टर किया जा सकता है.

डेटा ट्रांसफ़र

किसी सेवा को डेटा भेजने के लिए, इंटरफ़ेस में बताए गए तरीकों को कॉल करें .hal फ़ाइलें. ये तरीके दो तरह के होते हैं:

  • ब्लॉक करने के तरीके तब तक इंतज़ार करते हैं, जब तक सर्वर नतीजा.
  • एकतरफ़ा तरीके से सिर्फ़ एक ही दिशा में डेटा भेजा जाता है ब्लॉक. अगर RPC कॉल में इन-फ़्लाइट डेटा की मात्रा लागू करने से ज़्यादा हो जाती है सीमित कर देते हैं, तो कॉल या तो ब्लॉक हो सकते हैं या गड़बड़ी का संकेत दिखा सकते हैं (व्यवहार तय नहीं किया गया है).

ऐसा तरीका जो वैल्यू नहीं दिखाता, लेकिन उसे oneway अब भी ब्लॉक कर रहा है.

HIDL इंटरफ़ेस में बताए गए सभी तरीके एक ही दिशा में कॉल किए जाते हैं, एचएएल से या एचएएल में जाकर इंटरफ़ेस में यह नहीं बताया गया है कि जिस दिशा में उसे कॉल किया जाता है. ऐसे आर्किटेक्चर जिनके लिए कॉल करने की ज़रूरत होती है HAL को HAL पैकेज में दो या उससे ज़्यादा इंटरफ़ेस देने चाहिए और सही इंटरफ़ेस तैयार किया है. क्लाइंट शब्द और सर्वर का इस्तेमाल इंटरफ़ेस को कॉल करने की दिशा के हिसाब से किया जाता है (यानी कि HAL एक इंटरफ़ेस का सर्वर और दूसरे का क्लाइंट हो सकता है इंटरफ़ेस).

कॉलबैक

callback शब्द दो अलग-अलग कॉन्सेप्ट के बारे में बताता है, जो सिंक्रोनस कॉलबैक और एसिंक्रोनस कॉलबैक.

सिंक्रोनस कॉलबैक का इस्तेमाल कुछ HIDL तरीकों में किया जाता है, जो डेटा शामिल है. एक HIDL तरीका जो एक से ज़्यादा वैल्यू दिखाता है (या नॉन-प्राइमिटिव टाइप) कॉलबैक फ़ंक्शन के ज़रिए अपने नतीजे दिखाता है. अगर एक मान लौटाया जाता है और यह एक प्रिमिटिव टाइप है, कॉलबैक का इस्तेमाल नहीं किया जाता और तरीके से वैल्यू दी जाती है. सर्वर, HIDL मेथड लागू करता है और क्लाइंट, कॉलबैक लागू करता है.

एसिंक्रोनस कॉलबैक, HIDL इंटरफ़ेस के सर्वर को कॉल करने के लिए. ऐसा दूसरे इंटरफ़ेस का एक इंस्टेंस पास करके किया जाता है उस पर काम कर रहे हैं. पहले इंटरफ़ेस के क्लाइंट को का सर्वर है. पहले इंटरफ़ेस का सर्वर दूसरा इंटरफ़ेस ऑब्जेक्ट है. उदाहरण के लिए, एचएएल लागू करने पर वह Google को जानकारी भेज सकता है उस प्रक्रिया पर एसिंक्रोनस रूप से वापस जा सकता है जिसका उपयोग उस प्रोसेस से बनाया और दिखाया गया इंटरफ़ेस ऑब्जेक्ट. इंटरफ़ेस में इस्तेमाल किए गए तरीके एसिंक्रोनस कॉलबैक के लिए ब्लॉक किया जा सकता है (और कॉलर को वैल्यू लौटा सकता है) या oneway. उदाहरण के लिए, "एसिंक्रोनस कॉलबैक" देखें इंच HIDL C++.

मेमोरी के मालिकाना हक को आसान बनाने के लिए, मेथड कॉल और कॉलबैक सिर्फ़ in पैरामीटर और out का इस्तेमाल नहीं किया जा सकता या inout पैरामीटर.

लेन-देन की सीमाएं

HIDL में भेजे गए डेटा की मात्रा पर, हर लेन-देन की सीमाएं लागू नहीं होतीं तरीकों और कॉलबैक का इस्तेमाल करें. हालांकि, प्रति लेन-देन 4 केबी से अधिक वाले कॉल बहुत ज़्यादा काम करता है. अगर ऐसा दिखता है, तो दिए गए HIDL इंटरफ़ेस को फिर से संग्रहित करें का सुझाव दिया जाता है. दूसरी सीमा, HIDL में उपलब्ध संसाधन हैं एक साथ कई लेन-देन करने की सुविधा देने वाला इंफ़्रास्ट्रक्चर. एक से ज़्यादा कई थ्रेड की वजह से ट्रांज़ैक्शन फ़्लाइट के दौरान एक साथ हो सकते हैं या एक प्रोसेस या एक से ज़्यादा oneway कॉल को प्रोसेस करती है उन्हें पाने की प्रोसेस में तुरंत हैंडल नहीं किया जाता. ज़्यादा से ज़्यादा कुल स्टोरेज डिफ़ॉल्ट रूप से, एक साथ होने वाले सभी लेन-देन के लिए यह साइज़ 1 एमबी से ज़्यादा नहीं होना चाहिए.

अच्छी तरह से डिज़ाइन किए गए इंटरफ़ेस में, संसाधन की सीमाओं को पार करने से होना; अगर ऐसा होता है, तो उसके सीमा से ज़्यादा होने वाला कॉल तब तक ब्लॉक किया जा सकता है, जब तक संसाधन उपलब्ध हो जाते हैं या ट्रांसपोर्ट में कोई गड़बड़ी दिखती है. इसकी हर घटना हर ट्रांज़ैक्शन की सीमाओं को पार करना या HIDL लागू करने के संसाधनों से डीबगिंग को आसान बनाने के लिए कुल इन-फ़्लाइट लेन-देन लॉग किए जाते हैं.

तरीके लागू करना

HIDL ज़रूरी टाइप, तरीकों, और टारगेट की गई भाषा (C++ या Java) में कॉलबैक. HIDL-तय का प्रोटोटाइप तरीके और कॉलबैक, क्लाइंट और सर्वर कोड, दोनों के लिए एक जैसे होते हैं. द एचआईडीएल सिस्टम, प्रॉक्सी सर्वर पर तरीकों को प्रॉक्सी तरीके से लागू करने की सुविधा देता है कॉलर साइड जो आईपीसी ट्रांसपोर्ट और स्टब के डेटा को व्यवस्थित करता है कॉली साइड पर एक कोड होना चाहिए, जो डेटा को डेवलपर को लागू करने के लिए पास करता है तरीके हैं.

फ़ंक्शन (HIDL मेथड या कॉलबैक) के कॉलर के पास डेटा का मालिकाना हक होता है फ़ंक्शन में पास की गई स्ट्रक्चर, और कॉल के बाद मालिकाना हक बनी रहती हैं; इंच ऐसे सभी मामलों में जिन्हें कॉल करने वाले व्यक्ति को स्टोरेज खाली करने या खाली करने की ज़रूरत नहीं होती है.

  • C++ में, हो सकता है कि डेटा सिर्फ़ रीड-ओनली मोड में हो (इसमें लिखने की कोशिश करने पर सेगमेंटेशन में गड़बड़ी) और वे कॉल के दौरान मान्य हैं. क्लाइंट यह कर सकता है: डेटा को कॉल से आगे बढ़ाने के लिए, उसे डीप-कॉपी करें.
  • Java में, कोड को डेटा की एक लोकल कॉपी (एक सामान्य Java ऑब्जेक्ट) मिलती है, जिसे वह सेव रख सकता हो और उसमें बदलाव कर सकता हो या जिसे कूड़ा इकट्ठा करने की अनुमति देता हो.

नॉन-RPC डेटा ट्रांसफ़र

HIDL, RPC कॉल का इस्तेमाल किए बिना डेटा ट्रांसफ़र करने के दो तरीके हैं: शेयर किया गया मेमोरी और फ़ास्ट मैसेज क्यू (एफ़एमक्यू), दोनों का इस्तेमाल सिर्फ़ C++ में किया जा सकता है.

  • शेयर की गई यादें. पहले से मौजूद HIDL टाइप memory का इस्तेमाल, असाइन की गई शेयर की गई मेमोरी को दिखाने वाले ऑब्जेक्ट को पास करने के लिए किया जाता है. इसका इस्तेमाल, शेयर की गई 'यादें' को मैप करने के लिए, मैसेज पाने की प्रोसेस में किया जा सकता है.
  • तेज़ मैसेज की सूची (FMQ). HIDL टेंप्लेट वाला मैसेज उपलब्ध कराता है सूची का वह टाइप जो बिना इंतज़ार किए मैसेज भेजने की सुविधा लागू करता है. यह कर्नेल का इस्तेमाल नहीं करता या पासथ्रू या बाइंडराइज़्ड मोड में शेड्यूलर इस्तेमाल किया जा सकता है (इंटर-डिवाइस कम्यूनिकेशन इनमें ये प्रॉपर्टी मौजूद होती हैं). आम तौर पर, एचएएल आपकी सूची का आखिरी हिस्सा तय करता है. एक ऐसा ऑब्जेक्ट बनाना जिसे RPC के ज़रिए बिल्ट-इन HIDL टाइप MQDescriptorSync या MQDescriptorUnsync. यह सूची के दूसरे सिरे को सेट अप करने के लिए, ऑब्जेक्ट का इस्तेमाल किया जा सकता है.
    • सिंक करें सूची को ओवरफ़्लो करने की अनुमति नहीं है और सिर्फ़ एक ही सूची हो सकती है रीडर.
    • अनसिंक करें सूचियों को ओवरफ़्लो किया जा सकता है और इसमें कई लोग हो सकते हैं, और इनमें से हर एक को समय पर डेटा पढ़ना होगा या उसे खोना होगा.
    इनमें से किसी भी टाइप को अंडरफ़्लो (खाली सूची से पढ़ना विफल होना) की अनुमति नहीं है, और हर टाइप में सिर्फ़ एक राइटर हो सकता है.

एफ़एमक्यू के बारे में ज़्यादा जानकारी के लिए, यहां जाएं तेज़ मैसेज की सूची (FMQ).