בקטע הזה מפורטים פרטים טכניים שספציפיים לאפליקציית ההפניה של מרכז הבקרה.
מרכז הבקרה הוא אפליקציה חתומה על ידי המערכת, עם הרשאות מיוחדות, שלא כלולה בחבילה. כדי להשתמש בו, נדרשת גרסת 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 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.
ממשקי 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_
ההגדרות האלה צריכות להיות במשאבים של אפליקציית הלקוח ובמשאבים של מרכז הבקרה.
ניפוי באגים במרכז הבקרה
המחלקה 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 ממליצה לעשות זאת ברמת המערכת, כשנכנסים למסך.