ملحقات WindowManager

تتيح مكتبة Jetpack WindowManager لمطوري التطبيقات دعم عوامل شكل الأجهزة الجديدة والبيئات المتعددة النوافذ.

تعد WindowManager Extensions (Extensions) وحدة نمطية لنظام Android الأساسي تتيح مجموعة متنوعة من ميزات Jetpack WindowManager. يتم تنفيذ الوحدة في AOSP في frameworks/base/libs/WindowManager/Jetpack ويتم شحنها على الأجهزة التي تدعم ميزات WindowManager.

توزيع وحدة الامتدادات

يتم تجميع الملحقات في مكتبة .jar ووضعها في قسم system_ext على الجهاز إذا تم تمكين الملحقات في ملف تعريف الجهاز.

لتمكين الامتدادات على أحد الأجهزة، قم بإضافة ما يلي إلى ملف تعريف جهاز المنتج:

$(call inherit-product, $(SRC_TARGET_DIR)/product/window_extensions.mk)

يؤدي ذلك إلى تمكين حزم androidx.window.extensions و androidx.window.sidecar على الجهاز وتعيين الخاصية persist.wm.extensions.enabled . يؤدي تضمين هذه الحزم في ملف makefile أيضًا إلى وضع الإعلانات في etc/permissions/ ، مما يجعلها متاحة لعمليات التطبيق. عادةً ما يتم تحميل الوحدات النمطية وتنفيذها كجزء من عملية التطبيق في وقت التشغيل عند استخدامها بواسطة مكتبة Jetpack WindowManager، مما يجعل عملها مشابهًا لرمز إطار العمل من جانب العميل، كما هو موضح في الشكل التالي:

الشكل 1. تم تحميل ملحقات WindowManager في عملية التطبيق بشكل مشابه لرمز النظام الأساسي.

وحدة androidx.window.extensions هي وحدة الإضافات الحالية قيد التطوير النشط. وحدة androidx.window.sidecar هي وحدة قديمة تم تضمينها للتوافق مع الإصدارات الأقدم من Jetpack WindowManager، ولكن لم تعد تتم صيانة السيارة الجانبية بشكل نشط.

يوضح الشكل التالي منطق تحديد استخدام androidx.window.extensions أو androidx.window.sidecar .

الشكل 2. شجرة القرار للوصول إلى androidx.window.extensions أو androidx.window.sidecar .

وحدات الامتدادات

توفر الإضافات ميزات النوافذ للأجهزة ذات الشاشات الكبيرة القابلة للطي والأجهزة التي تدعم النوافذ على شاشات العرض الخارجية. تشمل المناطق المميزة ما يلي:

يمكن أن توفر تطبيقات OEM للملحقات مكونات أو مكونات فارغة مع تطبيقات افتراضية أو كعب روتين للأساليب الموجودة في واجهة WindowExtensions إذا كانت أجهزة الجهاز لا تدعم الميزات المقابلة، ما لم تكن الميزة مطلوبة على وجه التحديد في مستند تعريف التوافق (CDD) 7.1.1.1 .

الإضافات وواجهات برمجة تطبيقات Jetpack

توفر وحدة WindowManager Extensions سطح واجهة برمجة التطبيقات (API) الخاص بها بالإضافة إلى واجهات برمجة تطبيقات النظام الأساسي العام. تم تطوير وحدة الامتدادات بشكل عام في مكتبة Jetpack غير مخصصة للمطورين androidx.window.extensions ، بحيث يمكن لـ Jetpack WindowManager ( androidx.window ) الارتباط بها في وقت الترجمة. يوفر سطح Extensions API عادةً واجهات برمجة التطبيقات ذات المستوى الأدنى.

واجهات برمجة التطبيقات التي توفرها الامتدادات مخصصة للاستخدام بواسطة مكتبة Jetpack WindowManager فقط. ليس من المفترض أن يتم استدعاء واجهات برمجة تطبيقات الإضافات بواسطة مطوري التطبيقات مباشرةً. لا يجب إضافة مكتبة الملحقات باعتبارها تبعية لتطبيق ما في ملف إنشاء Gradle لضمان الأداء الوظيفي الصحيح. تجنب التحويل البرمجي المسبق لمكتبة الملحقات إلى تطبيق مباشرةً؛ بدلاً من ذلك، اعتمد على التحميل في وقت التشغيل لمنع حالة تحميل مزيج من فئات الامتدادات المترجمة مسبقًا والمقدمة في وقت التشغيل.

من المفترض أن تتم إضافة Jetpack WindowManager ( androidx.window ) باعتباره تطبيقًا تابعًا ويوفر واجهات برمجة التطبيقات العامة التي تواجه المطورين، بما في ذلك تلك الخاصة بميزات WindowManager Extensions. تقوم مكتبة WindowManager تلقائيًا بتحميل الامتدادات في عملية التطبيق وتغليف واجهات برمجة تطبيقات الامتدادات ذات المستوى الأدنى في تجريدات ذات مستوى أعلى وواجهات أكثر تركيزًا. تتبع واجهات برمجة تطبيقات WindowManager Jetpack معايير تطوير تطبيقات Android الحديثة وتهدف إلى توفير إمكانية التشغيل البيني المريح من خلال التكامل الجيد مع قواعد التعليمات البرمجية التي تستخدم مكتبات AndroidX الأخرى.

إصدارات الإضافات والتحديثات

يمكن تحديث وحدة الإضافات مع تحديثات نظام Android سنويًا أو ربع سنوي. تعمل التحديثات ربع السنوية على تمكين زيادة مستوى واجهة API للإضافات بين تحديثات واجهة برمجة التطبيقات لمنصة Android، مما يسمح بتكرار أسرع ويوفر لمصنعي المعدات الأصلية فرصة لإضافة وصول رسمي لواجهة برمجة التطبيقات إلى ميزات جديدة قريبة من إطلاق الأجهزة.

يسرد الجدول التالي إصدارات androidx.window.extensions API لإصدارات Android المختلفة.

نسخة منصة أندرويد مستوى API لملحقات WindowManager إصدار androidx.window.extensions API
أندرويد 14 3 1.2.0
أندرويد 13 كيو بي آر 3 2 1.1.0
أندرويد 13 1 1.0.0
أندرويد 12 لتر 1 1.0.0

يتم زيادة مستوى واجهة برمجة التطبيقات (العمود الأوسط) في كل مرة تتم فيها إضافة إلى سطح واجهة برمجة التطبيقات المستقر الحالي (العمود الأيمن).

التوافق إلى الخلف والأمام

يتعامل Jetpack WindowManager مع تعقيد التعامل مع تحديثات مستوى واجهة برمجة التطبيقات المتكررة، والتطور السريع لواجهة برمجة التطبيقات، والتوافق مع الإصدارات السابقة. عند تنفيذ كود المكتبة في عملية التطبيق، تتحقق المكتبة من مستوى Extensions API المعلن وتوفر الوصول إلى الميزات وفقًا للمستوى المعلن.

لحماية أحد التطبيقات من التعطل في وقت التشغيل، يقوم WindowManager أيضًا بإجراء فحص انعكاس Java في وقت التشغيل لواجهات API للملحقات المتوفرة وفقًا لمستوى Extensions API المُعلن. إذا كان هناك عدم تطابق، فيمكن لـ WindowManager تعطيل استخدام الامتدادات (جزئيًا أو كليًا) والإبلاغ عن الميزات ذات الصلة باعتبارها غير متوفرة للتطبيق.

يتم تنفيذ ملحقات WindowManager كوحدة system_ext تستخدم واجهات برمجة تطبيقات النظام الأساسي الخاص للاتصال بـ WindowManager الأساسي و DeviceStateManager وخدمات النظام الأخرى في تنفيذ ميزات الامتدادات.

قد لا يتم الحفاظ على التوافق مع إصدارات ما قبل النشر من الإضافات قبل إصدار نظام Android ربع السنوي أو السنوي المقابل والذي يتم من خلاله الانتهاء من الإصدارات. يمكن العثور على السجل الكامل لواجهات برمجة تطبيقات الامتدادات في window:extensions:extensions .

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

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

أداء

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

وحدات

تضمين النشاط

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

يجب أن يكون مكون تضمين النشاط متاحًا على جميع الأجهزة التي تحتوي على شاشة عرض مدمجة بحجم يساوي أو أكبر من sw600 dp . يجب أيضًا تمكين تضمين النشاط على الأجهزة التي تدعم اتصالات شاشات العرض الخارجية، حيث قد يتم عرض التطبيق بحجم أكبر عندما تكون شاشات العرض الخارجية متصلة في وقت التشغيل.

تكوين الجهاز

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

معلومات تخطيط النافذة

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

يجب على أجهزة Android القابلة للطي والتي تشتمل على مفصلة تربط مناطق لوحة العرض المنفصلة أو المستمرة أن تجعل المعلومات حول المفصلة متاحة للتطبيقات من خلال WindowLayoutComponent .

يجب الإبلاغ عن موضع المفصلة وحدودها بالنسبة لنافذة التطبيق المحددة بواسطة Context الذي تم تمريره إلى واجهة برمجة التطبيقات (API). إذا كانت حدود نافذة التطبيق لا تتقاطع مع حدود المفصلة، ​​فلا يجب الإبلاغ عن ميزة DisplayFeature المفصلية. ومن المقبول أيضًا عدم الإبلاغ عن ميزات العرض عندما لا يتم الإبلاغ عن موضعها بشكل موثوق، كما هو الحال عندما يمكن للمستخدم تحريك نافذة التطبيق بحرية في وضع النوافذ المتعددة أو وضع letterbox المتوافق.

بالنسبة لميزات الطي ، يجب الإبلاغ عن تحديثات الحالة عندما يتغير موضع المفصلة بين الحالات المستقرة. افتراضيًا، في حالة العرض المسطح، يجب أن تقوم واجهة برمجة التطبيقات (API) بالإبلاغ عن FoldingFeature.State.FLAT . إذا كان من الممكن ترك أجهزة الجهاز في وضع نصف مطوي في حالة مستقرة، فيجب أن تبلغ واجهة برمجة التطبيقات (API) عن FoldingFeature.State.HALF_OPENED . لا توجد حالة مغلقة في واجهة برمجة التطبيقات، لأنه في مثل هذه الحالة لن تكون نافذة التطبيق مرئية أو لن تتجاوز حدود المفصلة.

تكوين الجهاز

لدعم تنفيذ ميزة الطي، يجب على مصنعي المعدات الأصلية القيام بما يلي:

  • قم بتكوين حالات الجهاز في device_state_configuration.xml ليتم استخدامه بواسطة DeviceStateManagerService . راجع DeviceStateProviderImpl.java كمرجع.

    إذا لم تكن التطبيقات الافتراضية لـ DeviceStateProvider أو DeviceStatePolicy مناسبة للجهاز، فيمكن استخدام تطبيق مخصص.

  • قم بتمكين وحدة الامتدادات كما هو موضح في قسم توزيع وحدة الامتدادات .

  • حدد موقع ميزات العرض في مورد السلسلة com.android.internal.R.string.config_display_features (عادةً في frameworks/base/core/res/res/values/config.xml في تراكب الجهاز).

    التنسيق المتوقع للسلسلة هو:

    <type>-[<left>,<top>,<right>,<bottom>]

    يمكن أن يكون type إما fold أو hinge . قيم left top right bottom هي إحداثيات عدد صحيح للبكسل في مساحة إحداثيات العرض في اتجاه العرض الطبيعي. يمكن أن تحتوي سلسلة التكوين على ميزات عرض متعددة مفصولة بفواصل منقوطة.

    على سبيل المثال:

    <!-- Jetpack WindowManager display features -->
    <string name="config_display_features" translatable="false">fold-[1000,0,1000,2000]</string>
    
  • حدد التعيين بين معرفات حالة الجهاز الداخلية المستخدمة في DeviceStateManager وثوابت الحالة العامة المرسلة إلى المطورين في com.android.internal.R.array.config_device_state_postures .

    التنسيق المتوقع لكل إدخال هو:

    <device_specific_state_identifier>:<Jetpack WindowManager state identifier>

    معرفات الحالة المدعومة هي:

    • COMMON_STATE_NO_FOLDING_FEATURES = 1 : لا تحتوي الحالة على أي ميزات قابلة للطي للإبلاغ عنها. على سبيل المثال، يمكن أن تكون الحالة المغلقة لجهاز نموذجي قابل للطي مع وجود الشاشة الرئيسية على الجانب الداخلي.
    • COMMON_STATE_HALF_OPENED = 2 : ميزة الطي نصف مفتوحة.
    • COMMON_STATE_FLAT = 3 : ميزة الطي مسطحة. على سبيل المثال، يمكن أن تكون الحالة المفتوحة لجهاز نموذجي قابل للطي مع وجود الشاشة الرئيسية على الجانب الداخلي.
    • COMMON_STATE_USE_BASE_STATE = 1000 : في Android 14، قيمة يمكن استخدامها للحالات التي تمت مضاهاتها حيث يتم اشتقاق حالة المفصلة باستخدام الحالة الأساسية، كما هو محدد في CommonFoldingFeature.java

    راجع DeviceStateManager.DeviceStateCallback#onBaseStateChanged(int) لمزيد من المعلومات.

    على سبيل المثال:

    <!-- Map of System DeviceState supplied by DeviceStateManager to WindowManager posture.-->
    <string-array name="config_device_state_postures" translatable="false">
        <item>0:1</item>    <!-- CLOSED       : COMMON_STATE_NO_FOLDING_FEATURES -->
        <item>1:2</item>    <!-- HALF_OPENED  : COMMON_STATE_HALF_OPENED -->
        <item>2:3</item>    <!-- OPENED       : COMMON_STATE_FLAT -->
        <item>3:1</item>    <!-- REAR_DISPLAY : COMMON_STATE_NO_FOLDING_FEATURES -->
        <item>4:1000</item> <!-- CONCURRENT   : COMMON_STATE_USE_BASE_STATE -->
    </string-array>
    

منطقة النافذة

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

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

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

تكوين الجهاز

لدعم تنفيذ ميزة الطي، يجب على مصنعي المعدات الأصلية القيام بما يلي:

  • قم بتكوين حالات الجهاز في device_state_configuration.xml ليتم استخدامه بواسطة DeviceStateManagerService . راجع DeviceStateProviderImpl.java لمزيد من المعلومات.

    إذا لم يكن التنفيذ الافتراضي لـ DeviceStateProvider أو DeviceStatePolicy مناسبًا للجهاز، فيمكن استخدام تطبيق مخصص.

  • بالنسبة للأجهزة القابلة للطي التي تدعم الوضع المفتوح أو المسطح، حدد معرفات الحالة المقابلة في com.android.internal.R.array.config_openDeviceStates .

  • بالنسبة للأجهزة القابلة للطي التي تدعم الحالات المطوية، قم بإدراج معرفات الحالة المقابلة في com.android.internal.R.array.config_foldedDeviceStates .

  • بالنسبة للأجهزة القابلة للطي التي تدعم حالة نصف مطوية (المفصلة نصف مفتوحة مثل الكمبيوتر المحمول)، قم بإدراج الحالات المقابلة في com.android.internal.R.array.config_halfFoldedDeviceStates .

  • بالنسبة للأجهزة التي تدعم وضع العرض الخلفي:

    • قم بإدراج الحالات المقابلة في com.android.internal.R.array.config_rearDisplayDeviceStates لـ DeviceStateManager .
    • حدد عنوان العرض الفعلي للشاشة الخلفية في com.android.internal.R.string.config_rearDisplayPhysicalAddress .
    • حدد معرف الحالة في com.android.internal.R.integer.config_deviceStateRearDisplay ليتم استخدامه بواسطة الامتدادات.
    • أضف معرف الحالة في com.android.internal.R.array.config_deviceStatesAvailableForAppRequests لإتاحته للتطبيقات.
  • في نظام التشغيل Android 14، بالنسبة للأجهزة التي تدعم وضع العرض المزدوج (المتزامن):

    • اضبط com.android.internal.R.bool.config_supportsConcurrentInternalDisplays على true .
    • حدد عنوان العرض الفعلي للشاشة الخلفية في com.android.internal.R.config_deviceStateConcurrentRearDisplay .
    • حدد معرف الحالة في com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay ليتم استخدامه بواسطة الامتدادات إذا كان من المفترض أن يكون المعرف متاحًا للتطبيقات.
    • أضف معرف الحالة في com.android.internal.R.array.config_deviceStatesAvailableForAppRequests لإتاحته للتطبيقات.

تَحَقّق

يجب على مصنعي المعدات الأصلية التحقق من تطبيقاتهم لضمان السلوك المتوقع في السيناريوهات الشائعة. تتوفر اختبارات CTS والاختبارات باستخدام Jetpack WindowManager لمصنعي المعدات الأصلية لاختبار عمليات التنفيذ.

اختبارات سي تي إس

لتشغيل اختبارات CTS، راجع تشغيل اختبارات CTS . اختبارات CTS المتعلقة بـ Jetpack WindowManager موجودة ضمن cts/tests/framework/base/windowmanager/jetpack/ . اسم وحدة الاختبار هو CtsWindowManagerJetpackTestCases .

اختبارات مدير النوافذ

لتنزيل اختبارات Jetpack WindowManager، اتبع تعليمات Android Jetpack . توجد الاختبارات في مكتبة النوافذ ضمن window:window Module: window/window/src/androidTest/ .

لتشغيل اختبارات الجهاز لوحدة window:window من سطر الأوامر، قم بما يلي:

  1. قم بتوصيل جهاز تم تمكين خيارات المطور وتصحيح أخطاء USB فيه.
  2. اسمح للكمبيوتر بتصحيح أخطاء الجهاز.
  3. افتح Shell في الدليل الجذر لمستودع androidx.
  4. قم بتغيير الدليل إلى framework/support .
  5. قم بتشغيل الأمر التالي: ./gradlew window:window:connectedAndroidTest .
  6. تحليل النتائج.

لتشغيل الاختبارات من Android Studio، قم بما يلي:

  1. افتح ستوديو أندرويد.
  2. قم بتوصيل جهاز تم تمكين خيارات المطور وتصحيح أخطاء USB فيه.
  3. اسمح للكمبيوتر بتصحيح أخطاء الجهاز.
  4. انتقل إلى الاختبار داخل مكتبة النوافذ الخاصة بوحدة النافذة.
  5. افتح فصل اختبار وقم بتشغيله باستخدام الأسهم الخضراء الموجودة على الجانب الأيمن من المحرر.

وبدلاً من ذلك، يمكنك إنشاء تكوين في Android Studio لتشغيل طريقة اختبار أو فئة اختبار أو جميع الاختبارات في الوحدة النمطية.

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