फ़ोल्ड किए जा सकने वाले और मल्टी-स्क्रीन वाले डिवाइसों के लिए ऐप्लिकेशन
आम तौर पर, ऐप्लिकेशन को स्टैटिक आइडेंटिफ़ायर या ऐसे लॉजिक पर भरोसा नहीं करना चाहिए जो कुछ डिसप्ले आईडी पर निर्भर करता है. ज़्यादातर मामलों में, ऐप्लिकेशन को अलग-अलग डिसप्ले के हिसाब से साइज़ बदलना चाहिए और काम करना चाहिए. साथ ही, सिस्टम को यह कंट्रोल करना चाहिए कि ऐप्लिकेशन कहां दिखें. उदाहरण के लिए, फ़ोल्ड किए जा सकने वाले डिवाइसों के लिए नया और यूनीक अनुभव तैयार करना. साथ ही, डिवाइस को फ़ोल्ड करने पर बाहरी स्क्रीन पर कोई खास ऐप्लिकेशन लॉन्च करना.
इस मामले में, SystemUI (या कोई अन्य सिस्टम कॉम्पोनेंट) को फ़ोल्ड का पता लगाना चाहिए. साथ ही, यह तय करना चाहिए कि कोई कार्रवाई करना सही है या नहीं. इसके बाद, टारगेट गतिविधि लॉन्च करनी चाहिए और लॉन्च टारगेट के तौर पर बाहरी डिसप्ले आईडी तय करना चाहिए. ऐप्लिकेशन को इस कार्रवाई का पता नहीं चलना चाहिए. साथ ही, इसके जवाब में कोई कार्रवाई नहीं करनी चाहिए. इसके बाद, किसी खास डिसप्ले पर लॉन्च करना चाहिए. दूसरे शब्दों में कहें, तो यह न मान लें कि एक डिवाइस पर काम करने वाला तरीका, दूसरे डिवाइसों पर भी काम करेगा. संक्षेप में कहें, तो डिवाइस के हिसाब से कोड बनाने से फ़्रैगमेंटेशन बढ़ता है.
डिस्प्ले के ऐक्सेस पर पाबंदी लगाना
अगर डिवाइस के कॉन्फ़िगरेशन के लिए, एक या इससे ज़्यादा डिसप्ले के ऐक्सेस को सीमित करने की ज़रूरत है, तो हमारा सुझाव है कि ऐसे डिसप्ले को निजी के तौर पर मार्क करने के लिए, Display#FLAG_PRIVATE फ़्लैग का इस्तेमाल करें. ऐसा करने से, मालिक के अलावा किसी और व्यक्ति को डिसप्ले में कॉन्टेंट जोड़ने की अनुमति नहीं मिलती. अगर मालिक के अलावा कोई और व्यक्ति, गतिविधि लॉन्च करने या विंडो जोड़ने की कोशिश करता है, तो SecurityException दिखता है.
अगर सिस्टम के पास डिसप्ले का मालिकाना हक है, तो सिस्टम विंडो जोड़ सकता है और गतिविधियां लॉन्च कर सकता है.
इसके अलावा, डिसप्ले पर रखी गई इकाइयां, उस डिसप्ले को हमेशा ऐक्सेस कर सकती हैं. अगर मालिक किसी डिसप्ले पर कोई गतिविधि शुरू करता है, तो उस डिसप्ले पर अन्य गतिविधियां शुरू की जा सकती हैं. इसलिए, ऐक्सेस को सीमित करने और सिर्फ़ भरोसेमंद ऐप्लिकेशन को अनुमति देने की ज़िम्मेदारी मालिक की होती है.
इसके अलावा, वर्चुअल डिसप्ले पर ज़्यादा पाबंदियां लगाई गई हैं, क्योंकि कोई भी ऐप्लिकेशन इसे बना सकता है. हालांकि, यह उपयोगकर्ता को नहीं दिखता. अगर वर्चुअल डिसप्ले सिस्टम के मालिकाना हक में नहीं है, तो सिर्फ़ allowEmbedded
वाली गतिविधियां की जा सकती हैं. साथ ही, कॉल करने वाले के पास ACTIVITY_EMBEDDING
अनुमति होनी चाहिए.
ज़्यादा जानकारी के लिए यह देखें:
ActivityStackSupervisor#isCallerAllowedToLaunchOnDisplay()ActivityDisplay#isUidPresent()DisplayManagerService#isUidPresentOnDisplay()
गतिविधि लॉन्च को शर्तों के हिसाब से कंट्रोल करने के लिए, LaunchParamsController का इस्तेमाल करें. यह सभी गतिविधि लॉन्च को इंटरसेप्ट करता है और सिस्टम कॉम्पोनेंट को लॉन्च के लिए इस्तेमाल किए गए पैरामीटर में बदलाव करने की अनुमति देता है. यह सुविधा system_server में उपलब्ध है.
डिसप्ले विंडो की सेटिंग और सिस्टम डेकोरेशन कॉन्फ़िगर करना
DisplayWindowSettings में, हर डिसप्ले के लिए सिस्टम डेकोरेशन कॉन्फ़िगर किए जा सकते हैं. डिवाइस लागू करने वाला व्यक्ति या कंपनी, /data/system/display_settings.xml में डिफ़ॉल्ट कॉन्फ़िगरेशन उपलब्ध करा सकती है.
इस वैल्यू से यह तय होता है कि सिस्टम डेकोरेशन (लॉन्चर, वॉलपेपर, नेविगेशन बार, और अन्य डेकोर विंडो) और IME, डिसप्ले पर दिखेंगे या नहीं.
ज़्यादा जानकारी के लिए, DisplayWindowSettings#shouldShowSystemDecorsLocked()
और DisplayWindowSettings#shouldShowImeLocked() देखें.
डिस्प्ले की पहचान करने के लिए, यूनीक आईडी (डिफ़ॉल्ट रूप से DisplayInfo#uniqueId का इस्तेमाल किया जाता है) या हार्डवेयर डिस्प्ले के लिए फ़िज़िकल पोर्ट आईडी का इस्तेमाल करें (DisplayInfo#address देखें).
उदाहरण के लिए, डिसप्ले कॉन्फ़िगरेशन के इस उदाहरण में, सिम्युलेट किए गए डिसप्ले पर सिस्टम डेकोरेशन और आईएमई चालू किए गए हैं:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <display-settings> <config identifier="0" /> <display name="overlay:1" shouldShowSystemDecors="true" shouldShowIme="true" /> </display-settings>
ऊपर दिए गए उदाहरण में, uniqueId का इस्तेमाल, नाम एट्रिब्यूट में डिसप्ले आइडेंटिफ़िकेशन के लिए किया गया है. वहीं, सिम्युलेटेड डिसप्ले के लिए overlay:1 का इस्तेमाल किया गया है.
बिल्ट-इन डिसप्ले के लिए, सैंपल वैल्यू "local:45354385242535243453" हो सकती है.
एक और विकल्प यह है कि हार्डवेयर पोर्ट की जानकारी का इस्तेमाल करें और identifier="1" को DisplayWindowSettings#IDENTIFIER_PORT के तौर पर सेट करें. इसके बाद, "port:<port_id>" फ़ॉर्मैट का इस्तेमाल करने के लिए नाम अपडेट करें:
<?xmlversion='1.0' encoding='utf-8' standalone='yes' ?> <display-settings> <config identifier="1" /> <display name="port:12345" shouldShowSystemDecors="true" shouldShowIme="true" /> </display-settings>
ज़्यादा जानकारी के लिए, स्टैटिक डिसप्ले आइडेंटिफ़ायर देखें.
ज़्यादा जानकारी के लिए यह देखें:
डिसप्ले को मिरर करने और होस्ट करने के टास्क के बीच स्विच करना
Android 17 और इसके बाद के वर्शन में, DisplayManager FLAG_ALLOWS_CONTENT_MODE_SWITCH फ़्लैग का इस्तेमाल करता है. इससे यह कंट्रोल किया जाता है कि रन टाइम के दौरान, डिसप्ले मिररिंग और होस्टिंग टास्क के बीच स्विच करता है या नहीं. डिफ़ॉल्ट रूप से, यह फ़्लैग बाहरी डिसप्ले के लिए चालू होता है और अन्य सभी डिसप्ले के लिए बंद होता है.
FLAG_ALLOWS_CONTENT_MODE_SWITCH मौजूद होने पर, DisplayManager android.provider.Settings.Secure.MIRROR_BUILT_IN_DISPLAY सुरक्षित सेटिंग की निगरानी करता है. इससे यह तय किया जाता है कि टास्क को मिरर करना है या होस्ट करना है. यह डिफ़ॉल्ट लॉजिक है. हालांकि, ओईएम इस व्यवहार को अपनी पसंद के मुताबिक बना सकते हैं.
टोपोलॉजी और पॉइंटर का मूवमेंट दिखाना
Android 17 और इसके बाद के वर्शन में, डिसप्ले टोपोलॉजी से डिसप्ले की रिलेटिव पोज़िशन तय होती है. साथ ही, इससे माउस पॉइंटर की गतिविधि को टोपोलॉजी में मौजूद डिसप्ले के खास सेट तक सीमित किया जाता है.
WindowManager, टोपोलॉजी में डिसप्ले को शामिल करने का फ़ैसला करता है और DisplayManagerInternal.onDisplayBelongToTopologyChanged को कॉल करता है. DisplayManager, डिसप्ले जोड़ने से पहले DisplayTopologyCoordinator.isDisplayAllowedInTopology की जांच करता है. अगर लोकल डिसप्ले पर टास्क होस्ट किए जा सकते हैं, तो सिस्टम उन्हें डिफ़ॉल्ट रूप से जोड़ देता है.
अगर एक से ज़्यादा सार्वजनिक डिसप्ले पर टास्क होस्ट किए जा सकते हैं, तो डिफ़ॉल्ट डिसप्ले को शामिल करने का फ़ैसला, shouldIncludeDefaultDisplayInTopology बूलियन प्रोवाइडर लेता है. यह प्रोवाइडर, DisplayTopologyCoordinator को पास किया जाता है. अगर डिफ़ॉल्ट डिसप्ले ही ऐसा सार्वजनिक डिसप्ले है जिस पर टास्क होस्ट किए जा सकते हैं, तो यह हमेशा टोपोलॉजी में होता है. AOSP में, बूलियन प्रोवाइडर true सिर्फ़ तब दिखाता है, जब डिफ़ॉल्ट डिसप्ले पर डेस्कटॉप विंडोइंग की सुविधा काम करती हो या जब सुरक्षित सेटिंग Settings.Secure.INCLUDE_DEFAULT_DISPLAY_IN_TOPOLOGY true हो.
ऐप्लिकेशन, DisplayManager.getDisplayTopology का इस्तेमाल करके मौजूदा टोपोलॉजी के बारे में क्वेरी करते हैं. साथ ही, DisplayManager.registerTopologyListener के साथ लिसनर रजिस्टर करके, टोपोलॉजी में होने वाले बदलावों पर प्रतिक्रिया देते हैं.