PIP

Android モバイル デバイスのピクチャー イン ピクチャー(PIP)機能を使用すると、ユーザーは、アクティビティが進行中のアプリの表示サイズを変更して、小さなウィンドウで表示できます。PIP は、ユーザーが他の操作を自由に行う間もコンテンツを再生し続けるため、動画アプリには特に便利です。ユーザーは、このウィンドウの位置を SystemUI を介して操作し、アプリが提供するアクション(最大 3 つ)でピクチャー イン ピクチャー内にあるアプリを操作できます。

PIP は、PIP をサポートするアプリから明示的にオプトインする必要があり、アクティビティごとに機能します。1 つのアプリに複数のアクティビティを含めることができ、そのうちの 1 つのみが PIP になります。アクティビティは enterPictureInPictureMode() を呼び出してピクチャー イン ピクチャーの開始を要求し、onPictureInPictureModeChanged() の形式でアクティビティのコールバックを受け取ります。

setPictureInPictureParams() メソッドを使用すると、アクティビティは PIP やカスタム アクションの実行中でもアスペクト比を制御できるので、ユーザーはアクティビティを拡張せずに操作できます。PIP では、アクティビティは一時停止状態(ただしレンダリングは行われている)なので、タップ入力またはウィンドウ フォーカスを直接受け取りません。PIP では一度に 1 つのタスクのみを実行できます。

詳細については、Android デベロッパー向けのピクチャー イン ピクチャーのドキュメントをご覧ください。

端末の要件

PIP をサポートするには、/android/frameworks/base/core/java/android/content/pm/PackageManager.javaPackageManager#FEATURE_PICTURE_IN_PICTURE のシステム機能を有効化します。PIP をサポートするデバイスの画面の最小幅は 220 dp より大きくする必要があります。分割画面のマルチウィンドウと同様に、PIP では複数のアクティビティを画面上で同時に実行できます。したがって、デバイスには、このユースケースをサポートするために十分な CPU と RAM が必要です。

実装

アクティビティのライフサイクル管理のほとんどは、ActivityManagerWindowManager の間のシステムで行われます。参照 UI の実装は SystemUI パッケージにあります。

互換性テストスイート(CTS)テストで定義されるとおり、システムに修正を加えることで、本来備わっている動作に影響を及ぼすことはありません。PIP のシステム ロジックは、主に「固定済み」のスタック内のタスクとアクティビティの管理を中心に行われます。簡単なクラスの概要は次のとおりです。

  • ActivityRecord: 各アクティビティのピクチャー イン ピクチャーの状態を追跡します。ロック画面や VR の使用中などの特定の状況でユーザーが PIP を使用できないようにするには、checkEnterPictureInPictureState() にケースを追加します。
  • ActivityManagerService: PIP の開始を要求するアクティビティからのメインのインターフェースと、WindowManagerSystemUI から呼び出し、PIP アクティビティの状態を変更するためのインターフェース。
  • ActivityStackSupervisor: ActivityManagerService から呼び出され、固定されたスタック内外にタスクを移動し、必要に応じて WindowManager を更新します。
  • PinnedStackWindowController: ActivityManager からの WindowManager インターフェース。
  • PinnedStackController: IME の表示 / 非表示、アスペクト比の変更、アクションの変更など、システムの変更を SystemUI に報告します。
  • BoundsAnimationController: サイズ変更中に構成の変更をトリガーしない方法で PIP アクティビティ ウィンドウをアニメーション化します。
  • PipSnapAlgorithm: 画面の端近くの PIP ウィンドウのスナップ動作をコントロールするシステムと SystemUI の両方で使用される共有クラス。

リファレンス 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 など、PIP を配置する角をコントロールする重力整数。
  • config_defaultPictureInPictureScreenEdgeInsets: PIP を配置する画面の両側からのオフセット。
  • config_pictureInPictureDefaultSizePercentconfig_pictureInPictureDefaultAspectRatio: PIP のサイズを制御する画面の幅の割合とアスペクト比の組み合わせ。計算されたデフォルトの PIP サイズは、CTS と CDD で定義されるとおり、@dimen/default_minimal_size_pip_resizable_task より小さくしないでください。
  • config_pictureInPictureSnapMode: PipSnapAlgorithm で定義されているようなスナップ動作。

デバイスの実装では、CDD と CTS で定義されている最大と最小のアスペクト比を変更しないでください。

権限

AppOpsManagermaster/core/java/android/app/AppOpsManager.java)のパッケージごとの「アプリ操作」(OP_PICTURE_IN_PICTURE)により、ユーザーはシステム設定を介して PIP をアプリ単位で制御できます。デバイスの実装では、アクティビティがピクチャー イン ピクチャー モードに切り替わることを要求するとき、このチェックを尊重する必要があります。

テスト

PIP 実装をテストするには、/cts/hostsidetests/services/activitymanager の下の(特に ActivityManagerPinnedStackTests.java にある)ホスト側 CTS テスト内のピクチャー イン ピクチャー関連テストをすべて実行します。