गाड़ी के कैमरा एचएएल

Android में एक ऑटोमोटिव HIDL हार्डवेयर ऐब्स्ट्रैक्शन लेयर (HAL) होता है, जो Android बूट प्रोसेस में इमेज को बहुत जल्दी कैप्चर और दिखाने की सुविधा देता है और सिस्टम के जीवन में आगे भी काम करती रहेगी. एचएएल में एक्सटीरियर व्यू सिस्टम (ईवीएस) स्टैक. आम तौर पर, इसका इस्तेमाल रीयरव्यू में काम करने के लिए किया जाता है Android पर आधारित इन-वाहन मॉडल की मदद से, वाहनों में कैमरे और सराउंड व्यू की सुविधा का इस्तेमाल किया जा सकता है सूचना और मनोरंजन की सुविधा देने वाले (आईवीआई) सिस्टम. ईवीएस की मदद से, बेहतर सुविधाएं भी लागू की जा सकती हैं उपयोगकर्ता के ऐप्लिकेशन में.

Android में ईवीएस के हिसाब से कैप्चर और डिसप्ले ड्राइवर भी शामिल है इंटरफ़ेस (/hardware/interfaces/automotive/evs/1.0 में). हालांकि, यह Android ऑपरेटिंग सिस्टम पर, रीयरव्यू कैमरा ऐप्लिकेशन बनाने की सुविधा उपलब्ध है ऐसा हो सकता है कि ये ऐप्लिकेशन काफ़ी देरी से काम करें. Android बूट प्रोसेस शुरू हो जाती है. खास तौर पर बनाए गए एचएएल का इस्तेमाल करने से, बेहतर इंटरफ़ेस मिलता है साथ ही, यह भी साफ़ तौर पर बताया जाता है कि ईवीएस स्टैक के साथ काम करने के लिए, OEM को क्या लागू करने की ज़रूरत है.

सिस्टम के कॉम्पोनेंट

ईवीएस में सिस्टम के ये कॉम्पोनेंट शामिल होते हैं:

ईवीएस सिस्टम
कॉम्पोनेंट का डायग्राम अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
पहली इमेज. ईवीएस सिस्टम के कॉम्पोनेंट के बारे में खास जानकारी.

ईवीएस ऐप्लिकेशन

C++ ईवीएस ऐप्लिकेशन का सैंपल (/packages/services/Car/evs/app) से रेफ़रंस दिया गया है लागू करना. यह ऐप्लिकेशन, ईवीएस मैनेजर से, और तैयार फ़्रेम को ईवीएस मैनेजर पर वापस दिखाने के लिए भेजा जा रहा है. यह उम्मीद की जाती है कि ईवीएस और कार सर्विस उपलब्ध होते ही, इसे शुरू कर दिया जाएगा. चालू होने के दो (2) सेकंड के भीतर लक्षित होता है. OEM, ईवीएस में बदलाव कर सकते हैं या उसे बदल सकते हैं ऐप को ज़रूरत के हिसाब से चुनें.

ईवीएस मैनेजर

ईवीएस मैनेजर (/packages/services/Car/evs/manager) यह सुविधा देता है ये वे बिल्डिंग ब्लॉक होते हैं जिनकी ज़रूरत ईवीएस ऐप्लिकेशन को होती है. 6DOF मल्टी-कैमरा रेंडरिंग के लिए साधारण रीयरव्यू कैमरा डिसप्ले. इसका इंटरफ़ेस इसे HIDL के ज़रिए पेश किया जाता है और इसे एक साथ कई क्लाइंट को स्वीकार करने के लिए बनाया गया है. अन्य ऐप्लिकेशन और सेवाएं (खास तौर पर कार सेवा) ईवीएस के बारे में क्वेरी कर सकती हैं मैनेजर की स्थिति, ताकि यह पता लगाया जा सके कि ईवीएस सिस्टम कब चालू हुआ.

ईवीएस HIDL इंटरफ़ेस

ईवीएस सिस्टम, कैमरा और डिसप्ले एलिमेंट, दोनों को android.hardware.automotive.evs पैकेज. लागू करने का सैंपल जो इंटरफ़ेस का इस्तेमाल करती है (यह सिंथेटिक टेस्ट इमेज जनरेट करती है और दोतरफ़ा यात्रा के लिए इमेज) इसमें दिया गया है /hardware/interfaces/automotive/evs/1.0/default.

.hal फ़ाइलों में बताए गए एपीआई को लागू करने की ज़िम्मेदारी OEM की है /hardware/interfaces/automotive/evs में. इस तरह के लागू होने की वजह से जो फ़िज़िकल कैमरों से डेटा को कॉन्फ़िगर करने और इकट्ठा करने के लिए ज़िम्मेदार हैं. इसे साझा मेमोरी बफ़र के ज़रिए डिलीवर करता है, जिन्हें Gralloc से पहचाना जा सकता है. डिसप्ले लागू करने की प्रोसेस, शेयर की गई मेमोरी बफ़र को उपलब्ध कराने की ज़िम्मेदारी होती है जिसे ऐप्लिकेशन (आम तौर पर, EGL रेंडरिंग के ज़रिए) भरा जा सकता है और किसी भी अन्य चीज़ की तुलना में तैयार फ़्रेम फ़िज़िकल डिसप्ले. वेंडर के लिए ईवीएस इंटरफ़ेस की सेटिंग सेव की जा सकती है /vendor/… /device/… या hardware/… से कम (उदाहरण के लिए, /hardware/[vendor]/[platform]/evs).

कर्नेल ड्राइवर

ईवीएस स्टैक के साथ काम करने वाले डिवाइस के लिए, कर्नेल ड्राइवर होना ज़रूरी है. इसके बजाय नए ड्राइवर बनाते हुए, OEM के पास ईवीएस के लिए ज़रूरी सुविधाएं चालू करने का विकल्प होता है. इसके लिए, मौजूदा कैमरा या डिसप्ले हार्डवेयर ड्राइवर को ऐक्सेस करने की सुविधा मिलती है. ड्राइवर का दोबारा इस्तेमाल करने से यह हो सकता है फ़ायदा होता है, खास तौर पर उन डिसप्ले ड्राइवर के लिए जहां इमेज प्रज़ेंटेशन को अन्य ऐक्टिव थ्रेड के साथ कोऑर्डिनेट करने की ज़रूरत होती है. Android 8.0 में v4l2-आधारित वर्शन होता है सैंपल ड्राइवर (packages/services/Car/evs/sampleDriver में) को v4l2 समर्थन के लिए कर्नेल पर और प्रज़ेंटेशन के लिए SurfaceFlinger पर आउटपुट इमेज.

ईवीएस हार्डवेयर इंटरफ़ेस की जानकारी

इस सेक्शन में, एचएएल के बारे में बताया गया है. वेंडर से यह उम्मीद की जाती है कि वे इस एपीआई को उनके हार्डवेयर के हिसाब से लागू किया गया है.

IEvsEnumerator

यह ऑब्जेक्ट, उपलब्ध ईवीएस हार्डवेयर की गिनती सिस्टम (एक या ज़्यादा कैमरे और एक डिसप्ले डिवाइस).

getCameraList() generates (vec<CameraDesc> cameras);

एक वेक्टर लौटाता है जिसमें सिस्टम के सभी कैमरों के बारे में जानकारी होती है. हां यह माना जाता है कि कैमरों का सेट ठीक से काम कर रहा है और बूट के समय पता किया जा सकता है. जानकारी के लिए कैमरे की जानकारी, CameraDesc देखें.

openCamera(string camera_id) generates (IEvsCamera camera);

किसी खास कैमरे के साथ इंटरैक्ट करने के लिए इस्तेमाल किया गया इंटरफ़ेस ऑब्जेक्ट हासिल करता है इसकी पहचान यूनीक camera_id स्ट्रिंग से की जाती है. फ़ेल होने पर शून्य दिखाता है. पहले से खुले कैमरे को फिर से खोलने की कोशिशें विफल नहीं हो सकतीं. रेस से बचने के लिए ऐप्लिकेशन के चालू होने और उसके बंद होने से जुड़ी स्थितियों की जानकारी, कैमरा फिर से खोलना पिछले इंस्टेंस को बंद कर देना चाहिए, ताकि नया अनुरोध पूरा किया जा सके. ऐप्लिकेशन इस तरह से खाली किए गए कैमरा इंस्टेंस को इनऐक्टिव रखा जाना चाहिए वह राज्य, जो अंतिम विनाश की प्रतीक्षा कर रहा है और कैमरे की स्थिति, जिसमें रिटर्न कोड OWNERSHIP_LOST है.

closeCamera(IEvsCamera camera);

IEvsCamera इंटरफ़ेस रिलीज़ करता है (और यह openCamera() कॉल). कैमरे की वीडियो स्ट्रीम closeCamera पर कॉल करने से पहले, stopVideoStream() पर कॉल करके रोका गया.

openDisplay() generates (IEvsDisplay display);

सिस्टम से इंटरैक्ट करने के लिए इस्तेमाल किया जाने वाला इंटरफ़ेस ऑब्जेक्ट हासिल करता है ईवीएस डिसप्ले. सिर्फ़ एक क्लाइंट, IEvsDisplay का फ़ंक्शनल इंस्टेंस यहां सेव कर सकता है समय. खुले व्यवहार की जिस तरह से openCamera में जानकारी दी गई है, उसकी तरह ही, एक नया IEvsDisplay ऑब्जेक्ट, किसी भी समय बनाया जा सकता है और पिछले सभी फ़ंक्शन को बंद कर देता है इंस्टेंस. अमान्य इंस्टेंस मौजूद रहेंगे और फ़ंक्शन कॉल के जवाब देंगे ये अपने मालिकों से शामिल किए जाते हैं, लेकिन उनकी मृत्यु होने पर बदलाव नहीं किया जाना चाहिए. आखिर में, क्लाइंट ऐप्लिकेशन को OWNERSHIP_LOST गड़बड़ी दिख सकती है कोड वापस करने के साथ-साथ, इनऐक्टिव इंटरफ़ेस को बंद करके छोड़ भी देता है.

closeDisplay(IEvsDisplay display);

IEvsDisplay इंटरफ़ेस को रिलीज़ करता है (और यह openDisplay() कॉल). इसके साथ बकाया बफ़र मिले हैं getTargetBuffer() कॉल से पहले डिसप्ले में वापस आना ज़रूरी है डिसप्ले बंद कर रही हूँ.

getDisplayState() generates (DisplayState state);

इससे डिसप्ले की मौजूदा स्थिति की जानकारी मिलती है. एचएएल को लागू करने पर, असल मौजूदा स्थिति, जो हाल ही में अनुरोध की गई स्थिति से अलग हो सकती है. डिसप्ले स्टेटस बदलने वाला लॉजिक, डिवाइस के ऊपर मौजूद होना चाहिए इसकी वजह से, एचएएल को लागू करने में अपने-आप बदलाव नहीं होना चाहिए डिसप्ले स्टेट के लिए. अगर डिसप्ले फ़िलहाल किसी भी क्लाइंट के पास नहीं है (फ़ोन पर कॉल करके OpenDisplay) है, तो यह फ़ंक्शन NOT_OPEN दिखाता है. अगर ऐसा नहीं है, तो ईवीएस डिसप्ले की मौजूदा स्थिति की जानकारी देता है (देखें IEvsDisplay API).

struct CameraDesc {
    string      camera_id;
    int32       vendor_flags;       // Opaque value
}
  • camera_id. यह स्ट्रिंग किसी कैमरे की खास तौर पर पहचान करती है. यह डिवाइस के कर्नेल डिवाइस का नाम या डिवाइस का नाम हो सकता है, जैसे रीयरव्यू पर टैप करें. इस स्ट्रिंग के लिए वैल्यू, एचएएल लागू करने से चुनी जाती है का इस्तेमाल किया जाता है.
  • vendor_flags. विशेष कैमरे को पास करने का तरीका ड्राइवर से कस्टम ईवीएस ऐप्लिकेशन तक की जानकारी साफ़ तौर पर नहीं दी गई है. सर्टिफ़िकेट मिल गया इसमें ड्राइवर और ईवीएस ऐप्लिकेशन तक का डेटा शामिल होता है. इसे अनदेखा किया जा सकता है इसे.

IEvs कैमरा

यह ऑब्जेक्ट एक कैमरे को दिखाता है और इसके लिए मुख्य इंटरफ़ेस है इमेज कैप्चर करने में मदद मिलती है.

getCameraInfo() generates (CameraDesc info);

इस कैमरे का CameraDesc दिखाता है.

setMaxFramesInFlight(int32 bufferCount) generates (EvsResult result);

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

अगर अनुरोध किए गए बफ़रकाउंट को शामिल नहीं किया जा सकता, तो फ़ंक्शन रिटर्न करता है BUFFER_NOT_AVAILABLE या काम का अन्य गड़बड़ी कोड. इस मामले में, सिस्टम पहले से सेट की गई वैल्यू के साथ काम करता रहेगा.

startVideoStream(IEvsCameraStream receiver) generates (EvsResult result);

इस कैमरे से ईवीएस कैमरे के फ़्रेम की डिलीवरी का अनुरोध किया जाता है. IEvsCameraStream जब तक कि समय-समय पर नए इमेज फ़्रेम के साथ कॉल आने लगते हैं, तब तक stopVideoStream() पर कॉल किया गया है. फ़्रेम डिलीवर किए जाने शुरू होने चाहिए startVideoStream कॉल के 500 मि॰से॰ के अंदर और शुरू होने के बाद, ऐसा करना ज़रूरी है जो कम से कम 10 FPS (फ़्रेम प्रति सेकंड) पर जनरेट होता है. वीडियो स्ट्रीम शुरू होने में लगने वाला समय रीयर व्यू कैमरा के चालू होने में लगने वाले समय को कम करने में मदद मिलती है. अगर स्ट्रीम शुरू नहीं हुई है, तो गड़बड़ी कोड ज़रूर दिखना चाहिए; अगर ऐसा नहीं होता है, तो 'ठीक है' को वापस कर दिया जाता है.

oneway doneWithFrame(BufferDesc buffer);

वह फ़्रेम दिखाता है जो IEvsCameraStream से डिलीवर किया गया था. पूरा हो जाने पर अगर IEvsCameraStream इंटरफ़ेस पर डिलीवर किए गए फ़्रेम का इस्तेमाल किया जा रहा है, तो वह फ़्रेम फिर से इस्तेमाल करने के लिए IEvsCamera में वापस लाया गया. बफ़र की छोटी और सीमित संख्या होती है उपलब्ध (यह एक छोटा भी हो सकता है) और अगर सप्लाई खत्म हो गई हो, तो आगे नहीं फ़्रेम तब तक डिलीवर किए जाते हैं, जब तक बफ़र का इस्तेमाल नहीं किया जाता. इसकी वजह से, स्किप किए गए फ़्रेम (शून्य हैंडल वाला बफ़र, स्ट्रीम खत्म होने को दिखाता है और यह काम करता है इस फ़ंक्शन के ज़रिए लौटाने की ज़रूरत नहीं है). सफलता मिलने पर 'ठीक है' या गड़बड़ी का सही कोड डालें, जिसमें INVALID_ARG या BUFFER_NOT_AVAILABLE.

stopVideoStream();

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

getExtendedInfo(int32 opaqueIdentifier) generates (int32 value);

एचएएल लागू करने के तरीके से ड्राइवर से जुड़ी खास जानकारी का अनुरोध करता है. मान opaqueIdentifier के लिए ड्राइवर के लिए अनुमति है, लेकिन कोई मान नहीं पास होने पर ड्राइवर क्रैश हो सकता है. किसी भी अनजान व्यक्ति के लिए ड्राइवर को 0 दिखना चाहिए opaqueIdentifier.

setExtendedInfo(int32 opaqueIdentifier, int32 opaqueValue) generates (EvsResult result);

ड्राइवर के लिए खास वैल्यू को एचएएल लागू करता है. यह एक्सटेंशन है सिर्फ़ वाहन के लिए खास एक्सटेंशन की सुविधा के लिए दिए गए हैं और एचएएल को शामिल नहीं किया गया है डिफ़ॉल्ट स्थिति में काम करने के लिए, इस कॉल की ज़रूरत होनी चाहिए. अगर ड्राइवर मान को पहचानकर स्वीकार कर लेता है, ठीक है लौटाया जाना चाहिए; अन्य मामलों में INVALID_ARG या कोई दूसरा गड़बड़ी कोड दिखाया जाना चाहिए.

struct BufferDesc {
    uint32  width;      // Units of pixels
    uint32  height;     // Units of pixels
    uint32  stride;     // Units of pixels
    uint32  pixelSize;  // Size of single pixel in bytes
    uint32  format;     // May contain values from android_pixel_format_t
    uint32  usage;      // May contain values from Gralloc.h
    uint32  bufferId;   // Opaque value
    handle  memHandle;  // gralloc memory buffer handle
}

यह एपीआई की मदद से पास की गई इमेज के बारे में बताती है. HAL ड्राइव इसके लिए ज़िम्मेदार है इमेज बफ़र और एचएएल क्लाइंट के बारे में जानकारी देने के लिए, इस स्ट्रक्चर को भरना को इस स्ट्रक्चर को सिर्फ़ पढ़ने के लिए मानना चाहिए. फ़ील्ड में ज़रूरत के मुताबिक जानकारी है ताकि क्लाइंट, ANativeWindowBuffer ऑब्जेक्ट को फिर से बना सके, साथ ही, आपके विज्ञापन को EGL के साथ चित्र के साथ eglCreateImageKHR() एक्सटेंशन.

  • width. दिखाई गई इमेज की चौड़ाई (पिक्सल में).
  • height. दिखाई गई इमेज की ऊंचाई (पिक्सल में).
  • stride. हर पंक्ति की मेमोरी में मौजूद पिक्सल की संख्या, और पंक्तियों के अलाइनमेंट के लिए किसी भी पैडिंग (जगह) को ध्यान में रखें. मिलान करने के लिए पिक्सल में दिखाया गया इस तरीके का इस्तेमाल, gralloc के ज़रिए किया गया है. इसकी मदद से बफ़र की जानकारी देखी जा सकती है.
  • pixelSize. हर एक पिक्सल ने कितनी बाइट ली, इससे कॉलम में एक पंक्ति से दूसरी पंक्ति में जाने के लिए ज़रूरी बाइट में इमेज (stride बाइट = stride पिक्सल में * pixelSize).
  • format. इमेज में इस्तेमाल किया गया पिक्सल फ़ॉर्मैट. दिया गया फ़ॉर्मैट प्लैटफ़ॉर्म के OpenGL लागू होने के साथ काम करना चाहिए. पास होने के लिए साथ काम करने की क्षमता की जाँच, HAL_PIXEL_FORMAT_YCRCB_420_SP को यह होना चाहिए कैमरे के इस्तेमाल के लिए बेहतर है और RGBA या BGRA को यह करना चाहिए को दिखाने के लिए चुना जाए.
  • usage. इस्तेमाल के लिए फ़्लैग, एचएएल लागू करने की प्रक्रिया से सेट किए गए. HAL क्लाइंट उम्मीद की जाती है कि इन्हें बिना कोई बदलाव किए पास किया जाएगा (जानकारी के लिए, Gralloc.h मिलते-जुलते फ़्लैग).
  • bufferId. एक यूनीक वैल्यू, जिसे एचएएल लागू करने पर लागू किया जाता है. यह वैल्यू, HAL API से दोतरफ़ा यात्रा के बाद, बफ़र को पहचानने की अनुमति मिलती है. कॉन्टेंट बनाने इस फ़ील्ड में सेव की गई वैल्यू को एचएएल लागू करके मनचाहे तरीके से चुना जा सकता है.
  • memHandle. इसमें मौजूद मेमोरी बफ़र के लिए हैंडल में इमेज डेटा शामिल होता है. एचएएल को लागू करने पर, वह Gralloc का इस्तेमाल कर सकता है बफ़र हैंडल यहां देखें.

आईईवीएसकैमरास्ट्रीम

एसिंक्रोनस वीडियो फ़्रेम पाने के लिए क्लाइंट इस इंटरफ़ेस को लागू करता है डिलीवरी.

deliverFrame(BufferDesc buffer);

जब भी वीडियो फ़्रेम जांच के लिए तैयार होगा, तब इसे एचएएल से कॉल आएंगे. इस तरीके से मिलने वाले बफ़र हैंडल को IEvsCamera::doneWithFrame(). जब वीडियो स्ट्रीम बंद हो जाती है, तो IEvsCamera::stopVideoStream() को कॉल करें, यह कॉलबैक जारी रह सकता है क्योंकि पाइपलाइन में पानी खत्म हो रहा है. इसके बाद भी, हर फ़्रेम को लौटाया जाना चाहिए; जब आख़िरी फ़्रेम स्ट्रीम में डिलीवर कर दिया गया है, और शून्य bufferHandle डिलीवर किया गया है, इससे पता चलता है कि स्ट्रीम खत्म हो गई है और आगे कोई फ़्रेम डिलीवरी नहीं होगी. द शून्य bufferHandle को खुद इसके साथ वापस भेजने की आवश्यकता नहीं है doneWithFrame(), लेकिन अन्य सभी हैंडल वापस करने होंगे

हालांकि, मालिकाना बफ़र फ़ॉर्मैट तकनीकी तौर पर संभव है, लेकिन यह साथ काम करता है टेस्टिंग के लिए ज़रूरी है कि बफ़र इन चार फ़ॉर्मैट में से किसी एक में हो: NV21 (YCrCb 4:2:0 सेमी-प्लानर), YV12 (YCrCb 4:2:0 Planar), YUYV (YCrCb 4:2:2 इंटरलीव्ड), आरजीबीए (32 बिट R:G:B:x), BGRA (32 बिट B:G:R:x). चुना गया फ़ॉर्मैट मान्य होना चाहिए प्लैटफ़ॉर्म के जीएलईएस लागू करने पर, जीएल टेक्सचर सोर्स.

ऐप्लिकेशन को किसी भी बातचीत पर भरोसा नहीं करना चाहिए bufferId फ़ील्ड और memHandle के बीच BufferDesc स्ट्रक्चर. bufferId की वैल्यू यह हैं यह एचएएल ड्राइवर को लागू करने के लिए निजी होता है. साथ ही, इसे एचएएल ड्राइवर के तौर पर इस्तेमाल और फिर से इस्तेमाल किया जा सकता है उन्हें अपनी ज़रूरत के हिसाब से चुन सकते हैं.

IEvsडिसप्ले

यह ऑब्जेक्ट ईवीएस डिसप्ले दिखाता है और डिसप्ले की स्थिति को कंट्रोल करता है, और इमेज के असल प्रज़ेंटेशन को मैनेज करता है.

getDisplayInfo() generates (DisplayDesc info);

सिस्टम से मिले ईवीएस डिसप्ले के बारे में बुनियादी जानकारी देता है (देखें DisplayDesc).

setDisplayState(DisplayState state) generates (EvsResult result);

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

शुरू करने के बाद, डिसप्ले को NOT_VISIBLE स्थिति, जिसके बाद क्लाइंट अनुरोध करेगा VISIBLE_ON_NEXT_FRAME स्थिति में जाकर वीडियो उपलब्ध कराना शुरू करें. जब को दिखाने की ज़रूरत नहीं है, क्लाइंट से अनुरोध किया जाएगा पिछला वीडियो फ़्रेम पास होने के बाद, NOT_VISIBLE की स्थिति.

किसी भी राज्य के लिए कभी भी अनुरोध किया जा सकता है. अगर डिसप्ले पहले से दृश्यमान है, तो इस पर सेट होने पर यह दृश्यमान रहना चाहिए VISIBLE_ON_NEXT_FRAME. अनुरोध की गई स्थिति में, हमेशा 'ठीक है' दिखता है एक अमान्य ईनम मान है. इस मामले में INVALID_ARG है वापस किया गया.

getDisplayState() generates (DisplayState state);

इससे डिसप्ले की स्थिति पता चलती है. एचएएल को लागू करने पर, मौजूदा स्थिति होती है, जो हाल ही में अनुरोध की गई स्थिति से अलग हो सकती है. कॉन्टेंट बनाने डिसप्ले स्टेटस बदलने वाला लॉजिक, डिवाइस के ऊपर मौजूद होना चाहिए इसकी वजह से, एचएएल को लागू करने में अपने-आप बदलाव नहीं होना चाहिए डिसप्ले स्टेट के लिए.

getTargetBuffer() generates (handle bufferHandle);

डिसप्ले से जुड़े फ़्रेम बफ़र में हैंडल दिखाता है. यह बफ़र हो सकता है कि लॉक हो और सॉफ़्टवेयर और/या जीएल के ज़रिए लिखा हो. यह बफ़र लौटाया जाना चाहिए returnTargetBufferForDisplay() पर कॉल करके, भले ही डिसप्ले अब नहीं दिखाई दे रही है.

हालांकि, मालिकाना हक वाले बफ़र फ़ॉर्मैट की सुविधा तकनीकी तौर पर संभव है, लेकिन यह भी देखा जा सकता है कि ये फ़ॉर्मैट साथ काम करते हैं या नहीं. ज़रूरी है कि बफ़र इन चार फ़ॉर्मैट में से किसी एक में हो: NV21 (YCrCb 4:2:0 सेमी-प्लैनर), YV12 (YCrCb 4:2:0 Planar), YUYV (YCrCb 4:2:2 Interleaved), RGBA (32 बिट R:G:B:x), BGRA (32 बिट B:G:R:x). चुने गए फ़ॉर्मैट के लिए, मान्य जीएल फ़ॉर्मैट का इस्तेमाल किया जाना चाहिए प्लैटफ़ॉर्म के जीएलईएस लागू करने पर टारगेट रेंडर करना.

गड़बड़ी होने पर, शून्य हैंडल वाला बफ़र दिखाया जाता है, लेकिन ऐसा बफ़र नहीं होता returnTargetBufferForDisplay को वापस पास करना ज़रूरी है.

returnTargetBufferForDisplay(handle bufferHandle) generates (EvsResult result);

इससे डिसप्ले को पता चलता है कि बफ़र, डिसप्ले के लिए तैयार है. सिर्फ़ बफ़र वापस मिले getTargetBuffer() को किए गए कॉल के ज़रिए इस ऑफ़र का इस्तेमाल किया जा सकता है कॉल है और BufferDesc की सामग्री को क्लाइंट ऐप्लिकेशन में मिलेगा. इस कॉल के बाद, बफ़र का इस्तेमाल से संपर्क करने के लिए प्रोत्साहित करें. सफलता मिलने पर 'ठीक है' या गड़बड़ी का सही कोड दिखाता है INVALID_ARG या BUFFER_NOT_AVAILABLE सहित.

struct DisplayDesc {
    string  display_id;
    int32   vendor_flags;  // Opaque value
}

ईवीएस डिसप्ले की बुनियादी प्रॉपर्टी के बारे में बताता है और ईवीएस के लिए ज़रूरी है लागू करना. इस स्ट्रक्चर को भरने के लिए, एचएएल की ज़िम्मेदारी है ईवीएस डिसप्ले के बारे में बताओ. यह कोई फ़िज़िकल डिसप्ले या वर्चुअल डिसप्ले हो सकता है किसी दूसरे प्रेज़ेंटेशन डिवाइस के साथ लगाना या मिलाना.

  • display_id. ऐसी स्ट्रिंग जो डिसप्ले की खास तौर पर पहचान करती है. यह डिवाइस के कर्नेल डिवाइस का नाम या डिवाइस का कोई नाम हो सकता है, जैसे कि रीयरव्यू. इस स्ट्रिंग के लिए मान को HAL चुनता है लागू किया जाना चाहिए और ऊपर दिए गए स्टैक के ज़रिए अस्पष्ट रूप से इस्तेमाल किया जाना चाहिए.
  • vendor_flags. विशेष कैमरे को पास करने का तरीका ड्राइवर से पसंद के मुताबिक ईवीएस ऐप्लिकेशन तक की जानकारी साफ़ तौर पर नहीं दी गई है. सर्टिफ़िकेट मिल गया इसमें ड्राइवर और ईवीएस ऐप्लिकेशन तक का डेटा शामिल होता है. इसे अनदेखा किया जा सकता है इसे.
enum DisplayState : uint32 {
    NOT_OPEN,               // Display has not been “opened” yet
    NOT_VISIBLE,            // Display is inhibited
    VISIBLE_ON_NEXT_FRAME,  // Will become visible with next frame
    VISIBLE,                // Display is currently active
    DEAD,                   // Display is not available. Interface should be closed
}

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

ईवीएस मैनेजर

ईवीएस मैनेजर, ईवीएस सिस्टम को इस तरह का सार्वजनिक इंटरफ़ेस उपलब्ध कराता है जिससे कैमरे से व्यू इकट्ठा करना और दिखाना. हार्डवेयर ड्राइवर कहां-कहां ऐक्सेस करने की अनुमति देते हैं हर संसाधन (कैमरा या डिसप्ले) पर सिर्फ़ एक चालू इंटरफ़ेस, ईवीएस मैनेजर कैमरे को शेयर करने की सुविधा देता है. एक मुख्य ईवीएस ऐप्लिकेशन ईवीएस मैनेजर का पहला क्लाइंट है और वह अकेला ऐसा क्लाइंट है जिसके पास स्टोरेज में बदलाव करने की अनुमति है डेटा दिखाएं (अतिरिक्त क्लाइंट को कैमरे का रीड ओनली ऐक्सेस दिया जा सकता है इमेज).

ईवीएस मैनेजर उसी एपीआई को लागू करता है जो एचएएल ड्राइवर के लिए होता है और एकाधिक समवर्ती क्लाइंट ( इनमें से एक क्लाइंट ईवीएस मैनेजर से कैमरा खोल सकता है और वीडियो रिसीव कर सकता है स्ट्रीम).

ईवीएस मैनेजर और
ईवीएस हार्डवेयर एपीआई का डायग्राम.
दूसरी इमेज. ईवीएस मैनेजर की स्क्रीन पर ईवीएस की जानकारी हार्डवेयर एपीआई.

ईवीएस हार्डवेयर एचएएल का इस्तेमाल करते समय, ऐप्लिकेशन में कोई अंतर नहीं दिखता लागू किया जा सकता है या ईवीएस मैनेजर एपीआई को लागू किया जा सकता है. हालांकि, ईवीएस मैनेजर एपीआई अनुमति नहीं देता एक ही समय में कैमरे से स्ट्रीम करने की सुविधा. ईवीएस मैनेजर को अनुमति है ईवीएस हार्डवेयर एचएएल लेयर का क्लाइंट होता है और ईवीएस हार्डवेयर के लिए प्रॉक्सी के तौर पर काम करता है हैल.

नीचे दिए गए सेक्शन सिर्फ़ उन कॉल के बारे में बताते हैं जिनमें ईवीएस मैनेजर को लागू करने के दौरान (एक्सपेरिमेंट) व्यवहार; बाकी कॉल हैं यह जानकारी बिलकुल ईवीएस एचएएल से मिलती-जुलती है.

IEvsEnumerator

openCamera(string camera_id) generates (IEvsCamera camera);

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

IEvs कैमरा

EVS Manager की ओर से उपलब्ध कराया गया IEvsCamera लागू किया जाता है, तो इसे अंदरूनी तौर पर वर्चुअलाइज़ किया जाता है इसलिए, कैमरे पर एक क्लाइंट की कार्रवाइयों का असर दूसरे क्लाइंट पर नहीं पड़ता. उनके कैमरों का स्वतंत्र ऐक्सेस बनाए रखने में मदद मिलती है.

startVideoStream(IEvsCameraStream receiver) generates (EvsResult result);

वीडियो स्ट्रीम शुरू करता है. क्लाइंट स्वतंत्र रूप से वीडियो स्ट्रीम शुरू और बंद कर सकते हैं डेटा इस्तेमाल कर सकते हैं. डिवाइस में मौजूद कैमरा तब शुरू होता है, जब पहली बार शुरू करता है.

doneWithFrame(uint32 frameId, handle bufferHandle) generates (EvsResult result);

फ़्रेम दिखाता है. प्रोसेस पूरी होने के बाद, हर क्लाइंट को उनके फ़्रेम लौटाने होंगे, लेकिन उन्हें तब तक अपने फ़्रेम पर रखने की अनुमति है, जब तक वे चाहें. जब क्लाइंट के होल्ड किए गए फ़्रेम की संख्या, कॉन्फ़िगर की गई सीमा तक पहुंच जाती है, तो उसे नहीं मिलेगा कोई और फ़्रेम तब तक नहीं मिलेगा, जब तक इसकी वजह से कोई फ़्रेम नहीं आ जाता. इस फ़्रेम को स्किप करने से, दूसरे फ़्रेम पर कोई असर नहीं पड़ता क्लाइंट, जिन्हें सभी फ़्रेम मिलने के बावजूद उम्मीद के मुताबिक़ काम हो रहा है.

stopVideoStream();

वीडियो स्ट्रीम को रोकता है. प्रत्येक क्लाइंट किसी भी समय अपनी वीडियो स्ट्रीम को बिना किसी रुकावट के बंद कर सकता है का असर अन्य क्लाइंट पर पड़ रहा है. हार्डवेयर लेयर पर मौजूद कैमरा स्ट्रीम यह सुविधा तब बंद हो जाती है, जब किसी कैमरे के आखिरी क्लाइंट ने स्ट्रीम को बंद किया हो.

setExtendedInfo(int32 opaqueIdentifier, int32 opaqueValue) generates (EvsResult result);

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

IEvsडिसप्ले

डिसप्ले के सिर्फ़ एक मालिक को अनुमति है. यहां तक कि ईवीएस मैनेजर लेवल पर भी अनुमति नहीं दी जा सकती. कॉन्टेंट बनाने मैनेजर कोई सुविधा नहीं जोड़ता और सिर्फ़ IEvsDisplay इंटरफ़ेस पास कर देता है से सीधे तौर पर एचएएल लागू करने के तरीके तक पहुंचाता है.

ईवीएस ऐप्लिकेशन

Android में ईवीएस का नेटिव C++ रेफ़रंस शामिल है ऐसा ऐप्लिकेशन जो ईवीएस मैनेजर और वाहन के एचएएल से संपर्क करता है इनमें रीयरव्यू कैमरे के बुनियादी फ़ंक्शन उपलब्ध होते हैं. ऐप्लिकेशन के शुरू होने की उम्मीद है जो सिस्टम को चालू करने की प्रोसेस से बहुत पहले शुरू होता है. साथ ही, चालू वीडियो के हिसाब से उपलब्ध कैमरों और कार की स्थिति (गियर और मुड़ने के सिग्नल की स्थिति). OEM, ईवीएस ऐप्लिकेशन को अपने वाहन के हिसाब से बदल सकते हैं या मौजूदा ऐप्लिकेशन से बदल सकते हैं लॉजिक और प्रज़ेंटेशन के लिए इस्तेमाल करें.

अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
तीसरी इमेज. ईवीएस ऐप्लिकेशन का सैंपल लॉजिक, कैमरा डाउनलोड करें सूची.

अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
चौथी इमेज. ईवीएस ऐप्लिकेशन का सैंपल लॉजिक, पाएं फ़्रेम कॉलबैक करता है.

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

उदाहरण के लिए, ऐप्लिकेशन खुद पिक्सल डेटा को ट्रांसफ़र करने का विकल्प चुन सकता है, संभावित रूप से इनलाइन स्केल या रोटेशन ऑपरेशन के साथ किया जा सकता है. यह ऐप्लिकेशन ये काम कर सका के अलावा, सोर्स इमेज को OpenGL टेक्सचर के तौर पर इस्तेमाल करने का विकल्प चुना गया है. साथ ही, एक कॉम्प्लेक्स रेंडर करने के लिए आउटपुट बफ़र का सीन, जिसमें आइकॉन जैसे वर्चुअल एलिमेंट शामिल हैं, और ऐनिमेशन शामिल हैं. ऐसा हो सकता है कि ज़्यादा बेहतर ऐप्लिकेशन एक साथ कई इनपुट कैमरे इस्तेमाल कर सकते हैं और उन्हें एक आउटपुट फ़्रेम में मर्ज कर सकते हैं (जैसे, वाहन के आस-पास का वर्चुअल व्यू, टॉप-डाउन में इस्तेमाल करने के लिए).

ईवीएस डिसप्ले एचएएल में EGL/SurfaceFlinger का इस्तेमाल करें

इस सेक्शन में बताया गया है कि ईवीएस डिसप्ले एचएएल को लागू करने के लिए, ईजीएल का इस्तेमाल कैसे करें Android 10 में.

ईवीएस एचएएल रेफ़रंस लागू करने की प्रक्रिया में, कैमरे की झलक दिखाने वाली इमेज को रेंडर करने के लिए EGL का इस्तेमाल किया जाता है यह स्क्रीन और libgui का इस्तेमाल करता है टारगेट EGL रेंडर सरफ़ेस बनाने के लिए. Android 8 और उसके बाद के वर्शन में, libgui को VNDK-private की कैटगरी में रखा जाता है, इस ग्रुप में, वीएनडीके लाइब्रेरी के लिए उपलब्ध लाइब्रेरी के ग्रुप के बारे में बताया गया है. वेंडर प्रोसेस इसका इस्तेमाल नहीं कर सकते. एचएएल लागू करने का तरीका, वेंडर पार्टिशन में होना चाहिए. इसलिए, वेंडर इसका इस्तेमाल नहीं कर सकते Surface in HAL लागू करना.

वेंडर से जुड़ी प्रोसेस को मैनेज करने के लिए टूल बनाना

EGL/SurfaceFlinger में सिर्फ़ libgui का इस्तेमाल ही शामिल है में, ईवीएस डिसप्ले एचएएल लागू करें. libgui को लागू करने का सबसे आसान तरीका यह है के ज़रिए फ़्रेमवर्क/नेटिव/लिब्स/गुई बिल्ड स्क्रिप्ट में किसी अतिरिक्त बिल्ड टारगेट का इस्तेमाल करके सीधे तौर पर किया जा सकता है. यह टारगेट बिलकुल वैसा ही है दो फ़ील्ड को छोड़कर libgui टारगेट:

  • name
  • vendor_available
cc_library_shared {
    name: "libgui_vendor",
    vendor_available: true,
    vndk: {
        enabled: false,
    },
    double_loadable: true,

defaults: ["libgui_bufferqueue-defaults"],
srcs: [ … // bufferhub is not used when building libgui for vendors target: { vendor: { cflags: [ "-DNO_BUFFERHUB", "-DNO_INPUT", ], …

ध्यान दें: वेंडर के टारगेट NO_INPUT मैक्रो की मदद से बनाए जाते हैं. इससे पार्सल डेटा से एक 32-बिट शब्द हट जाता है. SurfaceFlinger फ़ाइल, हटाए जा चुके फ़ील्ड के हिसाब से काम करती है. इसलिए, SurfaceFlinger पार्सल को पार्स नहीं कर सका. ऐसा fcntl की गड़बड़ी के तौर पर देखा गया है:

W Parcel  : Attempt to read object from Parcel 0x78d9cffad8 at offset 428 that is not in the object list
E Parcel  : fcntl(F_DUPFD_CLOEXEC) failed in Parcel::read, i is 0, fds[i] is 0, fd_count is 20, error: Unknown error 2147483647
W Parcel  : Attempt to read object from Parcel 0x78d9cffad8 at offset 544 that is not in the object list

इस स्थिति को ठीक करने के लिए:

diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 6066421fa..25cf5f0ce 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -54,6 +54,9 @@ status_t layer_state_t::write(Parcel& output) const
    output.writeFloat(color.b);
#ifndef NO_INPUT
    inputInfo.write(output);
+#else
+    // Write a dummy 32-bit word.
+    output.writeInt32(0);
#endif
    output.write(transparentRegion);
    output.writeUint32(transform);

सैंपल बिल्ड निर्देश नीचे दिए गए हैं. पाने की उम्मीद करते हैं $(ANDROID_PRODUCT_OUT)/system/lib64/libgui_vendor.so.

$ cd <your_android_source_tree_top>
$ . ./build/envsetup.
$ lunch <product_name>-<build_variant>
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=10
TARGET_PRODUCT=<product_name>
TARGET_BUILD_VARIANT=<build_variant>
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=generic
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv7-a-neon
TARGET_2ND_CPU_VARIANT=cortex-a9
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=<host_linux_version>
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=QT
OUT_DIR=out
============================================

$ m -j libgui_vendor … $ find $ANDROID_PRODUCT_OUT/system -name "libgui_vendor*" .../out/target/product/hawk/system/lib64/libgui_vendor.so .../out/target/product/hawk/system/lib/libgui_vendor.so

ईवीएस एचएएल लागू करने के दौरान, बाइंडर का इस्तेमाल करें

Android 8 और उसके बाद के वर्शन में, /dev/binder डिवाइस नोड सिर्फ़ Android 8 और उसके बाद के वर्शन के लिए उपलब्ध है इसकी वजह से, वेंडर प्रोसेस को ऐक्सेस नहीं किया जा सकता. इसके बजाय, वेंडर प्रोसेस को /dev/hwbinder का इस्तेमाल करना चाहिए. साथ ही, उसे किसी भी एआईडीएल इंटरफ़ेस में बदलना होगा HIDL. अगर आपको वेंडर प्रोसेस के बीच एआईडीएल इंटरफ़ेस का इस्तेमाल जारी रखना है, तो बाइंडर डोमेन, /dev/vndbinder का इस्तेमाल करें.

आईपीसी डोमेन ब्यौरा
/dev/binder एआईडीएल इंटरफ़ेस के साथ फ़्रेमवर्क/ऐप्लिकेशन प्रोसेस के बीच आईपीसी
/dev/hwbinder HIDL इंटरफ़ेस वाले फ़्रेमवर्क/वेंडर प्रोसेस के बीच आईपीसी
HIDL इंटरफ़ेस के साथ वेंडर प्रोसेस के बीच आईपीसी
/dev/vndbinder एआईडीएल इंटरफ़ेस के साथ वेंडर/वेंडर प्रोसेस के बीच आईपीसी

SurfaceFlinger में एआईडीएल इंटरफ़ेस तय होता है, जबकि वेंडर प्रोसेस, इन कामों के लिए सिर्फ़ HIDL इंटरफ़ेस का इस्तेमाल कर सकती हैं फ़्रेमवर्क की प्रोसेस पूरी कर सकें. मौजूदा कन्वर्ज़न को बदलने के लिए ज़्यादा काम की ज़रूरत होती है एआईडीएल इंटरफ़ेस को HIDL में बदला गया. अच्छी बात यह है कि Android एक तरीका उपलब्ध कराता है, जिससे बाइंडर चुनें libbinder के लिए ड्राइवर, जिससे यूज़रस्पेस लाइब्रेरी प्रोसेस जुड़ी हुई हैं.

diff --git a/evs/sampleDriver/service.cpp b/evs/sampleDriver/service.cpp
index d8fb3166..5fd02935 100644
--- a/evs/sampleDriver/service.cpp
+++ b/evs/sampleDriver/service.cpp
@@ -21,6 +21,7 @@
#include <utils/Errors.h>
#include <utils/StrongPointer.h>
#include <utils/Log.h>
+#include <binder/ProcessState.h>

#include "ServiceNames.h"
#include "EvsEnumerator.h"
@@ -43,6 +44,9 @@ using namespace android;
int main() {
    ALOGI("EVS Hardware Enumerator service is starting");


+    // Use /dev/binder for SurfaceFlinger
+    ProcessState::initWithDriver("/dev/binder");
+


    // Start a thread to listen to video device addition events.
    std::atomic<bool> running { true };
    std::thread ueventHandler(EvsEnumerator::EvsUeventThread, std::ref(running));

ध्यान दें: वेंडर प्रोसेस को कॉल करने से पहले इसे कॉल करना चाहिए Process या IPCThreadState या बाइंडर कॉल करने से पहले.

SELinux नीतियां

अगर डिवाइस को लागू करने के लिए, फ़ुल ट्रेबल है, तो SELinux वेंडर को लागू करने से रोकता है /dev/binder का इस्तेमाल करने से प्रोसेस हो जाती हैं. उदाहरण के लिए, ईवीएस एचएएल सैंपल लागू करने की प्रक्रिया hal_evs_driver डोमेन को असाइन की गई है और इसके लिए ज़रूरी है binder_device डोमेन के लिए आर/डब्ल्यू अनुमतियां.

W ProcessState: Opening '/dev/binder' failed: Permission denied
F ProcessState: Binder driver could not be opened. Terminating.
F libc    : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 9145 (android.hardwar), pid 9145 (android.hardwar)
W android.hardwar: type=1400 audit(0.0:974): avc: denied { read write } for name="binder" dev="tmpfs" ino=2208 scontext=u:r:hal_evs_driver:s0 tcontext=u:object_r:binder_device:s0 tclass=chr_file permissive=0

हालांकि, इन अनुमतियों को जोड़ने से बिल्ड फ़ेल हो जाता है, क्योंकि इससे इन चीज़ों का उल्लंघन होता है फ़ुल-ट्रेबल डिवाइस के लिए, system/sepolicy/domain.te में तय किए गए नियमों को कभी अनुमति न दें.

libsepol.report_failure: neverallow on line 631 of system/sepolicy/public/domain.te (or line 12436 of policy.conf) violated by allow hal_evs_driver binder_device:chr_file { read write };
libsepol.check_assertions: 1 neverallow failures occurred
full_treble_only(`
neverallow {
    domain
    -coredomain
    -appdomain
    -binder_in_vendor_violators
} binder_device:chr_file rw_file_perms;
')

binder_in_vendor_violators अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है एक एट्रिब्यूट है, जो किसी गड़बड़ी को पकड़ने और डेवलपमेंट की गाइड के लिए दिया जाता है. इसका इस्तेमाल इन कामों के लिए भी किया जा सकता है ऊपर बताए गए Android 10 के उल्लंघन को ठीक करें.

diff --git a/evs/sepolicy/evs_driver.te b/evs/sepolicy/evs_driver.te
index f1f31e9fc..6ee67d88e 100644
--- a/evs/sepolicy/evs_driver.te
+++ b/evs/sepolicy/evs_driver.te
@@ -3,6 +3,9 @@ type hal_evs_driver, domain, coredomain;
hal_server_domain(hal_evs_driver, hal_evs)
hal_client_domain(hal_evs_driver, hal_evs)

+# Allow to use /dev/binder
+typeattribute hal_evs_driver binder_in_vendor_violators;
+
# allow init to launch processes in this context
type hal_evs_driver_exec, exec_type, file_type, system_file_type;
init_daemon_domain(hal_evs_driver)

वेंडर प्रोसेस के तौर पर, ईवीएस एचएएल रेफ़रंस को लागू करने की प्रोसेस बनाएं

रेफ़रंस के तौर पर, आपके पास ये बदलाव करने का विकल्प है packages/services/Car/evs/Android.mk. कृपया पक्का करें कि बताए गए सभी बदलाव, लागू करने के लिए काम करते हैं.

diff --git a/evs/sampleDriver/Android.mk b/evs/sampleDriver/Android.mk
index 734feea7d..0d257214d 100644
--- a/evs/sampleDriver/Android.mk
+++ b/evs/sampleDriver/Android.mk
@@ -16,7 +16,7 @@ LOCAL_SRC_FILES := \
LOCAL_SHARED_LIBRARIES := \
    android.hardware.automotive.evs@1.0 \
    libui \
-    libgui \
+    libgui_vendor \
    libEGL \
    libGLESv2 \
    libbase \
@@ -33,6 +33,7 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_INIT_RC := android.hardware.automotive.evs@1.0-sample.rc

LOCAL_MODULE := android.hardware.automotive.evs@1.0-sample
+LOCAL_PROPRIETARY_MODULE := true

LOCAL_MODULE_TAGS := optional
LOCAL_STRIP_MODULE := keep_symbols
@@ -40,6 +41,7 @@ LOCAL_STRIP_MODULE := keep_symbols
LOCAL_CFLAGS += -DLOG_TAG=\"EvsSampleDriver\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+LOCAL_CFLAGS += -Iframeworks/native/include

#NOTE:  It can be helpful, while debugging, to disable optimizations
#LOCAL_CFLAGS += -O0 -g
diff --git a/evs/sampleDriver/service.cpp b/evs/sampleDriver/service.cpp
index d8fb31669..5fd029358 100644
--- a/evs/sampleDriver/service.cpp
+++ b/evs/sampleDriver/service.cpp
@@ -21,6 +21,7 @@
#include <utils/Errors.h>
#include <utils/StrongPointer.h>
#include <utils/Log.h>
+#include <binder/ProcessState.h>

#include "ServiceNames.h"
#include "EvsEnumerator.h"
@@ -43,6 +44,9 @@ using namespace android;
int main() {
    ALOGI("EVS Hardware Enumerator service is starting");
+    // Use /dev/binder for SurfaceFlinger
+    ProcessState::initWithDriver("/dev/binder");
+
     // Start a thread to listen video device addition events.
    std::atomic<bool> running { true };
    std::thread ueventHandler(EvsEnumerator::EvsUeventThread, std::ref(running));
diff --git a/evs/sepolicy/evs_driver.te b/evs/sepolicy/evs_driver.te
index f1f31e9fc..632fc7337 100644
--- a/evs/sepolicy/evs_driver.te
+++ b/evs/sepolicy/evs_driver.te
@@ -3,6 +3,9 @@ type hal_evs_driver, domain, coredomain;
hal_server_domain(hal_evs_driver, hal_evs)
hal_client_domain(hal_evs_driver, hal_evs)

+# allow to use /dev/binder
+typeattribute hal_evs_driver binder_in_vendor_violators;
+
# allow init to launch processes in this context
type hal_evs_driver_exec, exec_type, file_type, system_file_type;
init_daemon_domain(hal_evs_driver)
@@ -22,3 +25,7 @@ allow hal_evs_driver ion_device:chr_file r_file_perms;

# Allow the driver to access kobject uevents
allow hal_evs_driver self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl;
+
+# Allow the driver to use the binder device
+allow hal_evs_driver binder_device:chr_file rw_file_perms;