private static native void nativeDestroy(long nativeObject);
private static native void nativeDisconnect(long nativeObject);
- private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken,
+ private static native GraphicBuffer nativeScreenshot(IBinder displayToken,
Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
boolean captureSecureLayers);
- private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
+ private static native GraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
Rect sourceCrop, float frameScale);
private static native long nativeCreateTransaction();
public static final int METADATA_TASK_ID = 3;
/**
- * A wrapper around GraphicBuffer that contains extra information about how to
- * interpret the screenshot GraphicBuffer.
- * @hide
- */
- public static class ScreenshotGraphicBuffer {
- private final GraphicBuffer mGraphicBuffer;
- private final ColorSpace mColorSpace;
-
- public ScreenshotGraphicBuffer(GraphicBuffer graphicBuffer, ColorSpace colorSpace) {
- mGraphicBuffer = graphicBuffer;
- mColorSpace = colorSpace;
- }
-
- /**
- * Create ScreenshotGraphicBuffer from existing native GraphicBuffer object.
- * @param width The width in pixels of the buffer
- * @param height The height in pixels of the buffer
- * @param format The format of each pixel as specified in {@link PixelFormat}
- * @param usage Hint indicating how the buffer will be used
- * @param unwrappedNativeObject The native object of GraphicBuffer
- * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named}
- */
- private static ScreenshotGraphicBuffer createFromNative(int width, int height, int format,
- int usage, long unwrappedNativeObject, int namedColorSpace) {
- GraphicBuffer graphicBuffer = GraphicBuffer.createFromExisting(width, height, format,
- usage, unwrappedNativeObject);
- ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
- return new ScreenshotGraphicBuffer(graphicBuffer, colorSpace);
- }
-
- public ColorSpace getColorSpace() {
- return mColorSpace;
- }
-
- public GraphicBuffer getGraphicBuffer() {
- return mGraphicBuffer;
- }
- }
-
- /**
* Builder class for {@link SurfaceControl} objects.
*/
public static class Builder {
throw new IllegalArgumentException("consumer must not be null");
}
- final ScreenshotGraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width,
- height, useIdentityTransform, rotation);
+ final GraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width, height,
+ useIdentityTransform, rotation);
try {
- consumer.attachAndQueueBuffer(buffer.getGraphicBuffer());
+ consumer.attachAndQueueBuffer(buffer);
} catch (RuntimeException e) {
Log.w(TAG, "Failed to take screenshot - " + e.getMessage());
}
}
SurfaceControl.rotateCropForSF(sourceCrop, rotation);
- final ScreenshotGraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width,
- height, useIdentityTransform, rotation);
+ final GraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width, height,
+ useIdentityTransform, rotation);
if (buffer == null) {
Log.w(TAG, "Failed to take screenshot");
return null;
}
- return Bitmap.wrapHardwareBuffer(
- HardwareBuffer.createFromGraphicBuffer(buffer.getGraphicBuffer()),
- buffer.getColorSpace());
+ // TODO(b/116112787) Now that hardware bitmap creation can take color space, we
+ // should continue to fix screenshot.
+ return Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(buffer),
+ ColorSpace.get(ColorSpace.Named.SRGB));
}
/**
* @return Returns a GraphicBuffer that contains the captured content.
* @hide
*/
- public static ScreenshotGraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop,
- int width, int height, boolean useIdentityTransform, int rotation) {
+ public static GraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop, int width,
+ int height, boolean useIdentityTransform, int rotation) {
if (display == null) {
throw new IllegalArgumentException("displayToken must not be null");
}
*
* @hide
*/
- public static ScreenshotGraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display,
+ public static GraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display,
Rect sourceCrop, int width, int height, boolean useIdentityTransform,
int rotation) {
if (display == null) {
* @return Returns a GraphicBuffer that contains the layer capture.
* @hide
*/
- public static ScreenshotGraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
+ public static GraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
float frameScale) {
return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale);
}
jfieldID white;
} gDisplayPrimariesClassInfo;
-static struct {
- jclass clazz;
- jmethodID builder;
-} gScreenshotGraphicBufferClassInfo;
-
-class JNamedColorSpace {
-public:
- // ColorSpace.Named.SRGB.ordinal() = 0;
- static constexpr jint SRGB = 0;
-
- // ColorSpace.Named.DISPLAY_P3.ordinal() = 6;
- static constexpr jint DISPLAY_P3 = 6;
-};
-
-constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace) {
- switch (dataspace) {
- case ui::Dataspace::DISPLAY_P3:
- return JNamedColorSpace::DISPLAY_P3;
- default:
- return JNamedColorSpace::SRGB;
- }
-}
-
-constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
- switch (colorMode) {
- case ui::ColorMode::DISPLAY_P3:
- case ui::ColorMode::BT2100_PQ:
- case ui::ColorMode::BT2100_HLG:
- case ui::ColorMode::DISPLAY_BT2020:
- return ui::Dataspace::DISPLAY_P3;
- default:
- return ui::Dataspace::V0_SRGB;
- }
-}
-
// ----------------------------------------------------------------------------
static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
if (displayToken == NULL) {
return NULL;
}
- const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
- const ui::Dataspace dataspace = pickDataspaceFromColorMode(colorMode);
-
Rect sourceCrop = rectFromObj(env, sourceCropObj);
sp<GraphicBuffer> buffer;
- status_t res = ScreenshotClient::capture(displayToken, dataspace,
+ status_t res = ScreenshotClient::capture(displayToken, ui::Dataspace::V0_SRGB,
ui::PixelFormat::RGBA_8888,
sourceCrop, width, height,
useIdentityTransform, rotation, captureSecureLayers, &buffer);
return NULL;
}
- const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
- return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz,
- gScreenshotGraphicBufferClassInfo.builder,
+ return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
+ gGraphicBufferClassInfo.builder,
buffer->getWidth(),
buffer->getHeight(),
buffer->getPixelFormat(),
(jint)buffer->getUsage(),
- (jlong)buffer.get(),
- namedColorSpace);
+ (jlong)buffer.get());
}
static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
}
sp<GraphicBuffer> buffer;
- const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
- status_t res = ScreenshotClient::captureChildLayers(layerHandle, dataspace,
+ status_t res = ScreenshotClient::captureChildLayers(layerHandle, ui::Dataspace::V0_SRGB,
ui::PixelFormat::RGBA_8888, sourceCrop,
frameScale, &buffer);
if (res != NO_ERROR) {
return NULL;
}
- const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
- return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz,
- gScreenshotGraphicBufferClassInfo.builder,
+ return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
+ gGraphicBufferClassInfo.builder,
buffer->getWidth(),
buffer->getHeight(),
buffer->getPixelFormat(),
(jint)buffer->getUsage(),
- (jlong)buffer.get(),
- namedColorSpace);
+ (jlong)buffer.get());
}
static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
(void*)nativeSetOverrideScalingMode },
{"nativeGetHandle", "(J)Landroid/os/IBinder;",
(void*)nativeGetHandle },
- {"nativeScreenshot",
- "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)"
- "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
+ {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)Landroid/graphics/GraphicBuffer;",
(void*)nativeScreenshot },
- {"nativeCaptureLayers",
- "(Landroid/os/IBinder;Landroid/graphics/Rect;F)"
- "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
+ {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/graphics/Rect;F)Landroid/graphics/GraphicBuffer;",
(void*)nativeCaptureLayers },
{"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
(void*)nativeSetInputWindowInfo },
gGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, graphicsBufferClazz,
"createFromExisting", "(IIIIJ)Landroid/graphics/GraphicBuffer;");
- jclass screenshotGraphicsBufferClazz = FindClassOrDie(env,
- "android/view/SurfaceControl$ScreenshotGraphicBuffer");
- gScreenshotGraphicBufferClassInfo.clazz =
- MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
- gScreenshotGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env,
- screenshotGraphicsBufferClazz,
- "createFromNative", "(IIIIJI)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;");
-
jclass displayedContentSampleClazz = FindClassOrDie(env,
"android/hardware/display/DisplayedContentSample");
gDisplayedContentSampleClassInfo.clazz = MakeGlobalRefOrDie(env, displayedContentSampleClazz);
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.ColorSpace;
+import android.graphics.GraphicBuffer;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.SensorManager;
if (token == null) {
return false;
}
- final SurfaceControl.ScreenshotGraphicBuffer gb =
- SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
- token, new Rect(), 0 /* width */, 0 /* height */,
- false /* useIdentityTransform */, 0 /* rotation */);
+ final GraphicBuffer gb = SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
+ token, new Rect(), 0 /* width */, 0 /* height */, false /* useIdentityTransform */,
+ 0 /* rotation */);
try {
- outSurface.attachAndQueueBuffer(gb.getGraphicBuffer());
+ outSurface.attachAndQueueBuffer(gb);
} catch (RuntimeException e) {
Slog.w(TAG, "Failed to take screenshot - " + e.getMessage());
}
Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + task);
return null;
}
- final SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer =
- SurfaceControl.captureLayers(
- task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction);
- final GraphicBuffer buffer = screenshotBuffer != null ? screenshotBuffer.getGraphicBuffer()
- : null;
+ final GraphicBuffer buffer = SurfaceControl.captureLayers(
+ task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction);
if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
if (DEBUG_SCREENSHOT) {
Slog.w(TAG_WM, "Failed to take screenshot for " + task);
import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDING_TIMEOUT;
import android.graphics.Bitmap;
+import android.graphics.ColorSpace;
+import android.graphics.GraphicBuffer;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.os.Bundle;
final Rect bounds = wallpaperWindowState.getBounds();
bounds.offsetTo(0, 0);
- SurfaceControl.ScreenshotGraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
+ GraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
wallpaperWindowState.getSurfaceControl().getHandle(), bounds, 1 /* frameScale */);
if (wallpaperBuffer == null) {
Slog.w(TAG_WM, "Failed to screenshot wallpaper");
return null;
}
- return Bitmap.wrapHardwareBuffer(
- HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer.getGraphicBuffer()),
- wallpaperBuffer.getColorSpace());
+ // TODO(b/116112787) Now that hardware bitmap creation can take color space, we
+ // should continue to fix screenshot.
+ return Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer),
+ ColorSpace.get(ColorSpace.Named.SRGB));
}
private WindowState getTopVisibleWallpaper() {