Compatibilidad con pantallas

A continuación, se proporcionan las actualizaciones que se realizan en estas áreas específicas de la pantalla:

Cómo cambiar el tamaño de las actividades y pantallas

Para indicar que una app puede no admitir el modo multiventana o el cambio de tamaño, las actividades usan el atributo resizeableActivity=false. Común Los problemas que encuentran las apps cuando se cambia el tamaño de las actividades incluyen los siguientes:

  • Una actividad puede tener una configuración diferente a la de la app o a otra no visual. Un error común es leer las métricas de pantalla desde la app adicional. Los valores mostrados no se ajustarán a las métricas del área visible en el que se muestra una actividad.
  • Es posible que una actividad no controle el cambio de tamaño y la falla, ni muestre una IU distorsionada. o pierde el estado debido al reinicio sin guardar el estado de la instancia.
  • Una app puede intentar usar coordenadas de entrada absolutas (en lugar de aquellas relativo a la posición de la ventana), lo que puede romper la entrada en el modo multiventana.

En Android 7 (y versiones posteriores), se puede configurar una app resizeableActivity=false para que siempre se ejecute en modo de pantalla completa En En este caso, la plataforma evita que se dividan actividades que no pueden cambiar de tamaño en la pantalla. Si el usuario intenta invocar una actividad que no puede cambiar de tamaño desde el selector mientras está en el modo de pantalla dividida, la plataforma sale del modo de pantalla dividida y inicia la actividad que no puede cambiar de tamaño en el modo de pantalla completa.

Las apps que establecen explícitamente este atributo como false en el el manifiesto no debe iniciarse en el modo multiventana, a menos que la se aplica el siguiente modo:

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

En Android 10, la plataforma evita que no pueden cambiar de tamaño pasen al modo de pantalla dividida, pero pueden ajustada de forma temporal si la actividad declaró una orientación o aspecto fijos proporción. De lo contrario, 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 declarada como incompatible con el modo multiventana a través de usar el atributo android:resizeableActivity y cuando la actividad cumple una de las condiciones que se describen a continuación y, luego, cuando se aplique configuración de la pantalla debe cambiar, la actividad y el proceso se guardan con el configuración original y se le da al usuario una indicación para reiniciar el proceso de la app para usar la configuración de pantalla actualizada.

  • Es una orientación fija mediante la aplicación de android:screenOrientation
  • La app tiene una relación de aspecto máxima o mínima predeterminada por nivel de API o declara explícitamente la relación de aspecto

En esta figura, se muestra una actividad que no puede cambiar de tamaño con una relación de aspecto declarada. Cuando se pliega el dispositivo, la ventana se reduce para ajustarse al área mientras manteniendo la relación de aspecto con el formato letterbox adecuado. Además, un se proporciona al usuario la opción de reiniciar la actividad cada vez que el área de visualización de se modifica la actividad.

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

Cuando no se establece resizeableActivity (o se establece en true), la app admite por completo el cambio de tamaño.

Implementación

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

Si la actividad de SCM no puede ocupar toda la pantalla, se alinea arriba y centrado horizontalmente. Los límites de actividad se calculan por AppWindowToken#calculateCompatBoundsTransformation()

Cuando una actividad de SCM usa una configuración de pantalla diferente a la de su contenedor (por ejemplo, se cambia el tamaño de la pantalla o se traslada la actividad a otro gráfico), ActivityRecord#inSizeCompatMode() es verdadero y SizeCompatModeActivityController (en la IU del sistema) recibe el elemento para mostrar el botón de reinicio del proceso.

Tamaños de pantalla y relaciones de aspecto

Android 10 admite nuevas relaciones de aspecto de pantallas largas y finas a proporciones de 1:1. Las apps pueden definir ApplicationInfo#maxAspectRatio y el ApplicationInfo#minAspectRatio de la pantalla capaz de manejar.

proporciones de apps en Android 10

Figura 1: Ejemplo de proporciones de apps admitidas en Android (10)

Las implementaciones de dispositivos pueden tener pantallas secundarias con tamaños y resoluciones menores que las requeridas por Android 9 y anteriores (mínimo de 2.5 pulgadas o altura, un mínimo de 320 DP para smallestScreenWidth) pero solo se pueden colocar actividades que admitan estas pantallas pequeñas ahí.

Para ello, las apps pueden declarar un tamaño mínimo admitido inferior a o igual al tamaño de visualización objetivo. Usa android:minHeight y Atributos de diseño de la actividad android:minWidth en el AndroidManifest.

Políticas de Display

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

  • Estado y rotación de la pantalla
  • Algunas teclas y el seguimiento de eventos de movimiento
  • IU del sistema y ventanas de decoración

En Android 9 (y versiones anteriores), la clase PhoneWindowManager controlaba políticas de visualización, estado y configuración, rotación, marco de ventana decorativo y mucho más. Android 10 traslada la mayor parte de esto a la clase DisplayPolicy, excepto el seguimiento de rotación, que tiene se movió a DisplayRotation.

Configuración de la ventana de visualización

En Android 10, la configuración por pantalla se amplió la configuración de la renderización en ventanas para incluir lo siguiente:

  • Modo de renderización en ventanas de visualización predeterminada
  • Sobrebarrido de valores
  • Modo de rotación y rotación del usuario
  • Tamaño, densidad y modo de escalamiento forzados
  • Modo de eliminación de contenido (cuando se quita la pantalla)
  • Compatibilidad con las decoraciones del sistema y el IME

La clase DisplayWindowSettings contiene la configuración para estas opciones de estado. Se conservan en el disco en la partición /data display_settings.xml cada vez que se cambia un parámetro de configuración. Para consulta DisplayWindowSettings.AtomicFileStorage y DisplayWindowSettings#writeSettings() Los fabricantes de dispositivos pueden proporcionar valores predeterminados en display_settings.xml para su dispositivo configuración. Sin embargo, como el archivo se almacena en /data, es posible que se necesite una lógica adicional para restablecer el archivo si se borra con una limpieza.

De forma predeterminada, Android 10 usa DisplayInfo#uniqueId como identificador para una pantalla cuando es persistente la configuración. Se debe propagar uniqueId para todas las pantallas. En además, es estable para pantallas físicas y de red. También puedes usa el puerto de una pantalla física como identificador, que se puede configurar en DisplayWindowSettings#mIdentifier Luego de cada escritura, toda la configuración están escritos para que sea seguro actualizar la clave que se usa para una entrada de visualización en y almacenamiento de los datos. Para obtener más información, consulta Identificadores de visualización estáticos.

La configuración se conserva en el directorio /data para los datos y otras razones. Originalmente, se utilizaban para conservar los parámetros de configuración establecidos por el usuario, como rotación de la pantalla.

Identificadores de visualización estáticos

Android 9 (y versiones anteriores) no proporcionó identificadores estables para las pantallas en la en un framework de nube. Cuando se agregó una pantalla al sistema, Display#mDisplayId o DisplayInfo#displayId era para esa pantalla incrementando un contador estático. Si el sistema se agregó y quitó la misma pantalla, se generó un ID diferente.

Si un dispositivo tuviera varias pantallas disponibles desde el inicio, estas podrían tener y se asignaron distintos identificadores, según el tiempo. Si bien Android 9 (y anteriormente) incluía DisplayInfo#uniqueId, esta no contenía suficientes información para diferenciar entre las pantallas porque las pantallas físicas identificados como local:0 o local:1 para representar la pantalla integrada y la externa.

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

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

Además de las actualizaciones de uniqueId, DisplayInfo.address contiene DisplayAddress, un identificador de visualización que es estable entre reinicios. En Android 10, DisplayAddress admite componentes físicos, y pantallas de red. DisplayAddress.Physical contiene un elemento estable ID visible (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 puede utilizarse en el framework para identificar de forma estática 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 que los fabricantes de dispositivos identifiquen pantallas en imágenes configuraciones de varias pantallas y de diferentes funciones y parámetros de configuración del sistema usando identificadores de pantalla estáticos, como puertos para pantallas físicas. Estos están ocultos y están destinados solo para utilizarse en system_server

Dado un ID de pantalla HWC (que puede ser opaco y no siempre estable), este 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 de EDID de la pantalla. SurfaceFlinger extrae información del fabricante o modelo del EDID para generar los IDs de pantalla estables de 64 bits expuestos al framework Si este método no es compatible o se producen errores, SurfaceFlinger recurre al modo médico heredado donde DisplayInfo#address es nulo y DisplayInfo#uniqueId está hard-coded, como se describió anteriormente.

Para verificar que esta función sea compatible, ejecuta el siguiente comando:

$ 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"

Usa más de dos pantallas

En Android 9 (y versiones anteriores), SurfaceFlinger y DisplayManagerService de la existencia de dos pantallas físicas como máximo con IDs hard-coded 0 y 1.

A partir de Android 10, SurfaceFlinger podría aprovechar una API de Hardware Composer (HWC) para generar IDs de pantalla estables, lo que le permite administrar una cantidad arbitraria de pantallas físicas. Para obtener más información, consulta Identificadores de visualización estáticos.

El framework puede buscar el token IBinder para una ubicación física. mostrar hasta SurfaceControl#getPhysicalDisplayToken después de obtener el ID de pantalla de 64 bits de SurfaceControl#getPhysicalDisplayIds o de un evento de conexión en caliente de DisplayEventReceiver.

En Android 10 (y versiones anteriores), la pantalla interna principal es TYPE_INTERNAL y todas las pantallas secundarias están marcadas como TYPE_EXTERNAL independientemente del tipo de conexión. Por lo tanto, las pantallas internas adicionales se tratan como externas. Como solución alternativa, el código específico del dispositivo puede hacer suposiciones DisplayAddress.Physical#getPort si se conoce el HWC y la asignación de puertos la lógica es predecible.

Esta limitación se quitará en Android 11 (y versiones posteriores).

  • En Android 11, la primera pantalla que se informa durante el inicio es la pantalla principal. El tipo de conexión (interna o externa) es irrelevante. Sin embargo, sigue siendo cierto que la pantalla principal no se puede desconectar y sigue ese debe ser una pantalla interna en la práctica. Ten en cuenta que algunos teléfonos plegables tienen múltiples pantallas internas.
  • Las pantallas secundarias están categorizadas correctamente como Display.TYPE_INTERNAL o Display.TYPE_EXTERNAL (anteriormente conocido como Display.TYPE_BUILT_IN y Display.TYPE_HDMI, respectivamente) según su tipo de conexión.

Implementación

En Android 9 y versiones anteriores, las pantallas se identifican con IDs de 32 bits, donde 0 es la pantalla interna, 1 es la pantalla externa, [2, INT32_MAX] son pantallas virtuales HWC y -1 representa una pantalla no válida o que no es HWC.

A partir de Android 10, las pantallas son estables. y los IDs persistentes, lo que permite que SurfaceFlinger y DisplayManagerService para realizar un seguimiento de más de dos pantallas y reconocer aquellas que ya se vieron. Si el HWC admite IComposerClient.getDisplayIdentificationData y proporciona visualización datos de identificación personal, SurfaceFlinger analiza la estructura EDID y asigna valores IDs de pantalla de 64 bits para pantallas físicas y virtuales HWC Los IDs se expresan con un tipo de opción, donde el valor nulo representa una pantalla no válida o una instancia pantalla. Sin compatibilidad con HWC, SurfaceFlinger recurre al comportamiento heredado con un la mayoría de las dos pantallas físicas.

Enfoque por pantalla

Para admitir varias fuentes de entrada que se orienten a pantallas individuales al mismo tiempo vez, se puede configurar Android 10 para que admita ventanas enfocadas, como máximo una por pantalla. Esto está destinado únicamente a aplicaciones tipos de dispositivos cuando múltiples usuarios interactúan con el mismo dispositivo en el mismo tiempo y usar diferentes métodos de entrada o dispositivos, como Android Industria automotriz.

Es muy recomendable que no esté habilitada esta función para dispositivos comunes, incluidos los multipantalla o los que se utilizan para computadoras de escritorio experiencias. Esto se debe principalmente a un problema de seguridad que podría causar que los usuarios preguntarse qué ventana tiene foco de entrada.

Imagina al usuario que ingresa información segura en un campo de entrada de texto, como iniciar sesión en una aplicación bancaria o ingresar texto que contenga datos información. Una aplicación maliciosa podría crear una visualización virtual fuera de la pantalla con el cual ejecutar una actividad, también con un campo de entrada de texto. Legítimas y Las actividades maliciosas están enfocadas y ambas muestran un indicador de entrada activo (el cursor parpadea).

Sin embargo, dado que la entrada de un teclado (hardware o software) se ingresa en solo la actividad principal (la última app que se inició), crear una pantalla virtual oculta, una aplicación maliciosa podría captar la entrada del usuario, incluso cuando se usa un teclado en pantalla en la pantalla principal del dispositivo.

Usa com.android.internal.R.bool.config_perDisplayFocusEnabled para configurar el enfoque por pantalla.

Compatibilidad

Problema: En Android 9 y versiones anteriores, como máximo una ventana en la un sistema de control a la vez.

Solución: En el caso poco frecuente de que dos ventanas de la mismo proceso se enfocaría, el sistema solamente se enfoca en la ventana que es más alto en el orden Z. Se quitará esta restricción para las apps segmentadas Android 10. A partir de ese momento, se espera que puedan admitir varias ventanas en las que se enfoca al mismo tiempo.

Implementación

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

ActivityStackSupervisor#getTopDisplayFocusedStack() toma un enfoque similar para aquellos casos en los que la pila enfocada en la parte superior del sistema se deben identificar los datos. Las pilas se recorren de arriba abajo, en busca de la primera pila apta.

InputDispatcher ahora puede tener varias 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, ya se envió a la ventana enfocada en la pantalla enfocada, que es la que el usuario interactuaste más recientemente.

Consulta InputDispatcher::mFocusedWindowHandlesByDisplay y InputDispatcher::setFocusedDisplay() Las apps enfocadas también se actualizan por separado en InputManagerService NativeInputManager::setFocusedApplication()

En WindowManager, también se realiza un seguimiento de las ventanas enfocadas por separado. Consulta DisplayContent#mCurrentFocus y DisplayContent#mFocusedApp y sus respectivos usos Enfoque relacionado de seguimiento y actualización se migraron de De WindowManagerService a DisplayContent.