รายละเอียดทางเทคนิค

ส่วนนี้จะให้รายละเอียดทางเทคนิคที่เฉพาะเจาะจงกับแอปอ้างอิง Control Center

ศูนย์ควบคุมเป็นแอปที่ไม่ได้รวมไว้ มีสิทธิ์ และระบบลงนาม ซึ่งต้องใช้ SDK เวอร์ชันขั้นต่ำ 35 (Android V (API ระดับ 35)) แอปนี้ติดตั้งไว้ใน system/priv-app เพื่อใช้ System APIs หากต้องการอ่านข้อมูลสื่อ แอปต้อง ได้รับการลงนามในแพลตฟอร์ม คุณอัปเดตแอปผ่านอากาศ (OTA) ได้

บริการที่ทำงานอยู่เบื้องหลัง

แอปศูนย์ควบคุมใช้บริการในเบื้องหลังสำหรับฟังก์ชันการทำงาน Control Center Service จะเริ่มต้นในสถานะ user-post-unlocked ใน วงจรของผู้ใช้โดย Vendor ServiceController ศูนย์ควบคุมต้องทำงานและสื่อสารในเบื้องหลังอยู่เสมอ แอปไม่สามารถพึ่งพาการที่ผู้ใช้เปิดแอปได้

Control Center Service เชื่อมต่อและสื่อสารกับอินสแตนซ์อื่นๆ ของตัวเองในโซนที่มีการเข้าใช้อื่นๆ โดยใช้ Communication API การอ่าน คู่มือการผสานรวมเป็นสิ่งสำคัญในการทำความเข้าใจวิธีที่อินสแตนซ์ของศูนย์ควบคุม ในผู้ใช้แต่ละรายสร้างการเชื่อมต่อ รวมถึงส่งและรับข้อมูล

แผนภาพที่แสดงให้เห็นว่า Vendor ServiceController เป็นผู้เริ่มบริการ Control Center
รูปที่ 5 Control Center Service started by 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 ในเครื่องจะถูกส่งไปยัง อินสแตนซ์ศูนย์ควบคุมอื่นๆ ผ่าน 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 สามารถจำลองงานใดก็ได้ จอแสดงผลเสมือนสร้างขึ้นโดยใช้ ขนาดของจอแสดงผลของผู้ส่ง หากจอแสดงผลของผู้รับใช้ความละเอียดและขนาดที่แตกต่างกัน จอแสดงผลเสมือนจะปรากฏตรงกลางหน้าจอ

งานที่แสดงใน Surface

Control Center ขยายแชสซี 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 ขอแนะนำให้คุณดำเนินการนี้ที่ระดับระบบเมื่อลงชื่อเข้าใช้จอแสดงผล