Proposta de design para visibilidade do SDK Runtime

Os SDKs de anúncios no SDK Runtime não podem acessar a hierarquia de visualização de um editor. Em vez disso, os SDKs no Runtime têm as próprias visualizações. O SDK não pode usar as mesmas APIs View usadas fora do SDK Runtime para determinar se o anúncio fica visível para o usuário, já que a visualização do anúncio não está anexada à janela do aplicativo. Isso inclui APIs View do Android, como getLocationOnScreen, getLocationInWindow ou getVisibility, que não retornam os valores esperados.

O suporte para a medição da visibilidade de anúncios é um requisito importante do SDK Runtime. O objetivo desta proposta de design é oferecer suporte ao Open Measurement (link em inglês) e a serviços de medição semelhantes. As soluções discutidas aqui também podem se aplicar às APIs Attribution Reporting. Recomendamos que você envie um feedback sobre esta proposta.

Capabilities

O objetivo deste design é oferecer suporte a SDKs de anúncios ou parceiros de medição para calcular os dados de visibilidade a seguir. Os nomes são provisórios e estão sujeitos a mudanças:

Ilustração mostrando a interoperabilidade dos componentes de visibilidade do SDK Runtime
Visão geral da visibilidade do SDK Runtime.
  • viewport [Rect]: representa a tela do dispositivo ou a geometria da janela do app, dependendo das capabilities da plataforma.
  • uiContainerGeometry [Rect]: a geometria da SandboxedSdkView que está sendo renderizada.
  • alpha [float]: a opacidade da SandboxedSdkView que está sendo renderizada.
  • onScreenGeometry [Rect]: o subconjunto da uiContainerGeometry, que não é recortado por visualizações mãe e vai até a viewport.
  • occludedGeometry [Rect]: as partes da onScreenGeometry que são obstruídas por qualquer visualização na hierarquia do aplicativo. Inclui um Rect para cada oclusão, correspondendo a zero, uma ou mais visualizações do app que cruzam com a SandboxedSdkView onScreenGeometry.

Requisitos

  • Os valores para uiContainerGeometry, onScreenGeometry e occludedGeometry são expressos no espaço de coordenadas da viewport.
  • Os relatórios de mudança de visibilidade ocorrem com latência mínima.
  • A visibilidade é mensurável para todo o ciclo de vida da visualização de anúncios, da primeira aparição à última.

Proposta de design

Esta proposta se baseia na forma como a apresentação da interface funciona usando as bibliotecas de interface do provedor e do cliente. Vamos estender as bibliotecas para permitir que o SDK registre um ou mais observadores da sessão da interface. O observador vai receber informações de visibilidade sempre que eventos relevantes que modificam os tipos de dados na seção capabilities forem detectados. Os SDKs de medição no SDK Runtime (implementações OMID e MRAID, links em inglês) podem anexar esse observador à sessão da interface para que essas informações possam ser enviadas diretamente a eles. Os parceiros de medição podem combinar informações recebidas das bibliotecas de interface com dados sobre o conteúdo já disponível (por exemplo, ao usar scripts de medição injetados no criativo do anúncio) para gerar eventos de visibilidade do JavaScript.

Fluxo de controle para visibilidade.
Fluxo de controle para visibilidade.

A biblioteca de cliente detecta mudanças na interface do anúncio usando listeners de eventos, como ViewTreeObserver. Sempre que ela determina que a interface do anúncio mudou de maneira que pode afetar a medição de visibilidade, a biblioteca de cliente verifica quando a última notificação foi enviada ao observador. Se a última atualização for maior que a latência permitida (configurável pelo SDK, até um mínimo de 200 ms em dispositivos móveis), um novo objeto AdContainerInfo será criado e uma notificação será enviada ao observador. Esse modelo baseado em eventos é melhor para a integridade do sistema do que a pesquisa feita pela maioria das implementações OMID no Android atualmente.

API

Os seguintes itens serão adicionados à biblioteca privacysandbox.ui.core:

  • SessionObserver: normalmente implementado pelo SDK de medição, anexado à sessão retornada pelo SDK usando o privacysandbox.ui. Essa interface também permite que o SDK de medição ative determinadas categorias de indicadores de visibilidade. Isso, por sua vez, permite que a biblioteca de cliente da interface colete apenas indicadores em que o observador está interessado, o que é melhor para a integridade do sistema em geral.
  • registerObserver(): adicionado à classe Session, esse método permite que qualquer pessoa com acesso à sessão registre um observador. Se o observador for registrado após a abertura da sessão da interface, ele vai receber o AdContainerInfo armazenado em cache imediatamente. Se registrado antes da abertura da sessão, ele vai receber o AdContainerInfo quando a sessão for aberta.
  • AdContainerInfo: uma classe com getters que permite ao observador receber informações do contêiner de anúncios somente leitura para os tipos de dados listados na seção Capabilities acima. Os valores de retorno desses getters vão corresponder, sempre que possível, aos valores de retorno fracionáveis de getters existentes na View e nas subclasses dela. Se o contêiner de anúncios foi criado usando o Jetpack Compose, as propriedades semânticas dele serão expostas. Essa classe pode ser usada para calcular eventos MRAID e OMID relacionados à visibilidade.
  • SessionObserverotifyAdContainerChanged(): usado para notificar o observador sempre que a visibilidade mudar. Transmite um objeto AdContainerInfo. Ele é chamado sempre que são detectados eventos que afetam os tipos de dados listados na seção "Capabilities". Observação: esse método pode ser chamado junto aos métodos na sessão. Por exemplo, Session.notifyResized() é chamado para solicitar que o SDK redimensione o anúncio, e SessionObserver.notifyAdContainerChanged() também é chamado quando isso acontece.
  • SessionObserverotifySessionClosed(): avisa ao observador que a sessão foi encerrada.

Futuras melhorias

Qualquer código em execução no processo do app, incluindo o da biblioteca privacysandbox.ui.client, pode ser modificado caso o aplicativo seja comprometido. Portanto, qualquer lógica de coleta de indicadores executada no processo do app está propensa a adulteração pelo código do aplicativo. Isso também se aplica ao código do SDK implantado antes da disponibilidade do Sandbox de privacidade em execução no processo do aplicativo. Consequentemente, a coleta de indicadores pela biblioteca da interface não piora a situação de segurança.

Além disso, o código no SDK Runtime pode usar uma API de plataforma chamada setTrustedPresentationCallback, que oferece garantias mais sólidas do framework sobre a apresentação da interface do anúncio. A setTrustedPresentationCallback funciona no nível da plataforma e pode ajudar a fazer declarações sobre a plataforma que contém a interface do anúncio especificando limites mínimos para a apresentação, como a porcentagem de pixels visíveis, o tempo na tela ou a escala. Esses dados podem ser comparados com os de visibilidade fornecidos pela biblioteca de cliente da interface, explicada acima. Como os dados fornecidos pelo framework são mais confiáveis, todos os eventos da biblioteca da interface com dados que não estão de acordo com os dados do framework podem ser descartados. Por exemplo, se o listener fornecido para setTrustedPresentationCallback for invocado com uma notificação de que nenhum pixel da interface do anúncio está aparecendo na tela e a biblioteca da interface do cliente mostrar um valor diferente de zero para o número de pixels na tela, os dados do segundo poderão ser descartados.

Perguntas

Gostaríamos de receber um feedback sobre estas questões:

  1. Você tem interesse em indicadores de visibilidade que não foram mencionados nesta explicação? Quais?
  2. A proposta atual é atualizar a visibilidade com frequência mínima a cada 200 milissegundos, desde que haja uma mudança relevante na interface. Essa frequência é aceitável? Se não for, qual frequência você prefere?
  3. Você prefere analisar as informações da setTrustedPresentationCallback ou que a biblioteca da interface do provedor elimine dados da biblioteca da interface do cliente quando eles não corresponderem aos dados da setTrustedPresentationCallback?
  4. Como você consome os indicadores de visibilidade? Envie um feedback respondendo a estas perguntas para que possamos entender melhor seus casos de uso.