Android มี Automotive HIDL Hardware Abstraction Layer (HAL) ที่ สามารถจับภาพและแสดงภาพตั้งแต่เนิ่นๆ ในการเปิดเครื่องของ Android และจะทำงานต่อไปตลอดชีวิตของระบบ HAL ประกอบด้วย ระบบมุมมองภายนอก (EVS) และมักจะใช้เพื่อรองรับการมองหลัง กล้องและมุมมองเซอร์ราวด์ในยานพาหนะที่ติดตั้งในรถ Android ระบบสาระบันเทิง (IVI) EVS ยังช่วยให้ใช้งานฟีเจอร์ขั้นสูงได้ด้วย ในแอปของผู้ใช้
Android ยังมีการจับภาพและไดรเวอร์จอแสดงผลเฉพาะของ EVS ด้วย
ของอินเทอร์เฟซ (ใน /hardware/interfaces/automotive/evs/1.0
) ขณะที่
แอปกล้องมองหลังได้นอกเหนือไปจาก Android เวอร์ชันที่มีอยู่
บริการกล้องและจอแสดงผล แอปดังกล่าวอาจทำงานช้าเกินไป
ในขั้นตอนการเปิดเครื่อง Android การใช้ HAL ที่เฉพาะเจาะจงช่วยให้อินเทอร์เฟซมีประสิทธิภาพ
และระบุอย่างชัดเจนถึงสิ่งที่ OEM ต้องใช้เพื่อรองรับกลุ่ม EVS
ส่วนประกอบของระบบ
EVS มีส่วนประกอบของระบบต่อไปนี้
![ระบบ EVS
แผนภูมิส่วนประกอบ](https://source.android.com/static/docs/automotive/images/vhal_evs_components.png?authuser=2&hl=th)
แอป EVS
ตัวอย่างแอป C++ EVS
(/packages/services/Car/evs/app
) ทำหน้าที่เป็นข้อมูลอ้างอิง
การใช้งานของคุณ แอปนี้มีหน้าที่ขอเฟรมวิดีโอจาก
ผู้จัดการ EVS และส่งเฟรมที่เสร็จแล้วสำหรับจอแสดงผลกลับไปยังผู้จัดการ EVS
คาดว่าจะเริ่มดำเนินการภายในทันทีที่ EVS และบริการรถยนต์พร้อมให้บริการ
กำหนดเป้าหมายภายในสอง (2) วินาทีหลังจากเปิดเครื่อง OEM จะแก้ไขหรือเปลี่ยน EVS ได้
แอปได้ตามต้องการ
ผู้จัดการ EVS
EVS Manager (/packages/services/Car/evs/manager
) ให้
องค์ประกอบพื้นฐานที่แอป EVS ต้องการเพื่อใช้งานทุกอย่างตั้งแต่
การแสดงผลจากกล้องหลังในแบบ 6DOF ที่ใช้งานง่าย อินเทอร์เฟซของ
นำเสนอผ่าน HIDL และสร้างมาเพื่อรับไคลเอ็นต์ที่ทำงานพร้อมกันหลายราย
แอปและบริการอื่นๆ (โดยเฉพาะบริการรถยนต์) สามารถค้นหา EVS ได้
สถานะผู้จัดการเพื่อดูว่าระบบ EVS ทำงานอยู่เมื่อใด
อินเทอร์เฟซ EVS HIDL
ระบบ EVS ทั้งองค์ประกอบกล้องและจอแสดงผลจะระบุไว้ใน
แพ็กเกจ android.hardware.automotive.evs
ตัวอย่างการใช้งาน
ที่ทำงานกับอินเทอร์เฟซ (สร้างภาพทดสอบสังเคราะห์และตรวจสอบ
รูปภาพที่ทำให้เกิด Conversion ไป-กลับ) จะระบุไว้ใน
/hardware/interfaces/automotive/evs/1.0/default
OEM มีหน้าที่ในการใช้ API ที่แสดงด้วยไฟล์ .hal
ใน /hardware/interfaces/automotive/evs
การติดตั้งใช้งานดังกล่าว
รับผิดชอบการกำหนดค่าและรวบรวมข้อมูลจากกล้องจริง
ส่งผ่านบัฟเฟอร์หน่วยความจำที่ใช้ร่วมกันที่ Gralloc รู้จัก จอแสดงผล
ของการติดตั้งใช้งานจะทำหน้าที่ให้บัฟเฟอร์หน่วยความจำที่ใช้ร่วมกัน
ที่แอปสามารถใช้เติมแต่งได้ (โดยมากจะมาพร้อมการแสดงผล EGL) และการนำเสนอ
เฟรมที่เสร็จแล้วที่ต้องการ อื่นๆ ที่อาจต้องการให้ปรากฏบน
จอแสดงผลจริง อาจมีการเก็บการใช้งานอินเทอร์เฟซ EVS ของผู้ให้บริการไว้
ภายใต้ /vendor/… /device/…
หรือ hardware/…
(เช่น
/hardware/[vendor]/[platform]/evs
)
ไดรเวอร์เคอร์เนล
อุปกรณ์ที่รองรับสแต็ก EVS ต้องใช้ไดรเวอร์เคอร์เนล แทนที่จะเป็น
การสร้างไดรเวอร์ใหม่ OEM มีตัวเลือกในการรองรับฟีเจอร์ที่จำเป็นต้องใช้ EVS
ไดรเวอร์ที่มีอยู่สำหรับกล้องหรือฮาร์ดแวร์จอแสดงผล การใช้คนขับซ้ำอาจเป็น
มีประโยชน์ โดยเฉพาะอย่างยิ่งสำหรับไดรเวอร์จอแสดงผลที่การนำเสนอภาพอาจ
ต้องมีการประสานงานกับชุดข้อความอื่นๆ ที่ทำงานอยู่ Android 8.0 มีรุ่นที่ใช้ v4l2
ตัวอย่างไดรเวอร์ (ใน packages/services/Car/evs/sampleDriver
) ที่
ขึ้นอยู่กับเคอร์เนลสำหรับการรองรับ v4l2 และบน SurfaceFlinger ในการนำเสนอ
ภาพเอาต์พุต
คำอธิบายอินเทอร์เฟซฮาร์ดแวร์ EVS
ส่วนนี้อธิบายเกี่ยวกับ HAL ผู้ให้บริการควรให้ การนำ API นี้ไปปรับใช้กับฮาร์ดแวร์
IEvsEnumerator
ออบเจ็กต์นี้มีหน้าที่ระบุฮาร์ดแวร์ EVS ที่พร้อมใช้งานใน (กล้องอย่างน้อย 1 ตัวและอุปกรณ์แสดงผล 1 เครื่อง)
getCameraList() generates (vec<CameraDesc> cameras);
แสดงผลเวกเตอร์ที่มีคำอธิบายสำหรับกล้องทุกตัวในระบบ ใช่เลย
ถือว่าชุดกล้องได้รับการแก้ไขแล้วและรู้ได้ทันทีที่เปิดเครื่อง สำหรับรายละเอียดเกี่ยวกับ
คำอธิบายกล้อง โปรดดูCameraDesc
openCamera(string camera_id) generates (IEvsCamera camera);
รับออบเจ็กต์อินเทอร์เฟซที่ใช้โต้ตอบกับกล้องบางตัว
ที่ระบุโดยสตริง camera_id ที่ไม่ซ้ำกัน แสดงผล NULL เมื่อล้มเหลว
การพยายามเปิดกล้องที่เปิดอยู่แล้วขึ้นมาใหม่จะไม่ล้มเหลว เพื่อหลีกเลี่ยงการแข่งขัน
เงื่อนไขที่เกี่ยวข้องกับการเริ่มต้นและปิดแอป การเปิดกล้องขึ้นมาอีกครั้ง
ควรปิดการทำงานอินสแตนซ์ก่อนหน้า เพื่อให้สามารถดำเนินการตามคำขอใหม่ได้ ต
อินสแตนซ์ของกล้องที่ถูกจองไว้แล้วในลักษณะนี้จะต้องอยู่ในสถานะไม่ทำงาน
เพื่อรอการทำลายครั้งสุดท้าย และตอบสนองคำขอใดๆ เพื่อให้มีผลต่อ
สถานะกล้องพร้อมรหัสส่งคืน OWNERSHIP_LOST
closeCamera(IEvsCamera camera);
เปิดตัวอินเทอร์เฟซ IEvscamera (และตรงข้ามกับ
openCamera()
สาย) สตรีมวิดีโอของกล้องต้อง
หยุดด้วยการโทรหา stopVideoStream()
ก่อนโทรหา closeCamera
openDisplay() generates (IEvsDisplay display);
รับออบเจ็กต์อินเทอร์เฟซที่ใช้เพื่อโต้ตอบกับ
จอแสดงผล EVS ไคลเอนต์เพียงเครื่องเดียวสามารถเก็บอินสแตนซ์ที่ทำงานของ IEvsDisplay ไว้ที่
คล้ายกับพฤติกรรมแบบเปิดเชิงรุกที่อธิบายไว้ใน openCamera
คุณสามารถสร้างออบเจ็กต์ IEvsDisplay ใหม่ได้ทุกเมื่อและปิดใช้
อินสแตนซ์ อินสแตนซ์ที่ใช้งานไม่ได้จะยังคงอยู่และตอบสนองต่อการเรียกใช้ฟังก์ชัน
จากเจ้าของ แต่ต้องไม่ดำเนินการเปลี่ยนแปลงใดๆ เมื่อตายแล้ว สุดท้ายแล้ว
แอปไคลเอ็นต์จะสังเกตเห็นข้อผิดพลาด OWNERSHIP_LOST
ส่งคืนโค้ด และปิดและปล่อยอินเทอร์เฟซที่ไม่มีการใช้งาน
closeDisplay(IEvsDisplay display);
แสดงอินเทอร์เฟซ IEvsDisplay (และตรงข้ามกับ
openDisplay()
สาย) บัฟเฟอร์ค้างรับที่ได้รับกับ
ต้องคืนการเรียก getTargetBuffer()
ไปที่จอแสดงผลก่อน
ปิดจอแสดงผล
getDisplayState() generates (DisplayState state);
รับสถานะการแสดงผลปัจจุบัน การติดตั้งใช้งาน HAL ควรรายงาน
สถานะปัจจุบันตามจริง ซึ่งอาจแตกต่างจากสถานะที่ขอล่าสุด
ควรระบุตรรกะที่เป็นผู้รับผิดชอบในการเปลี่ยนสถานะการแสดงผลเหนืออุปกรณ์
ซึ่งทำให้การใช้งาน HAL เปลี่ยนแปลงไปเองโดยไม่มีเหตุอันควร
แสดงสถานะ หากไม่มีไคลเอ็นต์ใดๆ ที่จอแสดงผลไม่ได้ถืออยู่ (โดยการเรียกไปยัง
openDisplay) ฟังก์ชันนี้จะแสดงผล NOT_OPEN
มิเช่นนั้น
รายงานสถานะปัจจุบันของจอแสดงผล EVS (โปรดดู
IEvsDisplay API)
struct CameraDesc { string camera_id; int32 vendor_flags; // Opaque value }
camera_id
สตริงที่ระบุกล้องโดยไม่ซ้ำกัน อาจเป็นชื่ออุปกรณ์เคอร์เนลของอุปกรณ์หรือชื่อของอุปกรณ์ เช่น กระจกหลัง ค่าสำหรับสตริงนี้เลือกโดยการใช้งาน HAL และใช้แบบทึบโดยกลุ่มด้านบนvendor_flags
วิธีการส่งผ่านกล้องเฉพาะทาง ข้อมูลไม่ชัดเจนจากคนขับไปยังแอป EVS ที่กำหนดเอง ผ่านแล้ว ไม่ตีความจากคนขับไปจนถึงแอป EVS ซึ่งไม่ต้องสนใจ ได้
กล้อง IEv
วัตถุนี้แสดงกล้องตัวเดียวและเป็นอินเทอร์เฟซหลักสำหรับ ที่กำลังจับภาพ
getCameraInfo() generates (CameraDesc info);
แสดง CameraDesc
ของกล้องนี้
setMaxFramesInFlight(int32 bufferCount) generates (EvsResult result);
ระบุความลึกของห่วงโซ่บัฟเฟอร์ที่กล้องจะขอรองรับ ไม่เกิน
เฟรมจำนวนมากนี้อาจใช้พร้อมกันโดยไคลเอ็นต์ของ IEvsกล้องถ่ายรูป หากสิ่งนี้
เฟรมจำนวนมากถูกส่งไปยังเครื่องรับโดยไม่มีการส่งคืนโดย
doneWithFrame
สตรีมจะข้ามเฟรมจนกว่าจะแสดงบัฟเฟอร์
เพื่อนำมาใช้ใหม่ การโทรนี้เปิดให้ทำได้ในเวลาใดก็ได้ แม้ในขณะที่สตรีม
ทำงานอยู่แล้ว ซึ่งในกรณีนี้ควรเพิ่มหรือนำบัฟเฟอร์ออกจากเชน
ตามความเหมาะสม ถ้าไม่มีการเรียกไปยังจุดแรกเข้านี้ IEvscamera จะสนับสนุน
อย่างน้อย 1 เฟรมโดยค่าเริ่มต้น ด้วยรูปแบบที่ยอมรับได้มากกว่า
หากไม่สามารถรองรับบัฟเฟอร์จำนวนที่ขอ ฟังก์ชันจะแสดงผล
BUFFER_NOT_AVAILABLE
หรือรหัสข้อผิดพลาดอื่นๆ ที่เกี่ยวข้อง ในกรณีนี้
ระบบจะยังคงทำงานต่อไปด้วยค่าที่กำหนดไว้ก่อนหน้านี้
startVideoStream(IEvsCameraStream receiver) generates (EvsResult result);
ส่งคำขอการนำส่งเฟรมกล้อง EVS จากกล้องนี้ สตรีมกล้อง IEv
เริ่มได้รับการเรียกเป็นระยะๆ พร้อมกรอบรูปใหม่จนถึง
โทรหา stopVideoStream()
ต้องเริ่มนำส่งเฟรม
ภายใน 500 มิลลิวินาทีของการโทร startVideoStream
และหลังจากเริ่มต้น ต้อง
สร้างอย่างน้อย 10 FPS เวลาที่ต้องใช้ในการเริ่มสตรีมวิดีโอ
นับรวมกับข้อกำหนดเวลาเริ่มต้นของกล้องมองหลังได้อย่างมีประสิทธิภาพ หาก
สตรีมไม่เริ่มต้น ต้องส่งคืนรหัสข้อผิดพลาด มิฉะนั้น ระบบจะแสดงผล OK
oneway doneWithFrame(BufferDesc buffer);
แสดงเฟรมที่ส่งโดย IEvscameraStream เมื่อทำเสร็จ
เมื่อใช้เฟรมที่ส่งไปยังอินเทอร์เฟซ IEvscameraStream เฟรมดังกล่าวจะต้อง
กลับไปที่ IEvsกล้องถ่ายรูป เพื่อใช้ซ้ำ มีบัฟเฟอร์ไม่มาก
ว่าง (อาจเหลือน้อยที่สุด) และหากอุปทานหมด ก็ไม่มี
จะแสดงเฟรมต่างๆ จนกว่าจะมีการส่งกลับบัฟเฟอร์ ซึ่งอาจส่งผลให้
เฟรมที่ข้าม (บัฟเฟอร์ที่มีแฮนเดิลเป็น Null หมายถึงจุดสิ้นสุดของสตรีมและ
ไม่จำเป็นต้องแสดงผลผ่านฟังก์ชันนี้) ส่งคืนสถานะตกลงเมื่อสำเร็จ หรือ
รหัสข้อผิดพลาดที่เหมาะสมซึ่งอาจรวม INVALID_ARG
หรือ
BUFFER_NOT_AVAILABLE
stopVideoStream();
หยุดการนำส่งเฟรมกล้อง EVS เนื่องจากการแสดงโฆษณาเป็นแบบไม่พร้อมกัน
เฟรมอาจยังปรากฏขึ้นเป็นระยะเวลาหนึ่งหลังจากการเรียกคืนสินค้านี้ แต่ละเฟรม
ต้องส่งคืนจนกว่าจะมีการปิดสตรีมไปยัง
IEvscameraStream การโทรหา stopVideoStream
ในสตรีมเป็นสิ่งที่ถูกกฎหมาย
ที่หยุดทำงานแล้วหรือไม่เคยเริ่ม ซึ่งในกรณีนี้ระบบจะไม่สนใจ
getExtendedInfo(int32 opaqueIdentifier) generates (int32 value);
ขอข้อมูลเฉพาะผู้ขับขี่จากการใช้งาน HAL ค่า
อนุญาตสำหรับ opaqueIdentifier
เป็นแบบเฉพาะผู้ขับ แต่ไม่มีค่า
เพราะอาจทำให้คนขับชนกัน คนขับควรแสดงผล 0 สำหรับข้อผิดพลาดที่ไม่รู้จัก
opaqueIdentifier
setExtendedInfo(int32 opaqueIdentifier, int32 opaqueValue) generates (EvsResult result);
ส่งค่าเฉพาะไดรเวอร์ไปยังการติดตั้งใช้งาน HAL ส่วนขยายนี้
ให้บริการเพื่ออำนวยความสะดวกส่วนขยายเฉพาะสำหรับยานพาหนะเท่านั้นและไม่มี HAL
ควรจำเป็นต้องเรียกใช้นี้เพื่อให้ทำงานในสถานะเริ่มต้น หาก
ไดรเวอร์รับรู้และยอมรับค่า ควรแสดงผล 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 }
อธิบายรูปภาพที่ส่งผ่าน API ไดรฟ์ HAL มีหน้าที่
กรอกโครงสร้างนี้เพื่ออธิบายบัฟเฟอร์รูปภาพและไคลเอ็นต์ HAL
ควรถือว่าโครงสร้างนี้เป็นอ่านอย่างเดียว ฟิลด์มีข้อมูลเพียงพอ
เพื่อให้ไคลเอ็นต์สร้างออบเจ็กต์ ANativeWindowBuffer
ใหม่
ตามที่จำเป็นสำหรับการใช้รูปภาพกับ EGL ด้วย
ส่วนขยาย eglCreateImageKHR()
width
ความกว้างเป็นพิกเซลของรูปภาพที่นำเสนอheight
ความสูงเป็นพิกเซลของรูปภาพที่นำเสนอstride
จำนวนพิกเซลที่แต่ละแถวจะใช้หน่วยความจำจริง โดยพิจารณาระยะห่างจากขอบของการจัดวางแถวด้วย แสดงเป็นพิกเซลเพื่อจับคู่ แบบแผนที่ Gralloc นำมาใช้สำหรับคำอธิบายบัฟเฟอร์pixelSize
จำนวนไบต์ที่แต่ละพิกเซลใช้งาน เปิดใช้งานการคำนวณขนาดเป็นไบต์ที่จำเป็นเพื่อสลับไปมาระหว่างแถวใน รูปภาพ (stride
ในไบต์ =stride
หน่วยเป็นพิกเซล *pixelSize
)format
รูปแบบพิกเซลที่รูปภาพใช้ รูปแบบที่ระบุ ต้องเข้ากันได้กับการใช้งาน OpenGL ของแพลตฟอร์ม จึงจะผ่าน การทดสอบความเข้ากันได้HAL_PIXEL_FORMAT_YCRCB_420_SP
ควรเป็น เหมาะสำหรับการใช้งานกล้อง และRGBA
หรือBGRA
ในการแสดงผลusage
แฟล็กการใช้งานที่กำหนดโดยการใช้งาน HAL ไคลเอ็นต์ HAL จะผ่านการแก้ไขเหล่านี้ (โปรดดูรายละเอียดที่ แฟล็กที่เกี่ยวข้องGralloc.h
รายการ)bufferId
ค่าที่ไม่ซ้ำกันที่ระบุโดยการใช้งาน HAL ช่วยให้ระบบรู้จักบัฟเฟอร์หลังจากที่รับส่งข้อมูลผ่าน HAL API ค่าที่จัดเก็บไว้ในช่องนี้อาจได้รับเลือกโดยการติดตั้งใช้งาน HALmemHandle
แฮนเดิลของบัฟเฟอร์หน่วยความจำเบื้องหลัง ที่มีข้อมูลภาพ การใช้งาน HAL อาจเลือกจัดเก็บ Gralloc แฮนเดิลตรงนี้
สตรีมจากกล้อง IEv
ไคลเอ็นต์ใช้อินเทอร์เฟซนี้เพื่อรับเฟรมวิดีโอแบบไม่พร้อมกัน ในการจัดส่ง
deliverFrame(BufferDesc buffer);
รับสายจาก HAL ทุกครั้งที่เฟรมวิดีโอพร้อมสำหรับการตรวจสอบ
แฮนเดิลบัฟเฟอร์ที่ได้รับจากวิธีนี้จะต้องส่งคืนผ่านการเรียกไปยัง
IEvsCamera::doneWithFrame()
เมื่อสตรีมวิดีโอหยุดด้วย
โทรหา IEvsCamera::stopVideoStream()
การติดต่อกลับนี้อาจดำเนินการต่อ
ขณะที่ท่อระบายน้ำ แต่ละเฟรมยังคงต้องส่งคืน เฟรมสุดท้าย
ในสตรีมมีการนำส่งแล้ว มีการส่ง bufferHandle
เป็นค่าว่าง
แสดงถึงจุดสิ้นสุดของสตรีม และไม่มีการส่งเฟรมใดๆ เกิดขึ้นอีก ค่าว่าง
ไม่จำเป็นต้องส่ง bufferHandle
กลับมาพร้อมกับ
doneWithFrame()
แต่ต้องส่งคืนแฮนเดิลอื่นๆ ทั้งหมดด้วย
แม้ว่ารูปแบบบัฟเฟอร์ที่เป็นกรรมสิทธิ์จะสร้างในทางเทคนิคได้ แต่ความเข้ากันได้ การทดสอบกำหนดให้บัฟเฟอร์อยู่ในรูปแบบที่รองรับ 1 ใน 4 รูปแบบ ได้แก่ NV21 (YCrCb) 4:2:0 กึ่งระนาบ) YV12 (YCrCb 4:2:0 ระนาบ) YUYV (YCrCb 4:2:2 แทรกสลับ) RGBA (32 บิต R:G:B:x), BGRA (32 บิต B:G:R:x) รูปแบบที่เลือกต้องเป็นรูปแบบที่ถูกต้อง แหล่งที่มาของพื้นผิว GL บนการติดตั้งใช้งาน GLES ของแพลตฟอร์ม
แอปควรไม่ต้องพึ่งพาการโต้ตอบใดๆ
ระหว่างฟิลด์ bufferId
และ memHandle
ในฟิลด์
BufferDesc
ค่า bufferId
คือ
มีความเฉพาะตัวในการใช้งานไดรเวอร์ HAL และอาจใช้ (และนำมาใช้ใหม่)
ตามที่เห็นสมควร
การแสดงผล IEv
ออบเจ็กต์นี้แสดงจอแสดงผล Evs ซึ่งควบคุมสถานะของการแสดงผล และจัดการการนำเสนอรูปภาพจริงๆ
getDisplayInfo() generates (DisplayDesc info);
แสดงข้อมูลพื้นฐานเกี่ยวกับจอแสดงผล EVS ของระบบ (โปรดดู DisplayDesc)
setDisplayState(DisplayState state) generates (EvsResult result);
ตั้งค่าสถานะการแสดงผล ลูกค้าสามารถตั้งค่าสถานะการแสดงผลเพื่อแสดง ที่ต้องการ และการใช้งาน HAL ต้องยอมรับคำขอ สถานะใดๆ ขณะที่อยู่ในสถานะอื่นๆ แม้ว่าการตอบสนองจะไม่คำนึงถึง อีกครั้ง
เมื่อเริ่มต้น การแสดงผลจะได้รับการกำหนดให้เริ่มต้นใน
NOT_VISIBLE
สถานะ ซึ่งคาดว่าไคลเอ็นต์จะส่งคำขอหลังจากนั้น
สถานะ VISIBLE_ON_NEXT_FRAME
และเริ่มต้นให้บริการวิดีโอ เมื่อ
ไม่จำเป็นต้องมีการแสดงผลอีกต่อไป ไคลเอ็นต์จะต้องส่งคำขอ
NOT_VISIBLE
จะอยู่ในสถานะหลังจากผ่านเฟรมวิดีโอสุดท้าย
ซึ่งสามารถขอได้ทุกเมื่อในทุกรัฐ หากจอแสดงผลเป็นแบบ
ปรากฏแล้ว โปรไฟล์ก็จะยังคงปรากฏหากตั้งค่าเป็น
VISIBLE_ON_NEXT_FRAME
แสดงผล "ตกลง" เสมอ เว้นแต่สถานะที่ร้องขอ
เป็นค่า enum ที่ไม่รู้จัก ซึ่งในกรณีนี้ INVALID_ARG
คือ
ส่งคืนแล้ว
getDisplayState() generates (DisplayState state);
รับสถานะการแสดงผล การติดตั้งใช้งาน HAL ควรรายงานเมตริก สถานะปัจจุบัน ซึ่งอาจแตกต่างจากสถานะที่ขอล่าสุด ควรมีตรรกะที่รับผิดชอบในการเปลี่ยนสถานะการแสดงผลอยู่เหนืออุปกรณ์ ซึ่งทำให้การใช้งาน HAL เปลี่ยนแปลงไปเองโดยไม่มีเหตุอันควร แสดงสถานะ
getTargetBuffer() generates (handle bufferHandle);
แสดงผลแฮนเดิลไปยังเฟรมบัฟเฟอร์ที่เชื่อมโยงกับจอแสดงผล บัฟเฟอร์นี้
อาจมีการล็อกและเขียนข้อมูลโดยซอฟต์แวร์และ/หรือ GL ต้องส่งคืนบัฟเฟอร์นี้
ด้วยการเรียกไปยัง returnTargetBufferForDisplay()
แม้ว่าจอแสดงผลจะ
จะไม่ปรากฏอีกต่อไป
แม้ว่ารูปแบบบัฟเฟอร์ที่เป็นกรรมสิทธิ์จะสร้างในทางเทคนิคได้ แต่การทดสอบความเข้ากันได้ บัฟเฟอร์ต้องอยู่ในรูปแบบที่รองรับทั้ง 4 รูปแบบ ได้แก่ NV21 (YCrCb 4:2:0 กึ่งระนาบ) YV12 (YCrCb 4:2:0 ระนาบ) YUYV (YCrCb 4:2:2 แบบแทรกสลับ) RGBA (32 บิต R:G:B:x), BGRA (32 บิต B:G:R:x) รูปแบบที่เลือกต้องเป็น GL ที่ถูกต้อง เป้าหมายการแสดงผลในการใช้งาน GLES ของแพลตฟอร์ม
หากเกิดข้อผิดพลาด บัฟเฟอร์ที่มีแฮนเดิลเป็น Null จะแสดงผล แต่บัฟเฟอร์ดังกล่าวไม่
จำเป็นต้องส่งคืนให้กับ returnTargetBufferForDisplay
returnTargetBufferForDisplay(handle bufferHandle) generates (EvsResult result);
บอกจอแสดงผลว่าบัฟเฟอร์พร้อมแสดงผลแล้ว เฉพาะบัฟเฟอร์ที่ดึงมา
ผ่านการโทรไปยัง getTargetBuffer()
ใช้ได้กับ
และเนื้อหาของ BufferDesc
อาจไม่ถูกแก้ไขโดย
แอปไคลเอ็นต์ หลังจากการเรียกใช้ บัฟเฟอร์นี้ไม่สามารถใช้ได้อีกต่อไปโดย
ไคลเอ็นต์ ส่งคืนสถานะตกลงเมื่อสำเร็จ หรือรหัสข้อผิดพลาดที่เหมาะสมซึ่งอาจ
รวมถึง INVALID_ARG
หรือ BUFFER_NOT_AVAILABLE
struct DisplayDesc { string display_id; int32 vendor_flags; // Opaque value }
อธิบายคุณสมบัติพื้นฐานของจอแสดงผล EVS และ EVS ต้องใช้ การใช้งานของคุณ HAL มีหน้าที่รับผิดชอบในการกรอกข้อมูลโครงสร้างนี้เพื่อ อธิบายจอแสดงผล EVS ซึ่งอาจเป็นจอแสดงผลจริงหรือเสมือน หรือซ้อนทับกับอุปกรณ์นำเสนออื่นๆ
display_id
สตริงที่ระบุการแสดงผลโดยไม่ซ้ำกัน ซึ่งอาจเป็นชื่ออุปกรณ์เคอร์เนลของอุปกรณ์ หรือชื่อสำหรับอุปกรณ์ เช่น การมองหลัง ค่าสำหรับสตริงนี้เลือกโดย HAL และการใช้งานแบบทึบแสงโดยกลุ่มด้านบนvendor_flags
วิธีการส่งผ่านกล้องเฉพาะทาง ข้อมูลไม่ชัดเจนจากคนขับไปยังแอป EVS ที่กำหนดเอง ผ่านแล้ว ไม่ตีความจากคนขับไปจนถึงแอป EVS ซึ่งไม่ต้องสนใจ ได้
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 }
อธิบายสถานะของจอแสดงผล EVS ซึ่งปิดใช้ได้ (ไม่ใช่
มองเห็นได้ คนขับ) หรือเปิดใช้ (แสดงรูปภาพให้คนขับเห็น)
รวมสถานะชั่วคราวซึ่งหน้าจอยังไม่ปรากฏแต่จัดเตรียมไว้
เพื่อให้มองเห็นได้จากการส่งเฟรมภาพถัดไปที่มี
returnTargetBufferForDisplay()
สาย
ผู้จัดการ EVS
EVS Manager ให้บริการอินเทอร์เฟซสาธารณะกับระบบ EVS สำหรับ เก็บรวบรวมและนำเสนอมุมมองกล้องภายนอก ส่วนที่ไดรเวอร์ฮาร์ดแวร์อนุญาต อินเทอร์เฟซที่ใช้งานอยู่เพียง 1 อินเทอร์เฟซต่อทรัพยากร (กล้องหรือจอแสดงผล) ตัวจัดการ EVS ช่วยให้เข้าถึงกล้องร่วมกันได้ง่ายขึ้น แอป EVS หลักแอปเดียวคือ ลูกค้ารายแรกของผู้จัดการ EVS และเป็นลูกค้ารายเดียวที่ได้รับอนุญาตให้เขียนข้อมูล ข้อมูลจอแสดงผล (ไคลเอ็นต์เพิ่มเติมจะได้รับสิทธิ์การเข้าถึงกล้องในระดับอ่านอย่างเดียว) รูปภาพ)
EVS Manager ใช้ API เดียวกับไดรเวอร์ HAL ที่สำคัญ และ ให้บริการเพิ่มเติมโดยการสนับสนุนลูกค้าที่ใช้งานพร้อมกันหลายราย (มากกว่า ลูกค้ารายหนึ่งสามารถเปิดกล้องผ่านตัวจัดการ EVS และรับวิดีโอ สตรีม)
![ผู้จัดการ EVS และ
แผนภาพ API ฮาร์ดแวร์ EVS](https://source.android.com/static/docs/automotive/images/vhal_evs_manager.png?authuser=2&hl=th)
แอปไม่เห็นความแตกต่างเมื่อทำงานผ่าน HAL ของฮาร์ดแวร์ EVS หรือ EVS Manager API ยกเว้นที่ EVS Manager API อนุญาตให้ เข้าถึงสตรีมจากกล้องพร้อมกัน ผู้จัดการ EVS เองก็เป็นผู้ได้รับอนุญาต เลเยอร์ฮาร์ดแวร์ EVS ฮาร์ดแวร์ HAL และทำหน้าที่เป็นพร็อกซีสำหรับฮาร์ดแวร์ EVS HAL
ส่วนต่อไปนี้จะอธิบายเฉพาะการเรียกที่มี พฤติกรรม (เพิ่มเติม) ในการใช้งานตัวจัดการ EVS การโทรที่เหลืออยู่คือ เหมือนกับคำอธิบาย EVS HAL
IEvsEnumerator
openCamera(string camera_id) generates (IEvsCamera camera);
รับออบเจ็กต์อินเทอร์เฟซที่ใช้โต้ตอบกับกล้องบางตัว
ที่ระบุโดยสตริง camera_id ที่ไม่ซ้ำกัน แสดงผล NULL เมื่อล้มเหลว
ในเลเยอร์ตัวจัดการ EVS หากทรัพยากรระบบมีเพียงพอ
กล้องที่เปิดอยู่แล้วอาจเปิดอีกครั้งด้วยกระบวนการอื่น ซึ่งทำให้
กระจายสตรีมวิดีโอไปยังแอปผู้บริโภคหลายแอป
สตริง camera_id
ที่เลเยอร์ EVS Manager เหมือนกันกับสตริง
รายงานไปยังเลเยอร์ฮาร์ดแวร์ EVS แล้ว
กล้อง IEv
ตัวจัดการ EVS จัดให้การใช้งาน IEvsกล้องถ่ายรูป ทำในระบบเสมือนจริงภายใน ดังนั้นการดำเนินการกับกล้องของลูกค้า 1 ราย ไม่ส่งผลกระทบต่อไคลเอ็นต์อื่นๆ สามารถเข้าถึงกล้องได้อย่างอิสระ
startVideoStream(IEvsCameraStream receiver) generates (EvsResult result);
เริ่มสตรีมวิดีโอ ไคลเอ็นต์จะเริ่มและหยุดสตรีมวิดีโอได้อย่างอิสระ ด้วยกล้องตัวเดิม กล้องที่อยู่ด้านล่างจะเริ่มทำงานเมื่อ เริ่ม
doneWithFrame(uint32 frameId, handle bufferHandle) generates (EvsResult result);
แสดงผลเฟรม ลูกค้าแต่ละรายต้องส่งคืนเฟรมของตนเมื่อเสร็จแล้ว ทั้งนี้ สามารถถือกรอบไว้ตราบเท่าที่ต้องการ เมื่อ จำนวนเฟรมที่ไคลเอ็นต์ถึงขีดจํากัดที่กำหนดค่าไว้ และจะไม่ได้รับ เฟรมอื่นได้อีกจนกว่าจะแสดงเฟรมเดียว การข้ามเฟรมนี้จะไม่มีผลกับ ซึ่งจะยังคงได้รับเฟรมทั้งหมดตามที่คาดไว้ต่อไป
stopVideoStream();
หยุดสตรีมวิดีโอ ลูกค้าแต่ละรายสามารถหยุดสตรีมวิดีโอของตนเองได้ทุกเมื่อ มีผลต่อไคลเอ็นต์อื่นๆ สตรีมจากกล้องที่ซ่อนอยู่ที่เลเยอร์ฮาร์ดแวร์คือ หยุดเมื่อไคลเอ็นต์สุดท้ายของกล้องที่ระบุหยุดสตรีม
setExtendedInfo(int32 opaqueIdentifier, int32 opaqueValue) generates (EvsResult result);
ส่งค่าเฉพาะของไดรเวอร์ ซึ่งอาจทําให้ไคลเอ็นต์หนึ่งมีผลกับ ลูกค้ารายอื่น เนื่องจาก EVS Manager ไม่เข้าใจผลของ คำควบคุมที่ผู้ให้บริการกำหนด ไม่ได้ใช้ระบบเสมือนจริง และผลข้างเคียงใดๆ จะมีผลกับไคลเอ็นต์ทั้งหมดของกล้องตัวนั้นๆ ตัวอย่างเช่น หากผู้ให้บริการใช้การเรียกนี้ ในการเปลี่ยนอัตราเฟรม ไคลเอ็นต์ทั้งหมดของกล้องที่มีเลเยอร์ฮาร์ดแวร์ที่ได้รับผลกระทบ จะได้รับเฟรมในอัตราใหม่
การแสดงผล IEv
อนุญาตเจ้าของจอแสดงผลเพียง 1 คน แม้ว่าจะอยู่ในระดับผู้จัดการ EVS ก็ตาม Manager ไม่ได้เพิ่มฟังก์ชันใดๆ และเพียงแค่ส่งอินเทอร์เฟซ IEvsDisplay เท่านั้น ไปจนถึงการติดตั้งใช้งาน HAL ที่สำคัญ
แอป EVS
Android มีการใช้การอ้างอิง C++ ที่มาพร้อมเครื่อง EVS แอปที่สื่อสารกับผู้จัดการ EVS และ HAL ของยานพาหนะเพื่อ จะมีฟังก์ชันพื้นฐานของกล้องหลัง แอปคาดว่าจะเริ่มทำงาน ในช่วงต้นของขั้นตอนการบูตระบบ โดยมีวิดีโอที่เหมาะสมแสดง กล้องที่พร้อมใช้งานและสถานะของรถ (สถานะเกียร์และไฟเลี้ยว) OEM สามารถแก้ไขหรือแทนที่แอป EVS ด้วยยานพาหนะเฉพาะของตน และการนำเสนอ
![](https://source.android.com/static/docs/automotive/images/vhal_evs_get_camera.png?authuser=2&hl=th)
วันที่
![](https://source.android.com/static/docs/automotive/images/vhal_evs_receive_frame.png?authuser=2&hl=th)
เนื่องจากข้อมูลรูปภาพแสดงอยู่ในแอปในรูปแบบกราฟิกมาตรฐาน บัฟเฟอร์ แอปมีหน้าที่ย้ายรูปภาพจากแหล่งที่มา ลงในบัฟเฟอร์เอาต์พุต แม้ว่าวิธีนี้จะทำให้ การคัดลอกข้อมูลมีค่าใช้จ่าย แต่ยังทำให้แอปมีโอกาสแสดงภาพลงใน แสดงผลบัฟเฟอร์ในรูปแบบใดก็ได้ตามต้องการ
ตัวอย่างเช่น แอปอาจเลือกที่จะย้ายข้อมูลพิกเซลเอง อาจมีการดำเนินการปรับขนาดหรือการหมุนแบบอินไลน์ แอปสามารถ และยังเลือกใช้ภาพต้นฉบับเป็นพื้นผิว OpenGL และแสดงผลที่ซับซ้อน ไปยังบัฟเฟอร์เอาต์พุต รวมถึงองค์ประกอบเสมือน เช่น ไอคอน หลักเกณฑ์ และภาพเคลื่อนไหว แอปที่ซับซ้อนขึ้นอาจเลือก กล้องอินพุตที่ทำงานพร้อมกันหลายตัวและรวมเข้าเป็นเฟรมเอาต์พุตเดียว (เช่น สำหรับใช้ในมุมมองด้านบนลง มุมมองเสมือนจริงของสภาพแวดล้อมยานพาหนะ)
ใช้ EGL/SurfaceFlinger ใน HAL จอแสดงผล EVS
ส่วนนี้จะอธิบายวิธีใช้ EGL เพื่อแสดงผลการใช้งาน HAL จอแสดงผล EVS ใน Android 10
รถยนต์ EVS
การใช้การอ้างอิง HAL ใช้ EGL เพื่อแสดงการแสดงตัวอย่างจากกล้อง
หน้าจอและใช้ libgui
เพื่อสร้างพื้นที่แสดงผล EGL เป้าหมาย ใน Android 8 (ขึ้นไป) libgui
ได้รับการจัดประเภทเป็น VNDK-private
หมายถึงกลุ่มไลบรารีที่มีให้กับไลบรารี VNDK ซึ่งกระบวนการของผู้ให้บริการไม่สามารถใช้งานได้
เนื่องจากการติดตั้งใช้งาน HAL ต้องอยู่ในพาร์ติชันผู้ให้บริการ ผู้ให้บริการจึงไม่สามารถใช้
แสดงให้เห็นการนำไปใช้งาน HAL
การสร้าง Libgui สำหรับกระบวนการของผู้ให้บริการ
การใช้ libgui
เป็นตัวเลือกเดียวในการใช้ EGL/SurfaceFlinger
ในการใช้งาน Display HAL ของ EVS วิธีใช้งาน libgui
ที่ง่ายที่สุดคือ
ผ่าน
เฟรมเวิร์ก/เนทีฟ/ไลบรารี/กุย
โดยตรงโดยใช้เป้าหมายบิลด์เพิ่มเติมในสคริปต์บิลด์ เป้าหมายนี้เหมือนกับ
เป้าหมาย libgui
ยกเว้นการเพิ่มฟิลด์ 2 ฟิลด์:
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 บิต 1 คำออกจากข้อมูลที่พัสดุ เนื่องจาก 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
ใช้ Binder ในการใช้งาน EVS HAL
ใน Android 8 (และสูงกว่า) โหนดอุปกรณ์ /dev/binder
จะมีเฉพาะใน Android 8
กระบวนการของเฟรมเวิร์ก และทำให้กระบวนการของผู้ให้บริการไม่สามารถเข้าถึงได้ แต่
กระบวนการของผู้ให้บริการควรใช้ /dev/hwbinder
และต้องแปลงอินเทอร์เฟซ AIDL ทั้งหมด
เป็น HIDL สำหรับผู้ที่ต้องการใช้อินเทอร์เฟซ AIDL ระหว่างกระบวนการของผู้ให้บริการต่อไป
ใช้โดเมน Binder ชื่อ /dev/vndbinder
โดเมน IPC | คำอธิบาย |
---|---|
/dev/binder |
IPC ระหว่างกระบวนการของเฟรมเวิร์ก/แอปด้วยอินเทอร์เฟซ AIDL |
/dev/hwbinder |
IPC ระหว่างกระบวนการของเฟรมเวิร์ก/ผู้ให้บริการกับอินเทอร์เฟซ HIDL IPC ระหว่างกระบวนการของผู้ให้บริการด้วยอินเทอร์เฟซ HIDL |
/dev/vndbinder |
IPC ระหว่างกระบวนการของผู้ให้บริการ/ผู้ให้บริการด้วยอินเทอร์เฟซ AIDL |
แม้ว่า SurfaceFlinger จะกำหนดอินเทอร์เฟซ AIDL แต่กระบวนการของผู้ให้บริการจะใช้ได้เฉพาะอินเทอร์เฟซ HIDL เพื่อทำสิ่งต่อไปนี้
สื่อสารกับกระบวนการของเฟรมเวิร์ก งานที่ไม่สำคัญนักเพื่อแปลงโฉม
อินเทอร์เฟซ AIDL จะเชื่อมต่อกับ HIDL โชคดีที่ Android มีวิธีการเลือกแฟ้ม
ไดรเวอร์ของ libbinder
ซึ่งลิงก์กับกระบวนการของไลบรารี userspace
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
หรือก่อนเรียกใช้ Binder
นโยบาย SELinux
ถ้าอุปกรณ์ติดตั้งใช้งานเสียงแหลมเต็ม SELinux จะป้องกันไม่ให้ผู้ให้บริการ
กระบวนการจากการใช้ /dev/binder
เช่น ตัวอย่าง EVS HAL
มีการกำหนดการติดตั้งใช้งานให้กับโดเมน hal_evs_driver
และต้อง
สิทธิ์ R/w สำหรับโดเมน 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)
สร้างการใช้ข้อมูลอ้างอิง EVS HAL ในฐานะผู้ให้บริการ
คุณสามารถใช้การเปลี่ยนแปลงต่อไปนี้เป็นข้อมูลอ้างอิง
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;