Android 휴대기기의 PIP(picture-in-picture) 기능을 사용하면 활동을 지속 중인 앱을 작은 창으로 전환할 수 있습니다. PIP가 동영상 앱에 특히 유용한 이유는 콘텐츠가 계속해서 재생해는 동안에도 사용자가 자유롭게 다른 작업을 수행할 수 있기 때문입니다. 사용자는 SystemUI를 통해 이 창의 위치를 변경하고 현재 앱에서 제공하는 작업(최대 3개)을 수행 중인 PIP 모드의 애플리케이션과 상호작용할 수 있습니다.
PIP에는 해당 기능을 지원하고 활동별 기준으로 작동하는 애플리케이션의 명시적인 선택이 요구됩니다. 한 애플리케이션에는 여러 개의 활동이 포함될 수 있으며, 여기서 하나만 PIP입니다. 활동은 enterPictureInPictureMode()
를 호출하여 PIP 전환을 요청하며, onPictureInPictureModeChanged()
형식의 활동 콜백을 수신합니다.
setPictureInPictureParams()
메서드는 활동이 PIP 및 맞춤 작업 상태에서 가로 세로 비율을 제어할 수 있게 해주며, 덕분에 사용자는 확장 없이 활동과 상호작용할 수 있습니다. PIP에서는 활동이 일시중지 상태이지만 계속해서 렌더링되며, 터치 입력 또는 창 포커스를 직접적으로 수신하지 않습니다.
한 번에 하나의 작업만 PIP 모드일 수 있습니다.
자세한 내용은 Android 개발자 PIP(Picture-in-picture) 문서를 참고하세요.
기기 요구사항
PIP를 지원하려면 /android/frameworks/base/core/java/android/content/pm/PackageManager.java
에서 PackageManager#FEATURE_PICTURE_IN_PICTURE
시스템 기능을 사용 설정합니다.
PIP를 지원하는 기기에는 가장 작은 너비가 200dp를 초과하는 큰 화면이 있어야 합니다. 화면 분할 멀티 윈도우처럼 PIP는 화면에서 여러 활동을 동시에 실행할 수 있게 해줍니다. 따라서 기기의 CPU 및 RAM은 이러한 사용 사례를 지원할 수 있을 만큼 충분해야 합니다.
구현
활동 수명 주기 관리의 대부분은 시스템에서 ActivityManager
및 WindowManager
사이에 실행됩니다.
참조 UI 구현은 SystemUI
패키지에 있습니다.
시스템 수정사항은 호환성 테스트 모음(CTS) 테스트에 의해 정의된 것처럼 시스템의 근본적인 동작에 영향을 미치면 안 됩니다. PIP의 시스템 논리는 기본적으로 '고정된' 스택 내의 작업 및 활동 관리를 중심으로 이루어집니다. 다음은 간단한 클래스 개요입니다.
ActivityRecord
: 활동의 PIP(picture-in-picture) 상태를 추적합니다. 특정 상황에서 사용자가 PIP 모드로 전환되지 않도록 하려면(예: 잠금 화면 또는 VR 도중)checkEnterPictureInPictureState()
에 사례를 추가합니다.ActivityManagerService
: PIP 모드로의 전환을 요청하기 위한 활동의 기본 인터페이스, 그리고 PIP 활동 상태를 변경하기 위한WindowManager
및SystemUI
의 호출 인터페이스입니다.ActivityStackSupervisor
:ActivityManagerService
에서 호출되어 고정된 스택 안팎으로 태스크를 이동하고, 필요에 따라WindowManager
를 업데이트합니다.PinnedStackWindowController
:ActivityManager
의WindowManager
인터페이스입니다.PinnedStackController
: 시스템의 변경사항을SystemUI
에 보고합니다(표시된/숨겨진 IME, 변경된 가로 세로 비율 또는 변경된 작업 등).BoundsAnimationController
: 크기 변경 도중 구성 변경을 트리거하지 않는 방식으로 PIP 활동 창에 애니메이션을 적용합니다.PipSnapAlgorithm
: 시스템 및 SystemUI에 사용되는 공유된 클래스입니다. 화면 가장자리 근처 PIP 창의 맞추기 동작을 제어합니다.
참조 SystemUI
는 확장 및 해제처럼 사용자 및 일반 변경에 대한 맞춤 작업 표시를 지원하는 온전한 PIP 구현을 제공합니다.
이 변경사항이 CDD에 의해 정의되는 근본적인 동작에 영향을 미치지 않는 한, 기기 제조업체는 이 변경사항을 기반으로 할 수 있습니다. 다음은 간단한 클래스 개요입니다.
PipManager
:SystemUI
로 시작하는SystemUI
구성요소입니다.PipTouchHandler
: PIP를 조작하는 동작을 제어하는 터치 핸들러입니다. PIP의 입력 소비자가 활성 상태인 경우에만 사용됩니다(InputConsumerController
참조). 여기에서 새 동작을 추가할 수 있습니다.PipMotionHelper
: PIP 위치와 화면의 허용되는 부분을 추적하는 편의성 클래스입니다.ActivityManagerService
를 통해 호출하여 PIP 위치 및 크기를 업데이트하거나 애니메이션을 적용합니다.PipMenuActivityController
: 현재 PIP의 활동에 의해 제공되는 작업을 표시하는 활동을 시작합니다. 이 활동은 작업 오버레이 활동이며, 오버레이된 입력 소비자를 제거하여 상호작용을 허용합니다.PipMenuActivity
: 메뉴 활동의 구현입니다.PipMediaController
: PIP의 기본 작업에 영향을 줄 수 있는 방식으로 미디어 세션이 변경될 때SystemUI
를 업데이트하는 리스너입니다.PipNotificationController
: 사용자가 PIP 기능을 사용하는 동안 알림이 활성화되도록 하는 컨트롤러입니다.PipDismissViewController
: 사용자가 PIP와 상호작용을 시작하면 사용자가 PIP를 해제할 수 있다고 표시하기 위해 표시되는 오버레이입니다.
기본 게재위치
PIP의 기본 게재위치를 제어하는 다양한 시스템 리소스가 있습니다.
config_defaultPictureInPictureGravity
: PIP를 배치할 모서리를 제어하는 중력 정수입니다(예:BOTTOM|RIGHT
).config_defaultPictureInPictureScreenEdgeInsets
: PIP 배치를 위한 화면 측면의 오프셋입니다.config_pictureInPictureDefaultSizePercent
및config_pictureInPictureDefaultAspectRatio
: 화면 너비 및 가로 세로 비율의 조합은 PIP 크기를 제어합니다. 계산된 기본 PIP 크기는 CTS 및 CDD에 의해 정의된@dimen/default_minimal_size_pip_resizable_task
보다 작을 수 없습니다.config_pictureInPictureSnapMode
:PipSnapAlgorithm
에 정의된 맞추기 동작입니다.
기기 구현은 CDD 및 CTS에 정의된 최소 및 최대 가로 세로 비율을 변경하면 안 됩니다.
권한
AppOpsManager
(master/core/java/android/app/AppOpsManager.java
)의 패키지별 '애플리케이션 작업'(OP_PICTURE_IN_PICTURE
)을 사용하면 사용자가 시스템 설정을 통해 애플리케이션별로 PIP를 제어할 수 있습니다.
기기 구현은 활동이 PIP 모드 전환을 요청할 때 이러한 확인 내용을 적용해야 합니다.
테스트
PIP 구현을 테스트하려면 /cts/hostsidetests/services/activitymanager
아래에서, 특히 ActivityManagerPinnedStackTests.java
에서 호스트 측 CTS 테스트에 있는 모든 PIP 관련 테스트를 실행합니다.