सिस्टम डेकोरेशन के लिए सहायता

डिस्प्ले से जुड़ी इन खास जगहों में किए गए अपडेट, इस पेज पर दिए जाते हैं.

सिस्टम डेकोरेशन

Android 10 में, सेकंडरी डिसप्ले को कॉन्फ़िगर करने की सुविधा जोड़ी गई है. इससे वॉलपेपर, नेविगेशन बार, और लॉन्चर जैसे सिस्टम डेकोरेशन दिखाए जा सकते हैं. डिफ़ॉल्ट रूप से, प्राइमरी डिसप्ले पर सिस्टम के सभी डेकोरेशन दिखते हैं. वहीं, सेकंडरी डिसप्ले पर वे डेकोरेशन दिखते हैं जिन्हें चालू किया गया है. इनपुट मेथड एडिटर (आईएमई) के लिए सहायता को अन्य सिस्टम डेकोरेशन से अलग सेट किया जा सकता है.

DisplayWindowSettings#setShouldShowSystemDecorsLocked() का इस्तेमाल करके, किसी डिसप्ले पर सिस्टम डेकोरेशन की सुविधा जोड़ी जा सकती है. इसके अलावा, /data/system/display_settings.xml में डिफ़ॉल्ट वैल्यू दी जा सकती है. उदाहरणों के लिए, डिसप्ले विंडो की सेटिंग देखें.

लागू करना

DisplayWindowSettings#setShouldShowSystemDecorsLocked() को टेस्टिंग के लिए WindowManager#setShouldShowSystemDecors() में भी दिखाया जाता है. सिस्टम डेकोर चालू करने के लिए इस तरीके को ट्रिगर करने से, वे डेकोर विंडो नहीं जुड़ती हैं जो पहले मौजूद नहीं थीं. साथ ही, अगर वे पहले से मौजूद थीं, तो उन्हें हटाया भी नहीं जाता. ज़्यादातर मामलों में, सिस्टम डेकोरेशन के लिए सहायता में बदलाव, डिवाइस को रीबूट करने के बाद ही पूरी तरह से लागू होता है.

WindowManager के कोड बेस में सिस्टम डेकोरेशन के साथ काम करने की सुविधा की जाँच करने के लिए, आम तौर पर DisplayContent#supportsSystemDecorations() का इस्तेमाल किया जाता है. वहीं, बाहरी सेवाओं की जाँच करने के लिए WindowManager#shouldShowSystemDecors() का इस्तेमाल किया जाता है. जैसे, System UI यह जाँच करता है कि नेविगेशन बार दिखना चाहिए या नहीं. यह सेटिंग क्या कंट्रोल करती है, यह समझने के लिए इन तरीकों के कॉल पॉइंट देखें.

सिस्टम यूज़र इंटरफ़ेस (यूआई) डेकोर विंडो

Android 10 में, नेविगेशन बार के लिए सिस्टम डेकोर विंडो की सुविधा जोड़ी गई है. हालांकि, यह सुविधा सिर्फ़ नेविगेशन बार के लिए है, क्योंकि गतिविधियों और ऐप्लिकेशन के बीच नेविगेट करने के लिए नेविगेशन बार ज़रूरी है. डिफ़ॉल्ट रूप से, नेविगेशन बार में 'वापस जाएं' और 'होम' बटन दिखते हैं. इसे सिर्फ़ तब शामिल किया जाता है, जब टारगेट डिसप्ले, सिस्टम डेकोरेशन के साथ काम करता हो (DisplayWindowSettings देखें).

स्टेटस बार, सिस्टम विंडो का एक ज़्यादा जटिल हिस्सा है. इसकी वजह यह है कि इसमें सूचना शेड, क्विक सेटिंग, और लॉक स्क्रीन भी शामिल होती हैं. Android 10 में, स्टेटस बार की सुविधा सेकंडरी डिसप्ले पर काम नहीं करती. इसलिए, सूचनाएं, सेटिंग, और पूरा कीगार्ड सिर्फ़ प्राइमरी डिसप्ले पर उपलब्ध होता है.

खास जानकारी/हाल ही के सिस्टम विंडो, सेकंडरी स्क्रीन पर काम नहीं करती है. Android 10 में, AOSP सिर्फ़ डिफ़ॉल्ट डिसप्ले पर 'हाल में इस्तेमाल किए गए ऐप्लिकेशन' दिखाता है. इसमें सभी डिसप्ले की गतिविधियां शामिल होती हैं. 'हाल ही के ऐप्लिकेशन' से लॉन्च करने पर, सेकंडरी डिसप्ले पर चल रही गतिविधि डिफ़ॉल्ट रूप से उस डिसप्ले पर सबसे ऊपर आ जाती है. इस तरीके से जुड़ी कुछ समस्याएं हैं. जैसे, जब ऐप्लिकेशन दूसरी स्क्रीन पर दिखते हैं, तब वे तुरंत अपडेट नहीं होते.

लागू करना

सिस्टम यूज़र इंटरफ़ेस (यूआई) की अतिरिक्त सुविधाओं को लागू करने के लिए, डिवाइस बनाने वाली कंपनियों को एक ही सिस्टम यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट का इस्तेमाल करना चाहिए. यह कॉम्पोनेंट, डिसप्ले के जुड़ने या हटने की जानकारी देता है और सही कॉन्टेंट दिखाता है.

मल्टी-डिसप्ले (एमडी) की सुविधा के साथ काम करने वाले सिस्टम यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट को इन मामलों को मैनेज करना चाहिए:

  • डिवाइस चालू होने पर, एक से ज़्यादा डिसप्ले शुरू करना
  • रन टाइम पर डिसप्ले जोड़ा गया
  • डिसप्ले को रन टाइम पर हटाया गया

जब System UI, WindowManager से पहले डिसप्ले जोड़ने का पता लगाता है, तो यह रेस कंडीशन बनाता है. DisplayManager.DisplayListener इवेंट की सदस्यता लेने के बजाय, डिसप्ले जोड़े जाने पर WindowManager से System UI तक कस्टम कॉलबैक लागू करके, इस समस्या से बचा जा सकता है. रेफ़रंस के तौर पर लागू करने के लिए, नेविगेशन बार के साथ काम करने वाले CommandQueue.Callbacks#onDisplayAddSystemDecorations और वॉलपेपर के लिए WallpaperManagerInternal#onDisplayAddSystemDecorations देखें.

इसके अलावा, Android 10 में ये अपडेट भी दिए गए हैं:

  • NavigationBarController क्लास, नेविगेशन बार से जुड़ी सभी सुविधाओं को कंट्रोल करती है.
  • अपनी पसंद के मुताबिक बनाया गया नेविगेशन बार देखने के लिए, CarStatusBar पर जाएं.
  • TYPE_NAVIGATION_BAR को अब एक ही इंस्टेंस तक सीमित नहीं रखा गया है. इसका इस्तेमाल हर डिसप्ले के लिए किया जा सकता है.
  • IWindowManager#hasNavigationBar() को अपडेट किया गया है, ताकि इसमें सिर्फ़ सिस्टम यूज़र इंटरफ़ेस (यूआई) के लिए displayId पैरामीटर शामिल किया जा सके.

लॉन्चर

Android 10 में, सिस्टम डेकोरेशन के साथ काम करने के लिए कॉन्फ़िगर किए गए हर डिसप्ले में, डिफ़ॉल्ट रूप से लॉन्चर की गतिविधियों के लिए एक होम स्टैक होता है. इसका टाइप WindowConfiguration#ACTIVITY_TYPE_HOME होता है. हर डिसप्ले, लॉन्चर ऐक्टिविटी के अलग-अलग इंस्टेंस का इस्तेमाल करता है:

पहली इमेज. मल्टी-डिसप्ले लॉन्चर का उदाहरण, प्लैटफ़ॉर्म/डेवलपमेंट/सैंपल/MultiDisplay के लिए.

ज़्यादातर मौजूदा लॉन्चर, एक से ज़्यादा इंस्टेंस के साथ काम नहीं करते. साथ ही, इन्हें बड़ी स्क्रीन के साइज़ के लिए ऑप्टिमाइज़ नहीं किया गया है. साथ ही, सेकंडरी/बाहरी डिसप्ले पर अक्सर अलग तरह के अनुभव की उम्मीद की जाती है. सेकंडरी स्क्रीन के लिए खास गतिविधि उपलब्ध कराने के लिए, Android 10 ने इंटेंट फ़िल्टर में SECONDARY_HOME कैटगरी पेश की है. इस गतिविधि के इंस्टेंस का इस्तेमाल उन सभी डिसप्ले पर किया जाता है जिन पर सिस्टम डेकोरेशन काम करते हैं. हर डिसप्ले पर एक इंस्टेंस का इस्तेमाल किया जाता है.

<activity>
    ...
    <intent-filter>
        <category android:name="android.intent.category.SECONDARY_HOME" />
        ...
    </intent-filter>
</activity>

गतिविधि का लॉन्च मोड ऐसा होना चाहिए जिससे एक से ज़्यादा इंस्टेंस को रोका न जा सके. साथ ही, यह अलग-अलग स्क्रीन साइज़ के हिसाब से अडजस्ट हो सके. लॉन्च मोड singleInstance या singleTask नहीं हो सकता.

लागू करना

Android 10 में, RootActivityContainer#startHomeOnDisplay() होम स्क्रीन लॉन्च करने के लिए इस्तेमाल किए गए डिसप्ले के हिसाब से, मनचाहे कॉम्पोनेंट और इंटेंट को अपने-आप चुन लेता है. RootActivityContainer#resolveSecondaryHomeActivity() में, चुने गए लॉन्चर के हिसाब से लॉन्चर ऐक्टिविटी कॉम्पोनेंट को ढूंढने का लॉजिक होता है. साथ ही, ज़रूरत पड़ने पर सिस्टम के डिफ़ॉल्ट लॉन्चर का इस्तेमाल किया जा सकता है (ActivityTaskManagerService#getSecondaryHomeIntent() देखें).

सुरक्षा से जुड़ी पाबंदियां

सेकंडरी डिसप्ले पर की जाने वाली गतिविधियों पर लागू होने वाली पाबंदियों के अलावा, नुकसान पहुंचाने वाले ऐप्लिकेशन को सिस्टम डेकोरेशन चालू करके वर्चुअल डिसप्ले बनाने और उपयोगकर्ता की संवेदनशील जानकारी को पढ़ने से रोकने के लिए, लॉन्चर सिर्फ़ सिस्टम के मालिकाना हक वाले वर्चुअल डिसप्ले पर दिखता है. लॉन्चर, सिस्टम के वर्चुअल डिसप्ले के अलावा किसी और वर्चुअल डिसप्ले पर कॉन्टेंट नहीं दिखाता है.

वॉलपेपर बदलने के लिए ऐप्लिकेशन

Android 10 और इसके बाद के वर्शन में, सेकंडरी डिस्प्ले पर वॉलपेपर इस्तेमाल किए जा सकते हैं:

दूसरी इमेज. इंटरनल (ऊपर) और एक्सटर्नल डिसप्ले (नीचे) पर लाइव वॉलपेपर.

डेवलपर, वॉलपेपर की सुविधा के लिए सहायता का एलान कर सकते हैं. इसके लिए, उन्हें WallpaperInfo एक्सएमएल डेफ़िनिशन में android:supportsMultipleDisplays="true" देना होगा. वॉलपेपर डेवलपर से भी यह उम्मीद की जाती है कि वे WallpaperService.Engine#getDisplayContext() में डिसप्ले कॉन्टेक्स्ट का इस्तेमाल करके ऐसेट लोड करें.

फ़्रेमवर्क, हर डिसप्ले के लिए एक WallpaperService.Engine इंस्टेंस बनाता है. इसलिए, हर इंजन का अपना सर्फ़ेस और डिसप्ले कॉन्टेक्स्ट होता है. डेवलपर को यह पक्का करना होगा कि हर इंजन, अलग-अलग फ़्रेम रेट पर स्वतंत्र रूप से ड्रॉ कर सकता हो. साथ ही, वह VSync का पालन करता हो.

हर स्क्रीन के लिए अलग-अलग वॉलपेपर चुनना

Android 10 में, अलग-अलग स्क्रीन के लिए वॉलपेपर चुनने की सुविधा नहीं है. इसके लिए, हर डिसप्ले के हिसाब से वॉलपेपर की सेटिंग को सेव रखने के लिए, एक स्टेबल डिसप्ले आइडेंटिफ़ायर की ज़रूरत होती है. Display#getDisplayId() डाइनैमिक होता है. इसलिए, इस बात की कोई गारंटी नहीं है कि रीबूट करने के बाद, किसी फ़िज़िकल डिसप्ले का आईडी वही रहेगा.

हालांकि, Android 10 में DisplayInfo.mAddress जोड़ा गया है. इसमें फ़िज़िकल डिसप्ले के लिए स्टेबल आइडेंटिफ़ायर होते हैं. इसका इस्तेमाल आने वाले समय में पूरी तरह से लागू करने के लिए किया जा सकता है. माफ़ करें, Android 10 के लिए लॉजिक लागू करने में देरी हो गई है. सुझाया गया समाधान:

  1. वॉलपेपर सेट करने के लिए, WallpaperManager क्लास का इस्तेमाल करें.

    WallpaperManager को Context ऑब्जेक्ट से हासिल किया जाता है. साथ ही, हर Context ऑब्जेक्ट में, उससे जुड़े डिसप्ले (Context#getDisplay()/getDisplayId()) की जानकारी होती है. इसलिए, नए तरीके जोड़े बिना, WallpaperManager इंस्टेंस से displayId हासिल किया जा सकता है.

  2. फ़्रेमवर्क की ओर से, displayId का इस्तेमाल करें. यह Context ऑब्जेक्ट से मिलता है. साथ ही, इसे स्टैटिक आइडेंटिफ़ायर (जैसे कि फ़िज़िकल डिसप्ले का पोर्ट) पर मैप करें. चुने गए वॉलपेपर को बनाए रखने के लिए, स्टैटिक आइडेंटिफ़ायर का इस्तेमाल करें.

इस तरीके में, वॉलपेपर पिकर के लिए मौजूदा सुविधाओं का इस्तेमाल किया जाता है. अगर इसे किसी खास डिसप्ले पर खोला गया था और यह सही कॉन्टेक्स्ट का इस्तेमाल करता है, तो वॉलपेपर सेट करने के लिए कॉल करने पर, सिस्टम डिसप्ले की पहचान अपने-आप कर सकता है.

अगर आपको मौजूदा डिसप्ले के अलावा किसी दूसरे डिसप्ले के लिए वॉलपेपर सेट करना है, तो टारगेट डिसप्ले (Context#createDisplayContext) के लिए एक नया Context ऑब्जेक्ट बनाएं. इसके बाद, उस डिसप्ले से WallpaperManager इंस्टेंस पाएं.

सुरक्षा से जुड़ी पाबंदियां

सिस्टम, उन वर्चुअल डिसप्ले पर वॉलपेपर नहीं दिखाएगा जिनका मालिकाना हक उसके पास नहीं है. सुरक्षा से जुड़ी समस्या की वजह से ऐसा होता है. कोई नुकसान पहुंचाने वाला ऐप्लिकेशन, सिस्टम डेकोरेशन की सुविधा चालू करके वर्चुअल डिसप्ले बना सकता है. साथ ही, उपयोगकर्ता की संवेदनशील जानकारी को सर्फ़ेस से पढ़ सकता है. जैसे, निजी फ़ोटो.

लागू करना

Android 10 में, IWallpaperConnection#attachEngine() और IWallpaperService#attach() इंटरफ़ेस, डिसप्ले के हिसाब से कनेक्शन बनाने के लिए displayId पैरामीटर स्वीकार करते हैं. WallpaperManagerService.DisplayConnector में, हर डिसप्ले के लिए वॉलपेपर इंजन और कनेक्शन होता है. WindowManager में, वॉलपेपर कंट्रोलर हर DisplayContent ऑब्जेक्ट के लिए कंस्ट्रक्शन के समय बनाए जाते हैं. ऐसा सभी डिसप्ले के लिए एक WallpaperController बनाने के बजाय किया जाता है.

सार्वजनिक WallpaperManager के कुछ तरीके (जैसे कि WallpaperManager#getDesiredMinimumWidth()) अपडेट किए गए थे, ताकि उनसे जुड़े डिसप्ले के लिए जानकारी का हिसाब लगाया जा सके और जानकारी दी जा सके. WallpaperInfo#supportsMultipleDisplays() और इससे जुड़ा संसाधन एट्रिब्यूट जोड़ा गया है, ताकि ऐप्लिकेशन डेवलपर यह रिपोर्ट कर सकें कि कौनसे वॉलपेपर कई स्क्रीन के लिए तैयार हैं.

अगर डिफ़ॉल्ट डिसप्ले पर दिखने वाली वॉलपेपर सेवा, एक से ज़्यादा डिसप्ले के साथ काम नहीं करती है, तो सिस्टम सेकंडरी डिसप्ले पर डिफ़ॉल्ट वॉलपेपर दिखाता है:

तीसरी इमेज. सेकंडरी डिसप्ले के लिए वॉलपेपर फ़ॉलबैक लॉजिक.