Sensors Multi-HAL היא מסגרת שמאפשרת ל-HAL של חיישנים לפעול לצד HAL של חיישנים אחרים. Sensors Multi-HAL טוען באופן דינמי HAL משני של חיישנים שנשמר כספריות דינמיות במחיצה של הספק, ומספק להם אובייקט קריאה חוזרת (callback) שיכול לטפל בפרסום אירועים ובקבלה ושחרור של נעילת ההתעוררות. HAL משני של חיישנים הוא HAL של חיישנים שמוטמע באובייקט משותף במחיצה של הספק, והוא משמש את המסגרת של HAL מרובה. רכיבי ה-HAL המשניים האלה לא תלויים זה בזה או בקוד ה-HAL המורכב שמכיל את הפונקציה הראשית של התהליך.
Sensors Multi-HAL 2.1, שזמין במכשירים עם Android מגרסה 11 ואילך, הוא גרסה משופרת של Sensors Multi-HAL 2.0 שתומכת בחיבור של HAL משניים שיכולים לחשוף את סוג החיישן של זווית הציר. כדי לתמוך בסוג החיישן הזה, ממשקי HAL משניים חייבים להשתמש בממשקי ה-API של HAL משני שמוגדרים בכותרת 2.1 SubHal.
במכשירים עם Android מגרסה 13 ואילך שמשתמשים ב-Sensors AIDL HAL, אפשר להשתמש בשכבת shim של HAL מרובה כדי לאפשר יכולת של HAL מרובה. פרטי ההטמעה מפורטים במאמר שימוש ב-Sensors Multi-HAL עם Sensors AIDL HAL.
ההבדל בין Sensors Multi-HAL 2 לבין Sensors HAL 2
Sensors Multi-HAL 2 זמין במכשירים עם Android מגרסה 10 ואילך, ומציג כמה הפשטות מעל Sensors HAL 2 כדי להקל על האינטראקציה עם ממשקי HAL API. ב-Sensors Multi-HAL 2 מוצג הכיתה HalProxy לטיפול בהטמעה של ממשק Sensors HAL 2 והממשק V2_1/SubHal
(או V2_0/SubHal
) כדי לאפשר ל-HalProxy
לקיים אינטראקציה עם ממשקי HAL משניים.
הממשק של ISensorsSubHal
שונה מהממשק של 2.1/ISensors.hal
(או 2.0/ISensors.hal
) בדרכים הבאות:
- שיטת initialize מעבירה את הכיתה
IHalProxyCallback
במקום שני FMQ ו-ISensorsCallback
. - ב-HAL משניים צריך להטמיע פונקציית ניפוי באגים כדי לספק מידע על ניפוי הבאגים בדוחות הבאגים.
- יש להטמיע פונקציית שם ב-HAL משני כדי שאפשר יהיה להבדיל בין ה-HAL המשני שנטען לבין HAL משני אחר.
ההבדל העיקרי בין Sensors Multi-HAL 2 לבין Sensors HAL 2 הוא בפונקציות ההפעלה. במקום לספק FMQs, הממשק IHalProxyCallback
מספק שתי שיטות: שיטה אחת לפרסום אירועי חיישנים למסגרת החיישנים, ושיטה אחת ליצירת נעילת התעוררות (wake lock). מתחת לפני השטח, ה-Multi-HAL של חיישנים מנהל את כל האינטראקציות עם ה-FMQ כדי להבטיח העברה בזמן של אירועי חיישנים לכל ה-HAL המשניים. מומלץ מאוד להשתמש בשיטה createScopedWakelock
ב-HAL המשני כדי להעביר את נטל הזמן הקצוב לנעילה ל-Sensors Multi-HAL, וכדי למרכז את השימוש בנעילה ל-wake lock אחד משותף לכל ה-Sensors Multi-HAL, וכך לצמצם את מספר הקריאות לנעילת הנעילה ולביטול הנעילה.
ב-Sensors Multi-HAL 2 יש גם כמה תכונות בטיחות מובנות. הוא מטפל במצבים שבהם ה-FMQ של החיישן מלא, או במצבים שבהם מסגרת החיישן של Android מופעלת מחדש ויש צורך לאפס את מצב החיישן. בנוסף, כשאירועים מפורסמים בכיתה HalProxy
אבל מסגרת החיישן לא יכולה לקבל את האירועים באופן מיידי, ה-Sensors Multi-HAL יכול להעביר את האירועים לשרשור רקע כדי לאפשר את המשך העבודה בכל ה-HAL המשניים בזמן ההמתנה לפרסום האירועים.
קוד מקור והטמעת הפניה
כל הקוד של Multi-HAL של חיישנים זמין ב-hardware/interfaces/sensors/common/default/2.X/multihal/
.
ריכזנו כאן כמה מקורות מידע.
HalProxy.h
: אובייקטHalProxy
נוצר על ידי Sensors multi-HAL ומטפל בהעברת הנתונים מ-HAL המשניים למסגרת החיישן.HalProxy.cpp
: ההטמעה שלHalProxy
מכילה את כל הלוגיקה הנדרשת למולטיפלקס של התקשורת בין ממשקי HAL משניים לבין מסגרת החיישן.SubHal.h
: הממשקISensorsSubHal
מגדיר את הממשק ש-HAL משניים חייבים לפעול לפיו כדי להיות תואם ל-HalProxy
. ה-HAL המשני מטמיע את השיטה initialize כדי שאפשר יהיה להשתמש באובייקטHalProxyCallback
עבורpostEvents
ו-createScopedWakelock
.בהטמעות של Multi-HAL 2.0, צריך להשתמש בגרסה 2.0 של
SubHal.h
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/
: בדיקות היחידות האלה מאמתות את ההטמעה שלHalProxy
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
: בדוגמה הזו להטמעת תת-HAL נעשה שימוש בחיישנים מזויפים ליצירת נתונים מזויפים. שימושי לבדיקת האינטראקציה בין מספר ממשקי HAL משניים במכשיר.
הטמעה
בקטע הזה מוסבר איך מטמיעים את Sensors Multi-HAL במקרים הבאים:
- שימוש ב-Sensors Multi-HAL עם Sensors AIDL HAL
- הטמעת Sensors Multi-HAL 2.1
- העברה מ-Sensors Multi-HAL 2.0 ל-Multi-HAL 2.1
- העברה מ-Sensors HAL 2.0
- העברה מ-Sensors HAL 1.0
- העברה מ-Sensors Multi-HAL 1.0
שימוש ב-Sensors Multi-HAL עם Sensors AIDL HAL
כדי לאפשר יכולת של HAL מרובה עם HAL של Sensors AIDL, מייבאים את מודול שכבת השימ של AIDL Multi-HAL שנמצא ב-hardware/interfaces/sensors/aidl/default/multihal/. המודול מטפל בהמרה בין סוגי ההגדרות של חיישנים ב-HAL של AIDL ו-HIDL, ומגדיר מעטפת סביב ממשק ה-HAL המורכב שמתואר במאמר הטמעת Sensors Multi-HAL 2.1. שכבת השימ של AIDL עם מספר ממשקי HAL תואמת למכשירים שמטמיעים את Sensors Multi-HAL 2.1.
שכבת השימ (shim) של AIDL עם מספר HAL מאפשרת לחשוף את סוגי החיישנים של מעקב תנועות הראש ו-IMU עם צירים מוגבלים ב-HAL של Sensors AIDL. כדי להשתמש בסוגי החיישנים האלה שמוגדרים בממשק AIDL HAL, צריך להגדיר את השדה type
ב-struct SensorInfo
בהטמעה getSensorsList_2_1()
. אפשר לעשות זאת בבטחה כי השדות של סוג החיישן שמגובים במספר שלם ב-HAL של חיישני AIDL ו-HIDL לא חופפים.
הטמעת Sensors Multi-HAL 2.1
כדי להטמיע את Sensors Multi-HAL 2.1 במכשיר חדש, פועלים לפי השלבים הבאים:
- מטמיעים את הממשק
ISensorsSubHal
כפי שמתואר במאמרSubHal.h
. - מטמיעים את השיטה
sensorsHalGetSubHal_2_1
ב-SubHal.h
. מוסיפים יעד
cc_library_shared
כדי ליצור את תת-ה-HAL שהוטמע לאחרונה. כשמוסיפים את היעד:- מוודאים שהיעד נדחף למקום כלשהו במחיצה של הספק במכשיר.
- בקובץ התצורה שנמצא בכתובת
/vendor/etc/sensors/hals.conf
, מוסיפים את הנתיב לספרייה בשורה חדשה. אם צריך, יוצרים את הקובץhals.conf
.
דוגמה לרשומה
Android.bp
ליצירת ספריית HAL משנית מופיעה בקטעhardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp
.מסירים את כל הרשומות של
android.hardware.sensors
מהקובץmanifest.xml
, שמכיל את רשימת ה-HAL הנתמכים במכשיר.מסירים את כל קבצי השירות
android.hardware.sensors
ו-service.rc
מקובץdevice.mk
ומוסיפים אתandroid.hardware.sensors@2.1-service.multihal
ו-android.hardware.sensors@2.1-service.multihal.rc
לקובץPRODUCT_PACKAGES
.
בזמן האתחול, HalProxy
מתחיל לפעול, מחפש את תת-ה-HAL שהוטמע לאחרונה ומפעיל אותו באמצעות קריאה ל-sensorsHalGetSubHal_2_1
.
העברה מ-Sensors Multi-HAL 2.0 ל-Multi-HAL 2.1
כדי להעביר מ-Multi-HAL 2.0 ל-Multi-HAL 2.1, מטמיעים את הממשק SubHal
ומרכיבים מחדש את ה-HAL המשני.
אלה ההבדלים בין הממשקים של SubHal
בגרסה 2.0 לבין אלה בגרסה 2.1:
- ב-
IHalProxyCallback
נעשה שימוש בסוגי הנתונים שנוצרו בגרסה 2.1 של המפרטISensors.hal
. - הפונקציה
initialize()
מעבירהIHalProxyCallback
חדש במקום זה שמגיע מהממשקSubHal
2.0 - ממשקי HAL משניים חייבים ליישם את
getSensorsList_2_1
ו-injectSensorData_2_1
במקום אתgetSensorsList
ו-injectSensorData
, כי השיטות האלה משתמשות בסוגי הנתונים החדשים שנוספו בגרסה 2.1 של מפרטISensors.hal
. - כדי ש-Multi-HAL יתייחס ל-HAL משניים כ-HAL משני בגרסה 2.1, הוא צריך לחשוף את
sensorsHalGetSubHal_2_1
במקום אתsensorsHalGetSubHal
.
יציאה מ-Sensors HAL 2.0
כשמשדרגים ל-Sensors Multi-HAL 2.0 מ-Sensors HAL 2.0, חשוב לוודא שההטמעה של HAL עומדת בדרישות הבאות.
אתחול ה-HAL
ל-Sensors HAL 2.0 יש פונקציית הפעלה שמאפשרת לשירות החיישן להעביר FMQs וקריאה חוזרת דינמית של חיישן. ב-Sensors Multi-HAL 2.0, הפונקציה initialize()
מעבירה קריאה חוזרת אחת שצריך להשתמש בה כדי לפרסם אירועי חיישנים, לקבל נעילת התעוררות ולהודיע על חיבורים ודילוגים דינמיים של חיישנים.
שליחת אירועי חיישנים להטמעת Multi-HAL
במקום לפרסם אירועי חיישנים דרך FMQ, תת-HAL צריך לכתוב אירועי חיישנים ב-IHalProxyCallback
כשאירועי חיישנים זמינים.
אירועי WAKE_UP
ב-Sensors HAL 2.0, ה-HAL יכול לנהל את נעילת ההתעוררות להטמעה שלו. ב-Sensors Multi-HAL 2.0, ממשקי ה-HAL המשניים מאפשרים להטמעת Multi-HAL לנהל את חסימות מצב השינה, והם יכולים לבקש חסימה של מצב השינה באמצעות קריאה ל-createScopedWakelock
.
צריך לקבל ולשלוח ל-postEvents
מנעול התעוררות ברמת הנעילה כשמפרסמים אירועי התעוררות להטמעת Multi-HAL.
חיישנים דינמיים
ב-Sensors Multi-HAL 2.0 נדרש קריאה ל-onDynamicSensorsConnected
ול-onDynamicSensorsDisconnected
ב-IHalProxyCallback
בכל פעם שמתבצע שינוי בחיבורי החיישנים הדינמיים. פונקציות הקריאה החוזרת האלה זמינות כחלק מהצבען IHalProxyCallback
שסופק באמצעות הפונקציה initialize()
.
יציאה מ-Sensors HAL 1.0
כשמשדרגים ל-Sensors Multi-HAL 2.0 מ-Sensors HAL 1.0, חשוב לוודא שההטמעה של HAL עומדת בדרישות הבאות.
אתחול ה-HAL
צריכה להיות תמיכה בפונקציה initialize()
כדי ליצור את הקריאה החוזרת בין HAL המשני לבין הטמעת ה-Multi-HAL.
חשיפת החיישנים הזמינים
ב-Sensors Multi-HAL 2.0, הפונקציה getSensorsList()
חייבת להחזיר את אותו ערך במהלך הפעלה יחידה של המכשיר, גם במהלך הפעלות מחדש של HAL של חיישנים. כך המערכת תוכל לנסות ליצור מחדש את החיבורים לחיישנים אם שרת המערכת יופעל מחדש. הערך שמוחזר על ידי getSensorsList()
יכול להשתנות אחרי שהמכשיר מופעל מחדש.
שליחת אירועי חיישנים להטמעת Multi-HAL
ב-Sensors HAL 2.0, במקום להמתין לקריאה ל-poll()
, רכיב ה-HAL המשני צריך לכתוב באופן יזום אירועי חיישנים ב-IHalProxyCallback
בכל פעם שאירועי חיישנים זמינים.
אירועי WAKE_UP
ב-Sensors HAL 1.0, ה-HAL יכול לנהל את נעילת ההתעוררות להטמעה שלו. ב-Sensors Multi-HAL 2.0, ממשקי ה-HAL המשניים מאפשרים להטמעת ה-Multi-HAL לנהל את החסימות של מצב השינה, והם יכולים לבקש חסימה של מצב השינה באמצעות קריאה ל-createScopedWakelock
.
צריך לקבל ולשלוח ל-postEvents
מנעול התעוררות ברמת הנעילה כשמפרסמים אירועי התעוררות להטמעת Multi-HAL.
חיישנים דינמיים
ב-Sensors HAL 1.0, חיישנים דינמיים מוחזרים דרך הפונקציה poll()
.
ב-Sensors Multi-HAL 2.0 נדרש קריאה ל-onDynamicSensorsConnected
ול-onDynamicSensorsDisconnected
ב-IHalProxyCallback
בכל פעם שמתבצע שינוי בחיבורי החיישנים הדינמיים. פונקציות הקריאה החוזרת האלה זמינות כחלק מהצבען IHalProxyCallback
שסופק באמצעות הפונקציה initialize()
.
יציאה מ-Sensors Multi-HAL 1.0
כדי להעביר הטמעה קיימת מ-Sensors Multi-HAL 1.0, פועלים לפי השלבים הבאים.
- מוודאים שהגדרת ה-HAL של החיישנים נמצאת ב-
/vendor/etc/sensors/hals.conf
. יכול להיות שתצטרכו להעביר את הקובץ שנמצא ב-/system/etc/sensors/hals.conf
. - מסירים כל התייחסות ל-
hardware/hardware.h
ול-hardware/sensors.h
, כי אין תמיכה בהם ב-HAL 2.0. - מעבירים את רכיבי ה-HAL המשניים כפי שמתואר במאמר העברה מ-Sensors Hal 1.0.
- מגדירים את Sensors Multi-HAL 2.0 כ-HAL הייעודי לפי השלבים 3 ו-4 בקטע הטמעת Sensors Mutli-HAL 2.0.
אימות
הפעלת VTS
אחרי שמשלבים HAL משני אחד או יותר עם Sensors Multi-Hal 2.1, אפשר להשתמש ב-Vendor Test Suite (VTS) כדי לוודא שהטמעות ה-HAL המשניים עומדות בכל הדרישות שהוגדרו בממשק ה-HAL של Sensors.
כדי להריץ רק את בדיקות ה-VTS של החיישנים כש-VTS מוגדר במכונה המארחת, מריצים את הפקודות הבאות:
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsHalSensorsV2_0Target && \
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsHalSensorsV2_1Target
אם אתם מפעילים את שכבת ה-shim של AIDL Multi-HAL, מריצים את הפקודה VtsAidlHalSensorsTargetTest
.
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsAidlHalSensorsTargetTest
הרצת בדיקות יחידה
בדיקות היחידה ב-HalProxy_test.cpp
בודקות את HalProxy
באמצעות HAL משניים מזויפים שנוצרים בבדיקה היחידה ולא נטענים באופן דינמי. כשיוצרים HAL משני חדש, הבדיקות האלה יכולות לשמש כמדריך להוספת בדיקות יחידה כדי לוודא שה-HAL המשני החדש מוטמע בצורה תקינה.
כדי להריץ את הבדיקות, מריצים את הפקודות הבאות:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
בדיקה עם HALs משניים מזויפים
ממשקי ה-HAL המשניים המזויפים הם הטמעות דמה של ממשק ISensorsSubHal
.
ממשקי ה-HAL המשניים חושפים רשימות שונות של חיישנים. כשהחיישנים מופעלים, הם מפרסמים מדי פעם ב-HalProxy
אירועי חיישן שנוצרו באופן אוטומטי, על סמך המרווחים שצוינו בבקשה נתונה של חיישן.
אפשר להשתמש ב-HALs המשניים המזויפים כדי לבדוק איך הקוד המלא של Multi-HAL פועל עם HALs משניים אחרים שנטענים למערכת, וכדי להפעיל לחץ על היבטים שונים של הקוד של Multi-HAL לחיישנים.
שני HAL משניים מזויפים זמינים בכתובת hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
.
כדי ליצור את קובצי ה-HAL המשניים המזויפים ולשלוח אותם למכשיר:
מריצים את הפקודות הבאות כדי ליצור את שלוש גרסת ה-HAL המשניות המזויפות ולשלוח אותן למכשיר:
$ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests/
mma
adb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
adb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
adb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
מעדכנים את הגדרת ה-HAL של החיישנים ב-
/vendor/etc/sensors/hals.conf
עם הנתיבים של ה-HAL המשניים המזויפים./vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
מפעילים מחדש את
HalProxy
וטעונים את שכבות ה-HAL המשניות החדשות שמפורטות בתצורה.adb shell stop
adb shell start
ניפוי באגים
מפתחים יכולים לנפות באגים במסגרת באמצעות הפקודה lshal
. כדי לבקש את הפלט של ניפוי הבאגים של HAL של החיישנים, מריצים את הפקודה הבאה:
adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default
לאחר מכן, המידע על המצב הנוכחי של HalProxy
ועל HALs המשניים שלו יופיע ביציאה של המסוף. בהמשך מוצגת דוגמה לפלט של הפקודה לגבי האובייקט HalProxy
ול-HALs משניים מזויפים.
Internal values:
Threads are running: true
Wakelock timeout start time: 200 ms ago
Wakelock timeout reset time: 73208 ms ago
Wakelock ref count: 0
# of events on pending write queue: 0
# of non-dynamic sensors across all subhals: 8
# of dynamic sensors across all subhals: 0
SubHals (2):
Name: FakeSubHal-OnChange
Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
Name: FakeSubHal-OnChange
Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
אם המספר שצוין עבור # of events on pending write queue
הוא מספר גדול (1,000 או יותר), סימן שיש הרבה אירועים בהמתנה לכתיבה למסגרת החיישנים. המשמעות היא ששירות החיישן נמצא במצב נעילה הדדית או קרס ולא מעבד אירועי חיישנים, או שקבוצה גדולה של אירועי חיישנים פורסמה לאחרונה מ-HAL משני.
אם מספר ההפניות של נעילת ההתעוררות גדול מ-0
, סימן ש-HalProxy
השיג נעילת התעוררות. הערך הזה צריך להיות גדול מ-0
רק אם ScopedWakelock
מופעל בכוונה או אם אירועי התעוררות נשלחו אל HalProxy
ולא עברו עיבוד על ידי מסגרת החיישן.
מתאר הקובץ שמוענק ל-method של ניפוי הבאגים של HalProxy
מועבר לכל HAL משני, ולכן המפתחים צריכים להטמיע את method של ניפוי הבאגים כחלק מממשק ISensorsSubHal
.