Cambios de comportamiento: todas las apps

Android 10 incluye cambios en el comportamiento que podrían afectar a tu app. Los cambios que se enumeran en este documento se aplican a tu app cuando se ejecuta en Android 10, independientemente de su targetSdkVersion. Deberías probar tu app y modificarla según sea necesario a fin de que admita estos cambios de manera correcta.

Si la targetSdkVersion de tu app es 29 o una versión posterior, también deberás admitir cambios adicionales. Asegúrate de leer los cambios en el comportamiento para apps que se orientan al nivel de API 29 a fin de obtener detalles.

Nota: Además de estos cambios en el comportamiento, asegúrate de revisar y admitir las funciones de privacidad de Android 10 que se muestran en este documento.

Restricciones en interfaces no SDK

Para asegurar la estabilidad y compatibilidad de las apps, la plataforma comenzó a restringir las interfaces no SDK que tu app puede usar en Android 9 (API nivel 28). Android 10 incluye listas actualizadas de este tipo de interfaces que están basadas en la colaboración con desarrolladores de Android y las pruebas internas más recientes. Nuestro objetivo es asegurarnos de que las alternativas públicas estén disponibles antes de restringir las interfaces que no pertenecen al SDK.

Si no orientarás tu app a Android 10 (nivel de API 29), es posible que algunos de estos cambios no te afecten de inmediato. No obstante, si bien actualmente puedes usar algunas interfaces que no pertenecen al SDK que se incluyen en la lista gris (según el nivel de API objetivo de tu app), el uso de cualquier método o campo que no pertenece al SDK siempre implica un gran riesgo de error para tu app.

Si no sabes con seguridad si tu app usa este tipo de interfaces, puedes probarla para verificar. Si tu app depende de interfaces no SDK, deberías planificar una migración hacia otras alternativas SDK, aunque sabemos que algunas apps tienen casos prácticos válidos para usarlas. Si no puedes encontrar una alternativa al uso de una interfaz ajena al SDK para una función de tu app, deberías solicitar una nueva API pública.

Para obtener más información, consulta las actualizaciones de restricciones sobre interfaces que no pertenecen al SDK para Android 10 y las restricciones sobre interfaces que no pertenecen al SDK.

Navegación por gestos

A partir de Android 10, los usuarios pueden habilitar la navegación por gestos en todo el dispositivo. Si un usuario habilita la navegación por gestos, esta acción afecta a todas las app en el dispositivo, independientemente de si se orientan al nivel de API 29 o no. Por ejemplo, si el usuario desliza el dedo hacia adentro desde el borde de la pantalla, el sistema interpreta ese gesto como una navegación "Atrás", a menos que una app anule específicamente ese gesto para determinadas secciones de la pantalla.

Para que tu app sea compatible con la navegación por gestos, te recomendamos extender el contenido de la app de borde a borde y administrar los gestos conflictivos de manera apropiada. Para obtener más detalles, consulta la documentación sobre la Navegación por gestos.

NDK

En Android 10, se incluyen los siguientes cambios en el NDK.

Los objetos compartidos no pueden contener reubicaciones de texto

En Android 6.0 (nivel de API 23) se prohibió el uso de reubicaciones de texto en objetos compartidos. El código se debe cargar sin modificaciones. Este cambio mejora la seguridad y los tiempos de carga de la app.

SELinux aplica esta restricción en las apps que se orientan a Android 10 o versiones posteriores. Si estas apps continúan usando objetos compartidos que contienen reubicaciones de texto, corren un alto riesgo de fallar.

Cambios en las bibliotecas Bionic y las rutas de vinculador dinámico

A partir de Android 10, varias rutas de acceso son vínculos simbólicos, en lugar de archivos normales. Las apps que han dependido de que las rutas fueran archivos normales podrían fallar:

  • /system/lib/libc.so -> /apex/com.android.runtime/lib/bionic/libc.so
  • /system/lib/libm.so -> /apex/com.android.runtime/lib/bionic/libm.so
  • /system/lib/libdl.so -> /apex/com.android.runtime/lib/bionic/libdl.so
  • /system/bin/linker -> /apex/com.android.runtime/bin/linker

Estos cambios se aplican también a las variantes de 64 bits del archivo, con lib/ reemplazada por lib64/.

Para la compatibilidad, los symlinks se proporcionan en las rutas de acceso anteriores. Por ejemplo, /system/lib/libc.so es un symlink a /apex/com.android.runtime/lib/bionic/libc.so. Por lo tanto, dlopen(“/system/lib/libc.so”) sigue funcionando, pero las apps encontrarán la diferencia cuando intenten examinar las bibliotecas cargadas mediante la lectura de /proc/self/maps o similar, lo cual no es común, pero hemos notado que algunas apps funcionan de esa manera como parte de su proceso antipiratería. Si es así, las rutas de acceso /apex/… deben agregarse como rutas de acceso válidas para los archivos Bionic.

Bibliotecas y objetos binarios del sistema asignados a memoria de solo ejecución

A partir de Android 10, los segmentos ejecutables de bibliotecas y objetos binarios del sistema se asignan a la memoria de solo ejecución (no de lectura) como técnica de endurecimiento contra los ataques de reutilización de código. Si tu app realiza operaciones de lectura en los segmentos de memoria marcados como de solo ejecución, ya sea por un error, una vulnerabilidad o una inspección intencional de la memoria, el sistema envía una señal SIGSEGV a tu app.

Para identificar si una falla fue producto de este cambio, examina el archivo de exclusión relacionado en /data/tombstones/. Una falla de solo ejecución contiene el siguiente mensaje de anulación:

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

Si quieres solucionar este problema para realizar operaciones como la inspección de memoria, puedes marcar los segmentos de solo ejecución como de lectura y ejecución mediante una llamada a mprotect(). Sin embargo, te recomendamos revertir la configuración a "solo ejecución" una vez que termines, ya que de esta manera se brindará más protección a tu app y los usuarios.

Seguridad

Android 10 incluye los siguientes cambios de seguridad.

TLS 1.3 habilitado de forma predeterminada

En Android 10 y versiones posteriores, TLS 1.3 está habilitado de forma predeterminada para todas las conexiones de TLS. A continuación, se muestran algunos detalles importantes sobre nuestra implementación de TLS 1.3:

  • Los conjuntos de cifrado de TLS 1.3 no se pueden personalizar. Aquellos que son compatibles siempre están habilitados cuando TLS 1.3 está habilitado. Se ignorará cualquier intento de inhabilitarlos mediante una llamada a setEnabledCipherSuites().
  • Cuando se negocia TLS 1.3, se llama a los objetos HandshakeCompletedListener antes de que se agreguen a la caché de sesiones. (En TLS 1.2 y otras versiones anteriores, se llama a estos objetos luego de que se agregan las sesiones a la caché de sesiones).
  • En algunas situaciones en las que las instancias de SSLEngine muestran una SSLHandshakeException en versiones anteriores de Android, estas instancias muestran una SSLProtocolException en Android 10 y versiones posteriores.
  • No se admite el modo 0-RTT.

Para obtener un SSLContext que tenga TLS 1.3 inhabilitado, llama a SSLContext.getInstance("TLSv1.2"). También puedes habilitar o inhabilitar versiones de protocolo por conexión si llamas a setEnabledProtocols() en un objeto correspondiente.

Los certificados firmados con SHA-1 no son confiables en TLS

En Android 10, los certificados que usan el algoritmo de hash SHA-1 no se consideran confiables en las conexiones de TLS. La CA raíz no emite ese certificado desde 2016, y ya no se consideran confiables en Chrome ni en otros navegadores importantes.

Fallará cualquier intento de establecer conexión con un sitio que presente un certificado que usa SHA-1.

Mejoras y cambios en el comportamiento de KeyChain

Algunos navegadores, como Google Chrome, les permiten a los usuarios elegir un certificado cuando un servidor TLS envía un mensaje de solicitud de certificado como parte de un protocolo de enlace de TLS. A partir de Android 10, los objetos KeyChain respetan los parámetros de especificación de claves y emisores cuando llaman a KeyChain.choosePrivateKeyAlias() a fin de mostrar a los usuarios una solicitud de selección de certificado. En particular, esta solicitud no contiene opciones que no cumplen con las especificaciones del servidor.

Si no hay ningún certificado disponible para que el usuario seleccione, como sucede cuando no hay ninguno que cumpla con las especificaciones del servidor o un dispositivo no tiene certificados instalados, no se mostrará la solicitud de selección de certificado.

Además, en Android 10 o versiones posteriores, no es necesario tener un bloqueo de pantalla del dispositivo para importar claves o certificados de CA al objeto KeyChain.

Otros cambios en la criptografía y en TLS

Se realizaron pequeños cambios en las bibliotecas de criptografía y TLS que se aplicarán en Android 10:

  • Los cifrados "AES/GCM/NoPadding" y "ChaCha20/Poly1305/NoPadding" muestran tamaños de búfer más precisos desde getOutputSize().
  • El conjunto de cifrado TLS_FALLBACK_SCSV se omite de los intentos de conexión con un protocolo máximo de TLS 1.2 o posterior. Como se incorporaron mejoras en las implementaciones del servidor TLS, no recomendamos revertir a la configuración de TLS externo. En su lugar, recomendamos basarse en la negociación de versiones de TLS.
  • ChaCha20-Poly1305 es un alias para ChaCha20/Poly1305/NoPadding.
  • Los nombres de hosts con puntos finales no se consideran nombres de hosts de SNI válidos.
  • Se respeta la extensión supported_signature_algorithms admitida en CertificateRequest cuando se elige una clave de firma para respuestas de certificados.
  • Las claves de firma opacas, como las del almacén de claves de Android, se pueden usar con firmas RSA-PSS en TLS.

Transmisiones por Wi-Fi directo

En Android 10, las siguientes emisiones relacionadas con Wi-Fi directo no son persistentes:

Si tu app dependía de la recepción de estas transmisiones en el registro debido a que eran fijas, en su lugar, usa el método get() apropiado en la inicialización para obtener la información.

Capacidades de reconocimiento de Wi-Fi

En Android 10, se agregó compatibilidad para facilitar la creación de un Socket TCP/UDP mediante rutas de acceso a datos de reconocimiento de Wi-Fi. Para crear un socket TCP/UDP que se conecte a ServerSocket, el dispositivo del cliente debe conocer la dirección IPv6 y el puerto del servidor. Anteriormente, este debía comunicarse por fuera de la banda (por ejemplo, por medio de mensajería de nivel 2 a través de Bluetooth o reconocimiento de Wi-Fi) o detectarse dentro de la banda mediante otros protocolos (por ejemplo, mDNS). Con Android 10, la información se puede transmitir como parte de la configuración de red.

El servidor puede realizar cualquiera de las siguientes acciones:

  • Inicializar un ServerSocket y obtener o configurar el puerto que se usará
  • Especificar la información del puerto como parte de la solicitud de red de reconocimiento de Wi-Fi

En la siguiente muestra de código, se indica cómo especificar la información del puerto como parte de la solicitud de red:

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();
    

Luego, el cliente realiza una solicitud de red de reconocimiento de Wi-Fi para obtener la dirección IPV6 y el puerto que proporciona el 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 en dispositivos Go

Las apps que se ejecutan en dispositivos con Android 10 (edición Go) no pueden obtener el permiso SYSTEM_ALERT_WINDOW. Esto se debe a que el procesamiento de ventanas superpuestas usa demasiada memoria, lo que es particularmente dañino para el rendimiento de los dispositivos Android con poca memoria.

Si una app que se ejecuta en un dispositivo Go con Android 9 o versiones anteriores recibe el permiso SYSTEM_ALERT_WINDOW, la app retiene este permiso incluso si el dispositivo se actualiza a Android 10. Sin embargo, las apps que todavía no tengan el permiso no podrán obtenerlo una vez que se realice la actualización.

Si una app en un dispositivo Go envía un intent con la acción ACTION_MANAGE_OVERLAY_PERMISSION, el sistema rechazará automáticamente la solicitud y llevará al usuario a una pantalla de Configuración en donde se indicará que se denegó el permiso porque ralentizaba el dispositivo. Si una app en un dispositivo Go invoca el método Settings.canDrawOverlays(), este siempre mostrará un resultado falso. Estas restricciones no se aplican a apps que recibieron el permiso SYSTEM_ALERT_WINDOW antes de que el dispositivo se actualizara a Android 10.

Advertencias para las apps orientadas a versiones anteriores de Android

Los dispositivos que ejecutan Android 10 o versiones posteriores advierten a los usuarios la primera vez que estos ejecutan una app orientada a Android 5.1 (nivel de API 22) o a una versión anterior. Si la app requiere que el usuario otorgue permisos, este tendrá la oportunidad de ajustar los permisos de esa app antes de permitir que se ejecute por primera vez.

Debido a los requisitos del nivel de API objetivo de Google Play, un usuario solo verá estas advertencias si ejecuta una app que no se actualizó recientemente. En el caso de apps que se distribuyen en otras tiendas, se aplicarán requisitos similares durante 2019. Para obtener más información sobre estos requisitos, consulta Cómo expandir los requisitos del nivel de API objetivo en 2019.

Eliminación de conjuntos de cifrado SHA-2 CBC

Se quitaron de la plataforma los siguientes conjuntos de cifrado SHA-2 CBC:

  • 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

Estos conjuntos de cifrado son menos seguros que otros similares que usan GCM y la mayoría de los servidores admite las dos variantes (GCM y CBC) o no admite ninguna.

Uso de apps

Android 10 presenta los siguientes cambios en el comportamiento relacionados con el uso de apps:

  • Mejoras de uso de la app UsageStats: Android 10 ahora supervisa correctamente el uso de la app mediante UsageStats cuando las apps se emplean en los modos de pantalla dividida o pantalla en pantalla. De manera adicional, Android 10 puede realizar un seguimiento adecuado del uso de las apps instantáneas.

  • Escala de grises por app: Android 10 ahora permite configurar el modo de visualización de cada app en escala de grises.

  • Estado de distracción por app: Android 10 puede configurar las apps con un "estado de distracción" de manera selectiva cuando las notificaciones de las apps se suprimen y no se muestran como apps sugeridas.

  • Suspensión y reproducción: En Android 10, las apps suspendidas no pueden reproducir audio.

Cambios en la conexión HTTPS

Si una app con Android 10 pasa null en setSSLSocketFactory(), se produce una IllegalArgumentException. En las versiones anteriores, pasar null en setSSLSocketFactory() tenía el mismo efecto que pasar el valor de fábrica predeterminado actual.

La biblioteca android.preference dejó de estar disponible

A partir de Android 10, la biblioteca android.preference dejó de estar disponible. En su lugar, los desarrolladores deben usar la biblioteca de preferencia de AndroidX, que forma parte de Android Jetpack. Para obtener recursos adicionales de ayuda durante la migración y el desarrollo, consulta la Guía de configuración actualizada, nuestra app de ejemplo pública y la documentación de referencia.

Cambios en la biblioteca de utilidades de archivos ZIP

En Android 10, se introducen los siguientes cambios en las clases en el paquete java.util.zip, que administra los archivos ZIP. Gracias a estos cambios, el comportamiento de la biblioteca es más consistente entre Android y otras plataformas que usan java.util.zip.

Inflater

En versiones anteriores, algunos métodos en la clase Inflater muestran una IllegalStateException si se invocan luego de una llamada a end(). Por el contrario, en Android 10, estos métodos muestran una NullPointerException.

ZipFile

En Android 10 y versiones posteriores, el constructor para ZipFile toma argumentos del tipo File, int y Charset que no muestra una ZipException si el archivo ZIP proporcionado no contiene archivos.

ZipOutputStream

En Android 10 y versiones posteriores, el método finish() en ZipOutputStream no muestra una ZipException si este intenta escribir una transmisión de salida para un archivo ZIP que no contiene archivos.

Cambios en la cámara

Muchas apps que usan la cámara asumen que, si el dispositivo está configurado verticalmente, entonces el dispositivo físico también tiene orientación vertical, como se describe en la orientación de la cámara. Esta suposición solía ser cierta, pero con la expansión de los factores de forma disponibles, como los dispositivos plegables, ya no se aplica, porque podría llevar a que el visor de la cámara se ajuste o rote (o ambas cosas) incorrectamente.

Las apps que se orientan al nivel de API 24 o a uno superior deberían establecer android:resizeableActivity de forma explícita y proporcionar la funcionalidad necesaria para controlar operaciones multiventana.

Seguimiento del uso de batería

A partir de Android 10, SystemHealthManager restablece las estadísticas de uso de batería cada vez que el dispositivo se desconecta luego de un evento de carga importante. En términos generales, un evento de carga importante puede ser que el dispositivo se cargó completamente o que pasó de tener muy poca carga a tenerla casi completa.

En versiones anteriores a Android 10, las estadísticas de uso de batería se restablecían cada vez que el dispositivo se desconectaba, independientemente del cambio en el nivel de la batería.

Baja de Android Beam

En Android 10, dejará de estar disponible Android Beam oficialmente, una antigua función para iniciar el uso compartido de datos entre dispositivos por medio de la Comunicación de campo cercano (NFC). También dejarán de estar disponibles varias funciones relacionadas con las API de NFC. Android Beam seguirá disponible de manera opcional para los socios fabricantes que quieran usarla, pero no se seguirá desarrollando. Sin embargo, Android aún admitirá otras API y capacidades de NFC, y los casos prácticos como la lectura de etiquetas y pagos seguirán funcionando como se espera.