يتم توفير التحديثات التي تم إجراؤها على هذه المناطق الخاصة بالعرض أدناه:
ديكورات النظام
يضيف Android 10 دعمًا لتكوين شاشات العرض الثانوية لإظهار زخارف نظام معينة، مثل ورق الحائط وشريط التنقل والمشغل. افتراضيًا، تعرض الشاشة الرئيسية جميع زخارف النظام، بينما تعرض شاشات العرض الثانوية تلك التي تم تمكينها اختياريًا. يمكن تعيين دعم محرر أسلوب الإدخال (IME) بشكل منفصل عن زخارف النظام الأخرى.
استخدم DisplayWindowSettings#setShouldShowSystemDecorsLocked()
لإضافة دعم لزخارف النظام على شاشة معينة أو توفير قيمة افتراضية في /data/system/display_settings.xml
. على سبيل المثال، راجع إعدادات نافذة العرض .
تطبيق
يتم عرض DisplayWindowSettings#setShouldShowSystemDecorsLocked()
أيضًا في WindowManager#setShouldShowSystemDecors()
للاختبار. لا يؤدي تشغيل هذه الطريقة بهدف تمكين ديكورات النظام إلى إضافة نوافذ الديكور التي كانت مفقودة سابقًا، أو إزالتها إذا كانت موجودة مسبقًا. في معظم الحالات، لا يسري تغيير دعم زخارف النظام بشكل كامل إلا بعد إعادة تشغيل الجهاز.
عادةً ما تمر عمليات التحقق من دعم زخارف النظام في قاعدة التعليمات البرمجية لـ WindowManager عبر DisplayContent#supportsSystemDecorations()
بينما تستخدم عمليات التحقق من الخدمات الخارجية (مثل واجهة مستخدم النظام للتحقق مما إذا كان يجب إظهار شريط التنقل) WindowManager#shouldShowSystemDecors()
. لفهم ما يتم التحكم فيه بواسطة هذا الإعداد، استكشف نقاط الاتصال الخاصة بهذه الطرق.
نوافذ ديكور واجهة المستخدم للنظام
يضيف Android 10 دعم نافذة ديكور النظام لشريط التنقل فقط ، لأن شريط التنقل ضروري للتنقل بين الأنشطة والتطبيقات. افتراضيًا، يعرض شريط التنقل إمكانيات العودة والمنزل. يتم تضمين ذلك فقط إذا كانت شاشة العرض المستهدفة تدعم زخارف النظام (راجع DisplayWindowSettings
).
يعد شريط الحالة نافذة نظام أكثر تعقيدًا، لأنه يحتوي أيضًا على مركز الإشعارات والإعدادات السريعة وشاشة القفل. في Android 10، لا يتم دعم شريط الحالة على شاشات العرض الثانوية. لذلك، تتوفر الإشعارات والإعدادات ولوحة المفاتيح الكاملة فقط على الشاشة الرئيسية.
نافذة النظام "نظرة عامة/الحديثة" غير مدعومة على الشاشات الثانوية. في Android 10، يعرض AOSP فقط الأحداث الأخيرة على الشاشة الافتراضية ويحتوي على أنشطة من جميع شاشات العرض. عند التشغيل من الأنشطة الأخيرة، يتم عرض النشاط الذي كان موجودًا على شاشة ثانوية إلى المقدمة على تلك الشاشة، بشكل افتراضي. يحتوي هذا الأسلوب على بعض المشكلات المعروفة، مثل عدم التحديث فورًا عند ظهور التطبيقات على شاشات أخرى.
تطبيق
لتنفيذ ميزات إضافية لواجهة مستخدم النظام، يجب على الشركات المصنعة للأجهزة استخدام مكون واحد لواجهة مستخدم النظام الذي يستمع إلى إضافة/إزالة شاشات العرض ويقدم المحتوى المناسب.
يجب أن يتعامل مكون واجهة مستخدم النظام الذي يدعم العرض المتعدد (MD) مع الحالات التالية:
- تهيئة العرض المتعدد عند بدء التشغيل
- تمت إضافة العرض في وقت التشغيل
- تمت إزالة العرض في وقت التشغيل
عندما تكتشف واجهة مستخدم النظام إضافة شاشة عرض قبل WindowManager، فإنها تقوم بإنشاء حالة سباق. يمكن تجنب ذلك عن طريق تنفيذ رد اتصال مخصص من WindowManager إلى System UI عند إضافة شاشة عرض بدلاً من الاشتراك في أحداث DisplayManager .DisplayListener
. للحصول على تطبيق مرجعي، راجع CommandQueue.Callbacks#onDisplayReady
لدعم شريط التنقل و WallpaperManagerInternal#onDisplayReady
للخلفيات.
بالإضافة إلى ذلك، يوفر Android 10 هذه التحديثات:
- تتحكم فئة
NavigationBarController
في جميع الوظائف الخاصة بأشرطة التنقل. - لعرض شريط التنقل المخصص، راجع
CarStatusBar
. - لم يعد
TYPE_NAVIGATION_BAR
يقتصر على مثيل واحد ويمكن استخدامه لكل شاشة عرض. - تم تحديث
IWindowManager#hasNavigationBar()
ليشمل معلمةdisplayId
لواجهة مستخدم النظام فقط.
منصة الإطلاق
في Android 10، تحتوي كل شاشة تم تكوينها لدعم زخارف النظام على حزمة رئيسية مخصصة لأنشطة المشغل من النوع WindowConfiguration#ACTIVITY_TYPE_HOME
افتراضيًا. تستخدم كل شاشة مثيلًا منفصلاً لنشاط المشغل.
الشكل 1. مثال على مشغل الشاشات المتعددة 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 (والإصدارات الأحدث)، يتم دعم الخلفيات على شاشات العرض الثانوية:
الشكل 2. خلفية حية على شاشات العرض الداخلية (أعلاه) والخارجية (أدناه)
يمكن للمطورين الإعلان عن دعم ميزة الخلفية من خلال توفير android:supportsMultipleDisplays="true"
في تعريف WallpaperInfo
XML. من المتوقع أيضًا أن يقوم مطورو الخلفيات بتحميل الأصول باستخدام سياق العرض في WallpaperService.Engine#getDisplayContext()
.
يقوم إطار العمل بإنشاء مثيل WallpaperService.Engine
واحد لكل شاشة عرض، بحيث يكون لكل محرك سطحه الخاص وسياق العرض الخاص به. يحتاج المطور إلى التأكد من أن كل محرك يمكنه الرسم بشكل مستقل، وبمعدلات إطارات مختلفة، مع احترام VSYNC.
حدد خلفيات للشاشات الفردية
لا يوفر Android 10 دعمًا مباشرًا للنظام الأساسي لاختيار خلفيات للشاشات الفردية. لتحقيق ذلك، هناك حاجة إلى معرف عرض ثابت للحفاظ على إعدادات خلفية الشاشة لكل شاشة عرض. Display#getDisplayId()
ديناميكي، لذلك ليس هناك ضمان بأن الشاشة الفعلية سيكون لها نفس المعرف بعد إعادة التشغيل.
ومع ذلك، أضاف Android 10 DisplayInfo.mAddress
، الذي يحتوي على معرفات ثابتة للشاشات الفعلية ويمكن استخدامه للتنفيذ الكامل في المستقبل. لسوء الحظ، فات الأوان لتطبيق المنطق الخاص بنظام Android 10. الحل المقترح:
- استخدم
WallpaperManager
API لتعيين الخلفيات. - يتم الحصول على
WallpaperManager
من كائنContext
، وكل كائنContext
لديه معلومات حول العرض المقابل (Context#getDisplay()/getDisplayId()
). لذلك، يمكنك الحصول علىdisplayId
من مثيلWallpaperManager
دون إضافة أساليب جديدة. - على جانب إطار العمل، استخدم
displayId
الذي تم الحصول عليه من كائنContext
وقم بتعيينه إلى معرف ثابت (مثل منفذ العرض الفعلي). استخدم المعرف الثابت للاستمرار في خلفية الشاشة المختارة.
يستخدم هذا الحل البديل التطبيقات الموجودة لمنتقي الخلفيات. إذا تم فتحه على شاشة معينة ويستخدم السياق الصحيح، فعندما يستدعي تعيين خلفية الشاشة، يمكن للنظام التعرف تلقائيًا على الشاشة.
إذا كانت هناك حاجة لتعيين خلفية شاشة لشاشة عرض أخرى غير الشاشة الحالية، فقم بإنشاء كائن Context
جديد للشاشة المستهدفة ( Context#createDisplayContext
) واحصل على مثيل WallpaperManager
من شاشة العرض تلك.
القيود الأمنية
لن يعرض النظام خلفيات على شاشات العرض الافتراضية التي لا يملكها. ويرجع ذلك إلى مخاوف أمنية تتمثل في إمكانية قيام تطبيق ضار بإنشاء شاشة عرض افتراضية مع دعم زخارف النظام الممكّن وقراءة المعلومات الحساسة للمستخدم من السطح (مثل الصورة الشخصية).
تطبيق
في Android 10، تقبل واجهات IWallpaperConnection#attachEngine()
و IWallpaperService#attach()
معلمة displayId
لإنشاء اتصالات لكل شاشة. يقوم WallpaperManagerService.DisplayConnector
بتغليف محرك خلفية الشاشة والاتصال. في WindowManager، يتم إنشاء وحدات تحكم خلفية الشاشة لكل كائن DisplayContent
عند الإنشاء بدلاً من WallpaperController
واحدة لجميع شاشات العرض.
تم تحديث بعض تطبيقات طريقة WallpaperManager
العامة (مثل WallpaperManager#getDesiredMinimumWidth()
) لحساب وتوفير المعلومات لشاشات العرض المقابلة. تمت إضافة WallpaperInfo#supportsMultipleDisplays()
وسمة المورد المقابلة، بحيث يمكن لمطوري التطبيقات الإبلاغ عن الخلفيات الجاهزة لشاشات متعددة.
إذا كانت خدمة خلفية الشاشة المعروضة على شاشة العرض الافتراضية لا تدعم شاشات العرض المتعددة، فسيعرض النظام خلفية الشاشة الافتراضية على شاشات العرض الثانوية.
الشكل 3. المنطق الاحتياطي للخلفية للشاشات الثانوية