2025년 3월 27일부터 AOSP를 빌드하고 기여하려면 aosp-main
대신 android-latest-release
를 사용하는 것이 좋습니다. 자세한 내용은 AOSP 변경사항을 참고하세요.
PIP 모드
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
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
(main/core/java/android/app/AppOpsManager.java
)의 패키지별 '애플리케이션 작업'(OP_PICTURE_IN_PICTURE
)을 사용하면 사용자가 시스템 설정을 통해 애플리케이션별로 PIP를 제어할 수 있습니다.
기기 구현은 활동이 PIP 모드 전환을 요청할 때 이러한 확인 내용을 적용해야 합니다.
테스트
PIP 구현을 테스트하려면 /cts/hostsidetests/services/activitymanager
아래에서, 특히 ActivityManagerPinnedStackTests.java
에서 호스트 측 CTS 테스트에 있는 모든 PIP 관련 테스트를 실행합니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-07-27(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-07-27(UTC)"],[],[],null,["# Picture-in-picture\n\nThe picture-in-picture (PIP) feature for Android handheld devices lets users resize an app with an\nongoing activity into a small window. PIP is especially useful for video apps because content\ncontinues to play while the user is free to perform other actions. Users can manipulate this\nwindow's position through the SystemUI and interact with the application currently\nin picture-in-picture with (up to three) app-provided actions.\n\n\nPIP requires explicit opt-in from applications that support it and works on a\nper-activity basis. (A single application can have multiple activities, only one\nof which is in PIP.) Activities request to enter picture-in-picture by calling\n`enterPictureInPictureMode()`, and receive activity callbacks in the\nform of `onPictureInPictureModeChanged()`.\n\n\nThe `setPictureInPictureParams()` method lets activities control their\naspect ratio while in PIP and custom actions, which allow users to interact with\nthe activity without having to expand it. In PIP, the activity is in a paused,\nbut rendering, state and doesn't directly receive touch input or window focus.\nOnly a single task can be in PIP at a time.\n\n\nMore information is available in the Android Developer\n[Picture-in-picture](https://developer.android.com/training/tv/playback/picture-in-picture.html)\ndocumentation.\n\nDevice requirements\n-------------------\n\n\nTo support PIP, enable the\n`PackageManager#FEATURE_PICTURE_IN_PICTURE` system feature in\n[/android/frameworks/base/core/java/android/content/pm/PackageManager.java](https://android.googlesource.com/platform/frameworks/base/+/android16-release/core/java/android/content/pm/PackageManager.java).\nDevices that support PIP must have a screen that is larger than 220dp at its\nsmallest width. Similar to split screen multi-window, PIP allows multiple\nactivities to run on-screen at the same time. Therefore, devices should have\nsufficient CPU and RAM to support this use case.\n\nImplementation\n--------------\n\n\nMost of the activity lifecycle management is done in system between\n[ActivityManager](https://android.googlesource.com/platform/frameworks/base/+/android16-release/services/core/java/com/android/server/am/) and [WindowManager](https://android.googlesource.com/platform/frameworks/base/+/android16-release/services/core/java/com/android/server/wm/).\nThe reference UI implementation is in the [SystemUI](https://android.googlesource.com/platform/frameworks/base/+/android16-release/packages/SystemUI/)\npackage.\n\n\nModifications to the system should not affect its intrinsic behavior as defined\nby the [Compatibility Test Suite (CTS) tests](#cts-tests).\nThe system logic for PIP mainly revolves around the management of tasks and\nactivities within the \"pinned\" stack. Here is a quick class overview:\n\n- **`ActivityRecord`:** tracks each activity's picture-in-picture state. To prevent users from entering PIP in certain circumstances, such as from the lock screen or during VR, add cases to `checkEnterPictureInPictureState()`.\n- **`ActivityManagerService`:** the primary interface from the activity to request entering PIP and the interface to calls from `WindowManager` and `SystemUI` to change the PIP activity state.\n- **`ActivityStackSupervisor`:** called from the `ActivityManagerService` to move tasks in or out of the pinned stack, updating the `WindowManager` as necessary.\n- **`PinnedStackWindowController`:** the `WindowManager` interface from `ActivityManager`.\n- **`PinnedStackController`:** reports changes in the system to `SystemUI`, such as IME shown/hidden, aspect ratio changed, or actions changed.\n- **`BoundsAnimationController`:** animates the PIP activity windows in a way that does not trigger a configuration change while resizing.\n- **`PipSnapAlgorithm`:** a shared class used in both the system and SystemUI that controls the snapping behaviour of the PIP window near the edges of the screen.\n\n\nThe reference [SystemUI](https://android.googlesource.com/platform/frameworks/base/+/android16-release/packages/SystemUI/)\nprovides a complete implementation of PIP that supports presenting custom\nactions to users and general manipulation, such as expansion and dismissal.\nDevice manufacturers can build upon these changes, as long as they do not affect\nthe intrinsic behaviours as defined by the CDD. Here is a quick class\noverview:\n\n- **`PipManager`:** the `SystemUI` component that is started with `SystemUI`.\n- **`PipTouchHandler`:** the touch handler, which controls the gestures that manipulate the PIP. This is only used while the input consumer for the PIP is active (see `InputConsumerController`). New gestures can be added here.\n- **`PipMotionHelper`:** a convenience class that tracks the PIP position, and allowable region on-screen. Calls through to `ActivityManagerService` to update or animate the position and size of the PIP.\n- **`PipMenuActivityController`:** starts an activity that shows the actions provided by the activity currently in PIP. This activity is a task-overlay activity, and removes the overlaying input consumer to allow it to be interactive.\n- **`PipMenuActivity`:** the implementation for the menu activity.\n- **`PipMediaController`:** the listener that updates `SystemUI` when the media session changes in a way that might affect the default actions on the PIP.\n- **`PipNotificationController`:** the controller that ensures that a notification is active while a user is using the PIP feature.\n- **`PipDismissViewController`:** the overlay shown to users when they start interacting with the PIP to indicate that it can be dismissed.\n\nDefault placement\n-----------------\n\n\nThere are various system resources that control the default placement of the\nPIP:\n\n- **`config_defaultPictureInPictureGravity`:** the [gravity](https://developer.android.com/reference/android/view/Gravity.html) integer, which controls the corner to place the PIP, such as `BOTTOM|RIGHT`.\n- **`config_defaultPictureInPictureScreenEdgeInsets`:** the offsets from the sides of the screen to place the PIP.\n- **`config_pictureInPictureDefaultSizePercent` and\n `config_pictureInPictureDefaultAspectRatio`:** the combination of percentage of the screen width and the aspect ratio controls the size of the PIP. The computed default PIP size should not be smaller than `@dimen/default_minimal_size_pip_resizable_task`, as defined by CTS and the CDD.\n- **`config_pictureInPictureSnapMode`:** the snapping behaviour as defined in `PipSnapAlgorithm`.\n\n\nDevice implementations should not change the minimum and maximum aspect ratios\nthat are defined in the CDD and CTS.\n\nPermissions\n-----------\n\n\nThe per-package \"application operation\"\n(`OP_PICTURE_IN_PICTURE`) in `AppOpsManager`\n(`main/core/java/android/app/AppOpsManager.java`), lets\nusers to control PIP on a per-application level through the system settings.\nDevice implementations need to respect this check when an activity requests to\nenter picture-in-picture mode.\n\nTesting\n-------\n\n\nTo test PIP implementations, run all picture-in-picture related tests found in\nthe host-side CTS tests under [/cts/hostsidetests/services/activitymanager](https://android.googlesource.com/platform/cts/+/android16-release/hostsidetests/services/activitymanager/src/android/server/cts),\nparticularly in `ActivityManagerPinnedStackTests.java`."]]