Instantáneas de tareas

Instantáneas de tareas es una infraestructura que se introdujo en Android 8.0 y que combina capturas de pantalla de miniaturas de Recientes y superficies guardadas del administrador de ventanas. Las miniaturas de Recientes representan el último estado de una tarea en la vista de Recientes.

Cuando una actividad pasaba a un estado detenido, el administrador de ventanas no destruía las superficies de la actividad mientras esta se encontrara en la parte superior de la tarea. Si esta actividad se tenía que mostrar de nuevo, el administrador de ventanas podía iniciar la animación sin esperar a que la actividad terminara de dibujar su primer fotograma, ya que podía usar esta superficie guardada.

Arquitectura

Los dos conceptos de miniaturas de Recents y superficies guardadas se unifican con las instantáneas de tareas. Cuando una tarea pasa a segundo plano, WindowManager coloca una captura de pantalla de esta tarea en un GraphicBuffer. Mientras la app de la actividad superior de la tarea permanezca en la memoria, este GraphicBuffer se retendrá en la memoria. Ahora, cuando la misma actividad se vuelva a traer al primer plano, WindowManager creará una ventana de inicio (TaskSnapshotSurface) y adjuntará el GraphicBuffer sin copiar memoria en la cola de búfer de la ventana de inicio. En cuanto la actividad dibuje su primer fotograma, la ventana de inicio de la instantánea de la tarea se desvanecerá suavemente, como las pantallas de presentación normales.

El mismo GraphicBuffer también se envía a través de Binder a SystemUI para dibujar el estado de vista previa de una tarea en la vista de Recientes. Dado que solo es una referencia a un búfer, enviarlo a través de Binder consume pocos recursos. Cuando el GraphicBuffer llega a SystemUI, se encapsula en un mapa de bits de hardware y, luego, se dibuja en la pantalla sin que se suba memoria a la memoria de gráficos.

Beneficios

Esta nueva arquitectura tiene tres beneficios principales:

  • Si la instantánea de la tarea se usa como ventana inicial, se produce una transición suave entre la instantánea y el contenido real.
  • Cuando se dibuja la instantánea de la tarea en SystemUI, se puede hacer sin ninguna copia. Anteriormente, el mapa de bits se tenía que copiar en Ashmem y, luego, en la memoria de gráficos. Dado que este método almacena la instantánea directamente en la memoria de gráficos, no se necesita ninguna copia.
  • El estado que ves en Recientes siempre coincide con el estado que verás por primera vez cuando vuelvas a abrir la app. Tener el mismo búfer aquí también ahorra mucha memoria. Por eso, ahora Recientes puede mostrar estas imágenes en resolución completa. Anteriormente, se reducía la muestra en un 64% para ahorrar memoria.

Implementación

Esta función existe completamente en la plataforma de Android. No se requiere integración y no se admite la personalización. Sin embargo, los fabricantes de dispositivos pueden inhabilitar por completo la función de instantáneas de tareas.

Para inhabilitar esta función, modifica lo siguiente:

frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java#215

Ten en cuenta que, si la función está inhabilitada, la vista Recientes no mostrará ninguna miniatura.

Instantáneas en alta y baja resolución

Las instantáneas de tareas se escriben en el disco en dos escalas. Cuando se restablece una instantánea de la tarea desde el disco, primero se leen las instantáneas de baja resolución y, luego, se reemplazan por sus equivalentes de alta resolución. Esta optimización mejora los tiempos de carga de las imágenes. De lo contrario, podría haber una pequeña demora al leer el archivo de instantánea del disco, y el usuario vería una tarjeta de tarea en blanco hasta que la imagen estuviera disponible. Puedes configurar las escalas en el archivo de configuración de superposición del dispositivo overlay/frameworks/base/core/res/res/values/config.xml estableciendo config_highResTaskSnapshotScale y config_lowResTaskSnapshotScale. De forma predeterminada, estos valores se establecen en 1.0 y 0.5, respectivamente. Para inhabilitar las instantáneas de baja resolución, establece config_lowResTaskSnapshotScale en 0.0.

Ejemplos y fuente

Encuentra el resto del código para esta función en los archivos TaskSnapshot* en:

frameworks/base/+/android16-release/services/core/java/com/android/server/wm/