מיקוד אודיו

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

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

אינטראקציות עם מוקד

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

  • בלעדי
  • דחייה
  • בו-זמנית

אינטראקציה בלעדית

זהו מודל האינטראקציה הנפוץ ביותר ב-Android.

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

דחיית אינטראקציה

באינטראקציות מסוג דחייה, הבקשה הנכנסת תמיד נדחית. לדוגמה, כשמנסים להפעיל מוזיקה בזמן שיחה. במקרה כזה, אם Dialer שומר על המיקוד באודיו לשיחה ואפליקציה שנייה מבקשת להתמקד בה כדי להפעיל מוזיקה, אפליקציית המוזיקה מקבלת את הערך AUDIOFOCUS_REQUEST_FAILED בתגובה לבקשה. מאחר שבקשת המיקוד נדחתה, לא נשלח אירוע של אובדן מיקוד לבעל המיקוד הנוכחי.

אינטראקציה בו-זמנית

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

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

טיפול בשידורים חיים בו-זמניים

יש אינטראקציות רבות שאפשר לבצע בו-זמנית, אבל חשוב להיזהר כשמערבבים ומשתמשים ב-ducking ברמת החומרה במכשירי הפלט השונים. מומלץ מאוד לנתב CarAudioContext שמותרים להפעלה בו-זמנית למכשירי פלט שונים.

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

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

מטריצה של אינטראקציות

בטבלה הבאה מוצגת מטריצת האינטראקציה כפי שמוגדרת על ידי CarAudioService. כל שורה מייצגת את CarAudioContext של בעל המיקוד הנוכחי, וכל עמודה מייצגת את CarAudioContext של הבקשה הנכנסת.

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

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

איור 1. מטריצה של אינטראקציה עם הרשאת אודיו.

ב-Android 11 הוספנו הגדרת משתמש חדשה שמאפשרת למשתמשים לשנות את התנהגות האינטראקציה בין הניווט לשיחות טלפון. כשהערך של android.car.KEY_AUDIO_FOCUS_NAVIGATION_REJECTED_DURING_CALL מוגדר, האינטראקציה בין בקשות NAVIGATION נכנסות ל-focus לבין בעלי ה-focus הנוכחיים ב-CALL משתנה מבו-זמנית לדחייה. אם משתמש מעדיף שההוראות הניווט לא יפריעו לשיחה, הוא יכול להפעיל את ההגדרה הזו. ההגדרה הזו נשמרת אצל המשתמש, וניתן להגדיר אותה באופן דינמי כדי שבקשות העברת המיקוד הבאות יתייחסו להגדרה החדשה.

הרשאת אודיו שניתן לדחות

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

כללים לבקשות מושהות להעברת המיקוד לאודיו

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

  • אפשר לדחות רק בקשה אחת בכל פעם. אם שולחים בקשה שניתן לעכב בזמן שכבר יש בקשה מושהית, הבקשה המקורית המושהית מקבלת אירוע שינוי מסוג AUDIOFOCUS_LOSS והבקשה החדשה מקבלת תשובה סינכרונית מסוג AUDIOFOCUS_REQUEST_DELAYED.

  • בקשות שאפשר לדחות חייבות לכלול את הערך OnAudioFocusChangeListener. אחרי שהבקשה מתעכבת, המאזין משמש כדי להודיע למבקש כשהבקשה תאושר בסופו של דבר (AUDIOFOCUS_GAIN), או אם היא תידחה מאוחר יותר (AUDIOFOCUS_LOSS).

בקשה להתמקד במשהו תוך עיכוב

כדי ליצור בקשה שאפשר לדחות:

  1. שימוש בכתובת AudioFocusRequest.Builder#setAcceptsDelayedFocusGain.

    mMediaWithDelayedFocusListener = new MediaWithDelayedFocusListener();
    
    mDelayedFocusRequest = new AudioFocusRequest
         .Builder(AudioManager.AUDIOFOCUS_GAIN)
         .setAudioAttributes(mMusicAudioAttrib)
         .setOnAudioFocusChangeListener(mMediaWithDelayedFocusListener)
         .setForceDucking(false)
         .setWillPauseWhenDucked(false)
         .setAcceptsDelayedFocusGain(true)
         .build();
    
  2. כששולחים את הבקשה, מטפלים בתגובה AUDIOFOCUS_REQUEST_DELAYED:

    int delayedFocusRequestResults = mAudioManager.requestAudioFocus(mDelayedFocusRequest);
    if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
        // start audio playback
        return;
    }
    if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
         // audio playback delayed to audio focus listener
         return;
    }
    
  3. כשהבקשה מתעכבת, מאזין המיקוד מטפל בשינויים במיקוד:

    private final class MediaWithDelayedFocusListener implements
    OnAudioFocusChangeListener {
           @Override
           public void onAudioFocusChange(int focusChange) {
               synchronized (mLock) {
                   switch (focusChange) {
                       case AudioManager.AUDIOFOCUS_GAIN:
                           … // Start focus playback
                       case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                           … // Pause media transiently
                       case AudioManager.AUDIOFOCUS_LOSS:
                           … // Stop media
    

ניהול התמקדות בכמה אזורים

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

בכל האפליקציות, ה-CarAudioService מנהל את המיקוד באופן אוטומטי. אזור האודיו של בקשת התמקדות נקבע לפי UserId או UID המשויכים אליה (פרטים נוספים זמינים במאמר ניתוב אודיו בכמה אזורים).

שליחת בקשה לקבלת אודיו מכמה תחומים בו-זמנית

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

//Create attribute with bundle and AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID
Bundle bundle = new Bundle();
bundle.putInt(CarAudioManager.AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID,
               zoneId);

AudioAttributes attributesWithZone = new AudioAttributes.Builder()
     .setUsage(AudioAttributes.USAGE_MEDIA)
     .addBundle(bundle)
     .build();

//Create focus request using built attributesWithZone

פרמטר החבילה הזה מאפשר למבקש לשנות את המיפויים האוטומטיים של תחומי האודיו, ולהשתמש במקום זאת במזהה האזור שצוין. לכן, אפליקציה יכולה לשלוח בקשות נפרדות לאזורי אודיו שונים.

מיקוד אודיו ב-HAL

החל מ-Android 11, ה-HAL מופעל כדי לבקש להתמקד בשידורים חיצוניים. השימוש בממשקי ה-API האלה הוא אופציונלי, אבל מומלץ מאוד להשתמש בהם כדי לאפשר לצלילים חיצוניים להשתלב בצורה אופטימלית בסביבת Android ולספק חוויית משתמש חלקה.

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

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

AudioControl@2.0

בגרסה 2.0 של AudioControl HAL נוספו ממשקי ה-API החדשים הבאים:

API המטרה
IAudioControl#registerFocusListener רישום מכונה של IFocusListener ב-HAL של AudioControl. המאזין הזה מאפשר ל-HAL לבקש את המיקוד באודיו ולבטל אותו. ה-HAL מספק מכונה של ICloseHandle שמערכת Android תשתמש בה כדי לבטל את הרישום של המאזין.
IAudioControl#onAudioFocusChange מודיע ל-HAL על שינויים בסטטוס של בקשות ל-focus שנשלחו על ידי ה-HAL דרך IFocusListener, כולל תגובות לבקשות ראשוניות ל-focus.
IFocusListener#requestAudioFocus בקשות להתמקד מטעם HAL לשימוש ספציפי, מזהה תחום וסוגי התמקדות.
IFocusListener#abandonAudioFocus ביטול בקשות ה-HAL הקיימות ל-focus עבור מזהה השימוש והתחום שצוינו.

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

מלבד registerFocusListener, הבקשות האלה הן oneway כדי לוודא שמערכת Android לא מעכבת את HAL בזמן עיבוד בקשת התמקדות. ה-HAL לא צריך להמתין לקבלת המיקוד לפני הפעלת צלילים שקשורים לבטיחות. ה-HAL יכול להאזין לשינויים במיקוד האודיו דרך IAudioControl#onAudioFocusChange ולהגיב להם.

שירות של יצרן ציוד מקורי להרשאת אודיו ברכב

ב-Android 14, הוספנו ל-AAOS את שירותי הפלאגין של יצרני הרכב המקוריים (OEM) כדי לאפשר הגדרה של חלק מרכיבי הרכב. בשירות הפלאגין של אודיו ברכב, שירות הפלאגין מאפשר ליצרני ציוד מקורי לנהל בקשות להתמקד ששירות האודיו ברכב תיקל עליה. כך יצרני ציוד מקורי יכולים לנהל את המיקוד בצורה גמישה יותר, בהתאם לכללים ותקנות. לכן, האינטראקציה עם התכונה 'מיקוד אודיו' עשויה להשתנות בין יצרנים ומאזור לאזור. ההנחה הבסיסית לגבי התמקדות באודיו עדיין בתוקף, כלומר אפליקציות עדיין צריכות לבקש התמקדות כדי לנהל את האודיו בצורה טובה יותר ולשפר את חוויית המשתמש. באופן כללי, עדיין חלים כללים מסוימים על בקשות של אפליקציות להתמקד באודיו:

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

  • כשהמיקוד במדיה פעיל:

    • אפליקציות שמבקשות להתמקד בשימוש בשיחות צריכות להיות מסוגלות לקבל את השיחה בו-זמנית או באופן בלעדי.

    • אפליקציות שמבקשות לקבל התמקדות ברכיב ממשק לצורך ניווט צריכות להיות מסוגלות לקבל את ההתמקדות הזו בו-זמנית או באופן בלעדי.

    • אפליקציות שמבקשות להתמקד בשימוש במסגרת העוזרת צריכות להיות מסוגלות לקבל את המיקוד בשימוש בו-זמנית או באופן בלעדי.

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

ההצעות שלמעלה לא מפורטות באופן מלא, אבל הן יכולות לעזור לאפליקציות שמבקשות להתמקד לקבל את המיקוד אם אין צלילים פעילים בעדיפות גבוהה. גם כשצלילים בעדיפות גבוהה פעילים, עדיין צריך לכבד בקשות מושהות להעברת המיקוד, והן אמורות לקבל את המיקוד כשהצליל בעדיפות גבוהה מפסיק.