Task Snapshots

Task Snapshots is infrastructure introduced in Android 8.0 that combines screenshots for Recents Thumbnails as well as Saved Surfaces from Window Manager. Recents Thumbnails represent the last state of a task in the Recents view.

When an activity went into a stopped state, Window Manager didn't destroy the surfaces of the activity as long as that activity was on the top of the task. If this activity had to be shown again, Window Manager was able to start the animation without waiting for the activity to finish drawing its first frame, as it was able to use this Saved Surface.

Architecture

The two concepts of Recents Thumbnails and Saved Surfaces are unified with Task Snapshots. When a task goes into background, Window Manager places a screenshot of this task into a GraphicBuffer. As long as the application of the top activity of the task stays in memory, this GraphicBuffer will be retained in memory. Now, when the same activity is brought to the front again, Window Manager will create a starting window (TaskSnapshotSurface), and attach the GraphicBuffer without copying any memory to the buffer queue of the starting window. As soon as the activity has drawn its first frame, the Task Snapshot starting window will fade out smoothly like regular splash screens.

The same GraphicBuffer is also sent over Binder to SystemUI to be used to draw the preview state of a task in the Recents view. Since this is just a reference to a buffer, sending it over binder expends few resources. When the GraphicBuffer arrives at SystemUI, it is wrapped into a hardware Bitmap and then drawn onto the screen without any memory uploading to the graphics memory.

Benefits

There are three main benefits to this new architecture:

  • If the task snapshot is used as a starting window, there is a nice crossfade between the snapshot and the real content.
  • When the task snapshot is drawn in SystemUI, it can be done so without any copying. Previously the bitmap had to be copied into Ashmem, then into graphics memory. Since this method stores the snapshot directly in graphics memory, no copying is needed.
  • The state you see in Recents always matches the state you'll first see when reopening the app. Having the same buffer here also saves a lot of memory. That's why Recents is now able to show these images at full resolution. Previously, it was down sampled by 64% to save memory.

Implementation

This feature exists entirely in the Android platform. No integration is required, and customization is not supported. Device manufacturers may, however, disable the Task Snapshots feature entirely.

To disable this feature, modify this function:

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

Note that if the feature is disabled, the Recents view will not show any thumbnails whatsoever.

High-res and low-res snapshots

Task snapshots are written to the disk at two scales. When restoring a task snapshot from the disk, low-res snapshots are read first, and then replaced by their high-res counterpart. This optimization improves image load times. Otherwise, there could be a slight delay when reading the snapshot file from the disk, and the user would see a blank task card until the image was available. You can configure the scales in the device overlay config file overlay/frameworks/base/core/res/res/values/config.xml by setting config_highResTaskSnapshotScale and config_lowResTaskSnapshotScale. By default, these are set to 1.0 and 0.5 respectively. Disable low-res snapshots by setting config_lowResTaskSnapshotScale to 0.0.

Examples and source

Find the rest of the code for this feature within the TaskSnapshot* files in:

frameworks/base/+/main/services/core/java/com/android/server/wm/