वाहन कैमरा HAL

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

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

तंत्र के अंश

ईवीएस में निम्नलिखित सिस्टम घटक शामिल हैं:

ईवीएस सिस्टम घटक आरेख

चित्र 1. ईवीएस सिस्टम घटकों का अवलोकन।

ईवीएस ऐप

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

ईवीएस प्रबंधक

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

ईवीएस एचआईडीएल इंटरफ़ेस

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

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

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

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

ईवीएस हार्डवेयर इंटरफ़ेस विवरण

यह अनुभाग एचएएल का वर्णन करता है। विक्रेताओं से अपेक्षा की जाती है कि वे अपने हार्डवेयर के लिए अनुकूलित इस एपीआई का कार्यान्वयन प्रदान करें।

IEvsप्रगणक

यह ऑब्जेक्ट सिस्टम में उपलब्ध ईवीएस हार्डवेयर (एक या अधिक कैमरे और एकल डिस्प्ले डिवाइस) की गणना करने के लिए जिम्मेदार है।

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

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

openCamera(string camera_id) generates (IEvsCamera camera);

अद्वितीय कैमरा_आईडी स्ट्रिंग द्वारा पहचाने गए विशिष्ट कैमरे के साथ इंटरैक्ट करने के लिए उपयोग किया जाने वाला एक इंटरफ़ेस ऑब्जेक्ट प्राप्त करता है। विफलता पर NULL लौटाता है. जो कैमरा पहले से खुला है उसे फिर से खोलने का प्रयास विफल नहीं हो सकता। ऐप स्टार्टअप और शटडाउन से जुड़ी दौड़ की स्थिति से बचने के लिए, कैमरे को दोबारा खोलने से पिछला उदाहरण बंद हो जाना चाहिए ताकि नया अनुरोध पूरा किया जा सके। एक कैमरा इंस्टेंस जिसे इस तरह से प्रीमेप्ट किया गया है, उसे निष्क्रिय स्थिति में रखा जाना चाहिए, अंतिम विनाश की प्रतीक्षा करनी चाहिए और 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);

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

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

IEvsCamera

यह ऑब्जेक्ट एकल कैमरे का प्रतिनिधित्व करता है और छवियों को कैप्चर करने के लिए प्राथमिक इंटरफ़ेस है।

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 एफपीएस पर उत्पन्न होना चाहिए। वीडियो स्ट्रीम को प्रभावी ढंग से शुरू करने के लिए आवश्यक समय किसी भी रियरव्यू कैमरा स्टार्टअप समय की आवश्यकता के विरुद्ध गिना जाता है। यदि स्ट्रीम प्रारंभ नहीं हुई है, तो एक त्रुटि कोड लौटाया जाना चाहिए; अन्यथा ओके लौटा दिया जाता है।

oneway doneWithFrame(BufferDesc buffer);

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

stopVideoStream();

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

getExtendedInfo(int32 opaqueIdentifier) generates (int32 value);

एचएएल कार्यान्वयन से ड्राइवर-विशिष्ट जानकारी का अनुरोध करता है। opaqueIdentifier के लिए अनुमत मान ड्राइवर-विशिष्ट हैं, लेकिन पारित कोई भी मान ड्राइवर को क्रैश नहीं कर सकता है। ड्राइवर को किसी भी अज्ञात opaqueIdentifier के लिए 0 लौटाना चाहिए।

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

एचएएल कार्यान्वयन के लिए ड्राइवर-विशिष्ट मान भेजता है। यह एक्सटेंशन केवल वाहन-विशिष्ट एक्सटेंशन की सुविधा के लिए प्रदान किया गया है और किसी भी एचएएल कार्यान्वयन के लिए इस कॉल को डिफ़ॉल्ट स्थिति में कार्य करने की आवश्यकता नहीं होनी चाहिए। यदि ड्राइवर मानों को पहचानता है और स्वीकार करता है, तो OK लौटाया जाना चाहिए; अन्यथा 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
}

एपीआई के माध्यम से पारित एक छवि का वर्णन करता है। एचएएल ड्राइव छवि बफर का वर्णन करने के लिए इस संरचना को भरने के लिए जिम्मेदार है और एचएएल क्लाइंट को इस संरचना को केवल-पढ़ने के लिए मानना ​​चाहिए। फ़ील्ड में क्लाइंट को ANativeWindowBuffer ऑब्जेक्ट को फिर से बनाने की अनुमति देने के लिए पर्याप्त जानकारी होती है, जैसा कि eglCreateImageKHR() एक्सटेंशन के माध्यम से EGL के साथ छवि का उपयोग करने के लिए आवश्यक हो सकता है।

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

IEvsCameraStream

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

deliverFrame(BufferDesc buffer);

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

जबकि मालिकाना बफ़र प्रारूप तकनीकी रूप से संभव हैं, संगतता परीक्षण के लिए बफ़र को चार समर्थित प्रारूपों में से एक में होना आवश्यक है: NV21 (YCrCb 4:2:0 सेमी-प्लानर), YV12 (YCrCb 4:2:0 प्लानर), YUYV (YCrCb 4: 2:2 इंटरलीव्ड), आरजीबीए (32 बिट आर:जी:बी:एक्स), बीजीआरए (32 बिट बी:जी:आर:एक्स)। चयनित प्रारूप प्लेटफ़ॉर्म के GLES कार्यान्वयन पर एक मान्य GL बनावट स्रोत होना चाहिए।

ऐप को BufferDesc संरचना में bufferId फ़ील्ड और memHandle के बीच किसी भी पत्राचार पर भरोसा नहीं करना चाहिए। bufferId मान एचएएल ड्राइवर कार्यान्वयन के लिए अनिवार्य रूप से निजी हैं, और यह उन्हें उचित समझे जाने पर उपयोग (और पुन: उपयोग) कर सकता है।

IEvsप्रदर्शन

यह ऑब्जेक्ट ईवीएस डिस्प्ले का प्रतिनिधित्व करता है, डिस्प्ले की स्थिति को नियंत्रित करता है, और छवियों की वास्तविक प्रस्तुति को संभालता है।

getDisplayInfo() generates (DisplayDesc info);

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

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);

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

जबकि मालिकाना बफ़र प्रारूप तकनीकी रूप से संभव हैं, संगतता परीक्षण के लिए बफ़र को चार समर्थित प्रारूपों में से एक में होना आवश्यक है: NV21 (YCrCb 4:2:0 सेमी-प्लानर), YV12 (YCrCb 4:2:0 प्लानर), YUYV (YCrCb 4: 2:2 इंटरलीव्ड), आरजीबीए (32 बिट आर:जी:बी:एक्स), बीजीआरए (32 बिट बी:जी:आर:एक्स)। चयनित प्रारूप प्लेटफ़ॉर्म के GLES कार्यान्वयन पर एक वैध GL रेंडर लक्ष्य होना चाहिए।

त्रुटि होने पर, शून्य हैंडल वाला एक बफ़र वापस कर दिया जाता है, लेकिन ऐसे बफ़र को 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 । एक स्ट्रिंग जो विशिष्ट रूप से डिस्प्ले की पहचान करती है। यह डिवाइस का कर्नेल डिवाइस नाम या डिवाइस का नाम हो सकता है, जैसे कि रियरव्यू । इस स्ट्रिंग का मान एचएएल कार्यान्वयन द्वारा चुना जाता है और उपरोक्त स्टैक द्वारा अपारदर्शी रूप से उपयोग किया जाता है।
  • 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() कॉल के माध्यम से इमेजरी के अगले फ्रेम की डिलीवरी के साथ दृश्यमान होने के लिए तैयार है।

ईवीएस प्रबंधक

ईवीएस प्रबंधक बाहरी कैमरा दृश्यों को एकत्र करने और प्रस्तुत करने के लिए ईवीएस सिस्टम को सार्वजनिक इंटरफ़ेस प्रदान करता है। जहां हार्डवेयर ड्राइवर प्रति संसाधन (कैमरा या डिस्प्ले) केवल एक सक्रिय इंटरफ़ेस की अनुमति देते हैं, ईवीएस प्रबंधक कैमरों तक साझा पहुंच की सुविधा प्रदान करता है। एक एकल प्राथमिक ईवीएस ऐप ईवीएस प्रबंधक का पहला क्लाइंट है, और एकमात्र क्लाइंट है जिसे डिस्प्ले डेटा लिखने की अनुमति है (अतिरिक्त क्लाइंट को कैमरा छवियों तक केवल पढ़ने के लिए पहुंच प्रदान की जा सकती है)।

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

ईवीएस प्रबंधक और ईवीएस हार्डवेयर एपीआई आरेख।

चित्र 2. ईवीएस प्रबंधक अंतर्निहित ईवीएस हार्डवेयर एपीआई को प्रतिबिंबित करता है।

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

निम्नलिखित अनुभाग केवल उन कॉलों का वर्णन करते हैं जिनका ईवीएस प्रबंधक कार्यान्वयन में एक अलग (विस्तारित) व्यवहार है; शेष कॉल ईवीएस एचएएल विवरण के समान हैं।

IEvsप्रगणक

openCamera(string camera_id) generates (IEvsCamera camera);

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

IEvsCamera

ईवीएस प्रबंधक द्वारा प्रदान किया गया 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 इंटरफ़ेस को पास करता है।

ईवीएस ऐप

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

चित्र 3. ईवीएस ऐप नमूना तर्क, कैमरा सूची प्राप्त करें।



चित्र 4. ईवीएस ऐप नमूना तर्क, फ़्रेम कॉलबैक प्राप्त करें।

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

उदाहरण के लिए, ऐप संभवतः इनलाइन स्केल या रोटेशन ऑपरेशन के साथ, पिक्सेल डेटा को स्वयं स्थानांतरित करना चुन सकता है। ऐप स्रोत छवि को ओपनजीएल बनावट के रूप में उपयोग करना भी चुन सकता है और आउटपुट बफर में एक जटिल दृश्य प्रस्तुत कर सकता है, जिसमें आइकन, दिशानिर्देश और एनिमेशन जैसे आभासी तत्व शामिल हैं। एक अधिक परिष्कृत ऐप कई समवर्ती इनपुट कैमरों का भी चयन कर सकता है और उन्हें एकल आउटपुट फ्रेम में मर्ज कर सकता है (जैसे कि ऊपर से नीचे, वाहन परिवेश के आभासी दृश्य में उपयोग के लिए)।

ईवीएस डिस्प्ले एचएएल में ईजीएल/सरफेसफ्लिंगर का उपयोग करें

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

ईवीएस एचएएल संदर्भ कार्यान्वयन स्क्रीन पर कैमरा पूर्वावलोकन प्रस्तुत करने के लिए ईजीएल का उपयोग करता है और लक्ष्य ईजीएल रेंडर सतह बनाने के लिए libgui उपयोग करता है। एंड्रॉइड 8 (और उच्चतर) में, libgui वीएनडीके-प्राइवेट के रूप में वर्गीकृत किया गया है, जो वीएनडीके पुस्तकालयों के लिए उपलब्ध पुस्तकालयों के एक समूह को संदर्भित करता है जिसका विक्रेता प्रक्रियाएं उपयोग नहीं कर सकती हैं। क्योंकि एचएएल कार्यान्वयन को विक्रेता विभाजन में रहना चाहिए, विक्रेताओं को एचएएल कार्यान्वयन में सरफेस का उपयोग करने से रोका जाता है।

विक्रेता प्रक्रियाओं के लिए लिबगुई का निर्माण

ईवीएस डिस्प्ले एचएएल कार्यान्वयन में ईजीएल/सरफेसफ्लिंगर का उपयोग करने के लिए 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

ईवीएस एचएएल कार्यान्वयन में बाइंडर का उपयोग करें

एंड्रॉइड 8 (और उच्चतर) में, /dev/binder डिवाइस नोड फ्रेमवर्क प्रक्रियाओं के लिए विशिष्ट हो गया और इसलिए, विक्रेता प्रक्रियाओं के लिए पहुंच योग्य नहीं है। इसके बजाय, विक्रेता प्रक्रियाओं को /dev/hwbinder उपयोग करना चाहिए और किसी भी AIDL इंटरफ़ेस को HIDL में परिवर्तित करना चाहिए। जो लोग विक्रेता प्रक्रियाओं के बीच एआईडीएल इंटरफेस का उपयोग जारी रखना चाहते हैं, उनके लिए बाइंडर डोमेन, /dev/vndbinder उपयोग करें।

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

जबकि सरफेसफ्लिंगर एआईडीएल इंटरफेस को परिभाषित करता है, विक्रेता प्रक्रियाएं फ्रेमवर्क प्रक्रियाओं के साथ संचार करने के लिए केवल एचआईडीएल इंटरफेस का उपयोग कर सकती हैं। मौजूदा एआईडीएल इंटरफेस को एचआईडीएल में बदलने के लिए बहुत कम काम की आवश्यकता होती है। सौभाग्य से, एंड्रॉइड एक विधि प्रदान करता है जिसके साथ 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 डोमेन के लिए r/w अनुमतियों की आवश्यकता है।

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 एक विशेषता है जो बग को पकड़ने और विकास का मार्गदर्शन करने के लिए प्रदान की जाती है। इसका उपयोग ऊपर वर्णित एंड्रॉइड 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;