SDK ランタイム UI 表示 API

SDK ランタイムでは、広告 SDK をサンドボックス環境で実行できるため、パブリッシャーのビュー階層にアクセスできません。広告を表示するために、プラットフォームが SandboxedSdkProvider.getView API を SDK に公開して広告ビューを取得し、これを SurfacePackage としてパッケージ化して IPC(プロセス間通信)経由でクライアント アプリケーションに送信します。これにはいくつかの欠点があります。これについては以下で説明します。このドキュメントでは、こうした課題に対処するために開発中の、Jetpack ライブラリ案も紹介します。

プラットフォーム API を拡張する理由

フレームワーク API は柔軟性を考慮して設計されており、UI 表示の間のサイドチャネルの構築のタスクをアプリと SDK に任せることができます。このサイドチャネルは次の処理を行います。

  1. SDK が全期間にわたって複数の広告ビューを管理し、SDK によって作成された広告 UI がどうなるかを把握できるようにします。
  2. ビューの作成とコンテンツ バインディングを分離します。サイドチャネルを使用すると、SDK は広告リクエストに対応するオブジェクトをアプリ(コンテンツ)に返すことができます。これは、アプリが適切と判断した場合はいつでも、広告コンテナにバインドできます。
  3. プロセス全体で UI を表示するために使用される、基盤となるプラットフォーム構造を取り除きます(プラットフォームは現在、SurfaceControlViewhost を使用して、そこから SurfacePackage を生成します)。
  4. 広告コンテナの UI が変更されたときに、SDK ランタイムの広告 SDK が自動的に通知を受け取れるようにします。パブリッシャーが広告コンテナのレイアウトを変更しても、パブリッシャーが明示的に API を呼び出して通知しない限り、SDK はその変更を認識しません。
  5. ユーザーに表示されるジャンクを発生させることなく、広告 UI と広告コンテナのサイズ変更を同期します。
  6. 下位互換性を自動的に管理します。SurfacePackage は、API レベル 30 より前のバージョンでは使用できません。また、SDK ランタイムがなく、SDK がパブリッシャーに対してプロセスローカルであるデバイスでは、ビューを直接 SDK から取得できる場合に広告用の SurfacePackage を作成することは無駄になります。サイドチャネルは、この複雑さを SDK およびアプリ デベロッパー コードから取り除きます。
  7. 広告 UI がコンポーザブルとシームレスに統合されます。ビューを使用しない Jetpack Compose デベロッパーは、引き続きビューを使用している SDK デベロッパーが生成した UI を引き続きホストできます。

UI ライブラリ

UI ライブラリは、上記で詳説した複雑さを取り除き、パブリッシャーと SDK がプロセス全体で UI を表示するために使用できるサイドチャネルを提供します。また、ユーザーによる UI およびデバイスの操作に応じて、UI を最新の状態に維持します。

UI ライブラリは 3 つ(コア、クライアント、プロバイダ)あります。コアライブラリは、クライアント ライブラリとプロバイダ ライブラリで使用されるインターフェースを提供します。UI プロバイダ(通常は SDK)はプロバイダ ライブラリに依存し、UI のコンシューマ(通常はパブリッシャー)はクライアント ライブラリに依存します。クライアント ライブラリとプロバイダ ライブラリが連携して、UI セッションの作成と維持に必要なサイドチャネルを形成します。

API

SDK ランタイム UI 表示用の API は次のとおりです。

SandboxedUiAdapter: SDK で作成され、パブリッシャーの UI に表示するコンテンツを取得する方法を提供します。

SandboxedSdkView: パブリッシャーにより作成されます。SandboxedUiAdapter を通じて取得したコンテンツを保持するコンテナです。

Session: SandboxedUiAdapter.openSession() に応じて SDK によって作成されます。1 つの UI セッション呼び出しを表します。これにより、SDK とパブリッシャー間の通信トンネルの SDK 側が形成されます。また、SandboxedSdkView の変更(ウィンドウのデタッチ、サイズ変更、設定の変更など)に関する通知を受け取ります。

SessionClient: クライアント ライブラリで作成され、SDK とパブリッシャー間の通信トンネルのパブリッシャー側を形成します。

SandboxedSdkUiSessionStateChangedListener: パブリッシャーによって作成されます。SandboxedSdkView に関連付けられた UI セッションの状態の変更のリスナー。

SDK ランタイム UI 表示 API の関係を示すイラスト。
SDK ランタイム UI 表示 API 間の関係

これらの API について詳しくは、privacysandbox-ui リファレンス ドキュメントをご覧ください。

制御フロー

次の図は、さまざまなシナリオでのクライアント UI ライブラリとプロバイダ UI ライブラリ間のやり取りを示しています。

上の図は、パブリッシャーがプログラムまたは XML を使用して SandboxedSdkView を作成し、SDK 定義の API を介して SDK から取得した SdkSandboxUiAdapter にアタッチする方法を示しています。すべての UI 状態の変化を監視するには、パブリッシャーは SdkSandboxUiAdapter をアタッチする前に SandboxedSdkUiSessionStateChangedListenerSandboxedSdkView に追加する必要があります。

オープン セッションのプロセスを示すイラスト。
SDK から UI を取得します。

この図は、パブリッシャーのアクティビティが構成の変更を処理する場合に、クライアント ライブラリが構成の変更を SDK に転送し、それに応じて UI を更新できるようにする方法を示しています。たとえば、ユーザーがデバイスを回転させた場合で、パブリッシャーが android:configChanges=["orientation"] を設定してアクティビティで構成変更の処理を宣言している場合に、このフローがトリガーされる可能性があります。

パブリッシャーが行う UI の変更。

次の図は、SDK が SessionClient のメソッドを使用して広告コンテナの変更をリクエストする方法を示しています。この API は、SDK が広告のサイズ変更をリクエストし、パブリッシャーが新しいサイズに合わせて広告コンテナのサイズを変更する必要があるときにトリガーされます。これは、mraid.resize() などのユーザー操作に応じて発生することがあります。

SDK によって開始される UI の変更。

次の図は、SandboxedSdkView がウィンドウからデタッチされたときにセッションがどのように終了するかを示しています。セッションは、SDK で SessionClient.onSessionError() を呼び出すことで、任意の時点で(たとえば、ユーザーがネットワーク接続を失ったときなどに)閉じることもできます。

UI セッションを終了する。

Z オーダー

クライアント UI ライブラリは、内部で SurfaceView を使用して SDK の UI をホストします。SurfaceView は Z オーダーを使用して、パブリッシャーのウィンドウの上または下に UI を表示できます。これは、ブール値 setOnTop を受け取る SandboxedSdkView.orderProviderUiAboveClientUi() メソッドによって制御されます。

setOnToptrue の場合、SandboxedSdkView のすべての android.view.MotionEvent が SDK に送信されます。false の場合、これらはパブリッシャーに送信されます。デフォルトでは、モーション イベントは SDK に送信されます。

通常、パブリッシャーは広告ビューのデフォルトの Z オーダーを変更する必要がありません。ただし、広告を覆う UI(プルダウン メニューなど)を表示する場合は、Z オーダーを一時的にデフォルトから切り替えて、覆う UI 要素が閉じたらこれを復元するようにする必要があります。現在、クライアント UI ライブラリでこのプロセスを自動化する方法を検討しています。

スクロール

広告 UI がパブリッシャー ウィンドウの上の Z に配置されると、広告 UI からの MotionEvents が SDK に送信されます。広告 UI で開始されるスクロール操作とフリング操作は特別な処理が行われます。

  1. 垂直スクロールとフリングのジェスチャーは、パブリッシャーのコンテナに送信され、コンテナによって処理されます。広告 UI が配置されるパブリッシャーのコンテナが垂直方向にスクロールできる場合に、これは優れた UX を実現できます。SDK やパブリッシャー側で特別な作業を行う必要はありません。
  2. 水平方向のスクロール操作とフリング操作は、SDK に送信され、SDK によって処理されます。広告 UI 自体が水平方向にスクロールできる場合(広告カルーセルなど)に、これは優れた UX を実現できます。

実装ガイド

SDK は以下を実装する必要があります。

  • SandboxedUiAdapter: SDK 定義の API(loadAd など)に応答してパブリッシャーに返されます。この実装の openSession() メソッドを使用して、SDK のサーバーに広告リクエストを行い、そのリクエストの広告ビューを準備する必要があります。
  • Session**: SandboxedUiAdapter.openSession 呼び出しに応答して返されます。これにより、クライアント ライブラリが広告 UI を取得し、この API の変更を SDK に通知できるようになります。すべての Session メソッドをここで実装する必要があります。

パブリッシャーは、次のことを行う必要があります。

  1. XML またはプログラムによって SandboxedSdkView を作成します。
  2. SandboxedSdkUiSessionStateChangedListenerSandboxedSdkView にアタッチして、UI の変化を監視します。
  3. SDK が提供する SandboxedUiAdapterSandboxedSdkView にアタッチします。
  4. 通常どおり SandboxedSdkView をウィンドウに追加し、SDK との UI セッションの作成とメンテナンスはクライアント ライブラリに任せます。
  5. 適宜、SandboxedSdkUiSessionChangedListener によってレポートされる状態の変化に対応します。たとえば、SDK がセッションを予期せず閉じた場合に、パブリッシャーは SandboxedSdkView を静止画像に置き換えたり、ビュー階層から削除したりできます。
  6. プルダウン メニューなど、広告 UI を覆うような遷移を行う場合は、一時的に orderProviderUiAboveClientUi を false にして、パブリッシャーのウィンドウの下に広告 UI を配置します。プルダウン メニューが閉じたら、orderProviderUiAboveClientUi を呼び出して true にします。

プラットフォーム API の今後

UI ライブラリがベータ版になった時点で、UI の表示に関連する SDK ランタイム プラットフォーム API(SdkSandboxManager.requestSurfacePackage()SandbxedSdkProvider.getView())のサポートを終了する予定です。

自由回答形式の質問

  1. UI ライブラリが自動的に処理する必要がある、より一般的な広告 UI ユースケースはありますか?
  2. 広告 UI を表示するためにどの UI フレームワークを使用していますか?UI ライブラリをそれらのフレームワークと統合する際に、問題が発生することが予想されますか?
  3. スクロール可能なパブリッシャーのコンテナにスクロール可能な広告 UI を配置するのは一般的なユースケースですか?この場合の、広告 UI とコンテナのスクロールはいずれの方向ですか?ユーザーが広告 UI でスクロールを開始したときに想定される動作は何ですか?