Sensors Multi-HAL

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

‫Sensors Multi-HAL 2.1, שזמין במכשירים עם Android 11 ומעלה, הוא איטרציה של Sensors Multi-HAL 2.0 שתומכת בטעינת רכיבי HAL משניים שיכולים לחשוף את סוג חיישן זווית הציר. כדי לתמוך בסוג החיישן הזה, ממשקי sub-HAL צריכים להשתמש בממשקי sub-HAL API שמוגדרים בכותרת 2.1 SubHal.

במכשירים עם Android מגרסה 13 ואילך שמשתמשים ב-Sensors AIDL HAL, אפשר להשתמש בשכבת ה-shim של multi-HAL כדי לאפשר יכולת multi-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.
  • ב-Sub-HALs צריך להטמיע פונקציית ניפוי באגים כדי לספק מידע על ניפוי באגים בדוחות על באגים.
  • ב-sub-HALs צריך להטמיע פונקציית שם כדי שאפשר יהיה להבחין בין sub-HALs שנטענו לבין sub-HALs אחרים.

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

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

קוד מקור ויישום לדוגמה

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

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

הטמעה

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

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

כדי לאפשר יכולת Multi-HAL עם חיישני AIDL HAL, צריך לייבא את מודול שכבת ה-shim של AIDL Multi-HAL, שנמצא ב-hardware/interfaces/sensors/aidl/default/multihal/. המודול מטפל בהמרה בין סוגי ההגדרות של חיישני HAL של AIDL ו-HIDL, ומגדיר עטיפה סביב ממשק ה-multi-HAL שמתואר במאמר הטמעה של חיישני multi-HAL 2.1. שכבת ה-shim של AIDL multi-HAL תואמת למכשירים שמטמיעים את Sensors Multi-HAL 2.1.

שכבת ה-shim של AIDL multi-HAL מאפשרת לכם לחשוף את סוגי החיישנים של מעקב תנועות הראש ושל IMU עם צירים מוגבלים ב-Sensors AIDL HAL. כדי להשתמש בסוגי החיישנים האלה שמוגדרים בממשק AIDL HAL, צריך להגדיר את השדה type במבנה SensorInfo בהטמעה של getSensorsList_2_1(). הפעולה הזו בטוחה כי שדות סוג החיישן שמגובים במספרים של AIDL ו-HIDL sensors HAL לא חופפים.

הטמעה של Sensors Multi-HAL 2.1

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

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

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

    דוגמה לרשומה Android.bp ליצירת ספריית sub-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 מתחיל, מחפש את ה-sub-HAL החדש ומאתחל אותו על ידי קריאה ל-sensorsHalGetSubHal_2_1.

העברה של יציאה מ-Sensors Multi-HAL 2.0 ל-Multi-HAL 2.1

כדי לבצע העברה מ-Multi-HAL 2.0 ל-Multi-HAL 2.1, מטמיעים את הממשק SubHal ומקמפלים מחדש את ה-sub-HAL.

אלה ההבדלים בין ממשקי 2.0 ו-2.1 של SubHal:

  • IHalProxyCallback משתמש בסוגים שנוצרו בגרסה 2.1 של מפרט ISensors.hal.
  • הפונקציה initialize() מעבירה IHalProxyCallback חדש במקום זה מהממשק של 2.0 SubHal
  • מודולי Sub-HAL צריכים להטמיע את getSensorsList_2_1 ואת injectSensorData_2_1 במקום את getSensorsList ואת injectSensorData, כי השיטות האלה משתמשות בסוגים החדשים שנוספו בגרסה 2.1 של מפרט ISensors.hal.
  • ממשקי HAL משניים צריכים לחשוף את sensorsHalGetSubHal_2_1 ולא את sensorsHalGetSubHal כדי שממשק Multi-HAL יתייחס אליהם כממשקי HAL משניים בגרסה 2.1.

העברה מ-Sensors HAL 2.0

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

אתחול ה-HAL

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

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

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

אירועי WAKE_UP

ב-Sensors HAL 2.0, ‏ HAL יכול לנהל את נעילת ההפעלה של ההטמעה שלו. ב-Sensors Multi-HAL 2.0, רכיבי ה-sub-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

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

חשיפה של חיישנים זמינים

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

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

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

אירועי WAKE_UP

ב-Sensors HAL 1.0, ‏ HAL יכול לנהל את נעילת ההשכמה לצורך ההטמעה שלו. ב-Sensors Multi-HAL 2.0,‏ ה-sub-HALs מאפשרים להטמעה של 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, פועלים לפי השלבים הבאים.

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

אימות

הפעלת VTS

אחרי שמשלבים HAL משני אחד או יותר עם Sensors Multi-Hal 2.1, צריך להשתמש ב-Vendor Test Suite (VTS) כדי לוודא שההטמעות של ה-HAL המשני עומדות בכל הדרישות שמוגדרות בממשק Sensors 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

אם מריצים את שכבת ה-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

בדיקה באמצעות רכיבי ה-HAL המדומים

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

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

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

כדי ליצור ולדחוף את ה-HAL המשני המזויף למכשיר:

  1. מריצים את הפקודות הבאות כדי ליצור ולדחוף את שלושת רכיבי המשנה המזויפים של 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
  2. מעדכנים את ההגדרה של חיישני 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
    
  3. מפעילים מחדש את HalProxy וטוענים את רכיבי ה-sub-HAL החדשים שמופיעים בהגדרות.

    adb shell stop
    adb shell start

ניפוי באגים

מפתחים יכולים לנפות באגים במסגרת באמצעות הפקודה lshal. כדי לבקש את פלט הניפוי באגים של Sensors HAL, מריצים את הפקודה הבאה:

adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default

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

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

אם מספר ההפניות לחסימת מצב שינה גדול מ-0, המשמעות היא ש-HalProxy קיבל חסימת מצב שינה. הערך הזה צריך להיות גדול מ-0 רק אם ScopedWakelock מתבצעת החזקה מכוונת או אם אירועי התעוררות נשלחו אל HalProxy ולא עברו עיבוד על ידי מסגרת החיישנים.

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