diff options
author | Xavier Ducrohet <xav@android.com> | 2009-09-15 20:09:08 -0700 |
---|---|---|
committer | Xavier Ducrohet <xav@android.com> | 2009-09-16 16:30:50 -0700 |
commit | 4eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1 (patch) | |
tree | 7a92b2755b1e4502a29785c946e1148b42941806 /ddms/libs/ddmlib/src/com | |
parent | ce9a326490f6f56c4e5d28ac4ce174d0168df0a9 (diff) | |
download | sdk-4eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1.zip sdk-4eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1.tar.gz sdk-4eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1.tar.bz2 |
Add support for new framebuffer protocol over adb.
This is backward compatible with the original protocol.
Change-Id: I93e811cb7775a10af82e70f31ae66d4cd74636b5
Diffstat (limited to 'ddms/libs/ddmlib/src/com')
-rw-r--r-- | ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java | 29 | ||||
-rw-r--r-- | ddms/libs/ddmlib/src/com/android/ddmlib/RawImage.java | 123 |
2 files changed, 144 insertions, 8 deletions
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java b/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java index 7a4d0ad..ce8d366 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java @@ -286,7 +286,8 @@ final class AdbHelper { return null; } - reply = new byte[16]; + // first the protocol version. + reply = new byte[4]; if (read(adbChan, reply) == false) { Log.w("ddms", "got partial reply from ADB fb:"); Log.hexDump("ddms", LogLevel.WARN, reply, 0, reply.length); @@ -296,10 +297,27 @@ final class AdbHelper { ByteBuffer buf = ByteBuffer.wrap(reply); buf.order(ByteOrder.LITTLE_ENDIAN); - imageParams.bpp = buf.getInt(); - imageParams.size = buf.getInt(); - imageParams.width = buf.getInt(); - imageParams.height = buf.getInt(); + int version = buf.getInt(); + + // get the header size (this is a count of int) + int headerSize = RawImage.getHeaderSize(version); + + // read the header + reply = new byte[headerSize * 4]; + if (read(adbChan, reply) == false) { + Log.w("ddms", "got partial reply from ADB fb:"); + Log.hexDump("ddms", LogLevel.WARN, reply, 0, reply.length); + adbChan.close(); + return null; + } + buf = ByteBuffer.wrap(reply); + buf.order(ByteOrder.LITTLE_ENDIAN); + + // fill the RawImage with the header + if (imageParams.readHeader(version, buf) == false) { + Log.e("Screenshot", "Unsupported protocol: " + version); + return null; + } Log.d("ddms", "image params: bpp=" + imageParams.bpp + ", size=" + imageParams.size + ", width=" + imageParams.width @@ -314,6 +332,7 @@ final class AdbHelper { adbChan.close(); return null; } + imageParams.data = reply; } finally { if (adbChan != null) { diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/RawImage.java b/ddms/libs/ddmlib/src/com/android/ddmlib/RawImage.java index 610cb59..e3d4e09 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/RawImage.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/RawImage.java @@ -16,17 +16,134 @@ package com.android.ddmlib; +import java.nio.ByteBuffer; + /** * Data representing an image taken from a device frame buffer. */ public final class RawImage { - /** - * bit-per-pixel value. - */ + public int version; public int bpp; public int size; public int width; public int height; + public int red_offset; + public int red_length; + public int blue_offset; + public int blue_length; + public int green_offset; + public int green_length; + public int alpha_offset; + public int alpha_length; public byte[] data; + + /** + * Reads the header of a RawImage from a {@link ByteBuffer}. + * <p/>The way the data is sent over adb is defined in system/core/adb/framebuffer_service.c + * @param version the version of the protocol. + * @param buf the buffer to read from. + * @return true if success + */ + public boolean readHeader(int version, ByteBuffer buf) { + this.version = version; + + if (version == 16) { + // compatibility mode with original protocol + this.bpp = 16; + + // read actual values. + this.size = buf.getInt(); + this.width = buf.getInt(); + this.height = buf.getInt(); + + // create default values for the rest. Format is 565 + this.red_offset = 11; + this.red_length = 5; + this.green_offset = 5; + this.green_length = 6; + this.blue_offset = 0; + this.blue_length = 5; + this.alpha_offset = 0; + this.alpha_length = 0; + } else if (version == 1) { + this.bpp = buf.getInt(); + this.size = buf.getInt(); + this.width = buf.getInt(); + this.height = buf.getInt(); + this.red_offset = buf.getInt(); + this.red_length = buf.getInt(); + this.blue_offset = buf.getInt(); + this.blue_length = buf.getInt(); + this.green_offset = buf.getInt(); + this.green_length = buf.getInt(); + this.alpha_offset = buf.getInt(); + this.alpha_length = buf.getInt(); + } else { + // unsupported protocol! + return false; + } + + return true; + } + + /** + * Returns the mask value for the red color. + * <p/>This value is compatible with org.eclipse.swt.graphics.PaletteData + */ + public int getRedMask() { + return getMask(red_length, red_offset); + } + + /** + * Returns the mask value for the green color. + * <p/>This value is compatible with org.eclipse.swt.graphics.PaletteData + */ + public int getGreenMask() { + return getMask(green_length, green_offset); + } + + /** + * Returns the mask value for the blue color. + * <p/>This value is compatible with org.eclipse.swt.graphics.PaletteData + */ + public int getBlueMask() { + return getMask(blue_length, blue_offset); + } + + /** + * Returns the size of the header for a specific version of the framebuffer adb protocol. + * @param version the version of the protocol + * @return the number of int that makes up the header. + */ + public static int getHeaderSize(int version) { + switch (version) { + case 16: // compatibility mode + return 3; // size, width, height + case 1: + return 12; // bpp, size, width, height, 4*(length, offset) + } + + return 0; + } + + /** + * creates a mask value based on a length and offset. + * <p/>This value is compatible with org.eclipse.swt.graphics.PaletteData + */ + private int getMask(int length, int offset) { + int res = 0; + for (int i = 0 ; i < length ; i++) { + res = (res << 1) + 1; + } + + res = res << offset; + + // if the bpp is 32 bits then we need to invert it because the buffer is in little endian + if (bpp == 32) { + return Integer.reverseBytes(res); + } + + return res; + } } |