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