子母畫面

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重力整數,控制放置 PIP 的角點,例如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 ( master/core/java/android/app/AppOpsManager.java ) 中的每個包“應用程序操作”( OP_PICTURE_IN_PICTURE ) 允許用戶通過系統設置在每個應用程序級別上控制 PIP。當活動請求進入畫中畫模式時,設備實現需要遵守此檢查。

測試

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