Картинка в картинке

Функция "Картинка в картинке" (PIP) на мобильных устройствах Android позволяет пользователям изменять размер приложения с текущей активностью в маленькое окно. Режим "Картинка в картинке" особенно полезен для видеоприложений, поскольку контент продолжает воспроизводиться, пока пользователь выполняет другие действия. Пользователи могут менять положение окна с помощью SystemUI и взаимодействовать с приложением, которое сейчас находится в режиме "картинка в картинке", с помощью предоставленных приложением действий (до трех).

Для использования режима "Картинка в картинке" требуется явное согласие приложений, которые его поддерживают. Режим работает на уровне отдельных действий. (В одном приложении может быть несколько действий, но только одно из них может быть в режиме PIP.) Чтобы перейти в режим "картинка в картинке", действия вызывают метод enterPictureInPictureMode() и получают обратные вызовы в виде onPictureInPictureModeChanged().

Метод setPictureInPictureParams() позволяет действиям контролировать соотношение сторон в режиме PIP и настраиваемые действия, которые позволяют пользователям взаимодействовать с действием без необходимости его расширения. В режиме PIP приложение приостановлено, но продолжает отрисовываться. Оно не получает фокус окна и не реагирует на сенсорный ввод. В режиме "Картинка в картинке" может быть только одна задача.

Дополнительную информацию можно найти в документации по функции «картинка в картинке» для разработчиков Android.

Требования к устройствам

Чтобы включить поддержку режима "Картинка в картинке", активируйте системную функцию PackageManager#FEATURE_PICTURE_IN_PICTURE в /android/frameworks/base/core/java/android/content/pm/PackageManager.java. Устройства, поддерживающие режим "картинка в картинке", должны иметь экран, ширина которого в самом узком месте составляет не менее 220 dp. Как и в многооконном режиме с разделением экрана, режим «Картинка в картинке» позволяет одновременно запускать на экране несколько действий. Поэтому у устройств должно быть достаточно ресурсов ЦП и ОЗУ.

Реализация

Большая часть управления жизненным циклом объекта activity выполняется в системе между ActivityManager и WindowManager. Реализация интерфейса находится в пакете SystemUI.

Изменения в системе не должны влиять на ее внутреннее поведение, определенное тестами Compatibility Test Suite (CTS). Логика работы режима "Картинка в картинке" в основном связана с управлением задачами и действиями в закрепленном стеке. Вот краткий обзор классов:

  • ActivityRecord отслеживает состояние режима "картинка в картинке" для каждого действия. Чтобы запретить пользователям переходить в режим PIP в определенных обстоятельствах, например на заблокированном экране или в режиме VR, добавьте соответствующие условия в checkEnterPictureInPictureState().
  • ActivityManagerService – основной интерфейс, который используется объектом activity для запроса перехода в режим "картинка в картинке", а также интерфейс для вызовов из WindowManager и SystemUI, позволяющий изменить состояние объекта activity в режиме "картинка в картинке".
  • ActivityStackSupervisor вызывается из ActivityManagerService для перемещения задач в закрепленный стек или из него, при необходимости обновляя WindowManager.
  • PinnedStackWindowController: интерфейс WindowManager от ActivityManager.
  • PinnedStackController сообщает SystemUI об изменениях в системе, например о том, что редактор метода ввода показан или скрыт, соотношение сторон изменено или действия изменены.
  • BoundsAnimationController анимирует окна PIP таким образом, чтобы при изменении размера не происходило смены конфигурации.
  • PipSnapAlgorithm – общий класс, используемый в системе и SystemUI, который управляет прикреплением окна PIP к краям экрана.

В справочнике SystemUI приведена полная реализация режима PIP, в котором поддерживаются пользовательские действия и общие манипуляции, например развертывание и закрытие. Производители устройств могут вносить изменения в эти функции, если они не влияют на поведение, определенное в CDD. Вот краткий обзор курса:

  • PipManager: компонент SystemUI, который начинается с SystemUI.
  • PipTouchHandler – обработчик сенсорных событий, который управляет жестами, используемыми для работы с режимом "Картинка в картинке". Используется, только когда активен потребитель входных данных для картинки в картинке (см. InputConsumerController). Сюда можно добавить новые жесты.
  • PipMotionHelper – вспомогательный класс, который отслеживает положение окна PIP и допустимую область на экране. Вызовы к ActivityManagerService для обновления или анимации положения и размера PIP.
  • PipMenuActivityController запускает действие, которое показывает действия, предоставляемые действием, которое в данный момент находится в режиме PIP. Это задание представляет собой наложение на задачу и удаляет перекрывающее его средство ввода, чтобы сделать его интерактивным.
  • PipMenuActivity – реализация действия меню.
  • PipMediaController – прослушиватель, который обновляет SystemUI, когда сеанс воспроизведения медиаконтента изменяется таким образом, что это может повлиять на действия по умолчанию в режиме "Картинка в картинке".
  • PipNotificationController – контроллер, который обеспечивает активность уведомления, когда пользователь использует функцию "Картинка в картинке".
  • PipDismissViewController – оверлей, который показывается пользователям, когда они начинают взаимодействовать с режимом "Картинка в картинке", чтобы сообщить, что его можно закрыть.

Место размещения по умолчанию

По умолчанию положение окна "Картинка в картинке" определяется системными ресурсами.

  • config_defaultPictureInPictureGravity: целое число gravity, которое определяет угол, в котором будет размещено окно PIP, например BOTTOM|RIGHT.
  • config_defaultPictureInPictureScreenEdgeInsets: смещения от краев экрана для размещения окна 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.