
เลเยอร์นามธรรมของฮาร์ดแวร์กล้อง (HAL) ของ Android เชื่อมต่อ API เฟรมเวิร์กกล้องระดับสูงกว่าใน กล้อง 2 กับไดรเวอร์กล้องและฮาร์ดแวร์พื้นฐานของคุณ ระบบย่อยของกล้องประกอบด้วยการใช้งานสำหรับส่วนประกอบไปป์ไลน์ของกล้อง ในขณะที่กล้อง HAL จัดเตรียมอินเทอร์เฟซสำหรับใช้ในการปรับใช้ส่วนประกอบเหล่านี้ในเวอร์ชันของคุณ
สถาปัตยกรรม
รูปและรายการต่อไปนี้อธิบายส่วนประกอบของ HAL

รูปที่ 1 สถาปัตยกรรมของกล้อง
- กรอบงานแอป
- ที่ระดับเฟรมเวิร์กของแอปคือโค้ดของแอป ซึ่งใช้ Camera 2 API เพื่อโต้ตอบกับฮาร์ดแวร์ของกล้อง ภายใน โค้ดนี้จะเรียกอินเทอร์เฟ ซ Binder ที่เกี่ยวข้องเพื่อเข้าถึงโค้ดเนทีฟที่โต้ตอบกับกล้อง
- โรคเอดส์
- อินเทอร์เฟซ Binder ที่เกี่ยวข้องกับ
CameraService
สามารถพบได้ที่ frameworks/av/camera/aidl/android/hardware รหัสที่สร้างขึ้นจะเรียกรหัสเนทิฟระดับล่างเพื่อรับการเข้าถึงกล้องจริงและส่งคืนข้อมูลที่ใช้ในการสร้างCameraDevice
และวัตถุCameraCaptureSession
ในที่สุดในระดับเฟรมเวิร์ก - กรอบงานดั้งเดิม
- เฟรมเวิร์กนี้อยู่ใน
frameworks/av/
ให้ค่าเทียบเท่ากับคลาสCameraDevice
และCameraCaptureSession
ดูเพิ่มเติม ที่ การอ้างอิงกล้อง NDK2 - อินเทอร์เฟซ IPC ของเครื่องผูก
- อินเทอร์เฟซ IPC Binder ช่วยให้การสื่อสารผ่านขอบเขตกระบวนการสะดวกขึ้น มีคลาส Camera Binder อยู่หลายคลาสที่อยู่ในไดเร็กทอรี
frameworks/av/camera/camera/aidl/android/hardware
ที่เรียกใช้บริการกล้องICameraService
เป็นส่วนต่อประสานกับบริการกล้องICameraDeviceUser
เป็นส่วนต่อประสานกับอุปกรณ์กล้องที่เปิดอยู่โดยเฉพาะ และICameraServiceListener
และICameraDeviceCallbacks
เป็นการเรียกกลับCameraService
และCameraDevice
ตามลำดับไปยังเฟรมเวิร์กแอปพลิเคชัน - บริการกล้อง
- บริการกล้องที่อยู่ใน
frameworks/av/services/camera/libcameraservice/CameraService.cpp
คือโค้ดจริงที่โต้ตอบกับ HAL - ฮาล
- เลเยอร์นามธรรมของฮาร์ดแวร์จะกำหนดอินเทอร์เฟซมาตรฐานที่บริการกล้องเรียกใช้และคุณต้องนำไปใช้เพื่อให้ฮาร์ดแวร์กล้องของคุณทำงานได้อย่างถูกต้อง
การนำ HAL ไปปฏิบัติ
HAL อยู่ระหว่างไดรเวอร์กล้องและเฟรมเวิร์ก Android ระดับสูงกว่า และกำหนดอินเทอร์เฟซที่คุณต้องใช้เพื่อให้แอปสามารถใช้งานฮาร์ดแวร์กล้องได้อย่างถูกต้อง อินเทอร์เฟ ซ HIDL สำหรับ Camera HAL ถูกกำหนดไว้ใน ฮาร์ดแวร์/อินเทอร์เฟซ/กล้อง
HAL ที่ถูกผูกไว้ทั่วไปต้องใช้อินเทอร์เฟซ HIDL ต่อไปนี้:
-
ICameraProvider
: สำหรับการแจกแจงอุปกรณ์แต่ละเครื่องและจัดการสถานะ -
ICameraDevice
: อินเทอร์เฟซอุปกรณ์กล้อง -
ICameraDeviceSession
: อินเทอร์เฟซเซสชันอุปกรณ์กล้องที่ใช้งานอยู่
การใช้งานอ้างอิง HIDL พร้อมใช้งานสำหรับ CameraProvider.cpp
, CameraDevice.cpp
และ CameraDeviceSession.cpp
การใช้งานจะรวม HAL เก่าที่ยังคงใช้ API เดิม เริ่มต้นด้วย Android 8.0 การใช้งาน Camera HAL ต้องใช้ HIDL API ไม่รองรับการใช้อินเทอร์เฟซแบบเดิม
การตรวจสอบอินพุต
เนื่องจาก HAL สามารถเข้าถึงทรัพยากรที่แตกต่างจากบริการกล้อง ขอบเขตระหว่างทั้งสองจึงถือเป็นขอบเขตด้านความปลอดภัย ซึ่งหมายความว่าพารามิเตอร์ที่ส่งจากบริการกล้องจะถือว่าไม่น่าเชื่อถือและไม่ถูกสุขอนามัย เพื่อป้องกันช่องโหว่ด้านความปลอดภัยที่ทำให้ผู้โจมตีสามารถขยายสิทธิ์หรือเข้าถึงข้อมูลที่พวกเขาไม่ได้ตั้งใจให้เข้าถึงได้ กล้อง HAL จะต้องตรวจสอบพารามิเตอร์ที่ส่งจากบริการกล้องไปยัง HAL ซึ่งรวมถึงการตรวจสอบว่าค่าความยาวบัฟเฟอร์อยู่ภายในช่วงที่อนุญาต และฆ่าเชื้อพารามิเตอร์ก่อนใช้งานและก่อนส่งต่อไปยังฮาร์ดแวร์หรือไดรเวอร์เคอร์เนล
ส่วนประกอบ HAL ดั้งเดิม
ส่วนนี้อธิบายสถาปัตยกรรมของส่วนประกอบ HAL ดั้งเดิมและวิธีการใช้งาน HAL การใช้งาน Camera HAL บน Android 8.0 ขึ้นไปต้องใช้ HIDL API แทนตามที่อธิบายไว้ข้างต้น
สถาปัตยกรรม (มรดก)
รูปและรายการต่อไปนี้อธิบายส่วนประกอบ HAL ของกล้องรุ่นเก่า

รูปที่ 2 สถาปัตยกรรมกล้องแบบเดิม
- กรอบงานแอป
- ที่ระดับเฟรมเวิร์กของแอปคือโค้ดของแอป ซึ่งใช้
android.hardware.Camera
API เพื่อโต้ตอบกับฮาร์ดแวร์ของกล้อง ภายใน โค้ดนี้จะเรียกคลาสกาว JNI ที่เกี่ยวข้องเพื่อเข้าถึงโค้ดเนทีฟที่โต้ตอบกับกล้อง - เจเอ็นไอ
- รหัส JNI ที่เกี่ยวข้องกับ
android.hardware.Camera
อยู่ในframeworks/base/core/jni/android_hardware_Camera.cpp
โค้ดนี้เรียกโค้ดเนทีฟระดับล่างเพื่อเข้าถึงกล้องจริงและส่งคืนข้อมูลที่ใช้ในการสร้างออบเจ็กต์android.hardware.Camera
ในระดับเฟรมเวิร์ก - กรอบงานดั้งเดิม
- เฟรมเวิร์กดั้งเดิมที่กำหนดไว้ใน
frameworks/av/camera/Camera.cpp
มอบเฟรมเวิร์กเนทิฟที่เทียบเท่ากับคลาสandroid.hardware.Camera
คลาสนี้เรียกพร็อกซี IPC Binder เพื่อเข้าถึงบริการกล้อง - เครื่องผูกพร็อกซี IPC
- พร็อกซีเครื่องผูก IPC อำนวยความสะดวกในการสื่อสารผ่านขอบเขตกระบวนการ มีคลาส Camera Binder สามคลาสที่อยู่ในไดเร็กทอรี
frameworks/av/camera
ที่เรียกใช้บริการกล้องICameraService
เป็นอินเทอร์เฟซสำหรับบริการกล้องICamera
เป็นอินเทอร์เฟซสำหรับอุปกรณ์กล้องที่เปิดเฉพาะ และICameraClient
เป็นอินเทอร์เฟซของอุปกรณ์กลับไปยังเฟรมเวิร์กแอป - บริการกล้อง
- บริการกล้องที่อยู่ใน
frameworks/av/services/camera/libcameraservice/CameraService.cpp
คือโค้ดจริงที่โต้ตอบกับ HAL - ฮาล
- เลเยอร์นามธรรมของฮาร์ดแวร์จะกำหนดอินเทอร์เฟซมาตรฐานที่บริการกล้องเรียกใช้และคุณต้องนำไปใช้เพื่อให้ฮาร์ดแวร์กล้องของคุณทำงานได้อย่างถูกต้อง
- ไดรเวอร์เคอร์เนล
- ไดรเวอร์ของกล้องโต้ตอบกับฮาร์ดแวร์กล้องจริงและการใช้งาน HAL ของคุณ กล้องและไดรเวอร์ต้องรองรับรูปแบบภาพ YV12 และ NV21 เพื่อรองรับการแสดงตัวอย่างภาพจากกล้องบนจอแสดงผลและการบันทึกวิดีโอ
การนำ HAL ไปใช้ (ดั้งเดิม)
HAL อยู่ระหว่างไดรเวอร์กล้องและเฟรมเวิร์ก Android ระดับสูงกว่า และกำหนดอินเทอร์เฟซที่คุณต้องใช้เพื่อให้แอปสามารถใช้งานฮาร์ดแวร์กล้องได้อย่างถูกต้อง อินเทอร์เฟซ HAL ถูกกำหนดไว้ในไฟล์ส่วนหัว hardware/libhardware/include/hardware/camera.h
และ hardware/libhardware/include/hardware/camera_common.h
camera_common.h
กำหนด camera_module
โครงสร้างมาตรฐานเพื่อรับข้อมูลทั่วไปเกี่ยวกับกล้อง เช่น ID กล้องและคุณสมบัติทั่วไปของกล้องทุกตัว (นั่นคือ ไม่ว่าจะเป็นกล้องหน้าหรือกล้องหลัง)
camera.h
มีโค้ดที่สอดคล้องกับ android.hardware.Camera
ไฟล์ส่วนหัวนี้ประกาศโครงสร้าง camera_device
ซึ่งจะมีโครงสร้าง camera_device_ops
พร้อมตัวชี้ไปยังฟังก์ชันที่ใช้อินเทอร์เฟซ HAL สำหรับเอกสารประกอบเกี่ยวกับพารามิเตอร์กล้องที่นักพัฒนาสามารถตั้งค่าได้ โปรดดูที่ frameworks/av/include/camera/CameraParameters.h
พารามิเตอร์เหล่านี้ได้รับการตั้งค่าด้วยฟังก์ชันที่ชี้ไปโดย int (*set_parameters)(struct camera_device *, const char *parms)
ใน HAL
สำหรับตัวอย่างการใช้งาน HAL โปรดดูการใช้งาน Galaxy Nexus HAL ใน hardware/ti/omap4xxx/camera
การกำหนดค่าไลบรารีที่ใช้ร่วมกัน
ตั้งค่าระบบบิลด์ Android เพื่อรวมการใช้งาน HAL ลงในไลบรารีที่ใช้ร่วมกันอย่างถูกต้อง และคัดลอกไปยังตำแหน่งที่เหมาะสมโดยการสร้างไฟล์ Android.mk
:
- สร้างไดเรกทอรี
device/<company_name>/<device_name>/camera
เพื่อเก็บไฟล์ต้นฉบับของไลบรารีของคุณ - สร้างไฟล์
Android.mk
เพื่อสร้างไลบรารีที่ใช้ร่วมกัน ตรวจสอบให้แน่ใจว่า makefile มีบรรทัดต่อไปนี้:LOCAL_MODULE := camera.<device_name> LOCAL_MODULE_RELATIVE_PATH := hw
ห้องสมุดของคุณต้องตั้งชื่อว่า
camera.<device_name>
(.so
จะถูกต่อท้ายโดยอัตโนมัติ) เพื่อให้ Android สามารถโหลดไลบรารีได้อย่างถูกต้อง ตัวอย่างเช่น ดูไฟล์ makefile สำหรับกล้อง Galaxy Nexus ที่อยู่ในhardware/ti/omap4xxx/Android.mk
- ระบุว่าอุปกรณ์ของคุณมีคุณสมบัติกล้องโดยการคัดลอกไฟล์ XML คุณสมบัติที่จำเป็นในไดเร็กทอรี
frameworks/native/data/etc
ด้วย makefile ของอุปกรณ์ของคุณ ตัวอย่างเช่น หากต้องการระบุว่าอุปกรณ์ของคุณมีแฟลชกล้องและสามารถโฟกัสอัตโนมัติได้ ให้เพิ่มบรรทัดต่อไปนี้ใน<device>/<company_name>/<device_name>/device.mk
makefile ของอุปกรณ์:PRODUCT_COPY_FILES := \ ... PRODUCT_COPY_FILES += \ frameworks/native/data/etc/android.hardware.camera.flash-autofocus.xml:system/etc/permissions/android.hardware.camera.flash-autofocus.xml \
สำหรับตัวอย่างของ makefile ของอุปกรณ์ โปรดดูที่
device/samsung/tuna/device.mk
- ประกาศความสามารถด้านตัวแปลงสัญญาณสื่อ รูปแบบ และความละเอียดของกล้องในไฟล์ XML
device/<company_name>/<device_name>/media_profiles.xml
device/<company_name>/<device_name>/media_codecs.xml
สำหรับรายละเอียด โปรดดู การเปิดเผยตัวแปลงสัญญาณกับเฟรมเวิร์ก - เพิ่มบรรทัดต่อไปนี้ใน
device/<company_name>/<device_name>/device.mk
makefile ของอุปกรณ์เพื่อคัดลอกไฟล์media_profiles.xml
และmedia_codecs.xml
ไปยังตำแหน่งที่เหมาะสม:# media config xml file PRODUCT_COPY_FILES += \ <device>/<company>/<device>/media_profiles.xml:system/etc/media_profiles.xml # media codec config xml file PRODUCT_COPY_FILES += \ <device>/<company>/<device>/media_codecs.xml:system/etc/media_codecs.xml
- หากต้องการรวมแอปกล้องไว้ในอิมเมจระบบของอุปกรณ์ ให้ระบุแอปในตัวแปร
PRODUCT_PACKAGES
ในdevice/<company>/<device>/device.mk
makefile:PRODUCT_PACKAGES := \ Gallery2 \ ...