子母畫面

Android 手持裝置的畫中畫 (PIP) 功能可讓使用者將正在進行的活動的應用程式調整到小視窗中。 PIP 對於視訊應用程式特別有用,因為當使用者可以自由執行其他操作時,內容會繼續播放。使用者可以透過 SystemUI 操縱此視窗的位置,並使用(最多三個)應用程式提供的操作與目前處於畫中畫狀態的應用程式互動。

PIP 需要支援它的應用程式明確選擇加入,並且基於每個活動進行工作。 (單一應用程式可以有多個 Activity,其中只有一個處於 PIP 模式。)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請求進入 PIP 的活動的主要接口,以及從WindowManagerSystemUI呼叫以變更 PIP 活動狀態的介面。
  • ActivityStackSupervisorActivityManagerService調用,將任務移入或移出固定堆疊,並根據需要更新WindowManager
  • PinnedStackWindowController ActivityManagerWindowManager介面。
  • PinnedStackControllerSystemUI報告系統中的更改,例如 IME 顯示/隱藏、寬高比更改或操作更改。
  • BoundsAnimationController以在調整大小時不會觸發配置變更的方式對 PIP 活動視窗進行動畫處理。
  • PipSnapAlgorithm系統和 SystemUI 中使用的共用類,用於控制螢幕邊緣附近 PIP 視窗的捕捉行為。

參考SystemUI提供了 PIP 的完整實現,支援向使用者呈現自訂操作和常規操作,例如擴充和關閉。設備製造商可以在這些變更的基礎上進行構建,只要它們不影響 CDD 定義的固有行為即可。以下是課程的快速概述:

  • PipManagerSystemUI一起啟動的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_pictureInPictureSnapMode PipSnapAlgorithm中定義的捕捉行為。

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

權限

AppOpsManager ( main/core/java/android/app/AppOpsManager.java ) 中的每個套件「應用程式操作」( OP_PICTURE_IN_PICTURE ) 允許使用者透過系統設定在每個應用程式層級上控制 PIP。當活動請求進入畫中畫模式時,設備實作需要遵守此檢查。

測試

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