نافذة ضمن النافذة

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

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

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

يتوفّر مزيد من المعلومات في مستندات المطوّرين على Android حول ميزة نافذة ضمن النافذة.

متطلبات الجهاز

لإتاحة ميزة "نافذة ضمن النافذة"، فعِّل ميزة النظام PackageManager#FEATURE_PICTURE_IN_PICTURE في /android/frameworks/base/core/java/android/content/pm/PackageManager.java. يجب أن تتضمّن الأجهزة التي تتيح ميزة "نافذة ضمن النافذة" شاشة أكبر من 220 وحدة بكسل مستقلة الكثافة في أصغر عرض لها. على غرار ميزة "نافذة متعددة" في وضع تقسيم الشاشة، تتيح ميزة "نافذة ضمن النافذة" تشغيل عدة أنشطة على الشاشة في الوقت نفسه. لذلك، يجب أن تتضمّن الأجهزة وحدة معالجة مركزية (CPU) وذاكرة وصول عشوائي (RAM) كافيتَين لإتاحة حالة الاستخدام هذه.

التنفيذ

تتم معظم عمليات إدارة دورة حياة النشاط في النظام بين ActivityManager و WindowManager. تتوفّر واجهة المستخدم المرجعية في SystemUI حزمة.

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

  • ActivityRecord: يتتبّع حالة "نافذة ضمن النافذة" لكل نشاط. لمنع المستخدمين من الانتقال إلى "نافذة ضمن النافذة" في ظروف معيّنة ، مثل شاشة القفل أو أثناء استخدام الواقع الافتراضي، أضِف حالات إلى checkEnterPictureInPictureState().
  • ActivityManagerService: الواجهة الأساسية من النشاط لطلب الانتقال إلى "نافذة ضمن النافذة" والواجهة التي يتم من خلالها استدعاء WindowManager وSystemUI لتغيير حالة نشاط "نافذة ضمن النافذة" .
  • ActivityStackSupervisor: يتم استدعاؤها من ActivityManagerService لنقل المهام إلى المكدّس المثبَّت أو إخراجها منه، وتعديل WindowManager حسب الحاجة.
  • PinnedStackWindowController: هي واجهة WindowManager من ActivityManager.
  • PinnedStackController: تُبلغ SystemUI بالتغييرات في النظام، مثل لوحة أساليب الإدخال (IME) التي يتم عرضها أو إخفاؤها أو تغيير نسبة العرض إلى الارتفاع أو تغيير الإجراءات.
  • BoundsAnimationController: تحرّك نوافذ نشاط "نافذة ضمن النافذة" بطريقة لا تؤدي إلى تغيير الإعدادات أثناء تغيير الحجم.
  • PipSnapAlgorithm: هي فئة مشترَكة تُستخدَم في كلّ من النظام وواجهة مستخدم النظام، وتتحكّم في سلوك تثبيت نافذة "نافذة ضمن النافذة" بالقرب من حواف الشاشة.

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

  • PipManager: هو مكوّن SystemUI الذي يتم تشغيله مع SystemUI.
  • PipTouchHandler: هي أداة معالجة اللمس التي تتحكّم في الإيماءات التي تعدّل "نافذة ضمن النافذة". لا يتم استخدام هذه الأداة إلا عندما يكون مستهلك الإدخال لـ "نافذة ضمن النافذة" نشطًا (راجِع InputConsumerController). ويمكن إضافة إيماءات جديدة هنا.
  • PipMotionHelper: هي فئة سهلة الاستخدام تتتبّع موضع "نافذة ضمن النافذة" والمنطقة المسموح بها على الشاشة. تتم عمليات الاستدعاء من خلال ActivityManagerService لتعديل موضع "نافذة ضمن النافذة" وحجمها أو تحريكهما.
  • PipMenuActivityController: تبدأ نشاطًا يعرض الإجراءات التي يوفّرها النشاط المعروض حاليًا في "نافذة ضمن النافذة". هذا النشاط هو نشاط تراكب المهام، ويزيل مستهلك الإدخال المتراكب للسماح بالتفاعل معه.
  • PipMenuActivity: هي عملية تنفيذ نشاط القائمة.
  • PipMediaController: هي أداة الاستماع التي تعدّل SystemUI عند تغيير جلسة الوسائط بطريقة قد تؤثر في الإجراءات التلقائية في "نافذة ضمن النافذة".
  • PipNotificationController: هي أداة التحكّم التي تضمن تفعيل إشعار أثناء استخدام المستخدم لميزة "نافذة ضمن النافذة".
  • PipDismissViewController: هي التراكب الذي يظهر للمستخدمين عندما يبدأون التفاعل مع "نافذة ضمن النافذة" للإشارة إلى أنّه يمكن إغلاقها.

الموضع التلقائي

هناك العديد من موارد النظام التي تتحكّم في الموضع التلقائي لـ "نافذة ضمن النافذة":

  • config_defaultPictureInPictureGravity: هي قيمة عددية للـ gravity تتحكّم في الزاوية التي يتم فيها وضع "نافذة ضمن النافذة"، مثل BOTTOM|RIGHT.
  • config_defaultPictureInPictureScreenEdgeInsets: هي الإزاحات من جوانب الشاشة لوضع "نافذة ضمن النافذة".
  • config_pictureInPictureDefaultSizePercent و config_pictureInPictureDefaultAspectRatio: يتحكّم مزيج النسبة المئوية لعرض الشاشة ونسبة العرض إلى الارتفاع في حجم "نافذة ضمن النافذة". يجب ألا يكون الحجم التلقائي المحسوب لـ "نافذة ضمن النافذة" أصغر من @dimen/default_minimal_size_pip_resizable_task، كما هو محدّد في مجموعة أدوات اختبار التوافق (CTS) ومستند تعريف التوافق (CDD).
  • config_pictureInPictureSnapMode: هو سلوك التثبيت كما هو محدّد في PipSnapAlgorithm.

يجب ألا تغيّر عمليات تنفيذ الأجهزة الحد الأدنى والأقصى لنسب العرض إلى الارتفاع المحدّدة في مستند تعريف التوافق (CDD) ومجموعة أدوات اختبار التوافق (CTS).

الأذونات

يسمح "عملية التطبيق" (OP_PICTURE_IN_PICTURE) لكل حزمة في AppOpsManager (main/core/java/android/app/AppOpsManager.java) للمستخدمين بالتحكّم في "نافذة ضمن النافذة" على مستوى كل تطبيق على حدة من خلال إعدادات النظام. يجب أن تحترم عمليات تنفيذ الأجهزة هذا الفحص عندما يطلب أحد الأنشطة الانتقال إلى وضع "نافذة ضمن النافذة".

الاختبار

لاختبار عمليات تنفيذ "نافذة ضمن النافذة"، شغِّل جميع الاختبارات ذات الصلة بـ "نافذة ضمن النافذة" التي تم العثور عليها في اختبارات مجموعة أدوات اختبار التوافق (CTS) على جانب المضيف ضمن /cts/hostsidetests/services/activitymanager، وخاصةً في ActivityManagerPinnedStackTests.java.