इस सेक्शन में, Control Center के रेफ़रंस ऐप्लिकेशन से जुड़ी तकनीकी जानकारी दी गई है.
Control Center, सिस्टम के लिए साइन किया गया एक ऐसा ऐप्लिकेशन है जो बंडल नहीं किया गया है और जिसे खास अधिकार मिले हुए हैं. इसके लिए, कम से कम एसडीके वर्शन 35 (Android V (एपीआई लेवल 35)) की ज़रूरत होती है. System APIs का इस्तेमाल करने के लिए, यह ऐप्लिकेशन system/priv-app में इंस्टॉल किया गया है. मीडिया की जानकारी पढ़ने के लिए, ऐप्लिकेशन को प्लैटफ़ॉर्म के हिसाब से साइन किया जाना चाहिए. ऐप्लिकेशन को ओवर-द-एयर (OTA) अपडेट किया जा सकता है.
बैकग्राउंड में चलने वाली सेवा
Control Center ऐप्लिकेशन, अपनी सुविधाओं के लिए बैकग्राउंड में चलने वाली सेवा पर निर्भर करता है.
Control Center Service को Vendor ServiceController ने उपयोगकर्ता के लाइफ़साइकल में user-post-unlocked स्थिति में शुरू किया है. कंट्रोल सेंटर हमेशा चालू रहना चाहिए और बैकग्राउंड में काम करना चाहिए. ऐप्लिकेशन को इस बात पर भरोसा नहीं करना चाहिए कि उपयोगकर्ता ने ऐप्लिकेशन खोला है.
Control Center Service, Communication API का इस्तेमाल करके, कार के दूसरे ऑक्यूपंट ज़ोन में मौजूद अपने अन्य इंस्टेंस से कनेक्ट होता है और उनसे इंटरैक्ट करता है. हर उपयोगकर्ता के डिवाइस पर Control Center के इंस्टेंस, कनेक्शन कैसे बनाते हैं और डेटा कैसे भेजते और पाते हैं, यह समझने के लिए इंटिग्रेशन गाइड पढ़ना ज़रूरी है.
कम्यूनिकेशन
कनेक्ट होने के बाद, Control Center Service, protobuf से कम्यूनिकेट करता है. 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
}
}
//…
}
डेटा
ऑक्यूपेंट ज़ोन की जानकारी, Control Center में OccupantZoneData ऑब्जेक्ट के तौर पर सेव की जाती है. स्थानीय OccupantZoneData में किए गए बदलावों को Comms API के ज़रिए, Control Center के अन्य इंस्टेंस को भेजा जाता है.
जब मिले हुए Payload को पार्स किया जाता है, तो पार्स किए गए डेटा को लोकल OccupantZoneStateRepository में पास किया जाता है. इसके बाद, यह बदलाव के बारे में व्यू को सूचना देता है. ज़्यादातर डेटा को क्लास के बीच Kotlin flows on Android की मदद से पास किया जाता है.
केबिन स्पीकर पर ऑडियो के लिए किए गए अनुरोधों को मैनेज करना
इसलिए, ड्राइवर को हमेशा यात्रियों के केबिन स्पीकर पर ऑडियो चलाने के अनुरोध मिल सकें, इसके लिए ड्राइवर का Control Center Service Primary ZoneMedia Audio RequestCallback को रजिस्टर करता है.
कॉलबैक को CarAudioManager#requestMediaAudioOnPrimaryZone पर किए गए कॉल की सूचना दी जाती है. ड्राइवर के Control Center Service, अनुरोधों को मैनेज करता है. इसके लिए, वह स्क्रीन पर सबसे ऊपर दिखने वाली सूचना (एचयूएन) बनाता है. इसे CarAudioManager#allowMediaAudioOnPrimaryZone(boolean) के ज़रिए स्वीकार या अस्वीकार किया जा सकता है.
दूसरी स्क्रीन पर किसी वीडियो को साथ मिलकर देखना
CarActivityManager में मौजूद Task Mirroring APIs की वजह से, लोगों के साथ मिलकर वीडियो देखने की सुविधा काम करती है. TaskMirroringManager सबसे पहले, CarActivityManager#getVisibleTasks में चल रहे MediaSession ऐप्लिकेशन के पैकेज को खोजता है. इसके बाद, VirtualDisplay बनाता है और CarActivityManager#moveRootTaskToDisplay के ज़रिए दिखने वाले टास्क को इस डिसप्ले पर ले जाता है.
इससे IBinder टोकन मिलता है. MirroredSurfaceView इसका इस्तेमाल लेआउट में कर सकता है, ताकि MirroredSurfaceView#mirrorSurface के ज़रिए टास्क दिखाया जा सके.
Communication API Payload ऑब्जेक्ट ने टोकन को अन्य ऑक्यूपेंट ज़ोन में पास कर दिया है.
उन ऑक्यूपेंट ज़ोन में मौजूद हर Control Center इंस्टेंस, Mirroring activity लॉन्च करता है. साथ ही, उस टोकन का इस्तेमाल करके MirroredSurfaceView में डेटा भरता है.
टास्क मिरर करने वाले एपीआई
Control Center, टास्क मिररिंग के लिए इन एपीआई का इस्तेमाल करता है:
CarActivityManager#getVisibleTasks(int displayId)<ActivityManager.RunningTaskInfo> ने भेजने वाले का डिसप्ले नेम दिखाने के लिए कॉल किया.CarActivityManager#moveRootTaskToDisplay(int virtualDisplayId)CarActivityManager#createTaskMirroringToken(int taskId)IBinder टोकन को मिरर करने के लिए एक टास्क बनाता है. इसे तब कॉल किया जाना चाहिए, जब टास्क को वर्चुअल डिसप्ले पर ले जाया जाता है.MirroredSurfaceView#mirrorSurface(IBinder token)Control Center में टास्क मिरर करने की सुविधा की सीमाएं
कंट्रोल सेंटर, सिर्फ़ MediaSession ऐप्लिकेशन के लिए टास्क मिररिंग की सुविधा देता है.
हालांकि, एपीआई किसी भी टास्क को दोहरा सकता है. वर्चुअल डिसप्ले, भेजने वाले के डिसप्ले के डाइमेंशन के हिसाब से बनाया जाता है. अगर रिसीवर के डिसप्ले में अलग-अलग रिज़ॉल्यूशन और डाइमेंशन का इस्तेमाल किया जाता है, तो वर्चुअल डिसप्ले स्क्रीन के बीच में दिखता है.
ऐसे टास्क जो सर्फ़ेस पर दिखते हैं
कंट्रोल सेंटर, चेसिस Theme.CarUi.NoToolbar को बढ़ाकर एक पारदर्शी विंडो बनाता है. इसका मतलब है कि जब किसी टास्क के ऊपर कंट्रोल सेंटर खोला जाता है, तो टास्क को CarActivityManager#getVisibleTasks में वापस भेज दिया जाता है. इससे टास्क को मिरर किया जा सकता है.
स्क्रीन मिरर करने की जानकारी पाना
कंट्रोल सेंटर, स्क्रीन मिरर करने के सेशन के बारे में अन्य ऐप्लिकेशन को सूचना देता है. अपडेट पाने के लिए, ऐप्लिकेशन को Control Center Service से बाइंड करना होगा. साथ ही, Handler क्लास को क्लाइंट के तौर पर भेजना होगा. यह क्लास, Control
Center Service से Messages को पाने और मैनेज करने का काम करती है.
क्लाइंट ऐप्लिकेशन को, मिरर किए गए ऐप्लिकेशन का पैकेज नाम मिल सकता है. साथ ही, वे कंट्रोल सेंटर में मौजूद मिरर किए गए ऐप्लिकेशन की गतिविधि के लिए, intent URI लॉन्च कर सकते हैं. इसके लिए, उन्हें इन कुंजियों की ज़रूरत होगी:
_config_msg_mirroring_pkg_name_key__config_msg_mirroring_redirect_uri_key_
ये कॉन्फ़िगरेशन, क्लाइंट ऐप्लिकेशन के संसाधनों और Control Center के संसाधनों में मौजूद होने चाहिए.
डीबग कंट्रोल सेंटर
Logger क्लास, Control Center के लॉग को मैनेज करती है. इसे लॉग को फ़ोर्स करने के लिए कॉन्फ़िगर किया जा सकता है.
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)
}
}
...
सिस्टम ऐप्लिकेशन और उसे अपडेट करने की सुविधा
कंट्रोल सेंटर एक सिस्टम ऐप्लिकेशन है. साथ ही, यह सिर्फ़ हस्ताक्षर वाली अनुमतियों का इस्तेमाल करता है. इसलिए, इसे प्लैटफ़ॉर्म से साइन किया जाता है. कंट्रोल सेंटर को डिवाइस पर पहले से इंस्टॉल होना चाहिए. साथ ही, इसे सिर्फ़ ओटीए के ज़रिए अपडेट किया जा सकता है. यह कार मीडिया ऐप्लिकेशन की तरह ही है.
सोर्स से कंट्रोल सेंटर बनाना
Control Center का सोर्स कोड पाने के लिए, अनबंडल किए गए ऐप्लिकेशन इंटिग्रेट करना लेख पढ़ें.
मल्टी-डिसप्ले के साथ उपयोगकर्ता की निजता
Control Center की मदद से, कार में बैठे सभी लोग सभी डिसप्ले पर मीडिया की जानकारी देख सकते हैं. Google का सुझाव है कि उपयोगकर्ताओं को सूचना देने के लिए, निजता नोटिस डालें जो पेज लोड होने में रुकावट न डाले. Google का सुझाव है कि आप ऐसा सिस्टम लेवल पर करें. इसके लिए, आपको किसी डिसप्ले में साइन इन करना होगा.