שירותי פלאגין חדשים של יצרני רכב ב-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 מכילה רשומות שהיו קודם ברשימת המפסידים של המיקוד, אבל עכשיו חסומות על ידי הרשומה החדשה. החסימה יכולה להיות קבועה או זמנית. אם החסימה קבועה, הרשומה תוסר מהמחסנית וההודעה על אובדן המיקוד תישלח למאזיני המיקוד. במקרה של אובדן מיקוד זמני,
הערך יישאר במחסנית של אובדן המיקוד, אבל חוסם מיקוד חדש יתווסף לרשימת החוסמים שלו. לא יישלח אובדן מיקוד כי הוא כבר נשלח כשנחסם בפעם הראשונה. הבקשה תבוטל בסופו של דבר אם כל החסימות הנוכחיות יוסרו, או שהיא תוסר מהמחסנית אם הפוקוס יבוטל.
ה-API השני, notifyAudioFocusChange, הוא חד-כיווני ומופעל בכל בקשה או ביטול של מיקוד אודיו. ה-API משמש בעיקר כדי לעדכן את שירות ה-OEM לגבי שינויים במיקוד, שיכולים להשפיע על ההתנהגות של שירות האודיו לרכב של ה-OEM.
הנחיות להערכת המיקוד
ב-AAOS, המיקוד באודיו משמש לניהול הפעלת האודיו ולקביעה איזו אפליקציה צריכה לפעול כדי לספק חוויה אופטימלית למשתמש. לכן, שירות הפלאגין של יצרן הציוד המקורי צריך לקחת בחשבון את הדברים הבאים כשמנהלים בקשה להעברת המיקוד של האודיו:
אם אין אפליקציות עם פוקוס אודיו קבוע בעדיפות גבוהה (כמו שיחת טלפון, מקרה חירום או בטיחות), אפליקציות אחרות צריכות להיות מסוגלות לקבל פוקוס אודיו באופן זמני או קבוע.
בזמן שההגדרה 'התמקדות במדיה' פעילה, אפליקציות שמבקשות:
המיקוד בשימוש בשיחות, צריך להיות אפשר לקבל מיקוד במקביל או באופן בלעדי.
המיקוד צריך להיות על השימוש בניווט, וצריכה להיות אפשרות לקבל מיקוד במקביל או באופן בלעדי.
השימוש ב-Assistant צריך להיות ממוקד, וצריכה להיות אפשרות לקבל מיקוד במקביל או באופן בלעדי.
בזמן שאפליקציות עם פוקוס אודיו בעדיפות גבוהה (כמו שיחת טלפון, התראה על מצב חירום או התראה על בטיחות) פעילות, כל בקשה נכנסת לפוקוס אודיו שמושהה צריכה לקבל אישור או להיות מושהית לפי הצורך.
ההצעות שלמעלה לא ממצות את כל האפשרויות, אבל הן יכולות לעזור להבטיח שאפליקציות שמבקשות להתמקד יוכלו להתמקד כשאין צלילים פעילים בעדיפות גבוהה. גם בזמן שצלילים בעדיפות גבוהה פעילים, צריך לכבד בקשות של מיקוד מושהה, ולאפשר להן לקבל מיקוד ברגע שהצליל בעדיפות גבוהה מפסיק.
שירות OEM לרכב
שירות האודיו ברכב מנהל את אירועי כפתור עוצמת הקול על ידי האזנה לשינויים בעוצמת הקול ממערכת האודיו או על ידי האזנה ישירה לאירועי כפתור עוצמת הקול משירות הקלט ברכב. בכל מקרה, התנהגות ברירת המחדל של שירות האודיו ברכב היא לקבוע איזו קבוצת עוצמת קול לשנות על סמך נגני האודיו הפעילים ורשימת עדיפות של הקשרים של האודיו.
אנחנו מספקים שתי רשימות עדיפות של נפחים. הרשימה הראשונה מתייחסת לכל ההקשרים של האודיו בסדר הזה. הרשימה מוצגת בסדר יורד, כך שהעדיפות הגבוהה ביותר מופיעה למעלה והעדיפות הנמוכה ביותר מופיעה למטה. לדוגמה, אם האודיו של הניווט והאודיו של המוזיקה פעילים בו-זמנית, עוצמת הקול של הניווט משתנה במהלך אירוע של מקש עוצמת הקול.
- ניווט
- התקשרות
- מוזיקה
- הכרזה
- פקודה קולית
- צלצול שיחה
- צלילי מערכת
- בטיחות
- התראה
- התראה
- סטטוס הרכב
- חירום
כדי לפשט את ניהול אירועי המקשים של עוצמת הקול, בשירות האודיו לרכב יש רשימת עדיפות שנייה של הקשרים של האודיו:
- התקשרות
- מדיה
- הכרזה
- פקודה קולית
הרשימה הזו מוצגת גם בסדר יורד. המטרה של הרשימה השנייה היא לאפשר שינוי של צלילים נפוצים יותר באמצעות אירועים מרכזיים. צלילים לא נפוצים, כמו צלילים קצרים יותר, ניתנים לניהול רק דרך ממשק המשתמש של הגדרות האודיו.
אפשר להגדיר את הגרסה בפועל של עוצמת הקול באמצעות ההגדרה audioVolumeAdjustmentContextsVersion. אפשר להגדיר את הערך 1 או 2 (2 הוא ברירת המחדל).
כדי לספק יותר גמישות בניהול עוצמת הקול, הוספנו את התכונה OemCarAudioVolumeService ב-Android 14:
public interface OemCarAudioVolumeService {
OemCarvolumeChangeInfo getSuggestedGroupForVolumeChange(
OemCarAudioVolumeRequest request, int volumeAdjustment);
}
לשירות עוצמת הקול של האודיו ברכב OEM יש שיטה אחת, שמקבלת 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 לגבי התקני האודיו שצריך להנמיך.
כשמוקד הפוקוס משתנה, מתבצעת הערכה של כל המיקומים הפעילים של הפוקוס כדי לקבוע אילו מהם יושתקו על סמך קבוצת הכללים הסטטיים להשתקה:
- צלילים במקרה חירום מנמיכים את כל הצלילים חוץ מצלילי שיחות
- ההשתקה של Safety Duck לא חלה על צלילים במקרה חירום
- הניווט מנמיך את עוצמת הקול של כל הצלילים חוץ מצלילים של בטיחות וחירום
- ההנמכה של עוצמת הקול מתרחשת בכל המקרים חוץ מבטיחות, חירום וניווט
- הנמכת עוצמת הקול של שיחות קוליות
- כל דבר צריך להנמיך את המוזיקה וההודעות
הכללים האלה לא ממצים את הנושא, ויצרני ציוד מקורי (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.
ניפוי באגים באפליקציית בדיקה
אפליקציית הבדיקה של שירות המכונית של יצרן ציוד מקורי (OEM) היא חלק מקוד המקור של 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 מציין שהוא לא מוכן.