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

รูปที่ 1. สถาปัตยกรรมกล้อง
- เฟรมเวิร์กแอพ
- ที่ระดับเฟรมเวิร์กของแอปคือโค้ดของแอป ซึ่งใช้ Camera 2 API เพื่อโต้ตอบกับฮาร์ดแวร์ของกล้อง ภายในโค้ดนี้เรียกอินเทอร์เฟซ Binder ที่เกี่ยวข้องเพื่อเข้าถึงโค้ดเนทีฟที่โต้ตอบกับกล้อง
- AIDL
- อินเทอร์เฟซเครื่องผูกที่เชื่อมโยงกับ
CameraService
สามารถพบได้ที่ frameworks/av/camera/aidl/android/hardware รหัสที่สร้างขึ้นจะเรียกรหัสดั้งเดิมระดับล่างเพื่อเข้าถึงกล้องจริงและส่งคืนข้อมูลที่ใช้ในการสร้างCameraDevice
และในที่สุดวัตถุCameraCaptureSession
ที่ระดับเฟรมเวิร์ก - เฟรมเวิร์กดั้งเดิม
- เฟรมเวิร์กนี้อยู่ใน
frameworks/av/
มีเนทีฟที่เทียบเท่ากับCameraDevice
และCameraCaptureSession
ดู การอ้างอิง NDK camera2 ด้วย - อินเทอร์เฟซ IPC ของ Binder
- อินเทอร์เฟซ IPC 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
- รหัส JNI ที่เชื่อมโยงกับ
android.hardware.Camera
อยู่ในframeworks/base/core/jni/android_hardware_Camera.cpp
รหัสนี้เรียกรหัสดั้งเดิมระดับล่างเพื่อเข้าถึงกล้องจริงและส่งคืนข้อมูลที่ใช้ในการสร้างวัตถุandroid.hardware.Camera
ที่ระดับเฟรมเวิร์ก - เฟรมเวิร์กดั้งเดิม
- เฟรมเวิร์กดั้งเดิมที่กำหนดไว้ใน
frameworks/av/camera/Camera.cpp
ให้เนทีฟเทียบเท่ากับคลาสandroid.hardware.Camera
คลาสนี้เรียกพร็อกซี Binder IPC เพื่อเข้าถึงบริการกล้อง - สารบัญ IPC พร็อกซี่
- พร็อกซีสารยึดเกาะ IPC อำนวยความสะดวกในการสื่อสารข้ามขอบเขตของกระบวนการ มีคลาสตัวผูกกล้องสามคลาสที่อยู่ในไดเร็กทอรี
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
anddevice/<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 \ ...