פרוטוקול החיישנים Multi-HAL הוא מסגרת שמאפשרת לחיישנים לה נתוני HAL לרוץ לצד מכשירי HAL אחרים של חיישנים. באמצעות התכונה 'חיישנים מרובי-HAL', מערכת החיישנים טוענת באופן דינמי תתי-HAL של חיישנים שמאוחסנים כספריות דינמיות במחיצת הספק, ונותנים להם אובייקט קריאה חוזרת שיכול לטפל בפרסום אירועים, לקבל ולפרסם את התכונה 'נעילת מצב שינה'. HAL משני של חיישנים הוא HAL של חיישנים שמוטמע באובייקט משותף במחיצה של הספק, והוא משמש את המסגרת של HAL מרובה. רכיבי המשנה HAL לא תלויים זה בזה או בקוד מרובה HAL שמכיל את הפונקציה הראשית של התהליך.
חיישן Multi-HAL 2.1 זמין במכשירים עם Android מגרסה 11 ואילך, הוא איטרציה של חיישנים 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.
ההבדל בין חיישנים Multi-HAL 2 לחיישנים HAL 2
באמצעות האפשרות 'חיישנים Multi-HAL 2' במכשירים עם Android מגרסה 10 ואילך, מוצגות כמה פשטות בנוסף ל-Sensors HAL 2 כדי להקל על האינטראקציה עם ממשקי API עם HAL. ב-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 משניים צריך להטמיע פונקציית ניפוי באגים כדי לספק מידע על ניפוי הבאגים בדוחות הבאגים.
- רכיבי Sub-HAL חייבים להטמיע פונקציית שם, כדי שיהיה אפשר להבדיל בין תת-ה-HAL שנטען לבין דפי משנה אחרים.
ההבדל העיקרי בין Sensors Multi-HAL 2 לבין Sensors HAL 2 הוא בפונקציות האתחול. במקום לספק FMQ, ממשק IHalProxyCallback
מספק שתי שיטות: אחת לפרסום אירועי חיישן במסגרת החיישנים ושיטה אחת ליצירת חסימות מצב שינה. מאחורי הקלעים, מערכת החיישנים Multi-HAL מנהלת את כל האינטראקציות עם מכשירי ה-FMQ כדי להבטיח אספקה מהירה של אירועי חיישנים לכל תתי ה-HAL. מומלץ מאוד להשתמש בשיטה createScopedWakelock
ב-HAL המשני כדי להעביר את נטל הזמן הקצוב לנעילה ל-Sensors Multi-HAL, וכדי למרכז את השימוש בנעילה ל-wake lock אחד משותף לכל ה-Sensors Multi-HAL, וכך למזער את מספר הקריאות לנעילת הנעילה ולביטול הנעילה.
לחיישן Multi-HAL 2 יש גם כמה תכונות בטיחות מובנות. הוא מטפל במצבים שבהם ה-FMQ של החיישן מלא, או במצבים שבהם מסגרת החיישן של Android מופעלת מחדש ויש צורך לאפס את מצב החיישן. בנוסף, כשאירועים מפורסמים בכיתה HalProxy
אבל מסגרת החיישן לא יכולה לקבל את האירועים באופן מיידי, ה-Sensors Multi-HAL יכול להעביר את האירועים לשרשור ברקע כדי לאפשר את המשך העבודה בכל ה-HAL המשניים בזמן ההמתנה לפרסום האירועים.
הטמעת קוד מקור והפניות
קוד Multi-HAL של כל החיישנים זמין בhardware/interfaces/sensors/common/default/2.X/multihal/
.
ריכזנו כאן כמה מקורות מידע.
HalProxy.h
: האובייקטHalProxy
נוצר באמצעות חיישנים מרובי-HAL, ומטפל בהעברת הנתונים מרכיבי המשנה-HAL למסגרת החיישן.HalProxy.cpp
: ההטמעה שלHalProxy
כוללת את כל הלוגיקה שנדרשת ליצירת תקשורת כפולה בין תת-פונקציות לבין מסגרת החיישן.SubHal.h
: הממשקISensorsSubHal
מגדיר את הממשק ש-HALs משניים חייבים לפעול לפיו כדי להיות תואמים ל-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 במצבים הבאים:
- שימוש בחיישנים מסוג Multi-HAL עם החיישנים AIDL HAL
- הטמעת חיישנים Multi-HAL 2.1
- ניוד מחיישנים Multi-HAL 2.0 אל Multi-HAL 2.1
- העברה מ-Sensors HAL 2.0
- העברה מ-Sensors HAL 1.0
- העברה מ-Sensors Multi-HAL 1.0
שימוש בחיישנים עם מולטי HAL עם חיישנים AIDL HAL
כדי לאפשר יכולת של פעילות מולטי HAL באמצעות החיישנים AIDL HAL, צריך לייבא את מודול שכבת ה-AIDL Multi-HAL shim, שנמצא ב-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
במבנה SensorInfo
בהטמעה getSensorsList_2_1()
. הפעולה הזו בטוחה כי אין חפיפה בשדות של סוגי החיישנים המגובים במספר שלם של חיישני AIDL ו-HIDL.
הטמעת Sensors Multi-HAL 2.1
כדי להטמיע את Sensors Multi-HAL 2.1 במכשיר חדש, פועלים לפי השלבים הבאים:
- מטמיעים את הממשק
ISensorsSubHal
כמו שמתואר ב-SubHal.h
. - מטמיעים את ה-method
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
.
יציאה מחיישנים Multi-HAL 2.0 ל-Multi-HAL 2.1
כדי לצאת מ-Multi-HAL 2.0 ל-Multi-HAL 2.1, עליכם להטמיע את הממשק SubHal
ולהדר מחדש את ה-Sub-HAL.
אלה ההבדלים בין ממשקי SubHal
בגרסה 2.0 לבין הגרסה 2.1:
- ב-
IHalProxyCallback
נעשה שימוש בסוגי הנתונים שנוצרו בגרסה 2.1 של מפרטISensors.hal
. - הפונקציה
initialize()
מעבירהIHalProxyCallback
חדש במקום זה שממשקSubHal
2.0 מעביר - רכיבי Sub-HAL חייבים להטמיע את
getSensorsList_2_1
ואתinjectSensorData_2_1
במקום אתgetSensorsList
ואתinjectSensorData
, כי ב-methods האלה נעשה שימוש בסוגים החדשים שנוספו בגרסה 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
לחיישנים HAL 2.0 יש פונקציה אתחול שמאפשרת לשירות החיישן לעבור אותות FMQ וקריאה חוזרת (callback) של חיישן דינמי. בחיישן Multi-HAL 2.0, הפונקציה initialize()
מעבירה קריאה חוזרת (callback) יחידה שמשמשת לפרסום אירועים של חיישנים, לקבלת חסימות מצב שינה ולשליחת התראות לגבי חיבור וניתוקים דינמיים של החיישנים.
פרסום אירועים של חיישנים בהטמעת Multi-HAL
במקום לפרסם אירועי חיישנים דרך ה-FMQ, תת-ה-HAL חייב לכתוב אירועי חיישנים ב-IHalProxyCallback
כשאירועי החיישנים זמינים.
אירועי WAKE_UP
ב-Sensors HAL 2.0, ה-HAL יכול לנהל את נעילת ההתעוררות להטמעה שלו. ב-Sensors Multi-HAL 2.0, ממשקי ה-HAL המשניים מאפשרים להטמעת ה-Multi-HAL לנהל את חסימות מצב השינה, והם יכולים לבקש חסימה של מצב השינה באמצעות קריאה ל-createScopedWakelock
.
כשמפרסמים אירועי יציאה ממצב שינה בהטמעה של Multi-HAL, צריך לרכוש חסימת מצב שינה בהיקף נעול ולהעביר אותה ל-postEvents
.
חיישנים דינמיים
לחיישנים 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
.
כשמפרסמים אירועי יציאה ממצב שינה בהטמעה של Multi-HAL, צריך לרכוש חסימת מצב שינה בהיקף נעול ולהעביר אותה ל-postEvents
.
חיישנים דינמיים
בחיישן HAL 1.0, החיישנים הדינמיים מוחזרים דרך הפונקציה poll()
.
לחיישנים Multi-HAL 2.0 נדרשת קריאה ל-onDynamicSensorsConnected
ול-onDynamicSensorsDisconnected
ב-IHalProxyCallback
בכל פעם שיש שינוי בחיבורי החיישנים הדינמיים. פונקציות הקריאה החוזרת האלה זמינות כחלק מהצבען IHalProxyCallback
שסופק באמצעות הפונקציה initialize()
.
יציאה מחיישנים 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 1.0.
- פועלים לפי שלבים 3 ו-4 בסעיף הטמעת חיישנים Mutli-HAL 2.0 כדי להגדיר את Sensors Multi-HAL 2.0 כ-HAL הייעודי.
אימות
הפעלת VTS
אחרי שתשלבו תת-HAL אחד או יותר עם חיישנים Multi-Hal 2.1, תוכלו להשתמש בחבילת הבדיקה של הספק (VTS) כדי לוודא שהטמעות המשנה מסוג HAL עומדות בכל הדרישות של ממשק ה-HAL של החיישנים.
כדי להריץ רק את בדיקות 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
אם מפעילים את שכבת AIDL Multi-HAL shim, מריצים את VtsAidlHalSensorsTargetTest
.
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsAidlHalSensorsTargetTest
הרצת בדיקות יחידה (unit testing)
בדיקות היחידה ב-HalProxy_test.cpp
בודקות את HalProxy
באמצעות HAL משניים מזויפים שנוצרים בבדיקה היחידה ולא נטענים באופן דינמי. כשיוצרים תת-HAL חדש, הבדיקות האלה צריכות לשמש כמדריך להוספה של בדיקות יחידה (unit testing) כדי לאמת ש-Sub-HAL החדש הוטמע כראוי.
כדי להריץ את הבדיקות, מריצים את הפקודות הבאות:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
בדיקה באמצעות תהליכי משנה מזויפים
דפי המשנה המזויפים הם יישומי דמה של הממשק של ISensorsSubHal
.
ממשקי ה-HAL המשניים חושפים רשימות שונות של חיישנים. כשהחיישנים מופעלים, הם מפרסמים מדי פעם אירועי חיישנים שנוצרו באופן אוטומטי ב-HalProxy
, על סמך המרווחים שצוינו בבקשה נתונה של חיישן.
אפשר להשתמש ב-HALs המשניים המזויפים כדי לבדוק איך הקוד המלא של Multi-HAL פועל עם HALs משניים אחרים שנטענים למערכת, וכדי להפעיל לחץ על היבטים שונים של הקוד של Multi-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
ומשימות המשנה שלו מיוצא לטרמינל. בהמשך מוצגת דוגמה לפלט של הפקודה לגבי האובייקט 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 או יותר), המשמעות היא שיש הרבה אירועים בהמתנה לכתיבה למסגרת החיישנים. הסטטוס הזה מציין ששירות החיישן נעול
אם מספר ההפניות של נעילת ההתעוררות גדול מ-0
, סימן ש-HalProxy
השיג נעילת התעוררות. הערך הזה צריך להיות גדול מ-0
רק אם ScopedWakelock
מוחזק באופן מכוון או אם אירועי יציאה ממצב שינה נשלחו אל HalProxy
ולא עברו עיבוד על ידי מסגרת החיישן.
מתאר הקובץ שמועבר לשיטת ניפוי הבאגים של HalProxy
מועבר לכל תת-HAL, כך שהמפתחים צריכים להטמיע את שיטת ניפוי הבאגים כחלק מהממשק ISensorsSubHal
.