APIs de presentación de la IU del entorno de ejecución de SDK

El entorno de ejecución de SDK permite que los SDKs de anuncios se ejecuten en un entorno de zona de pruebas, lo que evita que puedan acceder a la jerarquía de vistas de un publicador. Para mostrar anuncios, la plataforma expone una API de SandboxedSdkProvider.getView al SDK para obtener una vista de anuncio y la empaqueta como un elemento SurfacePackage que se enviará por IPC (comunicación entre procesos) a la aplicación cliente. Esto tiene varias desventajas, que se analizan a continuación. Más adelante en este documento, se presentará una biblioteca propuesta de Jetpack que se está compilando para abordar estos desafíos.

Razones para mejorar las APIs de la plataforma

Las APIs de framework se diseñaron para ofrecer flexibilidad y traspasan a la app y al SDK la tarea de crear un canal lateral entremedio para la presentación de la IU. Este canal lateral hace lo siguiente:

  1. Permite que el SDK administre varias vistas de anuncios durante su ciclo de vida y comprenda qué sucede con la IU del anuncio una vez que el SDK la crea.
  2. Separa la creación de vistas y la vinculación de contenido. El uso del canal lateral permite que el SDK muestre un objeto que corresponda a la solicitud de anuncio a la app (el contenido), que se puede vincular al contenedor de anuncios cuando la app lo considere apropiado.
  3. Abstrae las construcciones de plataforma subyacentes que se usan para mostrar la IU en todos los procesos (la plataforma actualmente usa un SurfaceControlViewhost y genera un objeto SurfacePackage a partir de este).
  4. Permite que los SDKs de anuncios en el entorno de ejecución de SDK reciban notificaciones automáticamente cuando cambia la IU del contenedor de anuncios. Si un publicador cambia el diseño del contenedor de anuncios, el SDK no reconoce estos cambios, a menos que llame, explícitamente, a una API para notificarlo.
  5. Sincroniza los cambios de tamaño de la IU del anuncio y del contenedor de anuncios sin ningún bloqueo visible para el usuario.
  6. Administra la retrocompatibilidad automáticamente. SurfacePackage no está disponible en niveles de API inferiores al 30. Además, en los dispositivos en los que no hay un entorno de ejecución de SDK y el SDK es un proceso local para el publicador, es una pérdida de tiempo crear un elemento SurfacePackage para un anuncio cuando una vista se puede obtener directamente del SDK. El canal lateral abstrae esta complejidad del SDK y del código del desarrollador de apps.
  7. Permite que la IU del anuncio se integre, sin problemas, en los componibles. Los desarrolladores de Jetpack Compose que no trabajan con vistas también pueden continuar alojando la IU que genera el desarrollador del SDK que aún trabaja con estas.

Bibliotecas de la IU

Las bibliotecas de la IU abstraen las complejidades que se detallaron anteriormente y proporcionan el canal lateral que el publicador y el SDK pueden usar para mostrar la IU en todos los procesos y mantenerla actualizada, a medida que el usuario interactúa con esta y con el dispositivo.

Existen tres bibliotecas de IU: la biblioteca principal, cliente y proveedor. La biblioteca principal proporciona las interfaces que usan las bibliotecas cliente y proveedor. El proveedor de la IU (por lo general, el SDK) depende de la biblioteca proveedor, y el consumidor de la IU (por lo general, el publicador) depende de la biblioteca cliente. En conjunto, las bibliotecas cliente y proveedor forman el canal lateral que se necesita para crear y mantener una sesión de la IU.

Las APIs

Las APIs para la presentación de la IU del entorno de ejecución de SDK son las siguientes:

SandboxedUiAdapter: Es creada por el SDK y proporciona una forma de obtener contenido que se mostrará en la IU del publicador.

SandboxedSdkView: Es creada por el publicador y es un contenedor que incluye todo aquello lo que se obtiene a través de SandboxedUiAdapter.

Session: Es creada por el SDK en respuesta a SandboxedUiAdapter.openSession(). Representa una llamada a la sesión de la IU. Forma el final del SDK del túnel de comunicación entre el SDK y el publicador, y recibe notificaciones sobre los cambios en SandboxedSdkView, como la desconexión de ventanas, los cambios de tamaño o de configuración.

SessionClient: Es creada por la biblioteca cliente y forma el final del publicador del túnel de comunicación entre el SDK y el publicador.

SandboxedSdkUiSessionStateChangedListener: Es creada por el publicador. Un objeto de escucha para los cambios en el estado de la sesión de la IU que se relaciona con SandboxedSdkView.

Ilustración que muestra las relaciones de las APIs de presentación de la IU del entorno de ejecución de SDK.
Relaciones entre las APIs de presentación de la IU del entorno de ejecución de SDK.

Lee la documentación de referencia de privacysandbox-ui para obtener más detalles sobre estas APIs.

Flujo de control

En los siguientes diagramas, se muestra la interacción entre las bibliotecas cliente y proveedor de la IU en varias situaciones:

En el diagrama anterior, se muestra cómo el publicador puede crear un SandboxedSdkView de manera programática o a través de su XML y adjuntarlo a un SdkSandboxUiAdapter que se obtiene del SDK a través de una API definida por este. Para observar todos los cambios de estado de la IU, el publicador debe agregar un objeto SandboxedSdkUiSessionStateChangedListener a SandboxedSdkView antes de conectar SdkSandboxUiAdapter.

Ilustración que muestra el proceso de la sesión abierta.
Obtén la IU del SDK.

En este diagrama, se muestra cómo la biblioteca cliente se encarga de reenviar el cambio de configuración al SDK si la actividad del publicador controla estos cambios, para que puedan actualizar su IU según corresponda. Por ejemplo, este flujo se puede activar con la configuración de android:configChanges=["orientation"] cuando el usuario rota el dispositivo y el publicador declara el control de los cambios de configuración en su actividad.

Cambio en la IU iniciado por el publicador.

En este diagrama, se ilustra cómo el SDK puede solicitar un cambio en el contenedor de anuncios mediante métodos en SessionClient. Esta API se activa cuando el SDK quiere cambiar el tamaño del anuncio y necesita que el publicador cambie el tamaño del contenedor de anuncios para adaptarse a las nuevas dimensiones. Esto puede ocurrir en respuesta a la interacción del usuario, por ejemplo, con mraid.resize().

Cambio en la IU iniciado por el SDK.

En este diagrama, se muestra cómo se cierra la sesión cuando SandboxedSdkView se desconecta de la ventana. El SDK también puede cerrar la sesión en cualquier momento si invoca a SessionClient.onSessionError() (p. ej., cuando el usuario pierde la conexión a la red).

Cierre de la sesión de la IU.

Orden en Z

La biblioteca cliente de la IU usa un objeto SurfaceView de forma interna para alojar la IU del SDK. SurfaceView puede usar el orden en Z para mostrar su IU en la parte superior de la ventana del publicador o debajo de esta. Esto se controla con el método SandboxedSdkView.orderProviderUiAboveClientUi(), que acepta un elemento setOnTop booleano.

Cuando setOnTop es true, cada android.view.MotionEvent en SandboxedSdkView se envía al SDK. Cuando sea false, se enviarán al publicador. De forma predeterminada, los eventos de movimiento se envían al SDK.

Por lo general, los publicadores no necesitan cambiar el orden predeterminado en Z de las vistas de anuncio. Sin embargo, cuando se muestra la IU que cubre un anuncio, como un menú desplegable, el orden en Z debe cambiarse temporalmente del valor predeterminado y, luego, restablecerse cuando se descarte el elemento de la IU que lo cubre. Estamos buscando formas de automatizar este proceso en la biblioteca cliente de la IU.

Desplazamiento

Cuando la IU del anuncio se coloca en el orden en Z sobre la ventana del publicador, los objetos MotionEvents de la IU del anuncio se envían al SDK. Los gestos de desplazamiento y deslizamiento que se inician en la IU del anuncio reciben un tratamiento especial:

  1. Los gestos de desplazamiento y deslizamiento verticales se envían al contenedor del publicador y son controlados por este. Esto proporciona una buena UX cuando el contenedor del publicador en el que se coloca la IU del anuncio se puede desplazar verticalmente. No requiere ningún acción adicional por parte del SDK o publicador.
  2. El SDK envía y controla los gestos de desplazamiento y deslizamiento horizontales. Esto proporciona una buena UX cuando la misma IU del anuncio se puede desplazar horizontalmente (como un carrusel de anuncios).

Guía de implementación

El SDK debe implementar lo siguiente:

  • SandboxedUiAdapter: Se muestra al publicador en respuesta a una API definida por el SDK, como loadAd. Se debe usar el método openSession() de esta implementación para realizar una solicitud de anuncio a los servidores del SDK y preparar una vista de anuncio para esa solicitud.
  • Session**: Se muestra en respuesta a la llamada a SandboxedUiAdapter.openSession. Proporciona una manera para que la biblioteca cliente obtenga la IU del anuncio y notifique al SDK sobre los cambios en esta API. Aquí se deben implementar todos los métodos Session.

El publicador debe hacer lo siguiente:

  1. Crear un elemento SandboxedSdkView, ya sea a través de XML o de manera programática
  2. Conectar un objeto SandboxedSdkUiSessionStateChangedListener a SandboxedSdkView para observar cambios en la IU
  3. Conectar un objeto SandboxedSdkView que proporciona el SDK al elemento SandboxedUiAdapter
  4. Agregar SandboxedSdkView a la ventana como de costumbre y dejar que la biblioteca cliente se encargue de crear y mantener la sesión de la IU con el SDK
  5. En los momentos adecuados, reaccionar a los cambios en el estado que informa SandboxedSdkUiSessionChangedListener (por ejemplo, si el SDK cierra la sesión de forma inesperada, el publicador puede reemplazar SandboxedSdkView por una imagen estática o quitarla de su jerarquía de vistas)
  6. Cuando realices transiciones que puedan cubrir la IU del anuncio, como un menú desplegable, establecer temporalmente orderProviderUiAboveClientUi como "false" para posicionar la IU del anuncio debajo de la ventana del publicador (una vez que se descarte el menú desplegable, llama a orderProviderUiAboveClientUi como true)

El futuro de las APIs de la plataforma

Una vez que las bibliotecas de IU estén en versión beta, planeamos dar de baja las APIs de la plataforma del entorno de ejecución de SDK que se relacionen con la presentación de la IU, es decir, SdkSandboxManager.requestSurfacePackage() y SandbxedSdkProvider.getView().

Preguntas abiertas

  1. ¿Existen casos de uso habituales de la IU del anuncio que las bibliotecas de la IU deberían controlar automáticamente?
  2. ¿Qué frameworks de la IU usas para mostrar la IU del anuncio? ¿Esperas que haya problemas para integrar las bibliotecas de la IU con estos frameworks?
  3. Según tu opinión, ¿es un caso de uso habitual la IU del anuncio desplazable que se ubican en un contenedor del publicador desplazable? En este caso, ¿cuál es la direccionalidad del desplazamiento para la IU del anuncio y el contenedor? ¿Qué comportamiento esperas cuando el usuario inicie un desplazamiento en la IU del anuncio?