שכבת ההפשטה של החומרה (HAL) של המצלמה ב-Android מחברת בין ממשקי ה-API של מסגרת המצלמה ברמה גבוהה יותר ב- Camera 2 לבין מנהל ההתקן והחומרה הבסיסיים של המצלמה. מערכת המשנה של המצלמה כוללת הטמעות של רכיבי צינור המצלמה, בעוד ש-HAL של המצלמה מספק ממשקים לשימוש בהטמעה של הגרסה שלכם של הרכיבים האלה.
ארכיטקטורה
באיור וברשימה הבאים מתוארים רכיבי ה-HAL.
איור 1. ארכיטקטורת המצלמה
- app framework
- ברמת מסגרת האפליקציה נמצא הקוד של האפליקציה, שמשתמש בממשק Camera 2 API כדי ליצור אינטראקציה עם חומרת המצלמה. באופן פנימי, הקוד הזה קורא לממשקי Binder המתאימים כדי לגשת לקוד ה-Native שפועל באינטראקציה עם המצלמה.
- AIDL
- ממשק ה-binder שמשויך ל-
CameraServiceנמצא בכתובת frameworks/av/camera/aidl/android/hardware. הקוד שנוצר קורא לקוד Native ברמה הנמוכה כדי לקבל גישה למצלמה הפיזית, ומחזיר נתונים שמשמשים ליצירת האובייקטיםCameraDeviceובהמשךCameraCaptureSessionברמת ה-framework. - native framework
-
- המסגרת הזו, שנמצאת ב-
frameworks/av/, מספקת שווי ערך מקורי למחלקותCameraDeviceו-CameraCaptureSession. אפשר לעיין גם ב הפניה ל-NDK camera2. - ממשק binder IPC
- ממשק ה-Binder של IPC מאפשר תקשורת בין גבולות התהליך.
יש כמה מחלקות של קבצים לאיגוד מצלמות בספרייה
frameworks/av/camera/camera/aidl/android/hardwareשקוראות לשירות המצלמה.ICameraServiceהוא הממשק לשירות המצלמה; ICameraDeviceUserהוא הממשק למכשיר מצלמה ספציפי שנפתח; ו-ICameraServiceListenerו-ICameraDeviceCallbacksהם הקריאות החוזרות (callback) המתאימותCameraServiceו-CameraDeviceלמסגרת האפליקציה. - שירות המצלמה
- שירות המצלמה, שנמצא ב-
frameworks/av/services/camera/libcameraservice/CameraService.cpp, הוא הקוד בפועל שמתקשר עם HAL. - HAL
- שכבת הפשטת החומרה מגדירה את הממשק הסטנדרטי שאליו שירות המצלמה מתקשר, ושאתם צריכים להטמיע כדי שחומרת המצלמה שלכם תפעל בצורה תקינה.
הטמעה של HAL
שכבת ה-HAL נמצאת בין מנהל ההתקן של המצלמה לבין מסגרת Android ברמה גבוהה יותר, והיא מגדירה ממשק שצריך להטמיע כדי שאפליקציות יוכלו להפעיל את חומרת המצלמה בצורה תקינה. ממשקי HIDL של Camera HAL מוגדרים ב- hardware/interfaces/camera.
בדרך כלל, בממשק HAL עם Binder צריך להטמיע את הממשקים הבאים של HIDL:
-
ICameraProvider: לספירת מכשירים בודדים ולניהול הסטטוס שלהם. -
ICameraDevice: ממשק מכשיר המצלמה. -
ICameraDeviceSession: ממשק פעיל של סשן במכשיר המצלמה.
הטמעות לדוגמה של HIDL זמינות עבור CameraProvider.cpp,
CameraDevice.cpp ו-CameraDeviceSession.cpp.
ההטמעה עוטפת HAL ישנים שעדיין משתמשים ב-API מדור קודם.
החל מ-Android 8.0, הטמעות של Camera HAL חייבות להשתמש ב-HIDL API. השימוש בממשק מדור קודם לא נתמך.
אימות קלט
ל-HAL יש גישה למשאבים שונים מאלה של שירות המצלמה, ולכן הגבול בין השניים נחשב לגבול אבטחה. המשמעות היא שפרמטרים שמועברים משירות המצלמה נחשבים ללא מהימנים ולא מחוטאים. כדי למנוע נקודות חולשה באבטחה שמאפשרות לתוקפים להשיג הרשאות גבוהות יותר או לגשת לנתונים שהם לא אמורים לגשת אליהם, ה-HAL של המצלמה צריך לאמת את הפרמטרים שמועברים משירות המצלמה ל-HAL. זה כולל בדיקה של ערכי האורך של buffer בטווחים המותרים, וניקוי של הפרמטרים לפני השימוש ולפני העברתם לדרייברים של חומרה או ליבת מערכת ההפעלה.
רכיבי HAL מדור קודם
בקטע הזה מתוארת הארכיטקטורה של רכיבי HAL מדור קודם ומוסבר איך להטמיע את HAL. הטמעות של Camera HAL ב-Android מגרסה 8.0 ומעלה חייבות להשתמש בממשק ה-API של HIDL, שמתואר למעלה.
ארכיטקטורה (גרסה קודמת)
באיור וברשימה הבאים מתוארים הרכיבים של HAL של מצלמה מדור קודם.
איור 2. ארכיטקטורת מצלמה מדור קודם
- app framework
- ברמת מסגרת האפליקציה נמצא הקוד של האפליקציה, שמשתמש ב-API
android.hardware.Cameraכדי ליצור אינטראקציה עם חומרת המצלמה. באופן פנימי, הקוד הזה קורא למחלקת דבק JNI תואמת כדי לגשת לקוד ה-Native שמתקשר עם המצלמה. - JNI
- קוד ה-JNI שמשויך ל-
android.hardware.Cameraנמצא ב-frameworks/base/core/jni/android_hardware_Camera.cpp. הקוד הזה קורא לקוד Native ברמה הנמוכה כדי לקבל גישה למצלמה הפיזית ומחזיר נתונים שמשמשים ליצירת האובייקטandroid.hardware.Cameraברמת ה-framework. - native framework
-
- המסגרת המקורית שמוגדרת ב-
frameworks/av/camera/Camera.cppמספקת מקבילה מקורית למחלקהandroid.hardware.Camera. המחלקות האלה קוראות ל-IPC binder proxies כדי לקבל גישה לשירות המצלמה. - שרתי proxy של IPC ל-Binder
- פרוקסי של IPC binder מאפשרים תקשורת בין תהליכים.
יש שלוש מחלקות של קבצים לאיגוד מצלמות שנמצאות בספרייה
frameworks/av/cameraשקוראת לשירות המצלמה. ICameraServiceהוא הממשק לשירות המצלמה,ICameraהוא הממשק למכשיר מצלמה ספציפי שנפתח, ו-ICameraClientהוא הממשק של המכשיר בחזרה למסגרת האפליקציה. - שירות המצלמה
- שירות המצלמה, שנמצא ב-
frameworks/av/services/camera/libcameraservice/CameraService.cpp, הוא הקוד בפועל שמתקשר עם HAL. - 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, מבנה סטנדרטי לקבלת מידע כללי על המצלמה, כמו מזהה המצלמה ומאפיינים משותפים לכל המצלמות (כלומר, אם זו מצלמה קדמית או אחורית).
camera.h contains code that corresponds to
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.
הגדרת הספרייה המשותפת
כדי להגדיר את מערכת ה-build של 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.mkmakefile של המכשיר: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.xmldevice/<company_name>/<device_name>/media_codecs.xmldevice/<company_name>/<device_name>/media_profiles.xml. פרטים נוספים זמינים במאמר בנושא חשיפת קודקים למסגרת. - כדי להעתיק את הקבצים
media_profiles.xmlו-media_codecs.xmlלמיקום המתאים, מוסיפים את השורות הבאות לקובץ ה-makefile של המכשיר:device/<company_name>/<device_name>/device.mk# 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.mkmakefile של המכשיר:PRODUCT_PACKAGES := \ Gallery2 \ ...