畫中畫

Android 手持設備的畫中畫 (PIP) 功能可讓用戶將正在進行的活動的應用程序調整為小窗口。 PIP 對於視頻應用程序特別有用,因為當用戶可以自由地執行其他操作時,內容會繼續播放。用戶可以通過 SystemUI 操作此窗口的位置,並使用(最多三個)應用程序提供的操作與當前畫中畫的應用程序進行交互。

PIP 需要從支持它的應用程序中明確選擇加入,並在每個活動的基礎上工作。 (單個應用可以有多個activity,其中只有一個是畫中畫。)activity通過調用enterPictureInPictureMode()請求進入畫中畫,並以onPictureInPictureModeChanged()的形式接收activity回調。

setPictureInPictureParams()方法允許活動在 PIP 和自定義操作中控制其縱橫比,這允許用戶與活動交互而無需展開它。在 PIP 中,活動處於暫停但正在渲染的狀態,並且不直接接收觸摸輸入或窗口焦點。一次只能有一個任務在 PIP 中。

Android 開發者畫中畫文檔中提供了更多信息。

設備要求

要支持 PIP,請在/android/frameworks/base/core/java/android/content/pm/PackageManager.java中啟用PackageManager#FEATURE_PICTURE_IN_PICTURE系統功能。支持 PIP 的設備的最小寬度必須大於 220dp。與分屏多窗口類似,PIP 允許多個活動同時在屏幕上運行。因此,設備應該有足夠的 CPU 和 RAM 來支持這個用例。

執行

大多數活動生命週期管理是在ActivityManagerWindowManager之間的系統中完成的。參考 UI 實現位於SystemUI包中。

對系統的修改不應影響其由兼容性測試套件 (CTS) 測試定義的內在行為。 PIP 的系統邏輯主要圍繞“固定”堆棧內的任務和活動的管理。這是一個快速的類概述:

  • ActivityRecord跟踪每個活動的畫中畫狀態。為了防止用戶在某些情況下(例如從鎖定屏幕或 VR 期間)進入 PIP,請在checkEnterPictureInPictureState()中添加案例。
  • ActivityManagerService : Activity請求進入 PIP 的主要接口,以及WindowManagerSystemUI調用以更改 PIP 活動狀態的接口。
  • ActivityStackSupervisorActivityManagerService調用以將任務移入或移出固定堆棧,並根據需要更新WindowManager
  • PinnedStackWindowController來自ActivityManagerWindowManager接口。
  • PinnedStackControllerSystemUI報告系統中的更改,例如 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 的默認位置:

  • config_defaultPictureInPictureGravity重力整數,控制角落放置畫中畫,如BOTTOM|RIGHT
  • config_defaultPictureInPictureScreenEdgeInsets放置 PIP 的屏幕兩側的偏移量。
  • config_pictureInPictureDefaultSizePercentconfig_pictureInPictureDefaultAspectRatio屏幕寬度百分比和縱橫比的組合控制 PIP 的大小。計算的默認 PIP 大小不應小於 CTS 和 CDD 定義的@dimen/default_minimal_size_pip_resizable_task
  • config_pictureInPictureSnapModePipSnapAlgorithm中定義的捕捉行為。

設備實現不應更改 CDD 和 CTS 中定義的最小和最大縱橫比。

權限

AppOpsManager ( master/core/java/android/app/AppOpsManager.java ) 中的每個包的“應用程序操作”( OP_PICTURE_IN_PICTURE ),允許用戶通過系統設置在每個應用程序級別控制 PIP。當活動請求進入畫中畫模式時,設備實現需要遵守此檢查。

測試

要測試 PIP 實現,請運行在/cts/hostsidetests/services/activitymanager下的主機端 CTS 測試中找到的所有畫中畫相關測試,特別是在ActivityManagerPinnedStackTests.java中。