שירותי פלאגין חדשים של יצרני רכב ב-Android 14 מאפשרים להגדיר רכיבים מסוימים ברכב. בנוסף, הוספנו שלושה שירותי פלאגין חדשים שמאפשרים ליצרני ציוד מקורי (OEM) להגדיר בצורה גמישה את ניהול האודיו במכשירי AAOS:
- שליטה בהרשאת אודיו
- שליטה בעוצמת הקול והשתקה
- הנמכה של עוצמת השמע
ארכיטקטורת שירות של פלאגין לרכב
באיור הבא מוצגת סקירה כללית של שירותי הרכב והקשר שלהם לשירות הרכב של יצרן הציוד המקורי (OEM). בדומה לתהליכי האפליקציה ולתהליך שירות הרכב, תהליך שירות הרכב של יצרן הציוד המקורי (OEM) תופס מקום משלו בתהליך.
שירות הרכב מפעיל את שירות הרכב של ה-OEM על ידי איתור הרכיב שמוגדר ב-config_oemCarService
. אם ההגדרה ריקה, שירות ה-OEM לא קיים ולא מופעל שום שירות. הרכיב חייב להרחיב את OemCarService.
שירות האודיו ברכב צריך להחליף את ממשקי ה-API כדי לקבל את שירות האודיו המקורי ברכב:
public final class OemCarServiceImp extends OemCarService {
@Override
public OemCarAudioFocusService getOemAudioFocusService();
@Override
public OemCarAudioDuckingService getOemAudioDuckingService();
@Override
public OemCarAudioVolumeService getOemAudioVolumeService();
}
לדוגמה, אפשר לעיין באפליקציית הבדיקה שמוגדרת במאמר packages/services/Car/tests/OemCarServiceTestApp
.
למרות שהשירות מופעל על ידי שירות הרכב, הוא לא מקבל באופן אוטומטי את ההרשאות שזמינות לשירות האודיו ברכב. לכן, כל הרשאה שנדרשת לשירותי OEM צריכה להתקבל באמצעות המנגנון המתאים. לדוגמה, אפשר לעיין בpackages/services/Car/data/etc/com.android.car.oemcarservice.testapp.xml
.
שירות אודיו לרכב עם ארכיטקטורת שירות OEM
ב-AAOS, שירות האודיו לרכב מנהל את הפעולות האלה:
- ניתוב אודיו
- מיקוד אודיו
- הנמכה של עוצמת השמע
- עוצמת הקול והשתקה
לפני Android 14, ההתנהגות הזו הייתה סטטית ברובה, ואפשר היה לשנות אותה רק דרך ההגדרות, אבל רק במקרים מוגבלים מאוד. ב-Android 14 הושק מנגנון לשירות אודיו לרכב, שמאפשר לו לתקשר עם רכיב שהוגדר על ידי OEM (יצרן ציוד מקורי) ומנהל את הפעולות הבאות:
- מיקוד אודיו
- הנמכה של עוצמת השמע
- עוצמת הקול והשתקה
באיור שלמטה מוצגת ארכיטקטורה פשוטה של שירות האודיו ברכב ושירות יצרן הרכב. שירות האודיו לרכב מגדיר ווים שונים שיכולים להפעיל את שירות האודיו של יצרן הרכב כדי לנהל את התנהגות האודיו. האפשרות השנייה מתרחשת רק אם מוגדר רכיב שירות שמע תואם לרכב של OEM. אחרת, שירות האודיו ברכב ישתמש בהתנהגות ברירת המחדל.
כדי לוודא ששירות האודיו של הרכב ושירות האודיו של יצרן הרכב תמיד מסונכרנים, בכל שיחה שירות האודיו של הרכב מעביר את החלקים הנדרשים של המצב הנוכחי של סטאק האודיו לשירות האודיו של יצרן הרכב. לדוגמה, כששירות האודיו ברכב מיירט בקשה להערכת מיקוד האודיו, הוא מעביר את המצב הנוכחי של הערימה לשירות האודיו של יצרן הציוד המקורי של הרכב. המצב הנוכחי כולל את הרכיב שמחזיק כרגע במיקוד ואת הרכיבים שאיבדו את המיקוד. מצב הריכוז מופעל. הזמן שנותר: .
שירות האודיו ברכב צריך לנהל את כל פעילות האודיו ברכב. אם שירות האודיו של הרכב לא מנהל חלק מההתנהגות של האודיו, המידע שמוצג לשירות האודיו של יצרן הרכב לא מלא. לדוגמה, אם יצרן ציוד מקורי (OEM) מחליף את הטיפול במיקוד האודיו בשירות הרכב על ידי רישום מדיניות מיקוד אודיו משלו, שירות האודיו של הרכב לא יכול לספק מידע מלא לשירות האודיו של יצרן הציוד המקורי של הרכב. הדבר יכול להשפיע על היכולת של שירות האודיו של יצרן הרכב לקבל החלטות, כי יכול להיות שחסר לו מידע שלא גלוי לשירות האודיו של הרכב.
כדי לבצע פעולות, שירות האודיו ברכב קורא לשירותי הרכב של יצרן הציוד המקורי. הקריאות האלה מתבצעות בין תהליכים, ולכן נדרשת תקשורת בין תהליכים (IPC). ה-IPC מוסיף זמן אחזור לכל שיחה. חשוב לצמצם את זמן האחזור בשירות OEM.
בגלל ששיחות שירות של שמע לרכב לשירות OEM חוסמות, שירות OEM לא צריך לקרוא לשירות השמע לרכב בהערכות ישירות של API. במקום זאת, שירות האודיו ברכב מספק את המידע הדרוש כדי שהקריאות בין שני התהליכים יצטרכו לנוע רק בכיוון אחד.
הגדרות של שירותי אודיו לרכב של יצרן ציוד מקורי (OEM)
שירות OEM להרשאת אודיו ברכב
שירות האודיו ברכב מנהל בקשות למיקוד אודיו מאפליקציות על ידי רישום של מאזין למיקוד מדיניות האודיו. לשירות האודיו לרכב יש מנגנון לניהול התנהגות המיקוד שמבוסס על מטריצת אינטראקציה סטטית. המטריצה מגדירה שלושה סוגים שונים של אינטראקציות:
אינטראקציה בו-זמנית. המשתתפים יכולים להישאר ממוקדים בו-זמנית.
אינטראקציות בלעדיות. בקשת פוקוס נכנסת מעבירה את הפוקוס מהאלמנט הנוכחי שמחזיק בפוקוס.
דחיית האינטראקציה הבקשה הנכנסת למיקוד נדחתה על סמך המיקוד הנוכחי.
הפתרון הזה מספיק לחלק מתרחישי השימוש ברכב, אבל הוא לא עונה על כל צורכי האינטראקציה, שיכולים להיות שונים בגלל דרישות של יצרני ציוד מקורי (OEM). לשם כך, אנחנו מציגים את OemCarAudioFocusService
:
public interface OEmCarAudioFocusService {
OemCarAuddioFocusResults evaluateAudioFocusRequest(
OemCarAudioFocusEvaluationRequest request);
void notifyAudioFocusChange(
List<AudioFocusEntry> holder,
List<AudioFocusEntry> losers, int zoneId);
}
הקריאה ל-API evaluateAudioFocusRequest
מתבצעת משירות האודיו ברכב בכל פעם שיש בקשה למיקוד אודיו שצריך להעריך. זהו API דו-כיווני שחוסם את התוצאות עד שהן חוזרות. הבקשה מכילה מידע
על המצב הנוכחי של ערימת האודיו:
אפשר להשתמש במידע הזה כדי להעריך את newFocusRequest
בהשוואה לבעלי המיקוד הנוכחיים ב-focusHolders
ולמי שאיבדו את המיקוד הנוכחי ב-focusLosers
. ה-API אמור להחזיר את התוצאות:
class OemCarAudioFocusResult {
int audioZoneId;
int audioFocusEvaluationResults;
AudioFocusEntry focusResult;
List<AudioFocusEntry> newLosers;
List<AudioFocusEntry> newlyBlocked;
}
השדה הזה מכיל את המידע על תוצאות ההערכה בפועל ב-audioFocusEvaluationResults
, שמציין אם הבקשה הנוכחית אושרה, נדחתה או נכשלה. כל שינוי במערך המיקוד הנוכחי צריך להיות מוגדר בערכים newLosers
ו-newlyBlocked
, בהתאם לאופי השינוי במערך.
כאשר newLosers
מכיל רשומות שהמיקוד היה בהן בעבר, אבל עכשיו המיקוד צריך לעבור מהן, באופן קבוע או זמני. האפליקציות שאיבדו את המיקוד באופן קבוע יוסרו מערימת המיקוד של האודיו, והאפליקציות שאיבדו את המיקוד באופן זמני יועברו לערימת האפליקציות הנוכחית שאיבדו את המיקוד עד שהן יקבלו אותו בחזרה או עד שהן יוסרו מהאפליקציה המקורית שביקשה את המיקוד. בכל מקרה, מאזין המיקוד של הבקשות יקבל מיקוד תואם שאבד.
הרשימה newlyBlocked
מכילה רשומות שהיו קודם ברשימת המפסידים של המיקוד, אבל עכשיו חסומות על ידי הרשומה החדשה. החסימה יכולה להיות קבועה או זמנית. אם החסימה קבועה, הרשומה תוסר מהמחסנית והאירוע focus loss יישלח למאזיני הפוקוס. במקרה של אובדן מיקוד זמני,
הערך יישאר במחסנית של אובדן המיקוד, אבל חוסם מיקוד חדש יתווסף לרשימת החוסמים שלו. לא יישלח אובדן מיקוד כי הוא כבר נשלח כשנחסם בפעם הראשונה. הבקשה תבוטל בסופו של דבר כשהחסימות הנוכחיות יוסרו, או שהיא תוסר מהמחסנית אם הפוקוס יבוטל.
ה-API השני, notifyAudioFocusChange
, הוא חד-כיווני ומופעל בכל בקשה או ביטול של מיקוד אודיו. ה-API משמש בעיקר כדי לעדכן את שירות ה-OEM לגבי שינויים במיקוד, שיכולים להשפיע על ההתנהגות של שירות האודיו לרכב של ה-OEM.
הנחיות להערכת המיקוד
ב-AAOS, התכונה 'מיקוד אודיו' משמשת לניהול השמעת אודיו ולקביעה איזו אפליקציה צריכה לפעול כדי לספק חוויה אופטימלית למשתמש. לכן, שירות הפלאגין של יצרן הציוד המקורי צריך לקחת בחשבון את הדברים הבאים כשמנהלים בקשה למיקוד אודיו:
אם אין לאפליקציה פוקוס אודיו קבוע בעדיפות גבוהה (למשל שיחת טלפון, מקרה חירום או בטיחות), היא צריכה להיות מסוגלת להשיג פוקוס אודיו באופן זמני או קבוע.
בזמן שמצב המיקוד במדיה פעיל, אפליקציות ששולחות בקשות:
ההתמקדות בשימוש בשיחות צריכה להיות כזו שאפשר לקבל התמקדות בו-זמנית או בלעדית.
המיקוד צריך להיות על השימוש בניווט, ואפשר לקבל מיקוד במקביל או באופן בלעדי.
השימוש ב-Assistant צריך להיות ממוקד, והוא צריך להיות מסוגל לקבל מיקוד במקביל או באופן בלעדי.
בזמן שאפליקציות עם עדיפות גבוהה למיקוד אודיו (כמו שיחת טלפון, התראה על מצב חירום או התראה על בטיחות) פעילות, כל בקשה נכנסת למיקוד אודיו מושהה צריכה לקבל אישור או להידחות לפי הצורך.
ההצעות שלמעלה לא ממצות את כל האפשרויות, אבל הן יכולות לעזור להבטיח שאפליקציות שמבקשות להתמקד יוכלו להתמקד כשאין צלילים פעילים בעדיפות גבוהה. גם בזמן שצלילים בעדיפות גבוהה פעילים, צריך לכבד בקשות להשהיית המיקוד ולאפשר להשיג מיקוד אחרי שהצליל בעדיפות גבוהה מפסיק.
שירות עוצמת קול לרכב OEM
שירות האודיו ברכב מנהל אירועים של מקשי עוצמת הקול על ידי האזנה לשינויים בעוצמת הקול ממערכת האודיו או על ידי האזנה ישירה לאירועים של מקשי עוצמת הקול משירות הקלט ברכב. בכל מקרה, התנהגות ברירת המחדל של שירות האודיו ברכב היא לקבוע איזו קבוצת עוצמת קול לשנות על סמך נגני האודיו הפעילים ורשימת עדיפויות של הקשרים של האודיו.
אנחנו מספקים שתי רשימות של סדרי עדיפויות לפי נפח. הרשימה הראשונה מתייחסת לכל ההקשרים של האודיו בסדר הזה. הרשימה מוצגת בסדר יורד, עם העדיפות הגבוהה ביותר בחלק העליון והעדיפות הנמוכה ביותר בחלק התחתון. לדוגמה, אם האודיו של הניווט והאודיו של המוזיקה פעילים בו-זמנית, עוצמת הקול של הניווט משתנה במהלך אירוע של מקש עוצמת הקול.
- ניווט
- התקשרות
- מוזיקה
- הכרזה
- פקודה קולית
- צלצול שיחה
- צלילי מערכת
- בטיחות
- שעון מעורר
- התראה
- סטטוס הרכב
- חירום
כדי לפשט את ניהול אירועי המקשים של עוצמת הקול, בשירות האודיו לרכב יש רשימת עדיפויות שנייה של הקשרים של אודיו:
- התקשרות
- מדיה
- הכרזה
- פקודה קולית
הרשימה הזו מוצגת גם בסדר יורד. המטרה של הרשימה השנייה היא לאפשר שינוי של צלילים נפוצים יותר באמצעות אירועים מרכזיים. צלילים לא נפוצים, כמו צלילים קצרים יותר, אפשר לנהל רק דרך ממשק המשתמש של הגדרות האודיו.
אפשר להגדיר את הגרסה בפועל של עוצמת הקול באמצעות ההגדרה audioVolumeAdjustmentContextsVersion
. אפשר להגדיר את התצורה לערך 1
או 2
(2
הוא ברירת המחדל).
כדי לספק יותר גמישות בניהול עוצמת הקול, ב-Android 14 הושק OemCarAudioVolumeService
:
public interface OemCarAudioVolumeService {
OemCarvolumeChangeInfo getSuggestedGroupForVolumeChange(
OemCarAudioVolumeRequest request, int volumeAdjustment);
}
לשירות עוצמת הקול של האודיו ברכב OEM יש method אחת, שמקבלת volumeAdjustment
ו-OemCarAudioVolumeRequest
:
class OemCarAudioVolumeRequest {
int audioZoneId;
int callState;
List<AudioAttributes> activePlaybackAttributes;
List<AudioAttributes> duckedAttributes;
List<CarVolumeGroupInfo> volumeGroupState;
}
המאפיין activePlaybackAttributes
של הבקשה מכיל את מאפייני האודיו הפעילים. duckedAttributes
הם כל מאפייני האודיו שמונמכים כרגע. השדה
volumeGroupState
מכיל את המצב הנוכחי של קבוצת אמצעי האחסון. הבקשה
מייצגת את המצב הנוכחי של מחסנית האודיו, ואפשר להשתמש בה כדי לקבוע
איזו קבוצת עוצמת קול צריך לשנות. התוצאות צריכות להיות מוחזרות בפורמט OemCarVolumeChangeInfo
:
class OemCarVolumeChangeInfo {
boolean change;
CarVolumeGroupInfo volumeGroupChanged;
}
הערך הבוליאני change
מציין אם נפח כלשהו השתנה, הערך true
מציין שיש שינוי וצריך לעדכן את קבוצת הנפחים. volumeGroupChanged
היא קבוצת עוצמת הקול שצריך לשנות. צריך לשנות את הקבוצה הזו בהתאם לפרמטר המקורי volumeAdjustment
שהועבר אל ה-API. לדוגמה, אם התוצאות מציינות שצריך להשתיק את קבוצת עוצמת הקול של הניווט, הערך הבוליאני יהיה true
וקבוצת עוצמת הקול שתוחזר תהיה זו של הניווט.
שירות הנמכת עוצמת הקול ברכב OEM
שירות האודיו ברכב מנהל את הנמכת האודיו על ידי מעקב אחרי שינויים במיקוד האודיו ושליחת אות ל-AudioControl
HAL לגבי מכשירי האודיו שצריך להנמיך.
כשמוקד הפוקוס משתנה, מתבצעת הערכה של כל המיקומים הפעילים של הפוקוס כדי לקבוע אילו מהם צריכים להיות מושתקים על סמך קבוצת הכללים הסטטיים להשתקה:
- צלילים במקרה חירום מנמיכים את כל הצלילים חוץ מצלילי שיחות
- ההשתקה האוטומטית של בטיחות משתיקה הכול חוץ מצלילים במקרה חירום
- הניווט מנמיך את עוצמת הקול של כל הצלילים חוץ מצלילי בטיחות וחירום
- השיחות מושתקות, חוץ מהצלילים שקשורים לבטיחות, למקרה חירום ולניווט
- הנמכת עוצמת הקול של שיחות קוליות
- ההנמכה צריכה לחול על מוזיקה ועל הודעות
הכללים האלה לא ממצים את כל האפשרויות, ויצרני ציוד מקורי (OEM) עדיין אחראים לקבוע איך להנמיך את עוצמת הקול בהתאם להנחיות האלה. יצרני ציוד מקורי יכולים לשלוט בהמלצות האלה באופן פעיל יותר בהתאם לדרישות הזמינות. OemCarDuckingService
מוצג ב-Android 14:
class OemCarAudioDuckingService {
List<AudioAttributes> evaluateAttributesToDuck(
OemCarAudioVolumeRequest request);
}
ה-API הזה נקרא משירות האודיו ברכב כשמתבצעים שינויים במיקוד האודיו. הוא משתמש מחדש ב-OemCarAudioVolumeRequest
שהוצג בשירות נפח הרכב של יצרן ציוד מקורי, ומכיל את המידע הרלוונטי לקבלת ההחלטה לגבי המאפיינים שיוסתר. רשימת מאפייני האודיו שצריך להנמיך מה-API מושווית למצב האודיו הנוכחי:
מאפיין האודיו שמונמך כרגע:
- ברשימה, ממשיך להיות מושתק
- לא ברשימה, הנמכת הווליום מושבתת
מאפיין האודיו לא מושתק כרגע:
- ברשימה, הנמכה
- לא ברשימה, הנמכת הווליום מושבתת
שירות האודיו ברכב קובע לאילו מכשירים להצגת מידע שייכים מאפייני האודיו, ומוסיף אותם לרשימת המכשירים להצגת מידע שבהם האודיו מושתק או לרשימת המכשירים להצגת מידע שבהם האודיו לא מושתק, בהתאם. הבקשה הזו נשלחת בסופו של דבר אל AudioControl HAL כדי לבצע את ההנמכה הנדרשת ברמת החומרה.
באיור הבא מוצג תרשים רצף פשוט של אמצעי הבקרה להנמכת עוצמת הקול עבור בקשת מיקוד, כשמשתמשים בשירות הנמכת עוצמת הקול של יצרן הציוד המקורי:
הרצף מתחיל כשבאפליקציה נשלחת בקשה לניהול של מיקוד האודיו דרך ממשקי API ציבוריים של מנהל האודיו. הבקשה מועברת לשירות האודיו ברכב כדי לקבוע את התוצאות. כשנקבע מוקד האודיו, שירות האודיו ברכב קורא ל-OemCarAudioDuckingService
כדי להעריך אילו מאפייני אודיו צריכים להיות מושתקים. אחרי שהתוצאות מוחזרות מ-evaluateAttributesToDuck
API, המערכת מחשבת את מכשירי האודיו שצריך להנמיך, ולבסוף המידע נשלח אל AudioControl
כדי להנמיך את עוצמת הקול של חומרת האודיו.
הטמעה לדוגמה של שירות אודיו לרכב OEM
AAOS מספק הטמעה לדוגמה של שירות הרכב של OEM ב-packages/services/Car/tests/OemCarServiceTestApp
, שמטמיע את OemCarService
, יחד עם OemCarAudioFocusService
, OemCarAudioDuckingService
ו-OemCarAudioVolumeService
. במקרה השני,
כל שירות משתמש בקובץ XML כדי לטעון התנהגות סטטית. לדוגמה, הפקודה OemCarAudioFocusServiceImp
טוענת את oem_focus_config.xml
, שמכיל מטריצת אינטראקציות. הטבלה משמשת להערכת בקשת המיקוד כשמתבצעת קריאה ל-evaluateAudioFocusRequest
.
ניפוי באגים באפליקציית בדיקה לדוגמה
אפליקציית הבדיקה של שירות המכונית של יצרן ציוד מקורי היא חלק מקוד המקור של AOSP. יצרני ציוד מקורי יכולים לבצע שינויים בהתאם לצרכים שלהם. לצורך ניפוי באגים, משתמשים בהגדרה config_oemCarService
כדי להפעיל את אפליקציית הבדיקה.
<!-- This is the component name for the OEM customization service. OEM can choose to implement
this service to customize car service behavior for different policies. If OEMs choose to
implement it, they have to implement a service extending OemCarService exposed by car-lib,
and implement the required component services.
If the component name is invalid, CarService would not connect to any OEM service.
Component name can not be a third party package. It should be pre-installed -->
<string name="config_oemCarService" translatable="false">
com.android.car.oemcarservice.testapp/.OemCarServiceImpl
</string>
כדי לוודא ששירות המכונית של יצרן הציוד המקורי משתמש בפקודה dump
של שירות המכונית בשביל שירות יצרן הציוד המקורי:
adb shell dumpsys car_service --oem-service
התוצאות יכולות להיות דומות לפלט שמוצג בהמשך:
***CarOemProxyService dump***
mIsFeatureEnabled: true
mIsOemServiceBound: true
mIsOemServiceReady: true
mIsOemServiceConnected: true
mInitComplete: true
OEM_CAR_SERVICE_CONNECTED_TIMEOUT_MS: 5000
OEM_CAR_SERVICE_READY_TIMEOUT_MS: 5000
mComponentName: com.android.car.oemcarservice.testapp/.OemCarServiceImpl
כל ערך בוליאני בכל אצווה של פרטי dump
קובע את המצב של התכונה והשירות. לדוגמה, בפרטי ה-dump mIsOemServiceReady
מצוין אם השירות מוכן לשימוש. הערך true
מציין שהשירות מוכן והערך false
מציין שהוא לא מוכן.