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