تتيح ميزة "نافذة ضمن النافذة" (PIP) لأجهزة Android الجوّالة للمستخدمين تغيير حجم تطبيق يتضمّن نشاطًا مستمرًا إلى نافذة صغيرة. تُعدّ ميزة "نافذة ضمن النافذة" مفيدة بشكل خاص لتطبيقات الفيديو لأنّ المحتوى يستمر في التشغيل بينما يمكن للمستخدم تنفيذ إجراءات أخرى. يمكن للمستخدمين التحكّم في موضع هذه النافذة من خلال SystemUI والتفاعل مع التطبيق المعروض حاليًا في وضع "نافذة ضمن النافذة" باستخدام (ما يصل إلى ثلاثة) إجراءات يوفّرها التطبيق.
تتطلّب ميزة "نافذة ضمن النافذة" موافقة صريحة من التطبيقات التي تتيحها، وتعمل على أساس كل نشاط على حدة. (يمكن أن يتضمّن تطبيق واحد أنشطة متعددة، ولكن يمكن عرض نشاط واحد فقط في وضع "نافذة ضمن النافذة"). تطلب الأنشطة فتح النوافذ باستخدام وضع "نافذة ضمن النافذة" من خلال استدعاء enterPictureInPictureMode()، وتتلقّى عمليات معاودة الاتصال الخاصة بالنشاط في شكل onPictureInPictureModeChanged().
تتيح طريقة setPictureInPictureParams() للأنشطة التحكّم في نسبة العرض إلى الارتفاع أثناء عرضها في وضع "نافذة ضمن النافذة" وفي الإجراءات المخصّصة التي تتيح للمستخدمين التفاعل مع النشاط بدون الحاجة إلى توسيعه. في وضع "نافذة ضمن النافذة"، يكون النشاط في حالة إيقاف مؤقت، ولكن يتم عرضه، ولا يتلقّى مباشرةً إدخال اللمس أو تركيز النافذة.
يمكن عرض مهمة واحدة فقط في وضع "نافذة ضمن النافذة" في كل مرة.
تتوفّر معلومات إضافية في مستندات وضع "نافذة ضمن النافذة" على موقع "مطوّرو تطبيقات Android".
متطلبات الأجهزة
لاستخدام ميزة "نافذة ضمن النافذة"، فعِّل ميزة النظام PackageManager#FEATURE_PICTURE_IN_PICTURE في /android/frameworks/base/core/java/android/content/pm/PackageManager.java.
يجب أن تتضمّن الأجهزة التي تتوافق مع ميزة "نافذة ضمن النافذة" شاشة أكبر من 220 وحدة بكسل مستقلة الكثافة في أصغر عرض لها. وعلى غرار ميزة النوافذ المتعددة في وضع تقسيم الشاشة، تتيح ميزة "نافذة ضمن النافذة" تشغيل أنشطة متعددة على الشاشة في الوقت نفسه. لذلك، يجب أن تتوفّر في الأجهزة سعة ذاكرة وصول عشوائي (RAM) وطاقة وحدة معالجة مركزية (CPU) كافيتان لدعم حالة الاستخدام هذه.
التنفيذ
تتم إدارة معظم مراحل نشاط التطبيق في النظام بين ActivityManager وWindowManager.
يتم تنفيذ واجهة المستخدم المرجعية في الحزمة SystemUI.
يجب ألا تؤثر التعديلات التي يتم إجراؤها على النظام في سلوكه الأساسي على النحو المحدّد في اختبارات مجموعة أدوات اختبار التوافق (CTS). تتمحور منطق النظام في وضع "نافذة ضمن النافذة" بشكل أساسي حول إدارة المهام والأنشطة في الحزمة "المثبّتة". في ما يلي نظرة عامة سريعة على الصف:
ActivityRecord: يتتبّع حالة كل نشاط في وضع "نافذة ضمن النافذة". لمنع المستخدمين من تفعيل وضع "نافذة ضمن النافذة" في ظروف معيّنة، مثل شاشة القفل أو أثناء استخدام الواقع الافتراضي، أضِف حالات إلىcheckEnterPictureInPictureState().ActivityManagerService: هي الواجهة الأساسية من النشاط لطلب الدخول إلى وضع "نافذة داخل النافذة" والواجهة التي تتلقّى طلبات منWindowManagerوSystemUIلتغيير حالة نشاط "نافذة داخل النافذة".ActivityStackSupervisor: تم استدعاؤها منActivityManagerServiceلنقل المهام إلى الحزمة المثبّتة أو خارجها، وتعديلWindowManagerحسب الحاجة.PinnedStackWindowController: واجهةWindowManagerمنActivityManagerPinnedStackController: تعرض هذه السمة التغييرات التي تطرأ على النظام إلىSystemUI، مثل عرض/إخفاء محرر أسلوب الإدخال (IME) أو تغيير نسبة العرض إلى الارتفاع أو تغيير الإجراءات.BoundsAnimationController: تحرّك نوافذ نشاط وضع "نافذة ضمن النافذة" بطريقة لا تؤدي إلى تغيير في الإعدادات أثناء تغيير الحجم.PipSnapAlgorithm: فئة مشتركة مستخدَمة في كل من النظام وSystemUI تتحكّم في سلوك المحاذاة لنافذة "الصورة داخل الصورة" بالقرب من حواف الشاشة.
يوفّر المرجع SystemUI
عملية تنفيذ كاملة لوضع "نافذة ضمن النافذة" تتيح عرض
إجراءات مخصّصة للمستخدمين وإجراء عمليات عامة، مثل التوسيع والإغلاق.
يمكن لمصنّعي الأجهزة الاستفادة من هذه التغييرات، شرط ألا تؤثّر في السلوكيات الأساسية المحدّدة في مستند تعريف التوافق. في ما يلي نظرة عامة سريعة على الفئة:
PipManager: تمثّل هذه السمة عنصرSystemUIالذي يبدأ بـSystemUI.-
PipTouchHandler: معالج اللمس الذي يتحكّم في الإيماءات التي يتم من خلالها التعامل مع وضع "نافذة ضمن النافذة". يتم استخدام هذا الإجراء فقط عندما يكون مستهلك الإدخال في وضع "نافذة ضمن النافذة" نشطًا (راجِعInputConsumerController). ويمكن إضافة إيماءات جديدة هنا. PipMotionHelper: فئة ملائمة تتتبّع موضع وضع "نافذة ضمن النافذة" والمنطقة المسموح بها على الشاشة. يتم إجراء مكالمات من خلالActivityManagerServiceلتعديل موضع نافذة العرض أثناء التنقل وحجمها أو تحريكها.- يبدأ
PipMenuActivityController: نشاطًا يعرض الإجراءات التي يوفّرها النشاط الحالي في وضع "نافذة ضمن النافذة". هذا النشاط هو نشاط تراكب مهام، ويزيل مستهلك الإدخال المتراكب للسماح بأن يكون تفاعليًا. PipMenuActivity: تمثّل هذه السمة عملية التنفيذ الخاصة بنشاط القائمة.PipMediaController: المستمع الذي يعدّلSystemUIعند تغيُّر جلسة الوسائط بطريقة قد تؤثّر في الإجراءات التلقائية في وضع "نافذة ضمن النافذة"PipNotificationController: هو أداة التحكّم التي تضمن بقاء الإشعار نشطًا أثناء استخدام المستخدم لميزة "نافذة ضمن النافذة".-
PipDismissViewController: هي الطبقة التي تظهر للمستخدمين عندما يبدأون التفاعل مع وضع "نافذة ضمن النافذة" للإشارة إلى أنّه يمكن إغلاقها.
موضع الإعلان التلقائي
تتوفّر العديد من موارد النظام التي تتحكّم في الموضع التلقائي لنافذة "وضع الصورة في الصورة":
config_defaultPictureInPictureGravity: عدد صحيح يمثّل موضع الجاذبية الذي يتحكّم في الزاوية التي سيتم وضع نافذة "الصورة داخل الصورة" فيها، مثلBOTTOM|RIGHT.config_defaultPictureInPictureScreenEdgeInsets: الإزاحات من جوانب الشاشة لوضع نافذة "الصورة في الصورة".config_pictureInPictureDefaultSizePercentوconfig_pictureInPictureDefaultAspectRatio: يؤدي الجمع بين نسبة عرض الشاشة إلى الارتفاع ونسبة العرض إلى الارتفاع إلى التحكّم في حجم وضع "نافذة ضمن النافذة". يجب ألا يقل حجم وضع "نافذة ضمن النافذة" التلقائي المحسوب عن@dimen/default_minimal_size_pip_resizable_task، كما هو محدّد في اختبار التوافق مع نظام التشغيل (CTS) ومستند تعريف التوافق (CDD).config_pictureInPictureSnapMode: سلوك المحاذاة كما هو محدّد فيPipSnapAlgorithm
يجب ألا تغيّر عمليات تنفيذ الأجهزة الحد الأدنى والحد الأقصى لنسبة العرض إلى الارتفاع المحدّدة في مستند تعريف التوافق ومجموعة اختبارات التوافق.
الأذونات
يتيح خيار "عملية التطبيق" (OP_PICTURE_IN_PICTURE) لكل حزمة في AppOpsManager (main/core/java/android/app/AppOpsManager.java) للمستخدمين التحكّم في ميزة "نافذة ضمن النافذة" على مستوى كل تطبيق من خلال إعدادات النظام.
يجب أن تراعي عمليات تنفيذ الأجهزة هذا الشرط عندما يطلب أحد الأنشطة الدخول إلى وضع "نافذة ضمن النافذة".
الاختبار
لاختبار عمليات تنفيذ ميزة "نافذة ضمن النافذة"، شغِّل جميع الاختبارات ذات الصلة بهذه الميزة والموجودة في اختبارات CTS على جانب المضيف ضمن /cts/hostsidetests/services/activitymanager، وخاصةً في ActivityManagerPinnedStackTests.java.