Google se compromete a promover la equidad racial para las comunidades negras. Ver cómo.
Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Soporte de pantalla

Las actualizaciones realizadas en estas áreas específicas de visualización se proporcionan a continuación:

Cambiar el tamaño de las actividades y pantallas

Para indicar que una aplicación puede no admitir el modo de ventana múltiple o cambiar el tamaño, las actividades usan el atributo resizeableActivity=false . Los problemas comunes que encuentran las aplicaciones cuando se redimensionan las actividades incluyen:

  • Una actividad puede tener una configuración diferente de la aplicación u otro componente no visual. Un error común es leer las métricas de visualización del contexto de la aplicación. Los valores devueltos no se ajustarán a las métricas del área visible en la que se muestra una actividad.
  • Una actividad puede no manejar el cambio de tamaño y bloquearse, mostrar una IU distorsionada o perder el estado debido al reinicio sin guardar el estado de la instancia.
  • Una aplicación puede intentar usar coordenadas de entrada absolutas (en lugar de las relativas a la posición de la ventana), lo que puede romper la entrada en múltiples ventanas.

En Android 7 (y superior), una aplicación se puede configurar resizeableActivity=false para que siempre se ejecute en modo de pantalla completa. En este caso, la plataforma evita que actividades no redimensionables entren en pantalla dividida. Si el usuario intenta invocar una actividad no redimensionable desde el iniciador mientras ya está en modo de pantalla dividida, la plataforma sale del modo de pantalla dividida e inicia la actividad no redimensionable en modo de pantalla completa.

Las aplicaciones que establecen explícitamente este atributo en false en el manifiesto no deben iniciarse en modo de ventanas múltiples, a menos que se aplique el modo de compatibilidad:

  • La misma configuración se aplica al proceso, que contiene todas las actividades y componentes que no son de actividad.
  • La configuración aplicada cumple con los requisitos de CDD para pantallas compatibles con la aplicación.

En Android 10, la plataforma aún evita que las actividades no redimensionables entren en modo de pantalla dividida, pero pueden escalarse temporalmente si la actividad ha declarado una orientación o relación de aspecto fija. Si no, la actividad cambia de tamaño para llenar toda la pantalla como en Android 9 y versiones anteriores.

La implementación predeterminada aplica la siguiente política:

Cuando una actividad se declara incompatible con múltiples ventanas mediante el uso del atributo android:resizeableActivity y cuando esa actividad cumple con una de las condiciones descritas a continuación, cuando la configuración de pantalla aplicada debe cambiar, la actividad y el proceso se guardan con la configuración original y el usuario tiene la posibilidad de reiniciar el proceso de la aplicación para usar la configuración de pantalla actualizada.

  • Se fija la orientación a través de la aplicación de android:screenOrientation
  • La aplicación tiene una relación de aspecto máxima o mínima predeterminada al orientar el nivel de API o declara la relación de aspecto explícitamente

Esta figura muestra una actividad no redimensionable con una relación de aspecto declarada. Al plegar el dispositivo, la ventana se reduce para ajustarse al área mientras se mantiene la relación de aspecto utilizando el buzón apropiado. Además, se proporciona al usuario una opción de actividad de reinicio cada vez que se cambia el área de visualización de la actividad.

Al desplegar el dispositivo, la configuración, el tamaño y la relación de aspecto de la actividad no cambian, pero se muestra la opción para reiniciar la actividad.

Cuando resizeableActivity no está configurado (o está establecido en true ), la aplicación es totalmente compatible con el cambio de tamaño.

Implementación

Una actividad no redimensionable con orientación fija o relación de aspecto se denomina modo de compatibilidad de tamaño (SCM) en el código. La condición se define en ActivityRecord#shouldUseSizeCompatMode() . Cuando se inicia una actividad SCM, la configuración relacionada con la pantalla (como el tamaño o la densidad) se fija en la configuración de anulación solicitada, por lo que la actividad ya no depende de la configuración de visualización actual.

Si la actividad de SCM no puede llenar toda la pantalla, está alineada y centrada horizontalmente. AppWindowToken#calculateCompatBoundsTransformation() calcula los límites de actividad.

Cuando una actividad SCM usa una configuración de pantalla diferente a su contenedor (por ejemplo, la pantalla cambia de tamaño o la actividad se mueve a otra pantalla), ActivityRecord#inSizeCompatMode() es verdadero y SizeCompatModeActivityController (en la interfaz de usuario del sistema) recibe la devolución de llamada para mostrar el proceso botón de reinicio.

Tamaños de pantalla y relaciones de aspecto

Android 10 brinda soporte para nuevas relaciones de aspecto, desde relaciones altas de pantallas largas y delgadas hasta relaciones 1: 1. Las aplicaciones pueden definir ApplicationInfo#maxAspectRatio y ApplicationInfo#minAspectRatio de la pantalla que pueden manejar.

Figura 1. Ejemplos de proporciones de aplicaciones compatibles con Android 10

Las implementaciones de dispositivos pueden tener pantallas secundarias con tamaños y resoluciones más pequeñas que las requeridas por Android 9, y más bajas (mínimo de 2,5 pulgadas de ancho o alto, mínimo de 320 DP para el smallestScreenWidth ancho de pantalla), pero solo se pueden realizar actividades que admitan estas pequeñas pantallas. colocado allí.

Las aplicaciones pueden optar por declarar un tamaño mínimo admitido que sea menor que oe igual al tamaño de visualización objetivo. Utilice el android:minHeight y android:minWidth atributos actividad de diseño en el AndroidManifest para hacerlo.

Mostrar políticas

Android 10 separa y mueve ciertas políticas de visualización de la implementación predeterminada de WindowManagerPolicy en PhoneWindowManager a clases por pantalla, como:

  • Mostrar estado y rotación
  • Algunas claves y seguimiento de eventos de movimiento
  • Sistema UI y ventanas decorativas

En Android 9 (y PhoneWindowManager ), la clase PhoneWindowManager manejaba las políticas de visualización, el estado y la configuración, la rotación, el seguimiento del marco de la ventana de decoración y más. Android 10 mueve la mayor parte de esto a la clase DisplayPolicy , excepto para el seguimiento de rotación, que se ha movido a DisplayRotation .

Configuración de la ventana de visualización

En Android 10, la configuración de ventanas configurable por pantalla se ha ampliado para incluir:

  • Modo de ventana de visualización predeterminado
  • Valores de sobreexploración
  • Rotación de usuario y modo de rotación
  • Tamaño forzado, densidad y modo de escala
  • Modo de eliminación de contenido (cuando se elimina la pantalla)
  • Soporte para decoraciones del sistema e IME

La clase DisplayWindowSettings contiene configuraciones para estas opciones. Se persisten en grabar en /data partición de /data en display_settings.xml cada vez que se cambia una configuración. Para más detalles, vea DisplayWindowSettings.AtomicFileStorage y DisplayWindowSettings#writeSettings() . Los fabricantes de dispositivos pueden proporcionar valores predeterminados en display_settings.xml para la configuración de sus dispositivos. Sin embargo, debido a que el archivo se almacena en /data , es posible que se necesite lógica adicional para restaurar el archivo si se borra con un borrado.

Por defecto, Android 10 usa DisplayInfo#uniqueId como identificador para una pantalla cuando persiste la configuración. uniqueId debe rellenarse para todas las pantallas. Además, es estable para pantallas físicas y de red. También es posible utilizar el puerto de una pantalla física como identificador, que se puede configurar en DisplayWindowSettings#mIdentifier . En cada escritura, todas las configuraciones se escriben, por lo que es seguro actualizar la clave que se usa para una entrada de pantalla en el almacenamiento. Para más detalles, consulte "Identificadores de visualización estática" a continuación.

La configuración persiste en el directorio /data por razones históricas. Originalmente, se usaban para mantener la configuración establecida por el usuario, como la rotación de la pantalla.

Identificadores de visualización estática

Android 9 (y versiones anteriores) no proporcionaban identificadores estables para pantallas en el marco. Cuando se agregó una pantalla al sistema, se generó Display#mDisplayId o DisplayInfo#displayId para esa pantalla al incrementar un contador estático. Si el sistema agregó y eliminó la misma pantalla, resultó una ID diferente.

Si un dispositivo tenía múltiples pantallas disponibles desde el arranque, las pantallas podrían tener diferentes identificadores, dependiendo del tiempo. Si bien Android 9 (y DisplayInfo#uniqueId anteriores) incluía DisplayInfo#uniqueId , no contenía suficiente información para diferenciar entre pantallas porque las pantallas físicas se identificaban como local:0 o local:1 , para representar la pantalla integrada y externa.

Android 10 cambia DisplayInfo#uniqueId para agregar un identificador estable y diferenciar entre pantallas locales, de red y virtuales.

Tipo de visualización Formato
Local
local:<stable-id>
Red
network:<mac-address>
Virtual
virtual:<package-name-and-name>

Además de las actualizaciones de uniqueId , DisplayInfo.address contiene DisplayAddress , un identificador de pantalla que es estable en todos los reinicios. En Android 10, DisplayAddress admite DisplayAddress físicas y de red. DisplayAddress.Physical contiene una ID de pantalla estable (igual que en uniqueId ) y se puede crear con DisplayAddress#fromPhysicalDisplayId() .

Android 10 también proporciona un método conveniente para obtener información del puerto ( Physical#getPort() ). Este método se puede usar en el marco para identificar estáticamente las pantallas. Por ejemplo, se usa en DisplayWindowSettings ). DisplayAddress.Network contiene la dirección MAC y se puede crear con DisplayAddress#fromMacAddress() .

Estas adiciones permiten a los fabricantes de dispositivos identificar pantallas en configuraciones de pantallas múltiples estáticas y configurar diferentes configuraciones y características del sistema utilizando identificadores de pantalla estáticos, como puertos para pantallas físicas. Estos métodos están ocultos y están destinados solo para usarse dentro de system_server .

Dada una ID de pantalla HWC (que puede ser opaca y no siempre estable), este método devuelve el número de puerto de 8 bits (específico de la plataforma) que identifica un conector físico para la salida de la pantalla, así como el blob EDID de la pantalla. SurfaceFlinger extrae información del fabricante o modelo del EDID para generar las ID de pantalla estables de 64 bits expuestas al marco. Si este método no es compatible o se producen errores, SurfaceFlinger recurre al modo MD heredado, donde la DisplayInfo#address es nula y DisplayInfo#uniqueId está codificado, como se describió anteriormente.

Para verificar que esta característica sea compatible, ejecute:

$ dumpsys SurfaceFlinger --display-id
# Example output.
Display 21691504607621632 (HWC display 0): port=0 pnpId=SHP displayName="LQ123P1JX32"
Display 9834494747159041 (HWC display 2): port=1 pnpId=HWP displayName="HP Z24i"
Display 1886279400700944 (HWC display 1): port=2 pnpId=AUS displayName="ASUS MB16AP"

Enfoque por pantalla

Para admitir varias fuentes de entrada que se dirigen a pantallas individuales al mismo tiempo, Android 10 se puede configurar para admitir múltiples ventanas enfocadas, como máximo una por pantalla. Esto está destinado solo a tipos especiales de dispositivos cuando varios usuarios interactúan con el mismo dispositivo al mismo tiempo y utilizan diferentes métodos o dispositivos de entrada, como Android Automotive.

Se recomienda encarecidamente que esta función no esté habilitada para dispositivos normales, incluidos dispositivos de pantallas múltiples o aquellos utilizados para experiencias de escritorio. Esto se debe principalmente a una preocupación de seguridad que puede hacer que los usuarios se pregunten qué ventana tiene foco de entrada.

Imagine al usuario que ingresa información segura en un campo de entrada de texto, tal vez iniciando sesión en una aplicación bancaria o ingresando texto que contiene información confidencial. Una aplicación maliciosa podría crear una visualización virtual fuera de la pantalla con la que ejecutar una actividad, también con un campo de entrada de texto. Las actividades legítimas y maliciosas tienen foco y ambas muestran un indicador de entrada activo (cursor parpadeante).

Sin embargo, dado que la entrada de un teclado (hardware o software) se ingresa solo en la actividad principal (esa aplicación que se lanzó más recientemente). Al crear una pantalla virtual oculta, una aplicación maliciosa podría captar la entrada del usuario, incluso cuando se utiliza un teclado de software en la pantalla del dispositivo principal.

Use com.android.internal.R.bool.config_perDisplayFocusEnabled para establecer el enfoque por pantalla.

Compatibilidad

Problema: en Android 9 y versiones anteriores, a lo sumo una ventana en el sistema tiene foco a la vez.

Solución: en el raro caso en que se enfocarían dos ventanas del mismo proceso, el sistema proporciona el foco solo a la ventana que está más arriba en el orden Z. Esta restricción se elimina para las aplicaciones que se dirigen a Android 10, momento en el que se espera que puedan admitir múltiples ventanas enfocadas simultáneamente.

Implementación

WindowManagerService#mPerDisplayFocusEnabled controla la disponibilidad de esta función. En ActivityManager , ActivityDisplay#getFocusedStack() ahora se usa en lugar del seguimiento global en una variable. ActivityDisplay#getFocusedStack() determina el enfoque en función del orden Z en lugar de almacenar en caché el valor. Esto es para que solo una fuente, WindowManager, necesite rastrear el orden Z de las actividades.

ActivityStackSupervisor#getTopDisplayFocusedStack() adopta un enfoque similar para aquellos casos en que se debe identificar la pila enfocada más alta del sistema. Las pilas se recorren de arriba a abajo, buscando la primera pila elegible.

InputDispatcher ahora puede tener múltiples ventanas enfocadas (una por pantalla). Si un evento de entrada es específico de la pantalla, se envía a la ventana enfocada en la pantalla correspondiente. De lo contrario, se envía a la ventana enfocada en la pantalla enfocada, que es la pantalla con la que el usuario interactuó más recientemente.

Ver InputDispatcher::mFocusedWindowHandlesByDisplay y InputDispatcher::setFocusedDisplay() . Las aplicaciones enfocadas también se actualizan por separado en InputManagerService a través de NativeInputManager::setFocusedApplication() .

En WindowManager , las ventanas enfocadas también se rastrean por separado. Consulte DisplayContent#mCurrentFocus y DisplayContent#mFocusedApp y los usos respectivos. Los métodos relacionados de seguimiento y actualización de foco se han movido de WindowManagerService a DisplayContent .