Mudanças de comportamento: todos os apps

A plataforma Android Q inclui mudanças de comportamento que podem afetar seu app. As seguintes mudanças de comportamento se aplicam a todos os apps quando são executados no Android Q, qualquer que seja a "targetSdkVersion". Teste seu app e modifique-o conforme necessário para ficar compatível com essas mudanças, quando aplicável.

Consulte também a lista de mudanças de comportamento que afetam apenas os apps voltados ao Android Q.

Restrições da interface não SDK

Para garantir a estabilidade e a compatibilidade do app, a plataforma começou a restringir quais interfaces não SDK seu app pode usar no Android 9 (API de nível 28). O Android Q inclui listas atualizadas de interfaces não SDK restritas, baseadas na colaboração com desenvolvedores do Android e nos testes internos mais recentes. Nosso objetivo é garantir que alternativas públicas estejam disponíveis antes de restringirmos as interfaces não SDK.

Se você não pretende desenvolver apps para o Android Q, algumas dessas mudanças podem não afetá-lo imediatamente. No entanto, embora atualmente seja possível usar as interfaces não SDK que fazem parte da lista cinza (dependendo do nível de API de destino do app), o uso de qualquer método ou campo não SDK sempre apresenta um alto risco de corromper o app.

Se você não souber se seu app usa interfaces não SDK, poderá testá-lo para descobrir. Se ele depende de interfaces não SDK, é necessário começar a planejar uma migração para alternativas SDK. No entanto, entendemos que alguns apps têm casos de uso válidos para interfaces não SDK. Caso você não encontre uma alternativa para deixar de usar uma interface não SDK em um recurso no seu app, solicite uma nova API public.

Para saber mais, consulte as páginas Atualizações para restrições de interface não SDK no Android Q e Restrições para interfaces que não são SDK.

NDK

O Android Q inclui as alterações do NDK descritas a seguir.

Objetos compartilhados não podem conter realocações de texto

O Android 6.0 (API de nível 23) não permitia o uso de realocações de texto em objetos compartilhados. O código precisa ser carregado como está e não pode ser modificado. Essa alteração melhora o tempo de carregamento e a segurança dos apps.

No Android Q Beta 1 e 2, o SELinux impõe essa restrição a apps destinados ao Android 8.0 (API de nível 26) ou versões posteriores. Esses apps correm alto risco de serem corrompidos caso continuem utilizando objetos compartilhados que contenham realocações de texto.

Binários/bibliotecas do sistema mapeados para memória somente de execução

A partir do Android Q, os segmentos executáveis de binários e bibliotecas do sistema são mapeados para memória somente de execução (não legível), como uma técnica para aumentar a proteção contra ataques de reutilização de código. Leituras intencionais e não intencionais em segmentos de memória marcados como somente de execução acionarão um SIGSEGV, seja por bug, vulnerabilidade ou introspecção intencional da memória.

É possível identificar se uma falha foi causada por essa mudança examinando o arquivo tombstone correspondente em /data/tombstones/. Uma falha relacionada à memória somente de execução incluirá a seguinte mensagem de cancelamento:

    Cause: execute-only (no-read) memory access error; likely due to data in .text.
    

Para evitar esse problema, os desenvolvedores podem marcar segmentos somente de execução como leitura+execução chamando, por exemplo, mprotect() para executar a inspeção de memória. No entanto, é altamente recomendável configurá-lo novamente como somente de execução em seguida, porque isso proporciona uma melhor proteção para seu app e seus usuários.

As chamadas para ptrace não são afetadas. Por esse motivo, a depuração de ptrace não é afetada.

Segurança

O Android Q inclui a mudança de segurança descrita a seguir.

Permissão de execução removida para o diretório inicial do app

Apps não confiáveis destinados ao Android Q não podem mais chamar exec() em arquivos no diretório inicial do app. Essa execução de arquivos do diretório inicial do app gravável é uma violação W^X. Os apps precisam carregar somente o código binário incorporado ao arquivo APK do app.

Além disso, os apps destinados ao Android Q não podem modificar o código executável na memória a partir de arquivos que foram modificados por dlopen(). Isso inclui todos os arquivos de objeto compartilhado (.so) com realocações de texto.

Transmissões do Wi-Fi Direct

No Android Q, as seguintes transmissões relacionadas ao Wi-Fi Direct deixaram de ser fixas:

Se seu app dependia do recebimento dessas transmissões no momento de registro porque elas eram fixas, use o método get() apropriado na inicialização para conseguir as informações.

Capacidades do Wi-Fi Aware

O Android Q adiciona compatibilidade para facilitar a criação de sockets TCP/UDP usando os caminhos de dados do Wi-Fi Aware. Para criar um socket TCP/UDP conectando-o a um ServerSocket, o dispositivo cliente precisa conhecer o endereço IPv6 e a porta do servidor. Antes da atualização, isso precisava ser comunicado fora da banda, por exemplo, com uma mensagem de camada dupla por BT ou Wi-Fi Aware, ou descoberto dentro da banda com outros protocolos, como mDNS. Com o Android Q, as informações podem ser comunicadas como parte da configuração da rede.

O servidor pode fazer uma destas ações:

  • Inicializar um ServerSocket e configurar ou adquirir a porta a ser usada.
  • Especificar as informações da porta como parte da solicitação de rede Wi-Fi Aware.

O exemplo de código a seguir mostra como especificar informações de porta como parte da solicitação de rede:

Kotlin

    val ss = ServerSocket()
    val ns = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle)
      .setPskPassphrase("some-password")
      .setPort(ss.localPort)
      .build()

    val myNetworkRequest = NetworkRequest.Builder()
      .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
      .setNetworkSpecifier(ns)
      .build()
    

Java

    ServerSocket ss = new ServerSocket();
    WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier
      .Builder(discoverySession, peerHandle)
      .setPskPassphrase(“some-password”)
      .setPort(ss.getLocalPort())
      .build();

    NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
      .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
      .setNetworkSpecifier(ns)
      .build();
    

Em seguida, o cliente realiza uma solicitação de rede Wi-Fi Aware para conseguir o IPv6 e a porta fornecida pelo servidor:

Kotlin


    val callback = object : ConnectivityManager.NetworkCallback() {
      override fun onAvailable(network: Network) {
        ...
      }

      override fun onLinkPropertiesChanged(network: Network,
          linkProperties: LinkProperties) {
        ...
      }

      override fun onCapabilitiesChanged(network: Network,
          networkCapabilities: NetworkCapabilities) {
        ...
        val ti = networkCapabilities.transportInfo
        if (ti is WifiAwareNetworkInfo) {
           val peerAddress = ti.peerIpv6Addr
           val peerPort = ti.port
        }
      }
      override fun onLost(network: Network) {
        ...
      }
    };

    connMgr.requestNetwork(networkRequest, callback)
    

Java

    callback = new ConnectivityManager.NetworkCallback() {
      @Override
      public void onAvailable(Network network) {
        ...
      }
      @Override
      public void onLinkPropertiesChanged(Network network,
          LinkProperties linkProperties) {
        ...
      }
      @Override
      Public void onCapabilitiesChanged(Network network,
          NetworkCapabilities networkCapabilities) {
        ...
        TransportInfo ti = networkCapabilities.getTransportInfo();
        if (ti instanceof WifiAwareNetworkInfo) {
           WifiAwareNetworkInfo info = (WifiAwareNetworkInfo) ti;
           Inet6Address peerAddress = info.getPeerIpv6Addr();
           int peerPort = info.getPort();
        }
      }
      @Override
      public void onLost(Network network) {
        ...
      }
    };

    connMgr.requestNetwork(networkRequest, callback);
    

SYSTEM_ALERT_WINDOW em dispositivos Android Go

Apps executados em dispositivos Android Q (versão Go) não podem ter a permissão SYSTEM_ALERT_WINDOW. Isso acontece porque o desenho de janelas de sobreposição usa memória demais e prejudica o desempenho de dispositivos Android com pouca memória.

Se um app executado em um dispositivo versão Go com o Android 9 ou anterior receber a permissão SYSTEM_ALERT_WINDOW, o app manterá a permissão mesmo se o dispositivo for atualizado para o Android Q. No entanto, os apps que ainda não têm essa permissão não poderão recebê-la depois da atualização do dispositivo.

Se um app em um dispositivo Go enviar um intent com a ação ACTION_MANAGE_OVERLAY_PERMISSION, o sistema negará a solicitação automaticamente e levará o usuário a uma tela de Configurações que informa que a ação não foi permitida porque torna o dispositivo lento. Se um app em um dispositivo Go chamar Settings.canDrawOverlays(), o método sempre retornará "false". Novamente, essas restrições não se aplicam a apps que receberam a permissão SYSTEM_ALERT_WINDOW antes da atualização do dispositivo para a versão Q.

Avisos para apps voltados a versões anteriores do Android

No Android Q, a plataforma avisará os usuários na primeira vez em que eles executarem qualquer app que seja destinado a uma versão de plataforma anterior ao Android 6.0 (API de nível 23). Se o app exigir que o usuário conceda permissões, o usuário também poderá ajustar as permissões do app antes que ele seja executado pela primeira vez.

Devido aos requisitos de API de destino do Google Play, um usuário só verá esses avisos se executar um app que não tenha sido atualizado recentemente. Para apps distribuídos por outras lojas, estão sendo lançados requisitos de API semelhantes em 2019. Para saber mais sobre esses requisitos, consulte Expanding target API level requirements in 2019 (em inglês).

Conjuntos de criptografia CBC SHA-2 removidos

Os seguintes conjuntos de criptografia CBC SHA-2 foram removidos da plataforma:

  • TLS_RSA_WITH_AES_128_CBC_SHA256
  • TLS_RSA_WITH_AES_256_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

Esses conjuntos de criptografia são menos seguros do que conjuntos de criptografia semelhantes que usam o GCM. A maior parte dos servidores ou é compatível com as variantes GCM e CBC desses conjuntos ou não é compatível com nenhum deles.

Uso de apps

O Android Q traz as seguintes mudanças de comportamento relacionadas ao uso de apps:

  • Melhorias no uso do app UsageStats: o Android Q agora monitora com precisão o uso de apps no modo de tela dividida ou picture-in-picture com o UsageStats. Além disso, o Android Q agora pode monitorar o uso de apps instantâneos.

  • Escala de cinza por app: o Android Q agora pode configurar apps para um modo de exibição em escala de cinza.

  • Estado de distração por app: o Android Q agora pode configurar apps seletivamente para um "estado de distração", que fará com que as notificações deles sejam suprimidas e que os apps não apareçam como sugeridos.

  • Suspensão e reprodução: no Android Q, os apps suspensos não podem mais reproduzir áudio.

A biblioteca android.preference está obsoleta

A biblioteca android.preference passou a ser obsoleta. Em vez dela, os desenvolvedores precisam usar a biblioteca de preferências do AndroidX, parte do Android Jetpack. Para descobrir recursos suplementares que podem ajudar na migração e no desenvolvimento, consulte o Guia de configurações atualizado, bem como nosso app de amostra público (link em inglês) e a documentação de referência.

Mudanças da câmera

Muitos apps que usam câmeras presumem que, se o dispositivo estiver em uma configuração de retrato, o dispositivo físico também estará na orientação de retrato, conforme descrito em Orientação da câmera. No passado, essa era uma suposição segura, mas isso mudou com a introdução; de novos formatos, como aparelhos dobráveis. Nesses dispositivos, essa suposição pode levar a uma exibição rotacionada ou dimensionada incorretamente (ou ambas) no visor da câmera.

Os apps para a API de nível 24 ou posterior precisam definir explicitamente a android:resizeableActivity e fornecer a funcionalidade necessária para operações em várias janelas.

Acompanhamento de uso da bateria

A partir do Android Q, o SystemHealthManager redefine as estatísticas de uso da bateria sempre que o dispositivo é desconectado depois de um grande evento de carga. Em termos gerais, um grande evento de carga ocorre quando o dispositivo foi completamente carregado ou quando a carga do dispositivo passou de quase vazia para quase cheia.

Antes do Android Q, as estatísticas de uso da bateria eram redefinidas sempre que o dispositivo era desconectado, independentemente de quão pequena tivesse sido a mudança no nível de bateria.