פרטים טכניים

בקטע הזה מפורטים פרטים טכניים שספציפיים לאפליקציית ההפניה של מרכז הבקרה.

מרכז הבקרה הוא אפליקציה חתומה על ידי המערכת, עם הרשאות מיוחדות, שלא כלולה בחבילה. כדי להשתמש בו, נדרשת גרסת SDK מינימלית של 35 ‏ (Android V (רמת API‏ 35)). האפליקציה מותקנת ב-system/priv-app כדי להשתמש ב-System APIs. כדי לקרוא את פרטי המדיה, האפליקציה צריכה להיות חתומה על ידי הפלטפורמה. אפשר לעדכן את האפליקציה באמצעות OTA (Over-the-Air).

שירות שפועל ברקע

הפונקציונליות של אפליקציית מרכז הבקרה מבוססת על שירות ברקע. ‫Control Center Service מתחיל בשלב user-post-unlocked במחזור החיים של המשתמש על ידי Vendor ServiceController. מרכז הבקרה צריך להיות תמיד פעיל ולתקשר ברקע – האפליקציה לא יכולה להסתמך על כך שהמשתמש יפתח אותה.

Control Center Service מתחבר למופעים אחרים של עצמו באזורי נוסעים אחרים ומתקשר איתם באמצעות Communication API. חשוב לקרוא את מדריך השילוב כדי להבין איך מופעלים המקרים של מרכז הבקרה אצל כל משתמש, ואיך הנתונים נשלחים ומתקבלים.

תרשים שממחיש את הפעלת שירות Control Center על ידי Vendor ServiceController.
איור 5. השירות של מרכז הבקרה הופעל על ידי Vendor ServiceController.

תקשורת

אחרי החיבור, Control Center Service מתקשר עם אובייקטים של protobuf שמעבירים מידע. כדי להעביר את protobuf לאזור תפוס אחר עם Communication APIs, המערכת ממירה את protobuf ל-byte array, יוצרת payload object ושולחת את Payload דרך CarOccupantConnectionManager#sendPayload.

message ControlCenterPayload {
    required Type messageType = 1;
    // ...
    enum Type {
       MEDIA_STATUS = 0;
       MEDIA_COMMAND = 1;
       INPUT_LOCK_COMMAND = 2;
       INPUT_LOCK_SUCCESSFUL = 3;
       CANCEL_AUDIO_REQUEST = 4;
       MIRRORING_REQUEST_RECEIVER_DECISION = 5;
       MIRRORING_SESSION_ENDED = 6;
    }
}

private fun parsePayload(
    senderZone: OccupantZoneInfo,
    payload: Payload
) {
     val parsedPayload =
         ControlCenterPayload.parseFrom(payload.bytes)
             when (parsedPayload.messageType) {
                 ControlCenterPayload.Type.MEDIA_STATUS -> {
                     // logic here
                 }
             }
             //…
}

נתונים

המידע על אזורי הנוסעים מאוחסן במרכז הבקרה בצורה של אובייקטים מסוג OccupantZoneData. השינויים שבוצעו ב-OccupantZoneData המקומי נשלחים למופעים אחרים של Control Center דרך Comms API.

כשמנתחים את הנתונים שהתקבלו מ-Payload, הנתונים המנותחים מועברים אל OccupantZoneStateRepository המקומי, שמודיע לתצוגות על השינוי. רוב הנתונים מועברים בין מחלקות באמצעות Kotlin flows on Android.

טיפול בבקשות להפעלת אודיו ברמקול של תא הנהג

כדי שהנהג יוכל תמיד לקבל בקשות מנוסעים להשמעת אודיו ברמקולים של תא הנוסעים, כשיוצרים את Control Center Service של הנהג, המערכת רושמת את Primary ZoneMedia Audio RequestCallback.

הפונקציה להחזרת קריאה מקבלת התראות על שיחות אל CarAudioManager#requestMediaAudioOnPrimaryZone. הנהג Control Center Service מטפל בבקשות על ידי יצירת התראה מוקדמת (HUN) שאפשר לאשר או לדחות דרך CarAudioManager#allowMediaAudioOnPrimaryZone(boolean).

צפייה משותפת בסרטון במסכים אחרים

הצפייה המשותפת פועלת בזכות Task Mirroring APIs ב-CarActivityManager. הפונקציה TaskMirroringManager מחפשת קודם את חבילת האפליקציה MediaSession שמופעלת ב-CarActivityManager#getVisibleTasks, ואז יוצרת VirtualDisplay ומעבירה את המשימה הגלויה לתצוגה הזו באמצעות CarActivityManager#moveRootTaskToDisplay.

הפונקציה מחזירה אסימון IBinder שאפשר להשתמש בו בפריסה של MirroredSurfaceView כדי להציג את המשימה דרך MirroredSurfaceView#mirrorSurface. האובייקט Communication API Payload העביר את האסימון לאזורים אחרים שבהם יש נוכחות.

כל מופע של מרכז הבקרה באזורי הדיירים האלה מפעיל Mirroring activity ומשתמש באסימון הזה כדי לאכלס את MirroredSurfaceView.

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

ממשקי API של שיקוף משימות

מרכז הבקרה משתמש בממשקי ה-API הבאים של שיקוף משימות:

CarActivityManager#getVisibleTasks(int displayId)
<ActivityManager.RunningTaskInfo> נקרא השם המוצג של השולח.

CarActivityManager#moveRootTaskToDisplay(int virtualDisplayId)
העברת המשימה הגלויה שנבחרה לתצוגה וירטואלית שנוצרה.

CarActivityManager#createTaskMirroringToken(int taskId)
יוצר משימה לשכפול של אסימון IBinder, והקריאה לפונקציה הזו צריכה להתבצע אחרי שהמשימה מועברת לתצוגה הווירטואלית.

MirroredSurfaceView#mirrorSurface(IBinder token)
אובייקט של תצוגה בהתאמה אישית שמשתמש באסימון כדי להציג את התוכן של |התצוגה הווירטואלית.

המגבלות של שיקוף משימות במרכז הבקרה

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

הצגת משימות

מרכז הבקרה מרחיב את המארז Theme.CarUi.NoToolbar לחלון שקוף למחצה. המשמעות היא שכאשר מרכז הבקרה נפתח מעל משימה, המשימה מוחזרת ב-CarActivityManager#getVisibleTasks, מה שמאפשר לשקף את המשימה.

קבלת מידע על שיקוף

מרכז הבקרה שולח לאפליקציות אחרות התראות על סשנים של שיקוף. כדי לקבל עדכונים, אפליקציות צריכות להיות מקושרות ל-Control Center Service ולשלוח מחלקה Handler כלקוח שמקבל ומטפל ב-Messages מ-Control Center Service.

אפליקציות לקוח יכולות לקבל את שם החבילה של האפליקציה המשוכפלת ולהפעיל intent URI לפעילות במרכז הבקרה שמארח את האפליקציה המשוכפלת באמצעות המפתחות הבאים:

  • _config_msg_mirroring_pkg_name_key_
  • _config_msg_mirroring_redirect_uri_key_

ההגדרות האלה צריכות להיות במשאבים של אפליקציית הלקוח ובמשאבים של מרכז הבקרה.

אפליקציות לקוח מקבלות מידע על שיקוף ממרכז הבקרה.
איור 7. לקבל מידע על שיקוף ממרכז הבקרה.

מרכז הבקרה של ניפוי הבאגים

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

class Logger(cls: Class<*>) {

   companion object {
       private const val FORCE_LOGS = false
   }

   private val tag: String

   init {
       tag = cls.simpleName
   }

   fun v(message: String) {
       if (Log.isLoggable(tag, Log.VERBOSE) || FORCE_LOGS) {
           Log.v(tag, message)
       }
   }
...

אפליקציית מערכת ויכולת עדכון

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

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

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

פרטיות המשתמשים עם תצוגה מרובת מסכים

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