প্রযুক্তিগত বিবরণ

এই বিভাগে কন্ট্রোল সেন্টার রেফারেন্স অ্যাপ সম্পর্কিত নির্দিষ্ট প্রযুক্তিগত বিবরণ দেওয়া হয়েছে।

কন্ট্রোল সেন্টার একটি আনবান্ডেলড, প্রিভিলেজড, সিস্টেম সাইনড অ্যাপ, যার জন্য ন্যূনতম SDK ভার্সন ৩৫ (অ্যান্ড্রয়েড V (API লেভেল ৩৫)) প্রয়োজন। System APIs ব্যবহার করার জন্য অ্যাপটি system/priv-app ফোল্ডারে ইনস্টল করা হয়। মিডিয়া তথ্য পড়ার জন্য, অ্যাপটিকে অবশ্যই প্ল্যাটফর্ম-সাইনড হতে হবে। আপনি ওভার-দ্য-এয়ার (OTA) এর মাধ্যমে অ্যাপটি আপডেট করতে পারেন।

পটভূমি পরিষেবা

কন্ট্রোল সেন্টার অ্যাপটি তার কার্যকারিতার জন্য একটি ব্যাকগ্রাউন্ড সার্ভিসের উপর নির্ভর করে। user-post-unlocked অবস্থায় Vendor ServiceController দ্বারা Control Center Service চালু করা হয়। কন্ট্রোল সেন্টারকে অবশ্যই ব্যাকগ্রাউন্ডে সর্বদা সক্রিয় এবং যোগাযোগরত থাকতে হবে—অ্যাপটি ব্যবহারকারীর দ্বারা অ্যাপটি খোলার উপর নির্ভর করতে পারে না।

Control Center Service কমিউনিকেশন এপিআই (Communication API) ব্যবহার করে অন্যান্য অকুপ্যান্ট জোনে থাকা নিজের অন্যান্য ইনস্ট্যান্সের সাথে সংযোগ স্থাপন করে এবং যোগাযোগ করে। প্রতিটি ব্যবহারকারীর কন্ট্রোল সেন্টার ইনস্ট্যান্সগুলো কীভাবে সংযোগ স্থাপন করে এবং ডেটা আদান-প্রদান করে, তা বোঝার জন্য ইন্টিগ্রেশন গাইডটি পড়া অপরিহার্য।

ভেন্ডর সার্ভিসকন্ট্রোলার দ্বারা কন্ট্রোল সেন্টার সার্ভিস চালু হওয়ার চিত্র।
চিত্র ৫. ভেন্ডর সার্ভিসকন্ট্রোলার দ্বারা চালু করা কন্ট্রোল সেন্টার সার্ভিস।

যোগাযোগ

একবার সংযুক্ত হলে , Control Center Service protobuf অবজেক্টের মাধ্যমে তথ্য আদান-প্রদান করে। Communication APIs ব্যবহার করে protobuf অন্য অকুপ্যান্ট জোনে পাঠানোর জন্য, protobuf একটি byte array রূপান্তর করা হয়, একটি payload object তৈরি করা হয় এবং CarOccupantConnectionManager#sendPayload এর মাধ্যমে Payload পাঠানো হয়।

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) এর মাধ্যমে গ্রহণ বা প্রত্যাখ্যান করা যায়।

অন্যান্য স্ক্রিনের সাথে একসাথে ভিডিও দেখুন

CarActivityManager এর Task Mirroring APIs কারণে কো-ওয়াচিং কাজ করে। TaskMirroringManager প্রথমে CarActivityManager#getVisibleTasks এর মাধ্যমে প্লে হওয়া MediaSession অ্যাপের প্যাকেজটি খোঁজে, তারপর একটি VirtualDisplay তৈরি করে এবং CarActivityManager#moveRootTaskToDisplay এর মাধ্যমে দৃশ্যমান টাস্কটিকে এই ডিসপ্লেতে সরিয়ে দেয়।

এটি একটি IBinder টোকেন ফেরত দেয় যা MirroredSurfaceView MirroredSurfaceView#mirrorSurface মাধ্যমে টাস্কটি প্রদর্শন করার জন্য একটি লেআউটে ব্যবহার করতে পারে। Communication API Payload অবজেক্টটি টোকেনটি অন্যান্য অকুপ্যান্ট জোনগুলিতে প্রেরণ করে।

ওই অকুপ্যান্ট জোনগুলিতে থাকা প্রতিটি কন্ট্রোল সেন্টার ইনস্ট্যান্স একটি Mirroring activity চালু করে এবং সেই টোকেনটি ব্যবহার করে MirroredSurfaceView কে ডেটা দিয়ে পূর্ণ করে।

অন্য স্ক্রিনে একটি টাস্ক প্রদর্শন করার জন্য মিররিং টোকেনের কার্যপ্রবাহ।
চিত্র ৬। টোকেন প্রবাহের প্রতিবিম্ব।

টাস্ক মিররিং এপিআই

কন্ট্রোল সেন্টার এই টাস্ক মিররিং এপিআইগুলো ব্যবহার করে:

CarActivityManager#getVisibleTasks(int displayId)
প্রেরক প্রদর্শনের জন্য <ActivityManager.RunningTaskInfo> কল করা হয়েছে।

CarActivityManager#moveRootTaskToDisplay(int virtualDisplayId)
নির্বাচিত দৃশ্যমান টাস্কটিকে একটি তৈরি করা ভার্চুয়াল ডিসপ্লেতে স্থানান্তর করে।

CarActivityManager#createTaskMirroringToken(int taskId)
IBinder টোকেনটির প্রতিরূপ তৈরি করার জন্য একটি টাস্ক তৈরি করে এবং টাস্কটি ভার্চুয়াল ডিসপ্লেতে স্থানান্তরিত হওয়ার পরে এটি কল করা উচিত।

MirroredSurfaceView#mirrorSurface(IBinder token)
একটি কাস্টম ভিউ অবজেক্ট যা টোকেন ব্যবহার করে ভার্চুয়াল ডিসপ্লের বিষয়বস্তু প্রদর্শন করে।

কন্ট্রোল সেন্টারে টাস্ক মিররিং-এর সীমাবদ্ধতা

কন্ট্রোল সেন্টার শুধুমাত্র 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_

এই কনফিগারেশনগুলো অবশ্যই ক্লায়েন্ট অ্যাপ রিসোর্স এবং কন্ট্রোল সেন্টার রিসোর্স-এ থাকতে হবে।

ক্লায়েন্ট অ্যাপগুলো কন্ট্রোল সেন্টার থেকে মিররিং সংক্রান্ত তথ্য গ্রহণ করে।
চিত্র ৭। কন্ট্রোল সেন্টার থেকে মিররিং তথ্য গ্রহণ করুন।

ডিবাগ কন্ট্রোল সেন্টার

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-এর মাধ্যমে আপডেট করা যায়।

উৎস থেকে কন্ট্রোল সেন্টার তৈরি করুন

কন্ট্রোল সেন্টারের সোর্স কোড পেতে, “Integrate unbundled apps” দেখুন।

একাধিক ডিসপ্লেতে ব্যবহারকারীর গোপনীয়তা

কন্ট্রোল সেন্টার গাড়ির সকল যাত্রীকে সমস্ত ডিসপ্লেতে মিডিয়া তথ্য দেখার সুযোগ দেয়। ব্যবহারকারীদের অবহিত করার জন্য গুগল একটি নন-ব্লকিং প্রাইভেসি নোটিশ যুক্ত করার পরামর্শ দেয়। গুগল আপনাকে সিস্টেম লেভেলে, অর্থাৎ কোনো ডিসপ্লেতে সাইন ইন করার সময়, এটি করার পরামর্শ দেয়।