am 8399a2bf: Merge change 25229 into eclair

Merge commit '8399a2bf6d415dc20788167b70b98e24b285466d' into eclair-plus-aosp

* commit '8399a2bf6d415dc20788167b70b98e24b285466d':
  Add support for new framebuffer protocol over adb.
This commit is contained in:
Xavier Ducrohet
2009-09-17 08:43:26 -07:00
committed by Android Git Automerger
3 changed files with 158 additions and 14 deletions

View File

@@ -286,7 +286,8 @@ final class AdbHelper {
return null; return null;
} }
reply = new byte[16]; // first the protocol version.
reply = new byte[4];
if (read(adbChan, reply) == false) { if (read(adbChan, reply) == false) {
Log.w("ddms", "got partial reply from ADB fb:"); Log.w("ddms", "got partial reply from ADB fb:");
Log.hexDump("ddms", LogLevel.WARN, reply, 0, reply.length); Log.hexDump("ddms", LogLevel.WARN, reply, 0, reply.length);
@@ -296,10 +297,27 @@ final class AdbHelper {
ByteBuffer buf = ByteBuffer.wrap(reply); ByteBuffer buf = ByteBuffer.wrap(reply);
buf.order(ByteOrder.LITTLE_ENDIAN); buf.order(ByteOrder.LITTLE_ENDIAN);
imageParams.bpp = buf.getInt(); int version = buf.getInt();
imageParams.size = buf.getInt();
imageParams.width = buf.getInt(); // get the header size (this is a count of int)
imageParams.height = buf.getInt(); 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=" Log.d("ddms", "image params: bpp=" + imageParams.bpp + ", size="
+ imageParams.size + ", width=" + imageParams.width + imageParams.size + ", width=" + imageParams.width
@@ -314,6 +332,7 @@ final class AdbHelper {
adbChan.close(); adbChan.close();
return null; return null;
} }
imageParams.data = reply; imageParams.data = reply;
} finally { } finally {
if (adbChan != null) { if (adbChan != null) {

View File

@@ -16,17 +16,134 @@
package com.android.ddmlib; package com.android.ddmlib;
import java.nio.ByteBuffer;
/** /**
* Data representing an image taken from a device frame buffer. * Data representing an image taken from a device frame buffer.
*/ */
public final class RawImage { public final class RawImage {
/** public int version;
* bit-per-pixel value.
*/
public int bpp; public int bpp;
public int size; public int size;
public int width; public int width;
public int height; 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; 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;
}
} }

View File

@@ -165,7 +165,8 @@ public class ScreenShotDialog extends Dialog {
Image image = getDeviceImage(); Image image = getDeviceImage();
if (image == null) { if (image == null) {
Display display = shell.getDisplay(); 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); mSave.setEnabled(false);
mBusyLabel.setText("Screen not available"); mBusyLabel.setText("Screen not available");
} else { } else {
@@ -199,15 +200,22 @@ public class ScreenShotDialog extends Dialog {
if (rawImage == null) if (rawImage == null)
return null; return null;
// convert raw data to an Image // convert raw data to an Image.
assert rawImage.bpp == 16; PaletteData palette = new PaletteData(
PaletteData palette = new PaletteData(0xf800, 0x07e0, 0x001f); rawImage.getRedMask(),
rawImage.getGreenMask(),
rawImage.getBlueMask());
ImageData imageData = new ImageData(rawImage.width, rawImage.height, 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. * Prompt the user to save the image to disk.
*/ */