API di presentazione dell'interfaccia utente di SDK Runtime

SDK Runtime consente l'esecuzione degli SDK per gli annunci in un ambiente in sandbox, impedendo loro di accedere alla gerarchia delle visualizzazioni di un publisher. Per mostrare gli annunci, la piattaforma espone un'API SandboxedSdkProvider.getView all'SDK per ottenere una visualizzazione dell'annuncio e la pacchettizza come SurfacePackage da inviare tramite IPC (comunicazione inter-processo) all'applicazione client. Questo approccio presenta diversi svantaggi, che vengono descritti di seguito. Questo documento presenterà quindi una libreria Jetpack proposta che è in fase di creazione per risolvere questi problemi.

Motivazione per l'aumento delle API di piattaforma

Le API del framework sono progettate per la flessibilità e lasciano all'app e all'SDK il compito di creare un canale laterale per la presentazione dell'interfaccia utente. Questo canale laterale svolge le seguenti operazioni:

  1. Consente all'SDK di gestire più visualizzazioni dell'annuncio durante il loro ciclo di vita e di capire cosa succede all'interfaccia utente dell'annuncio dopo che è stata creata dall'SDK.
  2. Separa la creazione della visualizzazione e il collegamento dei contenuti. L'utilizzo del canale laterale consente all'SDK di restituire all'app un oggetto corrispondente alla richiesta di annuncio (i contenuti), che può essere associato al contenitore dell'annuncio ogni volta che l'app lo ritiene opportuno.
  3. Astrae i costrutti della piattaforma di base utilizzati per mostrare l'interfaccia utente tra i vari processi. Attualmente la piattaforma utilizza un SurfaceControlViewhost e genera un SurfacePackage.
  4. Consente agli SDK per gli annunci nel runtime dell'SDK di ricevere automaticamente notifiche quando l'interfaccia utente del contenitore degli annunci cambia. Se un publisher modifica il layout del contenitore dell'annuncio, l'SDK rimane all'oscuro di queste modifiche, a meno che il publisher non chiami esplicitamente un'API per inviare una notifica.
  5. Sincronizza le ridimensionamenti dell'interfaccia utente dell'annuncio e del contenitore dell'annuncio senza alcun disturbo visibile all'utente.
  6. Gestisce automaticamente la compatibilità con le versioni precedenti. SurfacePackage non è disponibile prima del livello API 30. Inoltre, sui dispositivi in cui non è presente un ambiente di runtime dell'SDK e l'SDK è locale per il processo del publisher, è uno spreco creare un SurfacePackage per un annuncio quando una visualizzazione può essere ottenuta direttamente dall'SDK. Il canale laterale rimuove questa complessità dal codice sviluppatore dell'SDK e dell'app.
  7. Consente l'integrazione perfetta dell'interfaccia utente dell'annuncio con i Composable. Anche gli sviluppatori di Jetpack Compose che non utilizzano le visualizzazioni possono continuare a ospitare l'interfaccia utente generata dall'autore dell'SDK che continua a utilizzare le visualizzazioni.

Librerie UI

Le librerie UI mettono in primo piano le complessità descritte sopra e forniscono il canale laterale che il publisher e l'SDK possono utilizzare per mostrare l'interfaccia utente nelle varie procedure e mantenerla aggiornata man mano che l'utente interagisce con l'app e con il dispositivo.

Esistono tre librerie UI: core, client e provider. La libreria di base fornisce le interfacce utilizzate dalle librerie client e provider. Il provider dell'interfaccia utente (in genere l'SDK) dipende dalla libreria del provider e il consumatore dell'interfaccia utente (in genere l'editore) dipende dalla libreria client. Insieme, le librerie del client e del provider formano il canale laterale necessario per creare e gestire una sessione dell'interfaccia utente.

Le API

Le API per la presentazione dell'interfaccia utente di SDK Runtime sono le seguenti:

SandboxedUiAdapter: creato dall'SDK, fornisce un modo per ottenere i contenuti da visualizzare nell'interfaccia utente dell'editore.

SandboxedSdkView: creato dall'editore, è un contenitore che contiene i contenuti ottenuti tramite il SandboxedUiAdapter.

Session: creato dall'SDK in risposta a SandboxedUiAdapter.openSession(). Rappresenta una chiamata di sessione dell'interfaccia utente. Questo costituisce il lato SDK del tunnel di comunicazione tra l'SDK e il publisher e riceve notifiche relative alle modifiche in SandboxedSdkView, ad esempio scollegamento delle finestre, ridimensionamenti o modifiche alla configurazione.

SessionClient: creato dalla libreria client, costituisce il lato del publisher del tunnel di comunicazione tra l'SDK e il publisher.

SandboxedSdkUiSessionStateChangedListener: creato dall'editore. Un listener per le modifiche allo stato della sessione dell'interfaccia utente associata a SandboxedSdkView.

Illustrazione che mostra le relazioni tra le API di presentazione dell'interfaccia utente di SDK Runtime.
Relazioni tra le API di presentazione dell'interfaccia utente di SDK Runtime.

Per ulteriori dettagli su queste API, leggi la documentazione di riferimento di privacysandbox-ui.

Flusso di controllo

I seguenti diagrammi mostrano l'interazione tra le librerie UI del client e del provider in vari scenari:

Il diagramma precedente mostra in che modo il publisher può creare un SandboxedSdkView in modo programmatico o tramite il proprio XML e allegarlo a un SdkSandboxUiAdapter ottenuto dall'SDK tramite un'API definita dall'SDK. Per osservare tutte le modifiche dello stato dell'interfaccia utente, l'editore deve aggiungere un SandboxedSdkUiSessionStateChangedListener a SandboxedSdkView prima di collegare SdkSandboxUiAdapter.

Illustrazione che mostra la procedura di apertura della sessione.
Ottieni l'interfaccia utente dall'SDK.

Questo diagramma mostra come, se l'attività dell'editore gestisce le modifiche di configurazione, la libreria client si occupa di inoltrare la modifica all'SDK, in modo che possa aggiornare la propria UI di conseguenza. Ad esempio, questo flusso può essere attivato quando l'utente ruota il dispositivo e il publisher dichiara di gestire le modifiche di configurazione nella sua attività impostando android:configChanges=["orientation"].

Modifica dell'interfaccia utente avviata dal publisher.

Questo diagramma illustra in che modo l'SDK può richiedere una modifica nel contenitore dell'annuncio utilizzando metodi su SessionClient. Questa API viene attivata quando l'SDK vuole ridimensionare l'annuncio e il publisher deve ridimensionare il contenitore dell'annuncio per adattarlo alle nuove dimensioni. Ciò potrebbe accadere in risposta all'interazione dell'utente, ad esempio mraid.resize().

Modifica dell'interfaccia utente avviata dall'SDK.

Questo diagramma mostra come viene chiusa la sessione quando il SandboxedSdkView viene scollegato dalla finestra. La sessione può anche essere chiusa in qualsiasi momento (ad es. quando l'utente perde la connettività di rete) dall'SDK chiamando SessionClient.onSessionError().

Chiusura della sessione dell'interfaccia utente.

Ordine Z

La libreria dell'interfaccia utente client utilizza internamente un SurfaceView per ospitare l'interfaccia utente dell'SDK. SurfaceView può utilizzare l'ordine Z per mostrare la propria UI sopra o sotto la finestra del publisher. Questo viene controllato dal metodo SandboxedSdkView.orderProviderUiAboveClientUi(), che accetta un valore booleano setOnTop.

Quando setOnTop è true, ogni android.view.MotionEvent su SandboxedSdkView viene inviato all'SDK. Quando false, vengono inviati all'Editore. Per impostazione predefinita, gli eventi relativi al movimento vengono inviati all'SDK.

In genere, i publisher non devono modificare l'ordine Z predefinito delle visualizzazioni degli annunci. Tuttavia, quando viene mostrata un'interfaccia utente che copre un annuncio, ad esempio un menu a discesa, l'ordine Z deve essere temporaneamente invertito rispetto al valore predefinito e poi ripristinato quando l'elemento dell'interfaccia utente che copre viene ignorato. Stiamo studiando dei modi per automatizzare questo processo nella libreria UI del client.

Scorrimento

Quando l'interfaccia utente dell'annuncio è ordinata in Z sopra la finestra del publisher, MotionEvents dall'interfaccia utente dell'annuncio vengono inviati all'SDK. I gesti di scorrimento e lancio avviati nell'interfaccia utente dell'annuncio ricevono un trattamento speciale:

  1. I gesti di scorrimento verticale e fling vengono inviati e gestiti dal contenitore del publisher. Ciò garantisce un'esperienza utente ottimale quando il contenitore del publisher in cui è posizionata l'interfaccia utente dell'annuncio è scorrevole verticalmente. Non è richiesta alcuna operazione aggiuntiva da parte dell'SDK o del publisher.
  2. I gesti di scorrimento orizzontale e fling vengono inviati e gestiti dall'SDK. Questo offre un'esperienza utente positiva quando l'interfaccia utente dell'annuncio è scorrevole orizzontalmente (ad esempio un carosello di annunci).

Guida all'implementazione

L'SDK deve implementare quanto segue:

  • SandboxedUiAdapter: viene restituito al publisher in risposta a un'API definita dall'SDK, ad esempio loadAd. Il metodo openSession() di questa implementazione deve essere utilizzato per inviare una richiesta di annuncio ai server dell'SDK e preparare una visualizzazione dell'annuncio per la richiesta.
  • Session**: viene restituito in risposta alla chiamataSandboxedUiAdapter.openSession. Fornisce un modo per la libreria client di ottenere l'interfaccia utente dell'annuncio e di notificare all'SDK le modifiche a questa API. Tutti i metodi Session devono essere implementati qui.

L'editore deve:

  1. Crea un SandboxedSdkView tramite XML o tramite programmazione.
  2. Collega un SandboxedSdkUiSessionStateChangedListener al SandboxedSdkView per osservare le modifiche nell'interfaccia utente.
  3. Collega un SDK fornito da SandboxedUiAdapter al SandboxedSdkView.
  4. Aggiungi SandboxedSdkView alla finestra come di consueto e lascia che sia la libreria client a occuparsi della creazione e della gestione della sessione dell'interfaccia utente con l'SDK.
  5. Al momento opportuno, reagisci alle modifiche dello stato segnalate da SandboxedSdkUiSessionChangedListener. Ad esempio, se l'SDK chiude la sessione in modo imprevisto, il publisher può sostituire SandboxedSdkView con un'immagine statica o rimuoverla dalla gerarchia delle visualizzazioni.
  6. Quando esegui transizioni che potrebbero coprire l'interfaccia utente dell'annuncio, ad esempio un menu a discesa, imposta orderProviderUiAboveClientUi temporaneamente su false per posizionare l'interfaccia utente dell'annuncio sotto la finestra del publisher. Una volta chiuso il menu a discesa, chiama orderProviderUiAboveClientUi per true.

Il futuro delle API di piattaforma

Una volta che le librerie UI saranno disponibili in versione beta, prevediamo di ritirare le API di piattaforma di runtime dell'SDK relative alla presentazione dell'interfaccia utente, ovvero SdkSandboxManager.requestSurfacePackage() e SandbxedSdkProvider.getView().

Domande aperte

  1. Esistono casi d'uso dell'interfaccia utente degli annunci più comuni che le librerie dell'interfaccia utente dovrebbero gestire automaticamente?
  2. Quali framework UI utilizzi per mostrare l'interfaccia utente dell'annuncio? Prevedichi problemi di integrazione delle librerie UI con questi framework?
  3. L'interfaccia utente dell'annuncio scorrevole posizionata in un contenitore del publisher scorrevole è un caso d'uso comune per te? Qual è la direzione dello scorrimento per l'interfaccia utente dell'annuncio e per il contenitore in questo caso? Quale comportamento ti aspetti quando l'utente avvia un scorrimento nell'interfaccia utente dell'annuncio?