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

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

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

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

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

लागू करना

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

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

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

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

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

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

लागू करना

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

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

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

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

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

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

लॉन्चर

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

पहली इमेज. platform/development/samples/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. फ़्रेमवर्क की ओर, Context ऑब्जेक्ट से मिले displayId का इस्तेमाल करें और इसे किसी स्टैटिक आइडेंटिफ़ायर (जैसे कि फ़िज़िकल डिसप्ले का पोर्ट) से मैप करें. चुने गए वॉलपेपर को सेव करने के लिए, स्टैटिक आइडेंटिफ़ायर का इस्तेमाल करें.

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

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

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

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

लागू करना

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

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

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

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

लाइव वॉलपेपर की सुविधा चालू करना

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

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

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

अगर आपका हार्डवेयर, लाइव वॉलपेपर के एक से ज़्यादा इंस्टेंस रेंडर कर सकता है, तो इस कॉन्फ़िगरेशन को बदलें:

संसाधन का पाथ frameworks/base/core/res/res/values/config.xml
कॉन्फ़िगरेशन का नाम config_isLiveWallpaperSupportedInDesktopExperience

फ़ॉलबैक वॉलपेपर को कस्टमाइज़ करना

अगर लाइव वॉलपेपर की सुविधा बंद है या सेवा देने वाली कंपनी के पास यह सुविधा उपलब्ध नहीं है, तो सिस्टम डिफ़ॉल्ट कॉम्पोनेंट का इस्तेमाल करता है. इसे अपने स्टैटिक वॉलपेपर सेवा देने वाली कंपनी पर पॉइंट किया जा सकता है:

संसाधन का पाथ frameworks/base/core/res/res/values/config.xml
कॉन्फ़िगरेशन का नाम fallback_wallpaper_component

वॉलपेपर की सुविधा लागू करना

इन बदलावों को लागू करने के लिए, अपने डिवाइस के हिसाब से फ़ोल्डर में, बिल्ड-टाइम रिसॉर्स ओवरले का इस्तेमाल करें. आम तौर पर, यह device/<vendor>/<product>/overlay/frameworks/base/core/res/res/values/ होता है.