ממשק VHAL

ממשק AIDL VHAL מוגדר ב-android.hardware.automotive.vehicle namespace. ממשק VHAL מוגדר בכתובת IVehicle.aidl. אלא אם צוין אחרת, צריך להטמיע את כל השיטות עבור גרסה ספציפית של VHAL.

גרסאות

גרסת Android הגרסה העדכנית ביותר של VHAL הגרסה האחרונה של מאפיין VHAL הגרסה המינימלית התואמת של VHAL
Android 16 V4 V4 גרסה 1
Android 15 V3 V3 גרסה 1
Android 14 V2 V2 גרסה 1
Android 13 גרסה 1 (ממשק המאפיינים של VHAL לא מפוצל) גרסה 1

מומלץ להטמיע את הגרסה האחרונה של VHAL לגרסה ספציפית של Android.

פונקציות וקריאות חוזרות

הפונקציות של VHAL מוגדרות בכתובת IVehicle.aidl.

שיטה
VehiclePropConfigs getAllPropConfigs()
מחזירה רשימה של כל הגדרות הנכס שנתמכות על ידי HAL של הרכב הזה.
VehiclePropConfigs getPropConfigs(in int[] props)
מחזירה רשימה של הגדרות נכס עבור מזהי נכסים נתונים.
void getValues(IVehicleCallback callback, in GetValueRequests requests)
אחזור ערכי מאפייני הרכב באופן אסינכרוני. מטפלת באצווה של GetValueRequest באופן אסינכרוני. התוצאה מועברת באמצעות שיטת הקריאה החוזרת onGetValues.
void setValues(IVehicleCallback callback, in SetValueRequests requests)
הגדרה של ערכי מאפייני הרכב באופן אסינכרוני. מטפלת בקבוצה של SetValueRequest באופן אסינכרוני. התוצאה מועברת באמצעות שיטת הקריאה החוזרת onSetValues.
void subscribe(in IVehicleCallback callback, in SubscribeOptions[] options, int maxSharedMemoryFileCount)
הרשמה לאירועים בנכס עם אפשרויות שצוינו. אפשרויות המינוי כוללות את מזהה הנכס, מזהה האזור של הנכס וקצב הדגימה בהרץ (לנכס רציף). לא נעשה שימוש ב-maxSharedMemoryFileCount.
void unsubscribe(in IVehicleCallback callback, in int[] propIds)
מבטל את ההרשמה לאירועים של נכסים שנרשמו אליהם בעבר, עבור נכסים שצוינו.
returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId)
לא נעשה שימוש בשיטה הזו, ואפשר להטמיע אותה כפעולה שלא עושה כלום.
(חדש ב-Android 16)
SupportedValuesListResults getSupportedValuesLists(in List propIdAreaIds)
מקבל את רשימות הערכים הנתמכים עבור זוגות של מזהה נכס ומזהה אזור שצוינו.
הוצג ב-VHAL V4.
‫(חדש ב-Android 16)
MinMaxSupportedValueResults getMinMaxSupportedValue(in List propIdAreaIds)
מקבל את הערכים המינימליים והמקסימליים הנתמכים עבור זוגות של מזהה מאפיין ומזהה אזור שצוינו.
הוצג ב-VHAL V4.
void registerSupportedValueChangeCallback(in IVehicleCallback callback, in List propIdAreaIds)
רושם קריאה חוזרת (callback) שתופעל כשהערכים הנתמכים ישתנו.
הוצג ב-VHAL V4.
void unregisterSupportedValueChangeCallback(in IVehicleCallback callback, in List propIdAreaIds)
ביטול הרישום של הקריאה החוזרת (callback) לשינוי ערך נתמך.
הוצג ב-VHAL V4.

הפונקציות ל-callback מוגדרות ב-IVehicleCallback.aidl והן כוללות את ה-methods האלה.

שיטה
oneway void onGetValues(in GetValueResults responses)
פונקציית קריאה חוזרת עבור הפונקציה getValues להעברת תוצאות של קבלת ערך. הפונקציה נקראת כשאחד מהערכים לאחזור מוכן.
oneway void onSetValues(in SetValueResults responses)
פונקציית התקשרות חזרה לsetValues כדי להעביר תוצאות של ערך מוגדר. הפונקציה נקראת כש-VHAL מסיים לטפל בחלק מהבקשות להגדרת מאפיינים.
oneway void onPropertyEvent(in VehiclePropValues propValues, int sharedMemoryFileCount)
פונקציית Callback לדיווח על אירועי עדכון של נכסים.
בנכס CONTINUOUS, אירוע בנכס מתרחש על סמך קצב הדגימה של המינוי בהרץ או תדירות ההודעות באוטובוס של הרכב. אירוע בנכס יכול לקרות גם אם הסטטוס של הנכס משתנה. לדוגמה, מ'לא זמין' ל'זמין'.
במאפיין ON_CHANGE, אירוע של מאפיין מתרחש כשערך של מאפיין או הסטטוס של מאפיין משתנים.
המאפיין הזה צריך לשמש גם להעברת אירועים של שינוי סטטוס הנכס. לדוגמה, אם הנכס הופך ללא זמין או שיש שגיאה בקריאה שלו, צריך להעביר VehiclePropValue עם סטטוס לא זמין או שגיאה וערך ריק.
SharedMemoryFileCount תמיד 0.
oneway void onPropertySetError(in VehiclePropErrors errors)
Callback for reporting asynchronous property set errors that have no corresponding set request. אם אנחנו יודעים לאיזו בקשת הגדרה השגיאה מתייחסת, צריך להשתמש ב-onSetValues עם תוצאת שגיאה במקום בשיטה הזו.
oneway void onSupportedValueChange(in List propIdAreaIds)
קריאה חוזרת לדיווח על שינויים בערך המינימלי והמקסימלי הנתמך או ברשימת הערכים הנתמכים. המתקשר אמור להתקשר אל getMinMaxSupportedValue או אל getSupportedValuesLists כדי לקבל את הערכים המעודכנים.

ההטמעה של VHAL מאומתת על ידי VHAL VTS בכתובת VtsHalAutomotiveVehicle_TargetTest.cpp.

הבדיקה מוודאת שהשיטות הבסיסיות הוטמעו בצורה נכונה ושההגדרות של הנכס הנתמך נכונות. הבדיקה מופעלת מול כל המופעים של VHAL במכשיר, אבל AAOS משתמש רק במופע ברירת המחדל (android.hardware.automotive.vehicle.IVehicle/default)

ערך מאפיין הרכב

משתמשים במבנה VehiclePropValue כדי לתאר את הערך של כל מאפיין, שכולל את השדות הבאים:

שדה תיאור
timestamp חותמת הזמן שמייצגת את השעה שבה האירוע קרה, ומסונכרנת עם השעון של SystemClock.elapsedRealtimeNano().
prop מזהה הנכס של הערך הזה.
areaid מזהה האזור של הערך הזה. האזור צריך להיות אחד מהאזורים הנתמכים שמופיעים בהגדרת מזהה האזור, או 0 עבור נכסים גלובליים.
value מבנה נתונים שמכיל את הערך בפועל של המאפיין. בהתאם לסוג הנכס, שדה אחד או יותר בשדה הזה משמשים לאחסון הערך בפועל. לדוגמה, הרכיב הראשון ב-value.int32Values משמש למאפיינים מסוג Int32. פרטים נוספים מופיעים במאמר בנושא הגדרות של נכסים.
status הסטטוס של הנכס לקריאה. במאפיין read/write, יכול להיות שההגדרה הזו תחול גם על כתיבה, אבל זה לא מובטח. לדוגמה, יכול להיות שהמאפיין יהיה זמין לקריאה אבל לא לכתיבה. במקרה כזה, הסטטוס הוא AVAILABLE ושדה הערך מכיל מידע תקין. לרשימת הסטטוסים האפשריים, ראו VehiclePropertyStatus.

הפונקציות האסינכרוניות getValues ו-setValues

הפעולות getValues ו-setValues מתבצעות באופן אסינכרוני, כלומר הפונקציה עשויה להחזיר ערך לפני שהפעולה בפועל של קבלת או הגדרת הערך הושלמה. תוצאות הפעולה (לדוגמה, ערך הנכס של getValues או סטטוס ההצלחה או השגיאה של setValues) מועברות באמצעות פונקציות הקריאה החוזרת שמועברות כארגומנטים.

ההטמעה לא יכולה לחסום את התוצאה בשרשור של ה-binder שמטפל בבקשה. במקום זאת, מומלץ לאחסן את הבקשה בתור בקשות ולהשתמש בשרשור נפרד של handler כדי לטפל בבקשות באופן אסינכרוני. פרטים נוספים זמינים במאמר בנושא הטמעה לדוגמה.

איור 1. תהליך אסינכרוני.

‫parcelable גדולים

כל המבנים שנקראים XXXs, כמו VehiclePropConfigs,‏ SetValueRequests ו-VehiclePropValues, נקראים LargeParcelable (או StableLargeParcelable). כל אחד מהם מייצג רשימה של ערכים שמשמשים להעברת נתונים גדולים שעשויים לחרוג מהמגבלות של Binder (4KB בהטמעה של ספריית LargeParcelable) בין גבולות Binder. לכל אחד מהם יש הגדרת מבנה דומה שכוללת את השדות הבאים.

הדרכה תיאור
payloads רשימת ערכים אם גודל הערך מתאים למגבלת הזיכרון של הקלסר, או רשימה ריקה.
sharedMemoryFd מתאר קובץ שניתן לאפס שמצביע על קובץ זיכרון משותף שמאחסן את המטען הייעודי (payload) שעבר סריאליזציה אם רשימת הערכים גדולה מדי.

לדוגמה, VehiclePropConfigs מוגדר כך:

parcelable VehiclePropConfigs {
    // The list of vehicle property configs if they fit the binder memory
    // limitation.
    VehiclePropConfig[] payloads;
    // Shared memory file to store configs if they exceed binder memory
    // limitation. Created by VHAL, readable only at client. Client could keep
    // the fd opened or keep the FD mapped to access configs.
    @nullable ParcelFileDescriptor sharedMemoryFd;
}

VehiclePropConfigs מכיל מטען ייעודי (payload) לא ריק או sharedMemoryFd שאינו null.

  • אם payloads לא ריק, הוא מאחסן רשימה של הנתונים בפועל, שהם הגדרות הנכס.
  • אם sharedMemoryFd לא ריק, הוא מכיל קובץ של זיכרון משותף, שבו מאוחסנת הסדרה של המבנה של VehiclePropConfigs. המבנה משתמש בפונקציה writeToParcel כדי לבצע סריאליזציה של Parcel.

בתור לקוח Java של VHAL, ‏ Car Service מטפל בסריאליזציה ובדה-סריאליזציה של LargeParcelable. ביישומים של VHAL ובלקוחות מקומיים, צריך לבצע סריאליזציה ודה-סריאליזציה של LargeParcelable באמצעות הספרייה LargeParcelable או מחלקת wrapper שימושית לספרייה ב-ParcelableUtils.h.

לדוגמה, לקוח מקורי שמנתח בקשות ל-getValues שמתקבלות מ-binder:

// 'requests' are from the binder.
GetValueRequests requests;
expected<LargeParcelableBase::BorrowedOwnedObject, ScopedAStatus> deserializedResults = fromStableLargeParcelable(requests);
if (deserializedResults.ok()) {
    const std::vector& getValueRequests = deserializedResults.value().getObject()->payloads;
    // Use the getValueRequests.
  } else {
    // handle error.
}

בדוגמה הבאה מוצגת הטמעה של VHAL ששולחת תוצאות עבור getValues דרך ה-binder:

std::vector results = getResults();
GetValueResults parcelableResults;
ScopedAStatus status = vectorToStableLargeParcelable(std::move(results), &parcelableResults);
if (status.isOk()) {
    // Send parcelableResults through callback.
} else {
    // Handle error.
}