aboutsummaryrefslogtreecommitdiffstats
path: root/ddms/libs
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2009-09-15 20:09:08 -0700
committerXavier Ducrohet <xav@android.com>2009-09-16 16:30:50 -0700
commit4eaf2b3df2a3cdfd0ef21a51fad10ca5f584b7f1 (patch)
tree7a92b2755b1e4502a29785c946e1148b42941806 /ddms/libs
parentce9a326490f6f56c4e5d28ac4ce174d0168df0a9 (diff)
downloadsdk-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')
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java29
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/RawImage.java123
-rw-r--r--ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java20
3 files changed, 158 insertions, 14 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;
+ }
}
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java
index b0200fa..778c594 100644
--- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java
@@ -165,7 +165,8 @@ public class ScreenShotDialog extends Dialog {
Image image = getDeviceImage();
if (image == null) {
Display display = shell.getDisplay();
- image = ImageHelper.createPlaceHolderArt(display, 320, 240, display.getSystemColor(SWT.COLOR_BLUE));
+ image = ImageHelper.createPlaceHolderArt(
+ display, 320, 240, display.getSystemColor(SWT.COLOR_BLUE));
mSave.setEnabled(false);
mBusyLabel.setText("Screen not available");
} else {
@@ -199,15 +200,22 @@ public class ScreenShotDialog extends Dialog {
if (rawImage == null)
return null;
- // convert raw data to an Image
- assert rawImage.bpp == 16;
- PaletteData palette = new PaletteData(0xf800, 0x07e0, 0x001f);
+ // convert raw data to an Image.
+ PaletteData palette = new PaletteData(
+ rawImage.getRedMask(),
+ rawImage.getGreenMask(),
+ rawImage.getBlueMask());
ImageData imageData = new ImageData(rawImage.width, rawImage.height,
- rawImage.bpp, palette, 1, rawImage.data);
+ rawImage.bpp, palette, 1, rawImage.data);
- return new Image(getParent().getDisplay(), imageData);
+ if (imageData != null) {
+ return new Image(getParent().getDisplay(), imageData);
+ }
+
+ return null;
}
+
/*
* Prompt the user to save the image to disk.
*/