Visão geral do SDK Runtime

A plataforma Android usa o conceito de sandbox de app para manter uma execução robusta e limites de segurança, bem como limites de processo, para o código do app. É uma prática comum que os apps incluam código de terceiros, geralmente na forma de SDKs, como SDKs de anúncios ou de análise. Essa reutilização permite que os desenvolvedores de apps se concentrem em recursos que diferenciem os apps e tirem proveito do trabalho de especialistas no assunto para levar a execução do app a níveis mais elevados do que conseguiriam atingir facilmente por conta própria.

Como na maioria dos sistemas operacionais, no Android, os SDKs são executados no sandbox do app host e herdam os mesmos privilégios e permissões do app em que estão hospedados, bem como o acesso à memória e ao armazenamento do app host. Embora essa arquitetura permita a integração flexível de SDKs e apps, ela também cria a possibilidade de compartilhamento e coleta de dados não divulgados de usuários. Além disso, é possível que os desenvolvedores de apps não estejam totalmente cientes da extensão das funções de um SDK de terceiros e dos dados que ele acessa, o que dificulta a avaliação das práticas de coleta e compartilhamento de dados do app.

No Android 14, adicionamos um novo recurso de plataforma que permite que SDKs de terceiros sejam executados em um ambiente de execução dedicado, chamado de SDK Runtime. O SDK Runtime oferece as seguintes proteções e garantias em relação à coleta e ao compartilhamento de dados do usuário:

  • Ambiente de execução modificado
  • Permissões bem definidas e direitos de acesso a dados para SDKs

Queremos receber o feedback da comunidade que trabalha com publicidade em apps para dispositivos móveis com relação a esse modelo. O feedback de outros tipos de desenvolvedores também é bem-vindo para ajudar a definir futuras iterações do SDK Runtime, incluindo suporte para outros casos de uso.

Metas

Esta proposta busca atingir as metas abaixo:

  • Reduzir o acesso e o compartilhamento não revelado dos dados de apps de um usuário por SDKs de terceiros, implementando o isolamento de processos e um controle de acesso a APIs e dados bem definido. Saiba mais sobre o isolamento de processo em outra seção deste documento.
  • Reduzir o rastreamento não divulgado do uso de apps de usuários por SDKs de terceiros, limitando a possibilidade de acesso a identificadores exclusivos e persistentes pelos SDKs.
  • Acelerar a distribuição de atualizações do SDK para apps de forma segura, reduzindo o trabalho dos desenvolvedores de apps e dos usuários finais. Saiba mais sobre a proposta de modelo de distribuição de SDKs confiáveis em outra seção deste documento.
  • Ajudar os desenvolvedores a ter melhor controle sobre as práticas de acesso e compartilhamento de dados dos próprios apps.
  • Ajudar os desenvolvedores de SDKs a evitar adulterações por parte de outros SDKs, limitando o uso de algumas construções de linguagem que não são seguras, como o código JNI.
  • Ajudar os SDKs de anúncios a detectar e impedir tráfegos inválidos e fraude de anúncios mediante controle total sobre as visualizações remotas que mostram mídias.
  • Reduzir, o máximo possível, o impacto indevido aos desenvolvedores de apps e SDKs.

SDKs executados em um processo isolado

O SDK Runtime proposto permite que os SDKs compatíveis, chamados neste documento de SDKs ativados pelo ambiente de execução (RE, na sigla em inglês), operem em um processo separado do app. A plataforma facilita a comunicação bidirecional entre o processo do app e o SDK Runtime. Consulte a seção sobre comunicações deste documento para conferir mais informações. Os SDKs não RE permanecem no processo do app, como já ocorre atualmente. Os diagramas a seguir ilustram essas mudanças:

Diagrama mostrando tudo o que está executando o processo do app
Antes de ser adicionado ao SDK Runtime, o código que chama o SDK e os SDKs que recebem as chamadas desse código residem no processo do app

Diagrama mostrando a divisão de processos entre o processo do app e o processo do SDK Runtime
Depois de ser adicionado ao SDK Runtime, o código que chama o SDK, no processo em primeiro plano do app, se comunica com as interfaces do SDK. Em seguida, essas interfaces atravessam um limite de processo para chegar ao processo do SDK Runtime, a fim de chamar os próprios SDKs.

Novo modelo de distribuição confiável para SDKs

A separação entre o SDK e o app que está sendo proposta leva a outro conceito de separação: a separação entre o SDK e a distribuição do app. Nossa proposta exige um mecanismo confiável de distribuição e instalação para garantir que os SDKs corretos sejam instalados no SDK Runtime de um app. Isso ajuda a proteger os usuários e os desenvolvedores de apps contra o carregamento de SDKs inválidos e também permite que as app stores reduzam significativamente a carga de distribuição do SDK para os desenvolvedores de apps.

Os SDKs não vão precisar mais ser vinculados e agrupados estaticamente com os apps antes de serem enviados a uma app store para distribuição. Ao invés disso, ocorrerá o seguinte:

  1. Os desenvolvedores de SDKs poderão fazer upload das versões de SDKs para as app stores, separados dos respectivos apps.
  2. Os desenvolvedores de apps poderão especificar as dependências do SDK por versão, além de criar e fazer upload de uma versão do app que não inclua as dependências reais do SDK.
  3. Quando um usuário fizer o download desse app, o processo de instalação poderá usar as dependências do SDK especificadas do app e fazer o download delas na app store.

Esse novo mecanismo de distribuição vai permitir que os desenvolvedores de SDKs façam alterações não interruptivas nos SDKs, ou seja, sem nenhuma mudança nas APIs ou na semântica, bem como distribuir para dispositivos sem necessidade de envolvimento dos desenvolvedores de apps. Essas alterações não interruptivas do SDK poderão ser implantadas ou revertidas, sem que seja necessário esperar que os desenvolvedores de apps criem uma nova versão do app incluindo os novos SDKs ou que os usuários finais atualizem o app. As alterações interruptivas ainda precisarão ser atualizadas pelos desenvolvedores de apps, mas os desenvolvedores de SDKs poderão lançar as correções e alterações não interruptivas de maneira mais rápida e uniforme, para um número maior de pessoas e, preferencialmente, minimizando o suporte entre versões.

Os diagramas a seguir ilustram as mudanças propostas na distribuição do SDK:

Diagrama do processo antes da mudança.
Antes da introdução do SDK Runtime, os desenvolvedores enviavam os SDKs diretamente para os apps.

Diagrama do processo após a mudança.
Após a introdução do SDK Runtime, os desenvolvedores de SDKs usavam uma interface de upload do SDK para publicar os SDKs em uma app store. Assim, a app store vai processar a distribuição dos apps, junto de qualquer dependência dos SDKs, para os dispositivos dos usuários.

Mudanças na forma como os SDKs e os apps são criados, executados e distribuídos

Esta é uma proposta inicial de uma tecnologia flexível de distribuição e do SDK Runtime. Nas próximas seções, vamos propor uma série de mudanças nestas categorias amplas:

  • Acesso: permissões, memória, armazenamento.
  • Execução: idiomas, mudanças no ambiente de execução, ciclo de vida, renderização de mídia.
  • Comunicações: de app para SDK e SDK para SDK.
  • Desenvolvimento: como criar, depurar e testar nesse modelo.
  • Distribuição: como distribuir, atualizar e reverter diferentes versões do Android, apps e SDKs.

Este documento também inclui uma lista de perguntas frequentes para ajudar a responder às dúvidas mais comuns.

Esta é uma proposta de modelo inicial. Compreendemos que ela pode caracterizar uma mudança expressiva para alguns membros do ecossistema. Por isso, pedimos que você envie seu feedback pelo Issue Tracker.

Acesso

Gerenciar a privacidade de um sistema implica gerenciar a maneira como partes diferentes podem acessar recursos diferentes. Para cumprir nossa proposta de valor de privacidade, sugerimos atualizar o modelo de acesso a apps, SDKs e dados do usuário, a fim de seguir o princípio de privilégio mínimo e impedir o acesso não revelado a dados possivelmente sensíveis.

Permissões do SDK

Como um processo separado, o SDK Runtime terá um conjunto próprio e bem definido de permissões, em vez de herdar as concedidas ao app pelo usuário. Com base em uma pesquisa preliminar sobre as permissões usadas pelos SDKs relacionados a anúncios, propomos que as permissões abaixo possam ser acessadas pelos SDKs do SDK Runtime por padrão:

  • INTERNET: acesso à Internet para se comunicar com um serviço da Web.
  • ACCESS_NETWORK_STATE: acesso a informações sobre redes.
  • READ_BASIC_PHONE_STATE: acesso a informações sobre o estado do smartphone, por exemplo, o tipo de rede móvel.
  • Permissões para acessar as APIs de preservação de privacidade, que oferecem os principais recursos de publicidade sem precisar acessar identificadores entre apps.
  • AD_ID: capacidade de solicitar o ID de publicidade. Esse atributo também vai ser controlado pelo acesso do app a essa permissão.

No momento, estamos analisando se vamos incluir outras permissões e como fazer isso de modo a limitar o impacto para os usuários finais do ponto de vista da privacidade e usabilidade. Solicitamos que você envie feedback em relação a qualquer caso de uso que não seja atendido por esse conjunto de permissões.

Memória

O SDK Runtime terá um espaço de memória próprio e isolado, porque que ele tem um processo próprio. Por padrão, essa estrutura faria com que o acesso do SDK ao espaço de memória do app fosse negado. Da mesma forma, o aplicativo não poderia acessar o espaço de memória do SDK. Sugerimos manter esse comportamento padrão na proposta para que o princípio do privilégio mínimo seja seguido.

Armazenamento

Esta proposta tem como objetivo usar um armazenamento permanente para equilibrar a necessidade de que os SDKs acessem o armazenamento a fim de executar operações comuns e minimizar o rastreamento entre apps e em todo o processo. Propomos esta atualização no atual modo de acesso ao armazenamento:

  • Um app não poderá acessar diretamente o armazenamento dos SDKs e vice-versa.
  • O armazenamento externo do dispositivo não poderá ser acessado por SDKs.
  • Em cada SDK Runtime, haverá um armazenamento disponível para todos os SDKs e um armazenamento exclusivo para um SDK específico.

Assim como o modelo de armazenamento atual, o armazenamento em si não terá limites arbitrários de tamanho. Os SDKs podem usar o armazenamento para recursos de armazenamento em cache. Esse armazenamento será apagado periodicamente quando o SDK não estiver em execução.

Execução

Para garantir um sistema particular entre apps, SDKs e usuários, o próprio contexto de execução (formatos de código, construções de linguagem, APIs que podem ser acessadas e dados do sistema) precisa reforçar esses limites de privacidade ou, pelo menos, não oferecer oportunidades para os contornar. Ao mesmo tempo, queremos preservar o acesso a uma plataforma completa e à maioria dos recursos de ambiente de execução atualmente disponíveis para os SDKs. Neste documento, apresentamos a proposta de um conjunto de atualizações para o ambiente de execução, com o objetivo de alcançar esse equilíbrio.

Código

O código do Android, de apps e SDKs, é interpretado principalmente pelo Android Runtime (ART), seja ele escrito na linguagem de programação Kotlin ou Java. Os recursos do ART e as construções de linguagem que ele oferece, combinados à possibilidade de verificação oferecida quando comparado às alternativas (como o código nativo), parecem trazer um equilíbrio adequado entre funcionalidade e privacidade. Propomos que o código do SDK ativado pelo ambiente de execução seja apenas de bytecode Dex, em vez de oferecer suporte ao acesso JNI.

Estamos cientes de que existem casos de uso (como do SQLite personalizado) que, devido ao uso de código nativo, precisarão ser substituídos por uma alternativa, como a versão integrada do SDK do Android para SQLite.

SELinux

No Android, todos os processos, incluindo aqueles executados como raiz, são executados com um contexto específico do SELinux, o que permite que o kernel gerencie o controle de acesso a serviços, arquivos, dispositivos e outros processos do sistema. Para preservar a maioria dos casos de uso do SDK e minimizar o descumprimento das proteções de privacidade que estamos tentando propor, sugerimos as atualizações abaixo para o SDK Runtime no contexto do SELinux de um app que não é do sistema:

  • Um conjunto limitado de serviços do sistema vai poder ser acessado (em fase de desenvolvimento).
  • Os SDKs só vão poder carregar e executar o código no APK.
  • Um conjunto limitado de propriedades do sistema vai poder ser acessado (em fase de desenvolvimento).

APIs

É permitido usar APIs de reflexão e invocação no SDK Runtime. No entanto, um SDK não poderá usar as APIs de reflexão ou invocação em outro SDK ativado pelo ambiente de execução. Em uma atualização futura, vamos compartilhar uma proposta completa de APIs proibidas.

Além disso, as versões recentes da Plataforma Android têm restringido cada vez mais o acesso a identificadores persistentes, com o objetivo de melhorar a privacidade. No SDK Runtime, a proposta inclui limitações ainda maiores ao acesso a identificadores que podem ser usados para o rastreamento entre apps.

As APIs do SDK Runtime só podem ser acessadas por apps executados em primeiro plano. A tentativa de acessar APIs SdkSandboxManager de apps em segundo plano resulta na geração de uma SecurityException.

Por fim, os SDKs RE não podem usar as APIs de notificação para enviar notificações ao usuário em nenhum momento.

Ciclo de vida

Atualmente, os SDKs dos apps seguem o ciclo de vida do app host. Isso significa que, quando o app entra ou sai do primeiro plano, ele é desligado ou interrompido pelo sistema operacional devido à pressão da memória. O mesmo ocorre com os SDKs do app. Nossa proposta de mover os SDKs para um processo separado implica nas seguintes mudanças do ciclo de vida:

  • O processo do app pode ser encerrado pelo usuário ou pelo sistema operacional. Quando isso ocorrer, o SDK Runtime vai ser automaticamente encerrado em seguida.
  • O SDK Runtime pode ser encerrado pelo sistema operacional devido à pressão da memória ou, por exemplo, devido a uma exceção não processada em um SDK.

    No Android 14, quando um app está em primeiro plano, o SDK Runtime é executado em prioridade alta e é improvável que seja encerrado. Quando o app passa para o segundo plano, a prioridade do processo do SDK Runtime diminui, e ele fica qualificado para encerramento. Essa prioridade vai continuar baixa mesmo que o app volte para o primeiro plano. Por isso, é muito mais provável que o SDK seja encerrado sob pressão de memória em comparação com o app.

    No Android 14 e versões mais recentes, as prioridades de processo do app e do SDK Runtime estão alinhadas. As prioridades de processo de ActivityManager.RunningAppProcessInfo.importance para o app e o SDK Runtime são praticamente as mesmas.

    Caso o SDK Runtime seja encerrado enquanto o app estiver ativo, por exemplo, se houver uma exceção não processada no SDK, o estado do SDK Runtime, incluindo todos os SDKs e visualizações remotas já carregados, será perdido. O desenvolvedor do app pode lidar com o encerramento do SDK Runtime usando qualquer um destes métodos:

    • A proposta oferece métodos de callback do ciclo de vida relacionados aos desenvolvedores de apps para detectar quando o encerramento do SDK Runtime ocorreu.
    • Se o SDK Runtime for encerrado enquanto os anúncios estiverem sendo mostrados, talvez eles não funcionem como esperado. Por exemplo, as visualizações podem ficar congeladas na tela e não ser mais interativas. O app pode remover a visualização do anúncio se isso não afetar a experiência do usuário.
    • O app pode tentar carregar SDKs e solicitar anúncios novamente.
    • No Android 14, se o SDK Runtime for encerrado enquanto tiver SDKs carregados e se o desenvolvedor do app não tiver registrado os métodos de callback do ciclo de vida mencionados, o app vai ser encerrado por padrão. Somente os processos do app com os SDKs carregados são encerrados e saem normalmente.
    • Os objetos Binder retornados pelo SDK para se comunicar com ele (como SandboxedSdk) geram uma DeadObjectException se usados pelo app.

    Esse modelo do ciclo de vida está sujeito a mudanças em atualizações futuras.

    No caso de falhas persistentes, o desenvolvedor do app precisa planejar uma degradação suave sem o SDK ou notificar o usuário se o SDK for essencial para o recurso principal do app. Confira mais detalhes sobre essa interação do app para o SDK na seção de comunicações deste documento.

Os SDKs não RE podem continuar a usar os primitivos padrão do SO disponíveis para o app incorporado, incluindo serviços, atividades e transmissões. Já os SDKs RE não podem fazer o mesmo.

Casos especiais

Os casos abaixo não têm suporte e podem produzir um comportamento inesperado:

  • Se vários apps compartilham o mesmo UID, o SDK Runtime pode não funcionar corretamente. No futuro, será possível adicionar UIDs compartilhados.
  • Para apps com vários processos, o carregamento do SDK precisa ser feito no processo principal.

Renderização de mídia

Existem SDKs que renderizam conteúdos como texto, imagens e vídeos em uma visualização especificada pelo app. Para isso, sugerimos uma abordagem de renderização remota, em que o SDK renderiza a mídia no SDK Runtime, mas usa a API SurfaceControlViewHost para que a mídia seja renderizada em uma visualização especificada pelo app. Isso oferece ao SDK a capacidade de renderizar a mídia de maneira particular ao usuário, além de ajudar a impedir e detectar interações inválidas ou fraudulentas do usuário com a mídia renderizada.

Os SDKs no SDK Runtime vão oferecer suporte a anúncios nativos, que não são renderizados pelo SDK, mas sim pelo app. O processo de coleta de indicadores e busca de criativos vai acontecer de maneira consistente em anúncios não nativos. Essa área está em fase de análise.

Anúncios em vídeo in-stream são aqueles mostrados em um player de vídeo dentro do app. Como o vídeo é reproduzido em um player no app, e não um player ou uma visualização no SDK, o modelo de renderização é diferente de outros formatos de anúncio. Estamos analisando mecanismos para oferecer suporte à inserção de anúncios do lado do servidor e inserção de anúncios com base no SDK.

Integridade do sistema

Procuramos minimizar o impacto do estado de saúde do sistema que o SDK Runtime tem nos dispositivos do usuário final e estamos desenvolvendo maneiras de fazer isso. No entanto, é provável que alguns dispositivos Android 14 de nível básico com recursos de sistema muito limitados, como o Android (edição Go), não ofereçam suporte ao SDK Runtime devido ao impacto do estado de saúde do sistema. Em breve, compartilharemos os requisitos mínimos necessários para usar o SDK Runtime.

Comunicações

Como atualmente os apps e os SDKs são executados no mesmo processo, a comunicação entre eles não é inibida nem mediada. Além disso, o Android permite comunicações entre apps, mesmo que elas se iniciem e terminem com os SDKs. Esse modelo de comunicação de fluxo livre permite vários casos de uso, mas também introduz a possibilidade de compartilhamento de dados não revelado entre apps e entre SDKs dentro de um mesmo app e em apps diferentes. Esta proposta inclui as atualizações ao modelo de comunicações apresentadas abaixo. Procuramos encontrar um equilíbrio entre o valor dessas comunicações e o cumprimento dos nossos objetivos.

Do app para o SDK

A interface entre o app e o SDK é o caminho de comunicação mais comum para um SDK, e é na API do SDK que fica localizada a maior parte das diferenciações e inovações voltadas ao usuário. Buscamos preservar a capacidade dos SDKs de inovar e se diferenciarem nesse local. Por isso, nossa proposta permite que os SDKs exponham APIs aos apps e garante que eles tirem proveito de toda a inovação.

Devido à estrutura de limites do processo do SDK Runtime, sugerimos a criação de uma camada de marshaling, que pode ser acessada no app, para transportar as chamadas e respostas de API ou callbacks para além desse limite entre o app e o SDK. Propomos que a interface para essa camada de marshaling seja definida pelos desenvolvedores de SDKs e gerada por ferramentas de build de código aberto oficiais, que vão ser desenvolvidas por nossas equipes.

Com esta proposta, buscamos remover o trabalho de marshaling de código boilerplate dos desenvolvedores de apps e SDKs, oferecendo flexibilidade para os desenvolvedores de SDKs e garantindo que o código do SDK será executado no SDK Runtime de modo a cumprir nossas metas de privacidade. Se fizermos a implementação dessa forma, a linguagem e as ferramentas de definição de API vão precisar ser projetadas considerando o feedback dos desenvolvedores.

O modelo de interação geral será semelhante a este:

  • O app chama o SDK pela interface, transmitindo callbacks.
  • O SDK atende de forma assíncrona às solicitações e responde usando os callbacks.
  • Isso pode ser generalizado para qualquer modelo de editor/assinante, o que significa que um app pode se inscrever em eventos no SDK com callbacks e, quando esses eventos acontecerem, os callbacks serão acionados.

Uma das consequências da nova estrutura de processamento cruzado desta proposta é a necessidade de gerenciar dois ciclos de vida de processos: um para o próprio app e outro para o SDK Runtime. Nossa proposta procura automatizar esses processos o máximo possível, minimizando o impacto gerado para desenvolvedores de apps e SDKs. O diagrama a seguir mostra uma abordagem que estamos considerando:

Diagrama
Diagrama de sequência que mostra as interações do app para o SDK durante a inicialização do app e do SDK.

A plataforma vai expor novas APIs para que os apps carreguem SDKs dinamicamente no processo do SDK Runtime, recebam notificações sobre mudanças no estado do processo e interajam com os SDKs carregados no SDK Runtime.

O gráfico na figura anterior demonstra a comunicação do app para o SDK em um nível mais baixo, sem a camada de marshaling.

O app se comunica com o SDK em execução no processo do SDK Runtime seguindo estas etapas:

  1. Antes que o app possa interagir com um SDK, ele vai solicitar que a plataforma carregue o SDK. Para garantir a integridade do sistema, o app vai especificar os SDKs que pretende carregar no arquivo de manifesto, e esses SDKs serão os únicos permitidos.

    O snippet de código abaixo apresenta um exemplo ilustrativo da API:

    SdkSandboxManager.loadSdk(String sdkName, Bundle data, Executor executor,
        OutcomeReceiver<SandboxedSdk, LoadSdkException> receiver)
    
  2. O SDK é notificado de que foi carregado e retorna a interface dele. Essa interface é usada pelo processo do app. Para compartilhar a interface fora do limite do processo, ela precisa ser retornada como um objeto IBinder.

    O guia de serviços vinculados oferece maneiras diferentes de fornecer IBinder. Seja qual for a forma escolhida, ela precisa ser consistente entre o SDK e o app autor da chamada. O diagrama usa a AIDL como exemplo.

  3. O SdkSandboxManager recebe a interface IBinder e a retorna ao app.

  4. O app recebe o IBinder e o transmite para a interface do SDK, chamando as funções a seguir:

    IBinder binder = sandboxSdk.getInterface();
    ISdkInterface mySdkInterface = ISdkInterface.Stub.asInterface(binder);
    mySdkInterface.something();
    

O app também pode renderizar mídia do SDK seguindo estas etapas:

  1. Como explicado na seção sobre renderização de mídia deste documento, para que um app acesse um SDK de renderização de mídia em uma visualização, o app pode fazer uma chamada para requestSurfacePackage() e buscar o SurfaceControlViewHost.SurfacePackage correspondente.

    O snippet de código abaixo apresenta um exemplo ilustrativo da API:

    SdkSandboxManager.requestSurfacePackage(String sdkName, Bundle extraParams,
            Executor executor,
            OutcomeReceiver<Bundle, RequestSurfacePackageException> receiver)
    
  2. O app poderá incorporar o SurfacePackage retornado à SurfaceView usando a API setChildSurfacePackage na SurfaceView.

    O snippet de código abaixo apresenta um exemplo ilustrativo da API:

    SurfaceView.setChildSurfacePackage(SurfacePackage surfacePackage)
    

Nossa proposta é que as APIs IBinder e requestSurfacePackage() sejam genéricas e não sejam chamadas diretamente pelos apps. Em vez disso, essas APIs serão chamadas pela Referência da API gerada, que foi abordada acima, em uma camada "shim", para reduzir o fardo sobre os desenvolvedores de apps.

Do SDK para o SDK

Muitas vezes, dois SDKs no mesmo app precisam se comunicar. Isso pode acontecer quando um SDK específico é arquitetado para ser composto pelos SDKs constituintes e também quando dois SDKs de partes diferentes precisam colaborar para atender a uma solicitação do app de chamada.

Existem dois casos principais a serem considerados:

  • Quando os dois SDKs são ativados pelo ambiente de execução. Nesse caso, os dois SDKs são executados no SDK Runtime com todas as proteções. Eles não podem se comunicar no app da mesma forma que fazem atualmente. É por isso que uma API no SdkSandboxController foi adicionada para permitir a busca de objetos SandboxedSdk em todos os SDKs RE carregados. Dessa forma, um SDK RE consegue se comunicar com outros SDKs carregados no SDK Runtime.
  • Quando apenas um SDK é RE.
    • Se o SDK que fez a chamada estiver em execução no app, o processo será igual a quando o próprio app chama um segundo SDK no SDK Runtime.
    • Se o SDK de chamada está em execução no SDK Runtime, esta proposta recomenda expor um método usando o IBinder descrito na seção do app para o SDK, que vai ser detectado, processado e respondido pelo código do app com os callbacks fornecidos.
    • SDKs de anúncios que não são ativados pelo ambiente de execução podem não ser capazes de se registrar. Portanto, sugerimos a criação de um SDK mediador que inclua SDKs do app ou parceiro como dependências diretas e gerencie o registro. Esse SDK mediador estabelece a comunicação entre SDKs que não são ativados pelo ambiente de execução ou outras dependências do app e o mediador ativado pelo ambiente de execução que atua como adaptador.

O conjunto de atributos para a comunicação entre SDKs foi dividido nas seguintes categorias:

  • Comunicação entre SDKs no SDK Runtime (disponível na versão mais recente da prévia para desenvolvedores)
  • Comunicação de SDKs entre um app e o SDK Runtime (disponível na prévia para desenvolvedores mais recente)
  • Como as visualizações e a renderização remota funcionam para mediação (proposta em desenvolvimento)

Os seguintes casos de uso estão sendo considerados à medida que os primitivos são projetados:

  1. Mediação e lances. Muitos SDKs de publicidade oferecem um recurso de mediação ou de lances em que o SDK chama vários outros SDKs para receber impressões de anúncios (mediação) ou para coletar indicadores e realizar um leilão (lances). Normalmente, o SDK que realiza a coordenação chama outros SDKs usando um adaptador fornecido pelo próprio SDK. Considerando os primitivos acima, o SDK que realiza a coordenação, seja ele RE ou não, precisa conseguir acessar todos os SDKs para uma operação normal. A renderização nesse contexto está em análise constante.
  2. Descoberta de recursos. Alguns produtos do SDK consistem em SDKs menores que, por um processo de descoberta interna no SDK, determinam o conjunto de atributos final que vai ser exposto ao desenvolvedor do app. Os primitivos de registro e descoberta precisam permitir esse caso de uso.
  3. Modelos de editor e assinatura. Alguns SDKs são projetados para ter um editor central de eventos que outros SDKs ou apps podem assinar para receber notificações usando callbacks. Os primitivos acima precisam oferecer suporte a esse caso de uso.

Do app para o app

A comunicação entre apps acontece quando pelo menos um dos dois processos de comunicação é um SDK ativado pelo ambiente de execução e um possível vetor para o compartilhamento de dados não divulgados. Consequentemente, o SDK Runtime não consegue estabelecer um canal de comunicação direta com nenhum app diferente do aplicativo cliente ou com SDKs em outro SDK Runtime criado para outro app. Isso é possível das seguintes maneiras:

  • O SDK não pode definir componentes como <service>, <contentprovider> ou <activity> no manifesto.
  • O SDK não pode publicar um ContentProvider ou enviar uma transmissão.
  • O SDK pode iniciar uma atividade pertencente a outro app, mas com limites sobre o que pode ser enviado na intent. Por exemplo, nenhuma ação extra ou personalizada pode ser adicionada a essa intent.
  • O SDK só pode ser iniciado ou vinculado a uma lista de permissões de serviços.
  • O SDK só consegue acessar um subconjunto do sistema ContentProvider (como com.android.providers.settings.SettingsProvider), em que os dados recebidos não têm identificadores e não podem ser usados para criar uma impressão digital do usuário. Essas verificações também se aplicam ao acesso ao ContentProvider usando ContentResolver.
  • O SDK só pode acessar um subconjunto de broadcast receivers protegidos, como android.intent.action.AIRPLANE_MODE.

Tags de manifesto

Quando o SDK é instalado, o PackageManager analisa o manifesto do SDK e não consegue instalá-lo quando há tags de manifesto banidas. Por exemplo, o SDK pode não definir componentes como <service>, <activity>, <provider> ou <receiver> nem declarar uma <permission> no manifesto. As tags que causam a falha na instalação não são aceitas pelo SDK Runtime. As tags que não causam a falha na instalação, mas são ignoradas em silêncio, poderão receber suporte em versões futuras do Android.

Essas verificações também podem ser aplicadas por qualquer ferramenta de tempo de build que o SDK use para criar o pacote de SDKs e no momento do upload para a app store.

Suporte de atividade

Os SDKs no ambiente do SDK Runtime não podem adicionar uma tag de atividade ao arquivo de manifesto nem iniciar as próprias atividades usando Context.startActivity. Em vez disso, a plataforma cria as atividades para os SDKs quando recebe uma solicitação e as compartilha com os SDKs.

A atividade da plataforma é do tipo android.app.Activity. Ela começa em uma das atividades do app e faz parte da tarefa do app. FLAG_ACTIVITY_NEW_TASK não tem suporte.

Para que um SDK inicie uma atividade, ele precisa registrar uma instância do tipo SdkSandboxActivityHandler, que é usada para notificar sobre a criação de atividades quando o app chama SdkSandboxManager::startSdkSandboxActivity(Activity, IBinder) para iniciar a atividade.

O fluxo para solicitar uma atividade é mostrado no gráfico abaixo.

Diagrama
Diagrama de sequência que mostra o fluxo de início de uma atividade.

Desenvolvimento

Um princípio fundamental desta proposta é minimizar, na medida do possível, o impacto causado no ecossistema de desenvolvedores. Ela oferece aos desenvolvedores um conjunto abrangente de ferramentas de desenvolvimento para programar, criar e depurar apps e SDKs ativados pelo ambiente de execução. Para garantir a integridade da proposta, há algumas mudanças na forma como os apps e SDKs ativados pelo ambiente de execução são configurados e criados.

Criação

O Android Studio e as ferramentas relacionadas vão ser atualizados para reconhecer o SDK Runtime, ajudando a garantir que os desenvolvedores tenham configurado corretamente os apps e SDKs ativados pelo ambiente de execução, além de garantir que as chamadas legadas ou sem suporte sejam atualizadas para alternativas mais recentes, quando necessário. De acordo com nossa proposta, algumas etapas precisarão ser cumpridas pelos desenvolvedores durante a fase de criação.

Desenvolvedores de apps

Os apps vão precisar especificar os certificados de dependências do SDK e do SDK RE no manifesto do app. Nesta proposta, tratamos essa etapa como a fonte de verdade do desenvolvedor do aplicativo. Exemplo:

  • Nome: nome do pacote do SDK ou da biblioteca.
  • Versão principal: código da versão principal do SDK.
  • Síntese do certificado: uma síntese do certificado do build do SDK. Para builds específicos, sugerimos que o desenvolvedor de SDKs receba e registre o valor pela app store correspondente.

Isso se aplica somente a SDKs distribuídos por app stores, sejam eles ativados pelo ambiente de execução ou não. Os apps que vinculam os SDKs de forma estática podem usar os mecanismos de dependência atuais.

Considerando que nosso objetivo é gerar o mínimo de impacto possível para os desenvolvedores, é importante que, em casos em que um nível desejado da API com suporte ao SDK Runtime for especificado, os desenvolvedores de apps só precisem ter um único build, independente de ele ser executado em um dispositivo com suporte ao SDK Runtime ou não.

Desenvolvedores de SDKs

No modelo proposto, os desenvolvedores de SDKs RE precisam declarar explicitamente um novo elemento que represente a entidade do SDK ou da biblioteca no manifesto. Além disso, é necessário informar um conjunto de valores semelhante ao da dependência e uma versão secundária:

  • Nome: nome do pacote do SDK ou da biblioteca.
  • Versão principal: código da versão principal do SDK.
  • Versão secundária: código da versão secundária do SDK.

Caso os desenvolvedores de SDKs RE tenham outros SDKs do mesmo tipo como dependências no momento do build, vai ser necessário as declarar da mesma maneira que desenvolvedores de apps declarariam essas mesmas dependências. Os SDKs RE que dependem de SDKs não RE precisaram ser vinculados a eles de forma estática. Isso pode introduzir problemas que vão ser detectados durante o build ou durante a fase de testes se os SDKs não RE exigirem funcionalidades a que o SDK Runtime não oferece suporte ou se precisarem ser executados no processo do app.

É provável que os desenvolvedores de SDKs RE queiram continuar a oferecer suporte a dispositivos não compatíveis com RE, como o Android 12 ou versões anteriores e dispositivos básicos que usam o Android 14 e têm recursos de sistema muito limitados, conforme mencionado na seção Integridade do sistema deste documento. Estamos trabalhando em abordagens para garantir que os desenvolvedores de SDKs possam manter uma única base de código que ofereça suporte a ambientes RE e não RE.

Builds

Desenvolvedores de apps

Os desenvolvedores de apps vão observar poucas mudanças na etapa de criação. As dependências do SDK, seja ele distribuído localmente ou pela app store (ativado pelo ambiente de execução ou não), precisarão existir na máquina para inspeção, compilação e criação. Nossa proposta é que o Android Studio extraia esses detalhes do desenvolvedor do app com o uso normal e torne esse processo o mais transparente possível.

Embora seja esperado que um build de depuração inclua todo o código e os símbolos para fazer parte do build de depuração e ter capacidade de depuração, nos builds de lançamento, todos os SDKs distribuídos pela app store (RE ou não) poderão ser removidos do artefato final.

Estamos no início da fase de desenvolvimento e vamos compartilhar mais informações à medida que avançarmos.

Desenvolvedores de SDKs

Estamos trabalhando em um caminho para garantir que as versões não RE e RE de um SDK possam ser incorporadas a um único artefato para distribuição. Isso evitaria que os desenvolvedores de apps precisassem oferecer suporte a builds diferentes para versões RE e não RE de um SDK.

Assim como para os apps, todos os SDKs de dependência distribuídos por app stores precisam existir na máquina para inspeção, compilação e criação. Acreditamos que o Android Studio vai facilitar esse processo.

Testes

Desenvolvedores de apps

Conforme descrito em nossa proposta, os desenvolvedores de apps vão poder testar os aplicativos em dispositivos com o Android 14, como fariam normalmente. Após a criação, o app vai poder ser instalado em um dispositivo ou emulador RE. Esse processo de instalação garante que os SDKs corretos sejam instalados no SDK Runtime do dispositivo ou emulador, independente de os SDKs terem sido extraídos de um repositório remoto ou do cache do sistema de build.

Desenvolvedores de SDKs

Os desenvolvedores de SDKs geralmente usam apps de teste internos em dispositivos e emuladores para testar o desenvolvimento. Nossa proposta não muda esse processo. A validação no app vai seguir as mesmas etapas para desenvolvedores de apps definidas acima, com um único artefato de build para apps RE e não RE. Os desenvolvedores de SDKs vão poder percorrer o código, seja no SDK Runtime ou não. No entanto, pode haver algumas limitações no uso de ferramentas avançadas de depuração e criação de perfis. Essa área está em fase de análise.

Distribuição

Nossa proposta de modelo para a separação de um app dos SDKs gerou a possibilidade de distribuição de SDKs por app stores. Essa é uma possibilidade geral que não exclui nenhuma app store específica. Os benefícios são claros:

  • Garantir a qualidade e a consistência dos SDKs.
  • Simplificar a publicação para desenvolvedores SDK.
  • Facilitar o lançamento de atualizações de versões secundárias do SDK para apps instalados.

Para oferecer suporte à distribuição do SDK, uma app store provavelmente vai precisar fornecer a maioria dos recursos abaixo:

  • Um mecanismo para os desenvolvedores de SDK fazerem upload dos SDKs distribuíveis de app stores na loja, atualizar, reverter e, possivelmente, remover esses SDKs.
  • Um mecanismo para garantir a integridade de um SDK, um app e das procedências deles, além de resolver as dependências.
  • Um mecanismo para os implantar em dispositivos de maneira consistente e confiável e com alto desempenho.

Mudança nas restrições ao longo do tempo

Esperamos que as restrições enfrentadas pelo código no SDK Runtime mudem com as próximas versões do Android. Para garantir a compatibilidade do aplicativo, não vamos mudar essas restrições com atualizações do módulo principal para determinado nível do SDK. O comportamento associado a uma determinada targetSdkVersion é preservado até que o suporte a essa targetSdkVersion seja descontinuado pela política da app store. A descontinuação da targetSdkVersion pode acontecer em uma velocidade mais rápida do que para apps. Espera-se que as restrições mudem com frequência nas versões do SDK do Android, principalmente nas primeiras versões.

Além disso, estamos criando um mecanismo canário para permitir que testadores externos e internos participem de um grupo que receberá o conjunto de restrições proposto para a próxima versão do Android. Isso nos ajudará a receber feedback e confiar nas mudanças propostas para o conjunto de restrições.

Perguntas frequentes

  1. O que é um SDK relacionado à publicidade?

    Um SDK relacionado a anúncios é aquele que facilita qualquer parte da segmentação de usuários com mensagens para fins comerciais em apps que não pertencem ao anunciante. Isso inclui, entre outros, SDKs de análise em que os grupos de usuários podem ser criados para mais segmentação, SDKs para veiculação de anúncios, SDKs contra abusos e fraudes para anúncios, SDKs de engajamento e SDKs de atribuição.

  2. Qualquer SDK pode ser executado no SDK Runtime?

    Embora o foco inicial seja para SDKs relacionados a anúncios, os desenvolvedores de SDKs não relacionados a anúncios que buscam uma postura que valoriza a privacidade e acreditam que podem operar sob as condições descritas acima podem enviar feedback sobre os SDKs executados no SDK Runtime. Entretanto, o SDK Runtime não foi projetado para ser compatível com todos os tipos de SDKs. Além das limitações documentadas, o SDK Runtime provavelmente não é adequado para SDKs que precisam de comunicação com o app de hospedagem em tempo real ou com alta capacidade de processamento.

  3. Por que escolher o isolamento de processos em vez do isolamento em um ambiente de execução baseado em Java?

    Atualmente, o ambiente de execução baseado em Java não facilita prontamente os limites de segurança necessários para as garantias de privacidade desejadas para os usuários do Android. Tentar implementar algo nesses moldes provavelmente vai exigir um esforço de vários anos, sem garantia de sucesso. Portanto, o Sandbox de privacidade utiliza limites de processo de uso, uma tecnologia testada com sucesso e bem compreendida.

  4. Mover SDKs para o processo do SDK Runtime pode diminuir o tamanho de download ou economizar espaço de armazenamento?

    Se vários apps estiverem integrados a SDKs ativados pelo ambiente de execução da mesma versão, isso poderá reduzir o tamanho do download e economizar o espaço em disco.

  5. A que tipo de evento de ciclo de vida do app, como quando ele vai para o segundo plano, os SDKs terão acesso no SDK Runtime?

    Estamos trabalhando ativamente no suporte de design para notificar o SDK Runtime sobre eventos do ciclo de vida no nível do aplicativo cliente. Por exemplo, quando o app vai para o segundo ou primeiro plano. O design e o exemplo de código serão compartilhados em uma prévia para desenvolvedores futura.