تتيح ميزة "نافذة ضمن النافذة" (PiP) على أجهزة Android المحمولة للمستخدمين تغيير حجم تطبيق يعرض نشاطًا جاريًا إلى نافذة صغيرة. وتُعدّ ميزة "نافذة ضمن النافذة" مفيدة بشكل خاص لتطبيقات الفيديو لأنّ المحتوى يستمر في التشغيل بينما يكون المستخدم حرًا في تنفيذ إجراءات أخرى. يمكن للمستخدمين التحكّم في موضع هذه النافذة من خلال SystemUI والتفاعل مع التطبيق الذي يعمل حاليًا بوضع "نافذة ضمن نافذة" من خلال إجراءات (تصل إلى ثلاث) يوفّرها التطبيق.
تتطلّب ميزة "وضع الصورة في الصورة" موافقة صريحة من التطبيقات التي تتيحها، وتعمل على أساس
كل نشاط على حدة. (يمكن أن يتضمّن تطبيق واحد أنشطة متعددة، ويكون أحدها فقط
في وضع "صورة في صورة"). تطلب الأنشطة الدخول إلى وضع "نافذة ضمن النافذة" من خلال الاتصال
enterPictureInPictureMode()
، وتتلقّى عمليات استدعاء الأنشطة في
شكل onPictureInPictureModeChanged()
.
تتيح طريقة setPictureInPictureParams()
للأنشطة التحكّم في
نسبة العرض إلى الارتفاع أثناء استخدام وضع "صورة في صورة" والإجراءات المخصّصة، ما يسمح للمستخدمين بالتفاعل مع
النشاط بدون الحاجة إلى توسيعه. في وضع "صورة في صورة"، يكون النشاط في حالة إيقاف مؤقت، ولكنه يستمر في العرض، ولا يتلقّى مباشرةً إدخالات باللمس أو تركيز النافذة.
يمكن عرض مهمة واحدة فقط في وضع "صورة في صورة" في كل مرة.
يمكنك الاطّلاع على مزيد من المعلومات في مستندات المطوّرين على Android المتعلقة بميزة صورة في صورة.
متطلبات الأجهزة
لتفعيل ميزة "صورة في صورة"، فعِّل ميزة
PackageManager#FEATURE_PICTURE_IN_PICTURE
في النظام في
/android/frameworks/base/core/java/android/content/pm/PackageManager.java
.
يجب أن تكون شاشة الأجهزة المتوافقة مع وضع "صورة في صورة" أكبر من 220 وحدة بكسل مستقلة الكثافة عند
أصغر عرض لها. على غرار ميزة "نوافذ متعددة" في وضع "تقسيم الشاشة"، تتيح ميزة "صورة في صورة" تنفيذ عدّة
أنشطة على الشاشة في الوقت نفسه. لذلك، يجب أن تتضمّن الأجهزة
وحدة معالجة مركزية وذاكرة وصول عشوائي كافيتين لدعم حالة الاستخدام هذه.
التنفيذ
تتم معظم إدارة دورة حياة النشاط في النظام بين
ActivityManager
وWindowManager
.
يمكن العثور على واجهة المستخدم المرجعية في حزمة SystemUI
.
يجب ألا تؤثّر التعديلات التي يتم إجراؤها على النظام في سلوكه الأساسي كما هو محدّد من خلال اختبارات مجموعة أدوات اختبار التوافق (CTS). يدور منطق النظام في وضع "صورة في صورة" بشكل أساسي حول إدارة المهام والنشاطات ضمن الحزمة "المُثبَّتة". في ما يلي نظرة عامة سريعة على الصف:
-
ActivityRecord
: تتبُّع حالة "صورة في صورة" لكل نشاط لمنع المستخدمين من الدخول إلى وضع "صورة في صورة" في حالات معيّنة، مثل شاشة القفل أو أثناء استخدام الواقع الافتراضي، أضِف حالات إلىcheckEnterPictureInPictureState()
. ActivityManagerService
: الواجهة الأساسية من النشاط لطلب الدخول إلى وضع "نافذة ضمن النافذة" والواجهة للمكالمات منWindowManager
وSystemUI
لتغيير حالة نشاط "نافذة ضمن النافذة"-
ActivityStackSupervisor
: يتمّ استدعاؤه منActivityManagerService
لنقل المهام إلى الحزمة المثبّتة أو خارجها، وتعديلWindowManager
حسب الحاجة. PinnedStackWindowController
: واجهةWindowManager
منActivityManager
-
PinnedStackController
: يُبلغ عن التغييرات في النظام إلىSystemUI
، مثل عرض/إخفاء IME أو تغيير نسبة العرض إلى الارتفاع أو تغيير الإجراءات. -
BoundsAnimationController
: لإضافة تأثيرات متحركة على نوافذ نشاط "وضع الصورة في الصورة" بطريقة لا تؤدي إلى تغيير الإعدادات أثناء تغيير الحجم -
PipSnapAlgorithm
: فئة مشترَكة تُستخدَم في كلٍّ من النظام وSystemUI للتحكّم في سلوك التصاق نافذة "وضع الصورة في الصورة" بالقرب من حواف الشاشة
يقدّم المرجع SystemUI
تنفيذًا كاملاً لميزة "صورة في صورة" يتيح تقديم إجراءات
مخصّصة للمستخدمين والتعامل العام، مثل التوسيع والإغلاق.
يمكن لصنّاع الأجهزة الاستفادة من هذه التغييرات، شرط ألا تؤثّر في
السلوكيات الأساسية كما هو محدّد في CDD. في ما يلي نظرة عامة سريعة على الصف:
PipManager
: عنصرSystemUI
الذي يتم تشغيله باستخدامSystemUI
-
PipTouchHandler
: معالِج اللمس الذي يتحكّم في الإيماءات التي تُجري تعديلات على وضع "صورة في صورة" لا يتم استخدام هذا الإجراء إلا عندما يكون مستهلك الإدخال لميزة "صورة في صورة" نشطًا (راجِعInputConsumerController
). يمكن إضافة حركات جديدة هنا. -
PipMotionHelper
: فئة مساعدة ترصد موضع الصورة في وضع "صورة داخل صورة" والمنطقة المسموح بها على الشاشة. المكالمات التي يتم توجيهها إلىActivityManagerService
لتعديل موضع "نافذة ضمن النافذة" (PIP) أو حجمها أو إضافة تأثيرات متحركة إليها PipMenuActivityController
: يبدأ نشاطًا يعرض الإجراءات التي يوفّرها النشاط المعروض حاليًا في وضع "صورة في صورة". هذا النشاط هو نشاط تراكبي للمهام، ويزيل مستخدِم الإدخال المتراكب للسماح له بأن يكون تفاعليًا.PipMenuActivity
: تنفيذ نشاط القائمة-
PipMediaController
: مستمع يُعدِّلSystemUI
عندما تتغيّر جلسة الوسائط بطريقة قد تؤثّر في الإجراءات التلقائية في وضع "صورة داخل صورة" -
PipNotificationController
: وحدة التحكّم التي تضمن أنّ الإشعار نشط عندما يستخدم المستخدم ميزة "صورة في صورة" -
PipDismissViewController
: التراكب الذي يظهر للمستخدمين عند بدء التفاعل مع وضع "صورة داخل صورة" للإشارة إلى أنّه يمكنهم إغلاقه
موضع الإعلان التلقائي
هناك موارد نظام مختلفة تتحكّم في موضع وضع الصورة في الصورة التلقائي:
-
config_defaultPictureInPictureGravity
: القيمة الصحيحة gravity التي تتحكّم في الزاوية التي سيتم وضع الصورة المصغرة المتحركة فيها، مثلBOTTOM|RIGHT
. config_defaultPictureInPictureScreenEdgeInsets
: Offsets from the sides of the screen to place the PIP-
config_pictureInPictureDefaultSizePercent
وconfig_pictureInPictureDefaultAspectRatio
: تتحكم النسبة المئوية لعرض الشاشة ونسبة العرض إلى الارتفاع في حجم الصورة في الصورة. يجب ألا يكون حجم PIP التلقائي المحسوب أصغر من@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
.