diff options
| author | 2017-05-22 13:58:48 +0100 | |
|---|---|---|
| committer | 2017-05-22 16:17:04 +0100 | |
| commit | e952792fdfde0f5034a4c1bb6bd47c0043b25405 (patch) | |
| tree | ddae4f31a67493f77f2b129baa895362f889e0d5 | |
| parent | c8a5b6c38a4e934a7953b07cc12046b01c32ae5d (diff) | |
ahat: better handle bitmaps without pixel info available.
Don't print an exception nor show a broken link for bitmaps whose
pixel data is unavailable.
Bug: 30307315
Test: m ahat-test
Test: Open recent heap dump and view list of Bitmaps.
Change-Id: I4dda48f192ce6d4613decf52bf1f5e5100cdd846
| -rw-r--r-- | tools/ahat/src/heapdump/AhatClassInstance.java | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/tools/ahat/src/heapdump/AhatClassInstance.java b/tools/ahat/src/heapdump/AhatClassInstance.java index 273530af64..c10d604630 100644 --- a/tools/ahat/src/heapdump/AhatClassInstance.java +++ b/tools/ahat/src/heapdump/AhatClassInstance.java @@ -154,10 +154,7 @@ public class AhatClassInstance extends AhatInstance { } @Override public AhatInstance getAssociatedBitmapInstance() { - if (isInstanceOfClass("android.graphics.Bitmap")) { - return this; - } - return null; + return getBitmapInfo() == null ? null : this; } @Override public boolean isClassInstance() { @@ -178,14 +175,27 @@ public class AhatClassInstance extends AhatInstance { * Returns null if the field value is null, not a byte[] or could not be read. */ private byte[] getByteArrayField(String fieldName) { - Value value = getField(fieldName); - if (!value.isAhatInstance()) { - return null; + AhatInstance field = getRefField(fieldName); + return field == null ? null : field.asByteArray(); + } + + private static class BitmapInfo { + public final int width; + public final int height; + public final byte[] buffer; + + public BitmapInfo(int width, int height, byte[] buffer) { + this.width = width; + this.height = height; + this.buffer = buffer; } - return value.asAhatInstance().asByteArray(); } - public BufferedImage asBitmap() { + /** + * Return bitmap info for this object, or null if no appropriate bitmap + * info is available. + */ + private BitmapInfo getBitmapInfo() { if (!isInstanceOfClass("android.graphics.Bitmap")) { return null; } @@ -205,20 +215,34 @@ public class AhatClassInstance extends AhatInstance { return null; } + if (buffer.length < 4 * height * width) { + return null; + } + + return new BitmapInfo(width, height, buffer); + + } + + public BufferedImage asBitmap() { + BitmapInfo info = getBitmapInfo(); + if (info == null) { + return null; + } + // Convert the raw data to an image // Convert BGRA to ABGR - int[] abgr = new int[height * width]; + int[] abgr = new int[info.height * info.width]; for (int i = 0; i < abgr.length; i++) { abgr[i] = ( - (((int) buffer[i * 4 + 3] & 0xFF) << 24) - + (((int) buffer[i * 4 + 0] & 0xFF) << 16) - + (((int) buffer[i * 4 + 1] & 0xFF) << 8) - + ((int) buffer[i * 4 + 2] & 0xFF)); + (((int) info.buffer[i * 4 + 3] & 0xFF) << 24) + + (((int) info.buffer[i * 4 + 0] & 0xFF) << 16) + + (((int) info.buffer[i * 4 + 1] & 0xFF) << 8) + + ((int) info.buffer[i * 4 + 2] & 0xFF)); } BufferedImage bitmap = new BufferedImage( - width, height, BufferedImage.TYPE_4BYTE_ABGR); - bitmap.setRGB(0, 0, width, height, abgr, 0, width); + info.width, info.height, BufferedImage.TYPE_4BYTE_ABGR); + bitmap.setRGB(0, 0, info.width, info.height, abgr, 0, info.width); return bitmap; } } |