From 62915b28e022d4de26357284d740dec5f108e601 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 10 Apr 2019 12:28:47 -0700 Subject: [PATCH] Fixing HardwareBuffer leak when creating a bitmap Callers are supposed to close the hardware buffer themselves. Creating a utility method around this Bug: 123874711 Test: No more leak warning on device Change-Id: I2cf215f0646222f63e564a58edab1ffffa396ff3 --- core/java/android/app/ActivityOptions.java | 4 +--- .../ContentSuggestionsService.java | 4 +--- core/java/android/view/SurfaceControl.java | 5 +---- graphics/java/android/graphics/Bitmap.java | 12 ++++++++++++ .../systemui/shared/recents/model/ThumbnailData.java | 5 +---- .../com/android/server/wm/TaskSnapshotPersister.java | 4 +--- .../com/android/server/wm/WallpaperController.java | 4 +--- 7 files changed, 18 insertions(+), 20 deletions(-) diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index da9ea83598544..926044bffdd0e 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -33,7 +33,6 @@ import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.GraphicBuffer; import android.graphics.Rect; -import android.hardware.HardwareBuffer; import android.os.Bundle; import android.os.Handler; import android.os.IRemoteCallback; @@ -925,8 +924,7 @@ public class ActivityOptions { // Unpackage the GraphicBuffer from the parceled thumbnail final GraphicBuffer buffer = opts.getParcelable(KEY_ANIM_THUMBNAIL); if (buffer != null) { - mThumbnail = Bitmap.wrapHardwareBuffer( - HardwareBuffer.createFromGraphicBuffer(buffer), null); + mThumbnail = Bitmap.wrapHardwareBuffer(buffer, null); } mStartX = opts.getInt(KEY_ANIM_START_X, 0); mStartY = opts.getInt(KEY_ANIM_START_Y, 0); diff --git a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java index 45a8466bfca1c..55e61410b9e23 100644 --- a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java +++ b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java @@ -31,7 +31,6 @@ import android.app.contentsuggestions.SelectionsRequest; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.GraphicBuffer; -import android.hardware.HardwareBuffer; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -67,8 +66,7 @@ public abstract class ContentSuggestionsService extends Service { Bitmap wrappedBuffer = null; if (contextImage != null) { - wrappedBuffer = Bitmap.wrapHardwareBuffer( - HardwareBuffer.createFromGraphicBuffer(contextImage), null); + wrappedBuffer = Bitmap.wrapHardwareBuffer(contextImage, null); } mHandler.sendMessage( diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 79363edb0955c..b5ad908e5ea57 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -41,7 +41,6 @@ import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; -import android.hardware.HardwareBuffer; import android.hardware.display.DisplayedContentSample; import android.hardware.display.DisplayedContentSamplingAttributes; import android.os.Build; @@ -1917,9 +1916,7 @@ public final class SurfaceControl implements Parcelable { Log.w(TAG, "Failed to take screenshot"); return null; } - return Bitmap.wrapHardwareBuffer( - HardwareBuffer.createFromGraphicBuffer(buffer.getGraphicBuffer()), - buffer.getColorSpace()); + return Bitmap.wrapHardwareBuffer(buffer.getGraphicBuffer(), buffer.getColorSpace()); } /** diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 170dec26f361b..07f81c18e1caa 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -762,6 +762,18 @@ public final class Bitmap implements Parcelable { return nativeWrapHardwareBufferBitmap(hardwareBuffer, colorSpace.getNativeInstance()); } + /** + * Utility method to create a hardware backed bitmap using the graphics buffer. + * @hide + */ + @Nullable + public static Bitmap wrapHardwareBuffer(@NonNull GraphicBuffer graphicBuffer, + @Nullable ColorSpace colorSpace) { + try (HardwareBuffer hb = HardwareBuffer.createFromGraphicBuffer(graphicBuffer)) { + return wrapHardwareBuffer(hb, colorSpace); + } + } + /** * Creates a new bitmap, scaled from an existing bitmap, when possible. If the * specified width and height are the same as the current width and height of 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 1413ac1433f16..98a8110209e6d 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 @@ -23,7 +23,6 @@ import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_ import android.app.ActivityManager.TaskSnapshot; import android.graphics.Bitmap; import android.graphics.Rect; -import android.hardware.HardwareBuffer; /** * Data for a single thumbnail. @@ -53,9 +52,7 @@ public class ThumbnailData { } public ThumbnailData(TaskSnapshot snapshot) { - thumbnail = Bitmap.wrapHardwareBuffer( - HardwareBuffer.createFromGraphicBuffer(snapshot.getSnapshot()), - snapshot.getColorSpace()); + thumbnail = Bitmap.wrapHardwareBuffer(snapshot.getSnapshot(), snapshot.getColorSpace()); insets = new Rect(snapshot.getContentInsets()); orientation = snapshot.getOrientation(); reducedResolution = snapshot.isReducedResolution(); diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java index 3c9a46b43a2f4..0b63f484c8e26 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java @@ -26,7 +26,6 @@ import android.app.ActivityManager; import android.app.ActivityManager.TaskSnapshot; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; -import android.hardware.HardwareBuffer; import android.os.Process; import android.os.SystemClock; import android.util.ArraySet; @@ -363,8 +362,7 @@ class TaskSnapshotPersister { // TODO(b/116112787) TaskSnapshot needs bookkeep the ColorSpace of the // hardware bitmap when created. final Bitmap bitmap = Bitmap.wrapHardwareBuffer( - HardwareBuffer.createFromGraphicBuffer(mSnapshot.getSnapshot()), - mSnapshot.getColorSpace()); + mSnapshot.getSnapshot(), mSnapshot.getColorSpace()); if (bitmap == null) { Slog.e(TAG, "Invalid task snapshot hw bitmap"); return false; diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index 166a33d7a5604..da873b8bc3082 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -35,7 +35,6 @@ import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDIN import android.graphics.Bitmap; import android.graphics.Rect; -import android.hardware.HardwareBuffer; import android.os.Bundle; import android.os.Debug; import android.os.IBinder; @@ -744,8 +743,7 @@ class WallpaperController { return null; } return Bitmap.wrapHardwareBuffer( - HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer.getGraphicBuffer()), - wallpaperBuffer.getColorSpace()); + wallpaperBuffer.getGraphicBuffer(), wallpaperBuffer.getColorSpace()); } private WindowState getTopVisibleWallpaper() {