summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/screencap/screencap.cpp2
-rw-r--r--core/java/android/view/SurfaceControl.java36
-rw-r--r--core/jni/android_view_SurfaceControl.cpp26
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java6
4 files changed, 47 insertions, 23 deletions
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index a57de01..2efe4d3 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -141,7 +141,7 @@ int main(int argc, char** argv)
ScreenshotClient screenshot;
sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
- if (display != NULL && screenshot.update(display) == NO_ERROR) {
+ if (display != NULL && screenshot.update(display, false) == NO_ERROR) {
base = screenshot.getPixels();
w = screenshot.getWidth();
h = screenshot.getHeight();
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 97a1f21..5a8d2c8 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -39,9 +39,11 @@ public class SurfaceControl {
private static native void nativeDestroy(long nativeObject);
private static native Bitmap nativeScreenshot(IBinder displayToken,
- int width, int height, int minLayer, int maxLayer, boolean allLayers);
+ int width, int height, int minLayer, int maxLayer, boolean allLayers,
+ boolean useIdentityTransform);
private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
- int width, int height, int minLayer, int maxLayer, boolean allLayers);
+ int width, int height, int minLayer, int maxLayer, boolean allLayers,
+ boolean useIdentityTransform);
private static native void nativeOpenTransaction();
private static native void nativeCloseTransaction();
@@ -554,10 +556,15 @@ public class SurfaceControl {
* include in the screenshot.
* @param maxLayer The highest (top-most Z order) surface layer to
* include in the screenshot.
+ * @param useIdentityTransform Replace whatever transformation (rotation,
+ * scaling, translation) the surface layers are currently using with the
+ * identity transformation while taking the screenshot.
*/
public static void screenshot(IBinder display, Surface consumer,
- int width, int height, int minLayer, int maxLayer) {
- screenshot(display, consumer, width, height, minLayer, maxLayer, false);
+ int width, int height, int minLayer, int maxLayer,
+ boolean useIdentityTransform) {
+ screenshot(display, consumer, width, height, minLayer, maxLayer, false,
+ useIdentityTransform);
}
/**
@@ -572,7 +579,7 @@ public class SurfaceControl {
*/
public static void screenshot(IBinder display, Surface consumer,
int width, int height) {
- screenshot(display, consumer, width, height, 0, 0, true);
+ screenshot(display, consumer, width, height, 0, 0, true, false);
}
/**
@@ -582,7 +589,7 @@ public class SurfaceControl {
* @param consumer The {@link Surface} to take the screenshot into.
*/
public static void screenshot(IBinder display, Surface consumer) {
- screenshot(display, consumer, 0, 0, 0, 0, true);
+ screenshot(display, consumer, 0, 0, 0, 0, true, false);
}
@@ -602,15 +609,20 @@ public class SurfaceControl {
* include in the screenshot.
* @param maxLayer The highest (top-most Z order) surface layer to
* include in the screenshot.
+ * @param useIdentityTransform Replace whatever transformation (rotation,
+ * scaling, translation) the surface layers are currently using with the
+ * identity transformation while taking the screenshot.
* @return Returns a Bitmap containing the screen contents, or null
* if an error occurs. Make sure to call Bitmap.recycle() as soon as
* possible, once its content is not needed anymore.
*/
- public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer) {
+ public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer,
+ boolean useIdentityTransform) {
// TODO: should take the display as a parameter
IBinder displayToken = SurfaceControl.getBuiltInDisplay(
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
- return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false);
+ return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false,
+ useIdentityTransform);
}
/**
@@ -629,17 +641,19 @@ public class SurfaceControl {
// TODO: should take the display as a parameter
IBinder displayToken = SurfaceControl.getBuiltInDisplay(
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
- return nativeScreenshot(displayToken, width, height, 0, 0, true);
+ return nativeScreenshot(displayToken, width, height, 0, 0, true, false);
}
private static void screenshot(IBinder display, Surface consumer,
- int width, int height, int minLayer, int maxLayer, boolean allLayers) {
+ int width, int height, int minLayer, int maxLayer, boolean allLayers,
+ boolean useIdentityTransform) {
if (display == null) {
throw new IllegalArgumentException("displayToken must not be null");
}
if (consumer == null) {
throw new IllegalArgumentException("consumer must not be null");
}
- nativeScreenshot(display, consumer, width, height, minLayer, maxLayer, allLayers);
+ nativeScreenshot(display, consumer, width, height, minLayer, maxLayer, allLayers,
+ useIdentityTransform);
}
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 88ec0d7..480d0ac 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -72,12 +72,15 @@ public:
}
status_t update(const sp<IBinder>& display, int width, int height,
- int minLayer, int maxLayer, bool allLayers) {
+ int minLayer, int maxLayer, bool allLayers,
+ bool useIdentityTransform) {
status_t res = (width > 0 && height > 0)
? (allLayers
- ? mScreenshot.update(display, width, height)
- : mScreenshot.update(display, width, height, minLayer, maxLayer))
- : mScreenshot.update(display);
+ ? mScreenshot.update(display, width, height,
+ useIdentityTransform)
+ : mScreenshot.update(display, width, height,
+ minLayer, maxLayer, useIdentityTransform))
+ : mScreenshot.update(display, useIdentityTransform);
if (res != NO_ERROR) {
return res;
}
@@ -162,7 +165,8 @@ static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
}
static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj,
- jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) {
+ jint width, jint height, jint minLayer, jint maxLayer, bool allLayers,
+ bool useIdentityTransform) {
sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
if (displayToken == NULL) {
return NULL;
@@ -170,7 +174,7 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject display
ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL);
if (pixels->update(displayToken, width, height,
- minLayer, maxLayer, allLayers) != NO_ERROR) {
+ minLayer, maxLayer, allLayers, useIdentityTransform) != NO_ERROR) {
delete pixels;
return NULL;
}
@@ -202,7 +206,8 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject display
static void nativeScreenshot(JNIEnv* env, jclass clazz,
jobject displayTokenObj, jobject surfaceObj,
- jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) {
+ jint width, jint height, jint minLayer, jint maxLayer, bool allLayers,
+ bool useIdentityTransform) {
sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
if (displayToken != NULL) {
sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj);
@@ -213,7 +218,8 @@ static void nativeScreenshot(JNIEnv* env, jclass clazz,
}
ScreenshotClient::capture(
displayToken, consumer->getIGraphicBufferProducer(),
- width, height, uint32_t(minLayer), uint32_t(maxLayer));
+ width, height, uint32_t(minLayer), uint32_t(maxLayer),
+ useIdentityTransform);
}
}
}
@@ -417,9 +423,9 @@ static JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeRelease },
{"nativeDestroy", "(J)V",
(void*)nativeDestroy },
- {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZ)Landroid/graphics/Bitmap;",
+ {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZZ)Landroid/graphics/Bitmap;",
(void*)nativeScreenshotBitmap },
- {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;IIIIZ)V",
+ {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;IIIIZZ)V",
(void*)nativeScreenshot },
{"nativeOpenTransaction", "()V",
(void*)nativeOpenTransaction },
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8f07e27..e664050 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5757,7 +5757,11 @@ public class WindowManagerService extends IWindowManager.Stub
+ " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
}
}
- rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer);
+ // TODO: Replace 'false' in the following line with a variable that indicates
+ // whether the screenshot should use the identity transformation matrix
+ // (e.g., enable it when taking a screenshot for recents, since we might be in
+ // the middle of the rotation animation, but don't want a rotated recent image).
+ rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer, false);
}
} while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES);
if (retryCount > MAX_SCREENSHOT_RETRIES) Slog.i(TAG, "Screenshot max retries " +