diff options
6 files changed, 42 insertions, 5 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java index b9ddd3650b86..0f9260c9deaa 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java @@ -54,7 +54,13 @@ public interface TaskStackListenerCallback { default void onTaskDescriptionChanged(RunningTaskInfo taskInfo) { } - default void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) { } + /** + * @return whether the snapshot is consumed and the lifecycle of the snapshot extends beyond + * the lifecycle of this callback. + */ + default boolean onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) { + return false; + } default void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) { } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java index 85e2654e4ebe..9e0a48b13413 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java @@ -275,9 +275,15 @@ public class TaskStackListenerImpl extends TaskStackListener implements Handler. } case ON_TASK_SNAPSHOT_CHANGED: { Trace.beginSection("onTaskSnapshotChanged"); + final TaskSnapshot snapshot = (TaskSnapshot) msg.obj; + boolean snapshotConsumed = false; for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) { - mTaskStackListeners.get(i).onTaskSnapshotChanged(msg.arg1, - (TaskSnapshot) msg.obj); + boolean consumed = mTaskStackListeners.get(i).onTaskSnapshotChanged( + msg.arg1, snapshot); + snapshotConsumed |= consumed; + } + if (!snapshotConsumed && snapshot.getHardwareBuffer() != null) { + snapshot.getHardwareBuffer().close(); } Trace.endSection(); break; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java index cde4247c575f..95bc579a4a51 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java @@ -389,6 +389,9 @@ public class TaskSnapshotWindow { reportDrawn(); // In case window manager leaks us, make sure we don't retain the snapshot. + if (mSnapshot.getHardwareBuffer() != null) { + mSnapshot.getHardwareBuffer().close(); + } mSnapshot = null; mSurfaceControl.release(); } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java index 1142e05f4649..07733473f298 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java @@ -65,6 +65,12 @@ public class ThumbnailData { snapshotId = 0; } + public void recycleBitmap() { + if (thumbnail != null) { + thumbnail.recycle(); + } + } + private static Bitmap makeThumbnail(TaskSnapshot snapshot) { Bitmap thumbnail = null; try (final HardwareBuffer buffer = snapshot.getHardwareBuffer()) { diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java index acd42228f4e2..362d7a9390d4 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java @@ -33,7 +33,14 @@ public interface TaskStackChangeListener { // Main thread callbacks default void onTaskStackChanged() { } - default void onTaskSnapshotChanged(int taskId, ThumbnailData snapshot) { } + + /** + * @return whether the snapshot is consumed and the lifecycle of the snapshot extends beyond + * the lifecycle of this callback. + */ + default boolean onTaskSnapshotChanged(int taskId, ThumbnailData snapshot) { + return false; + } default void onActivityPinned(String packageName, int userId, int taskId, int stackId) { } default void onActivityUnpinned() { } default void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible, diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java index 2fd5aaefa34b..8af934f66b2a 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java @@ -294,8 +294,17 @@ public class TaskStackChangeListeners { Trace.beginSection("onTaskSnapshotChanged"); final TaskSnapshot snapshot = (TaskSnapshot) msg.obj; final ThumbnailData thumbnail = new ThumbnailData(snapshot); + boolean snapshotConsumed = false; for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) { - mTaskStackListeners.get(i).onTaskSnapshotChanged(msg.arg1, thumbnail); + boolean consumed = mTaskStackListeners.get(i).onTaskSnapshotChanged( + msg.arg1, thumbnail); + snapshotConsumed |= consumed; + } + if (!snapshotConsumed) { + thumbnail.recycleBitmap(); + if (snapshot.getHardwareBuffer() != null) { + snapshot.getHardwareBuffer().close(); + } } Trace.endSection(); break; |