إتاحة زينة النظام

تظهر التعديلات التي تم إجراؤها على هذه المناطق الخاصة بالشاشة في هذه الصفحة.

عناصر تزيين النظام

يتيح نظام التشغيل 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) مع الحالات التالية:

  • إعداد شاشات متعددة عند بدء التشغيل
  • الشاشة المُضافة أثناء التشغيل
  • الشاشة المزالة أثناء التشغيل

عندما يرصد System UI إضافة شاشة عرض قبل WindowManager، يؤدي ذلك إلى حدوث حالة سباق. يمكنك تجنُّب ذلك من خلال تنفيذ دالة ردّ اتصال مخصّصة من WindowManager إلى واجهة مستخدم النظام عند إضافة شاشة بدلاً من الاشتراك في أحداث DisplayManager.DisplayListener. للحصول على نموذج تنفيذ، راجِع CommandQueue.Callbacks#onDisplayAddSystemDecorations بشأن إتاحة شريط التنقّل وWallpaperManagerInternal#onDisplayAddSystemDecorations بشأن خلفيات الشاشة.

بالإضافة إلى ذلك، يوفّر نظام التشغيل Android 10 التحديثات التالية:

  • يتحكّم الصف NavigationBarController في جميع الوظائف الخاصة بأشرطة التنقّل.
  • للاطّلاع على شريط تنقّل مخصّص، يُرجى الاطّلاع على CarStatusBar.
  • لم يعُد استخدام TYPE_NAVIGATION_BAR محصورًا بمثيل واحد، بل يمكن استخدامه لكل شاشة عرض.
  • تم تعديل IWindowManager#hasNavigationBar() ليشمل المَعلمة displayId لواجهة مستخدم النظام فقط.

مشغِّل التطبيقات

في Android 10، تحتوي كل شاشة تم ضبطها لتتوافق مع زخارف النظام على حزمة منزلية مخصّصة لأنشطة مشغّل التطبيقات التي تحمل النوع WindowConfiguration#ACTIVITY_TYPE_HOME تلقائيًا. يستخدم كلّ عرض نسخة منفصلة من نشاط مشغّل التطبيقات:

الشكل 1. مثال على مشغّل الشاشات المتعددة لمنصة/تطوير/عينات/MultiDisplay

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

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

يجب أن يتضمّن النشاط وضع تشغيل لا يمنع تشغيل عدة مثيلات، ومن المتوقّع أن يتكيّف مع أحجام الشاشات المختلفة. لا يمكن أن يكون وضع التشغيل singleInstance أو singleTask.

التنفيذ

في نظام التشغيل Android 10، يختار RootActivityContainer#startHomeOnDisplay() تلقائيًا المكوّن والغرض المطلوبَين استنادًا إلى الشاشة التي يتم تشغيل الشاشة الرئيسية عليها. يحتوي RootActivityContainer#resolveSecondaryHomeActivity() على منطق البحث عن مكوّن نشاط مشغّل التطبيقات استنادًا إلى مشغّل التطبيقات المحدّد حاليًا، ويمكنه استخدام الإعداد التلقائي للنظام إذا لزم الأمر (راجِع ActivityTaskManagerService#getSecondaryHomeIntent()).

قيود الأمان

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

الخلفيات

في الإصدار 10 من نظام التشغيل Android والإصدارات الأحدث، تتوفّر خلفيات الشاشة على شاشات العرض الثانوية:

الشكل 2. خلفية متحركة على الشاشة الداخلية (أعلاه) والخارجية (أدناه)

يمكن للمطوّرين الإفصاح عن توفّر ميزة الخلفية من خلال توفير ‎ android:supportsMultipleDisplays="true" في تعريف ‎ WallpaperInfo بتنسيق XML. من المفترض أيضًا أن يقوم مطوّرو الخلفيات بتحميل مواد العرض باستخدام سياق العرض في WallpaperService.Engine#getDisplayContext().

ينشئ إطار العمل مثيلاً واحدًا من WallpaperService.Engine لكل شاشة عرض، وبالتالي يكون لكل محرك مساحة عرض وسياق عرض خاصَّين به. على المطوّر التأكّد من أنّ كل محرك يمكنه الرسم بشكل مستقل، وبمعدلات عرض لقطات مختلفة، مع مراعاة VSync.

اختيار خلفيات لشاشات فردية

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

ومع ذلك، أضاف نظام التشغيل Android 10 السمة DisplayInfo.mAddress، التي تحتوي على معرّفات ثابتة للشاشات المادية ويمكن استخدامها في عملية تنفيذ كاملة في المستقبل. للأسف، فات الأوان لتنفيذ المنطق في Android 10. الحلّ المقترَح:

  1. استخدِم الفئة WallpaperManager لضبط الخلفيات.

    يتم الحصول على WallpaperManager من عنصر Context، ويحتوي كل عنصر Context على معلومات حول العرض المقابل (Context#getDisplay()/getDisplayId()). وبالتالي، يمكنك الحصول على displayId من مثيل WallpaperManager بدون إضافة طرق جديدة.

  2. من جهة إطار العمل، استخدِم displayId الذي تم الحصول عليه من عنصر Context واربطه بمعرّف ثابت (مثل منفذ شاشة عرض فعلية). استخدِم المعرّف الثابت للاحتفاظ بالخلفية التي اخترتها.

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

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

قيود الأمان

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

التنفيذ

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

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

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

الشكل 3. منطق احتياطي للخلفية على الشاشات الثانوية: