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:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
if (imageData != null) {
|
||||
return new Image(getParent().getDisplay(), imageData);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prompt the user to save the image to disk.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user