Sensors Multi-HAL

‏Sensors Multi-HAL הוא מסגרת שמאפשרת ל-HAL של חיישנים לפעול לצד HAL של חיישנים אחרים. ‏Sensors Multi-HAL טוען באופן דינמי HAL משני של חיישנים שנשמרים כספריות דינמיות במחיצה של הספק, ומספק להם אובייקט קריאה חוזרת (callback) שיכול לטפל בפרסום אירועים ובקבלה וביטול של נעילת ההתעוררות. תת-HAL של חיישנים הוא ממשק אנושי (HAL) של חיישנים המובנה באובייקט משותף של ספק מסוים, והוא נמצא בשימוש של מסגרת multi-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. לפרטים על ההטמעה: לראות שימוש בחיישנים מסוג Multi-HAL עם החיישנים AIDL HAL.

ההבדל בין חיישנים Multi-HAL 2 לחיישנים HAL 2

חיישנים Multi-HAL 2, זמינים במכשירים עם מערכת Android 10 ומעלה, מציג כמה פשטות בנוסף לחיישן 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.
  • רכיבי Sub-HAL חייבים להטמיע פונקציית ניפוי באגים לניפוי באגים מידע בדוחות איתור באגים.
  • יש להטמיע פונקציית שם ב-HAL משני כדי שאפשר יהיה להבדיל בין ה-HAL המשני שנטען לבין HAL משני אחר.

ההבדל העיקרי בין Sensors Multi-HAL 2 לבין Sensors HAL 2 הוא בפונקציות ההפעלה. במקום לספק FMQs, הממשק IHalProxyCallback מספק שתי שיטות: שיטה אחת לפרסום אירועי חיישנים למסגרת החיישנים, ושיטה אחת ליצירת נעילת התעוררות (wake lock). מתחת לפני השטח, ה-Multi-HAL של חיישנים מנהל את כל האינטראקציות עם ה-FMQ כדי להבטיח העברה בזמן של אירועי חיישנים לכל ה-HAL המשניים. מומלץ מאוד שכלי משנה ל-HAL ישתמשו שיטה createScopedWakelock להאציל את הנטל של תזמון חסימות מצב שינה אל באמצעות החיישנים עם מולטי HAL, וניתן לרכז את השימוש בחסימות מצב שינה באמצעות התכונה 'נעילת מצב שינה' משותפת לחיישן Multi-HAL כולו, שמצמצם שיחות נעילה וביטול נעילה.

ב-Sensors Multi-HAL 2 יש גם כמה תכונות בטיחות מובנות. הוא מטפל במצבים שבהם ה-FMQ של החיישן מלא, או במצבים שבהם מסגרת החיישן של Android מופעלת מחדש ויש צורך לאפס את מצב החיישן. בנוסף, כשאירועים מפורסמים בכיתה HalProxy אבל מסגרת החיישן לא יכולה לקבל את האירועים באופן מיידי, ה-Sensors Multi-HAL יכול להעביר את האירועים לשרשור רקע כדי לאפשר את המשך העבודה בכל ה-HAL המשניים בזמן ההמתנה לפרסום האירועים.

קוד מקור והטמעת הפניה

קוד מרובה HAL של כל החיישנים זמין hardware/interfaces/sensors/common/default/2.X/multihal/ ריכזנו כאן כמה מקורות מידע.

  • HalProxy.h: האובייקט HalProxy נוצר באמצעות חיישנים מרובי-HAL ומטפל העברת נתונים מתת-ה-HAL למסגרת החיישן.
  • HalProxy.cpp: ההטמעה של HalProxy מכילה את כל הלוגיקה הנדרשת למולטיפלקס של התקשורת בין ממשקי HAL משניים לבין מסגרת החיישן.
  • SubHal.h: הממשק ISensorsSubHal מגדיר את הממשק ש-HAL משניים חייבים לפעול לפיו כדי להיות תואם ל-HalProxy. מודול המשנה HAL מיישם את מתחילה את ה-method כדי שיהיה אפשר להשתמש באובייקט 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/: בדוגמה הזו להטמעה של Sub-HAL נעשה שימוש בחיישנים מזויפים כדי ליצור . שימושי לבדיקת האינטראקציה של מספר תתי-פלטפורמות של HAL במכשיר.

הטמעה

בקטע הזה מתואר איך להטמיע חיישנים Multi-HAL בסעיפים הבאים מצבים:

שימוש ב-Sensors Multi-HAL עם Sensors AIDL HAL

כדי לאפשר יכולות מרובות HAL עם החיישנים AIDL HAL, צריך לייבא את הפונקציה AIDL מודול שכבת shim מרובה-HAL, שנמצא hardware/interfaces/sensors/aidl/default/multihal/. המודול מטפל בהמרה שבין חיישני AIDL ו-HIDL להגדרות HAL ומגדיר wrapper במסגרת ממשק ריבוי HAL שמתואר הטמעת חיישנים 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 לא חופפים.

הטמעת חיישנים עם Multi-HAL 2.1

כדי להטמיע את Sensors Multi-HAL 2.1 במכשיר חדש, פועלים לפי השלבים הבאים:

  1. הטמעת הממשק של ISensorsSubHal כפי שמתואר ב SubHal.h.
  2. ליישם את sensorsHalGetSubHal_2_1 ב-SubHal.h.
  3. צריך להוסיף יעד cc_library_shared כדי ליצור את תת-ה-HAL החדש שהוטמע. כשמוסיפים את היעד:

    1. מוודאים שהיעד נדחף למקום כלשהו בספק למחיצה של המכשיר.
    2. בקובץ התצורה שנמצא בכתובת /vendor/etc/sensors/hals.conf, להוסיף את הנתיב לספרייה בשורה חדשה. אם צריך, יוצרים את הקובץ hals.conf.

    לדוגמה של רשומה Android.bp ליצירת ספריית HAL משנית, ראו hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp.

  4. מסירים את כל הרשומות של android.hardware.sensors מהקובץ manifest.xml, שמכיל את רשימת ה-HAL הנתמכים במכשיר.

  5. הסרת כל שירות 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.
  • רכיבי Sub-HAL חייבים לחשוף את sensorsHalGetSubHal_2_1 במקום sensorsHalGetSubHal ל-Multi-HAL כדי להתייחס אליהם כמו לגרסה 2.1 תמיכה ב-HAL.

יציאה מחיישנים HAL 2.0

כשמשדרגים ל-Sensors Multi-HAL 2.0 מ-Sensors HAL 2.0, חשוב לוודא שההטמעה של HAL עומדת בדרישות הבאות.

אתחול HAL

ל-Sensors HAL 2.0 יש פונקציית הפעלה שמאפשרת לשירות החיישן להעביר FMQs וקריאה חוזרת דינמית של חיישן. ב-חיישנים Multi-HAL 2.0, הפונקציה initialize() מעבירה קריאה חוזרת אחת (callback) שצריך להשתמש בה כדי לפרסם אירועי חיישנים, קבלת חסימות מצב שינה, והתראה על חיבור חיישן דינמי בזמן ניתוקים.

פרסום אירועים של חיישנים בהטמעת Multi-HAL

במקום לפרסם אירועי חיישנים דרך FMQ, תת-HAL צריך לכתוב אירועי חיישנים ב-IHalProxyCallback כשאירועי חיישנים זמינים.

אירועי WAKE_UP

בחיישן HAL 2.0, טכנולוגיית HAL יכולה לנהל את התכונה 'נעילת מצב שינה' לצורך הטמעה. לחשבון באמצעות חיישנים Multi-HAL 2.0, תתי-ה-HAL מאפשרים להטמעה של Multi-HAL לנהל חסימות מצב שינה ולבקש נעילת מצב שינה על ידי הפעלה createScopedWakelock יש לרכוש חסימת מצב שינה בהיקף נעול ולהעביר אותה אל postEvents כאשר פרסום אירועי יציאה ממצב שינה בהטמעה של Multi-HAL.

חיישנים דינמיים

ב-Sensors Multi-HAL 2.0 נדרש לקרוא לפונקציות onDynamicSensorsConnected ו-onDynamicSensorsDisconnected ב-IHalProxyCallback בכל פעם שמתבצע שינוי בחיבורי החיישנים הדינמיים. פונקציות הקריאה החוזרת האלה זמינות כחלק מהצבען IHalProxyCallback שסופק באמצעות הפונקציה initialize().

יציאה מחיישנים HAL 1.0

כשמשדרגים לחיישן Multi-HAL 2.0 מ-Sensors HAL 1.0, יש לוודא שתקן HAL שעומד בדרישות הבאות.

אתחול HAL

צריכה להיות תמיכה בפונקציה initialize() כדי ליצור את הקריאה החוזרת בין HAL המשני לבין הטמעת ה-Multi-HAL.

חשיפת חיישנים זמינים

ב-Sensors Multi-HAL 2.0, הפונקציה getSensorsList() חייבת להחזיר את אותו ערך במהלך הפעלה יחידה של המכשיר, גם במהלך הפעלות מחדש של HAL של חיישנים. כך אפשר המסגרת בניסיון ליצור מחדש חיבורי חיישן, אם שרת המערכת מופעלת מחדש. הערך שמוחזר על ידי getSensorsList() יכול להשתנות אחרי שהמכשיר מבצע הפעלה מחדש.

פרסום אירועים של חיישנים בהטמעת Multi-HAL

בגרסה HAL 2.0 של החיישנים, במקום להמתין לקריאת poll(), אפשר לתת ל-Sub-HAL חייבים לכתוב באופן יזום אירועי חיישנים IHalProxyCallback בכל פעם שאירועי חיישן זמינים.

אירועי WAKE_UP

בחיישן HAL 1.0, מדד HAL יכול לנהל את התכונה 'נעילת מצב שינה' לצורך הטמעה. ב-Sensors Multi-HAL 2.0, ממשקי ה-HAL המשניים מאפשרים להטמעת ה-Multi-HAL לנהל את החסימות של מצב השינה, והם יכולים לבקש חסימה של מצב השינה באמצעות קריאה ל-createScopedWakelock. יש לרכוש חסימת מצב שינה בהיקף נעול ולהעביר אותה אל postEvents כאשר פרסום אירועי יציאה ממצב שינה בהטמעה של Multi-HAL.

חיישנים דינמיים

ב-Sensors HAL 1.0, חיישנים דינמיים מוחזרים דרך הפונקציה poll(). לחיישנים Multi-HAL 2.0 נדרשת התאמה של onDynamicSensorsConnected ושל onDynamicSensorsDisconnected אינץ' IHalProxyCallback מופעלות בכל פעם שחיבורי החיישנים הדינמיים משתנים. פונקציות הקריאה החוזרת האלה זמינות כחלק מהצבען IHalProxyCallback שסופק באמצעות הפונקציה initialize().

יציאה מחיישנים Multi-HAL 1.0

כדי להעביר הטמעה קיימת מ-Sensors Multi-HAL 1.0, פועלים לפי השלבים הבאים.

  1. צריך לוודא שהגדרת ה-HAL של החיישנים ממוקמת ב /vendor/etc/sensors/hals.conf יכול להיות שתצטרכו להעביר את הקובץ שנמצא ב-/system/etc/sensors/hals.conf.
  2. מסירים כל התייחסות ל-hardware/hardware.h ול-hardware/sensors.h, כי אין תמיכה בהם ב-HAL 2.0.
  3. שקעי משנה של יציאות כפי שמתואר במאמר ניוד מחיישנים עם האלר 1.0.
  4. מגדירים את Sensors Multi-HAL 2.0 כ-HAL הייעודי לפי השלבים 3 ו-4 בקטע הטמעת Sensors Mutli-HAL 2.0.

אימות

הפעלת 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 הוטמעה כראוי.

כדי להריץ את הבדיקות, מריצים את הפקודות הבאות:

cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest

בדיקה עם HALs משניים מזויפים

דפי המשנה המזויפים הם יישומי דמה של הממשק של ISensorsSubHal. תתי-ה-HAL חושפות רשימות שונות של חיישנים. כשהחיישנים מופעלים, הם מפרסמים מדי פעם אירועי חיישנים שנוצרו באופן אוטומטי ב-HalProxy, על סמך המרווחים שצוינו בבקשה נתונה של חיישן.

אפשר להשתמש ב-Sub-HAL המזויפים כדי לבדוק איך קוד Multi-HAL המלא פועל עם תת-נושאים אחרים שנטענות במערכת וכדי להדגיש היבטים שונים של קוד Multi-HAL מחיישנים.

שני תהליכי משנה מזויפים זמינים בכתובת hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/

כדי ליצור ולדחוף הודעות משנה מזויפות למכשיר, מבצעים את השלבים הבאים:

  1. מריצים את הפקודות הבאות כדי ליצור ולדחוף את שלושת הצורות המזויפות השונות השלמת פעולות משנה למכשיר:

    $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
  2. עדכון הגדרת HAL של החיישנים ב-/vendor/etc/sensors/hals.conf עם את הנתיבים של תוכניות המשנה המזויפות.

    /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
    
  3. צריך להפעיל מחדש את HalProxy ולטעון את רכיבי המשנה החדשים המפורטים בהגדרה.

    adb shell stop
    adb shell start

ניפוי באגים

מפתחים יכולים לנפות באגים ב-framework באמצעות הפקודה 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 ולא עברו עיבוד על ידי מסגרת החיישן.

מתאר הקובץ שמוענק לשיטת ניפוי הבאגים של HalProxy מועבר לכל HAL משני, ולכן המפתחים צריכים להטמיע את שיטת ניפוי הבאגים כחלק מהממשק ISensorsSubHal.