دعم زخارف النظام

تنظيم صفحاتك في مجموعات يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.

يتم توفير التحديثات التي تم إجراؤها على هذه المناطق الخاصة بالعرض أدناه:

زخارف النظام

يضيف Android 10 دعمًا لتكوين شاشات العرض الثانوية لإظهار بعض زخارف النظام ، مثل الخلفية وشريط التنقل والقاذفة. بشكل افتراضي ، تُظهر الشاشة الأساسية جميع زخارف النظام ، بينما تُظهر الشاشات الثانوية تلك الممكّنة اختياريًا. يمكن تعيين دعم محرر أسلوب الإدخال (IME) بشكل منفصل عن زخارف النظام الأخرى.

استخدم DisplayWindowSettings#setShouldShowSystemDecorsLocked() لإضافة دعم لزخارف النظام على شاشة معينة أو توفير قيمة افتراضية في /data/system/display_settings.xml . للحصول على أمثلة ، راجع إعدادات نافذة العرض .

تطبيق

DisplayWindowSettings#setShouldShowSystemDecorsLocked() تعرض أيضًا في WindowManager#setShouldShowSystemDecors() للاختبار. لا يؤدي تشغيل هذه الطريقة بقصد تمكين ديكورات النظام إلى إضافة نوافذ ديكور كانت مفقودة سابقًا ، أو إزالتها إذا كانت موجودة مسبقًا. في معظم الحالات ، لا يسري تغيير دعم زخارف النظام بالكامل إلا بعد إعادة تشغيل الجهاز.

عمليات التحقق من دعم زخارف النظام في قاعدة التعليمات البرمجية لـ WindowManager تمر عادةً عبر DisplayContent#supportsSystemDecorations() أثناء عمليات التحقق من الخدمات الخارجية (مثل System UI للتحقق مما إذا كان يجب عرض شريط التنقل) استخدم WindowManager#shouldShowSystemDecors() . لفهم ما يتحكم فيه هذا الإعداد ، استكشف نقاط الاتصال لهذه الطرق.

نظام نوافذ ديكور واجهة المستخدم

يضيف Android 10 دعم نافذة ديكور النظام لشريط التنقل فقط ، لأن شريط التنقل ضروري للتنقل بين الأنشطة والتطبيقات. بشكل افتراضي ، يعرض شريط التنقل إمكانيات العودة والمنزل. يتم تضمين ذلك فقط إذا كانت شاشة العرض المستهدفة تدعم زخارف النظام (راجع DisplayWindowSettings ).

يعد شريط الحالة نافذة نظام أكثر تعقيدًا ، لأنه يحتوي أيضًا على Notification Shade و Quick Settings و Lock Screen. في Android 10 ، لا يتم دعم شريط الحالة على شاشات العرض الثانوية. لذلك ، لا تتوفر الإشعارات والإعدادات وحارس المفاتيح الكامل إلا على الشاشة الأساسية.

لا يتم دعم نافذة النظرة العامة / الأخيرة للنظام على الشاشات الثانوية. في Android 10 ، يعرض AOSP فقط Recents على الشاشة الافتراضية ويحتوي على أنشطة من جميع شاشات العرض. عند بدء التشغيل من Recents ، يتم عرض نشاط كان على شاشة ثانوية في المقدمة على تلك الشاشة افتراضيًا. يحتوي هذا الأسلوب على بعض المشكلات المعروفة ، مثل عدم التحديث فورًا عند ظهور التطبيقات على الشاشات الأخرى.

تطبيق

لتنفيذ ميزات واجهة مستخدم النظام الإضافية ، يجب على الشركات المصنعة للأجهزة استخدام مكون واحد لواجهة مستخدم النظام الذي يستمع إلى إضافة / إزالة شاشات العرض وتقديم المحتوى المناسب.

يجب أن يتعامل مكون واجهة مستخدم النظام الذي يدعم العرض المتعدد (MD) مع الحالات التالية:

  • عرض متعدد التهيئة عند بدء التشغيل
  • تمت إضافة العرض في وقت التشغيل
  • تمت إزالة العرض في وقت التشغيل

عندما يكتشف System UI إضافة شاشة قبل WindowManager ، فإنه ينشئ حالة سباق. يمكن تجنب ذلك من خلال تنفيذ رد اتصال مخصص من WindowManager إلى واجهة مستخدم النظام عند إضافة عرض بدلاً من الاشتراك في DisplayManager .DisplayListener events. لتطبيق مرجعي ، راجع CommandQueue.Callbacks#onDisplayReady لدعم شريط التنقل و WallpaperManagerInternal#onDisplayReady for wallpapers.

بالإضافة إلى ذلك ، يوفر 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. الحل المقترح:

  1. استخدم WallpaperManager API لتعيين الخلفيات.
  2. يتم الحصول على WallpaperManager من كائن Context ، وكل كائن Context يحتوي على معلومات حول العرض المقابل ( Context#getDisplay()/getDisplayId() ). لذلك ، يمكنك الحصول على displayId من مثيل WallpaperManager بدون إضافة طرق جديدة.
  3. على جانب إطار العمل ، استخدم displayId تم الحصول عليه من كائن Context وقم بتعيينه إلى معرف ثابت (مثل منفذ العرض المادي). استخدم المعرف الثابت لاستمرار الخلفية المختارة.

يستخدم هذا الحل البديل عمليات التنفيذ الموجودة لمنتقي الخلفيات. إذا تم فتحه على شاشة معينة واستخدم السياق الصحيح ، فعندما يستدعي تعيين خلفية ، يمكن للنظام تحديد الشاشة تلقائيًا.

إذا كانت هناك حاجة لتعيين خلفية لعرض آخر غير الشاشة الحالية ، فقم بإنشاء كائن Context جديد للعرض الهدف ( Context#createDisplayContext ) واحصل على مثيل WallpaperManager من تلك الشاشة.

قيود أمنية

لن يعرض النظام خلفيات على شاشات افتراضية لا يمتلكها. ويرجع ذلك إلى مخاوف أمنية من أن أحد التطبيقات الضارة يمكن أن ينشئ شاشة افتراضية مع دعم زخارف النظام الممكّنة وقراءة معلومات حساسة للمستخدم من السطح (مثل صورة شخصية).

تطبيق

في Android 10 ، IWallpaperConnection#attachEngine() و IWallpaperService#attach() معلمة displayId لإنشاء اتصالات لكل شاشة. WallpaperManagerService.DisplayConnector يغلف محرك خلفية واتصال لكل شاشة عرض. في WindowManager ، يتم إنشاء وحدات تحكم خلفية الشاشة لكل كائن DisplayContent عند الإنشاء بدلاً من متحكم ورق WallpaperController واحد لجميع شاشات العرض.

تم تحديث بعض تطبيقات طريقة WallpaperManager العامة (مثل WallpaperManager#getDesiredMinimumWidth() ) لحساب وتوفير المعلومات لشاشات العرض المقابلة. WallpaperInfo#supportsMultipleDisplays() تمت إضافة سمة مورد مقابلة ، بحيث يمكن لمطوري التطبيق الإبلاغ عن الخلفيات الجاهزة لشاشات متعددة.

إذا كانت خدمة الخلفية المعروضة على الشاشة الافتراضية لا تدعم شاشات العرض المتعددة ، فإن النظام يعرض الخلفية الافتراضية على شاشات العرض الثانوية.

الشكل 3. منطق الرجوع للخلفية للشاشات الثانوية