diff options
7 files changed, 47 insertions, 28 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 395c867de9d7..a30dab9ac1f6 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -1787,17 +1787,17 @@ public class ActivityManager { private final float mScale; private final int mSystemUiVisibility; private final boolean mIsTranslucent; - - // TODO(b/116112787) TaskSnapshot must also book keep the color space from hardware bitmap - // when created. - private final ColorSpace mColorSpace = ColorSpace.get(ColorSpace.Named.SRGB); + // Must be one of the named color spaces, otherwise, always use SRGB color space. + private final ColorSpace mColorSpace; public TaskSnapshot(@NonNull ComponentName topActivityComponent, GraphicBuffer snapshot, - int orientation, Rect contentInsets, boolean reducedResolution, float scale, - boolean isRealSnapshot, int windowingMode, int systemUiVisibility, - boolean isTranslucent) { + @NonNull ColorSpace colorSpace, int orientation, Rect contentInsets, + boolean reducedResolution, float scale, boolean isRealSnapshot, int windowingMode, + int systemUiVisibility, boolean isTranslucent) { mTopActivityComponent = topActivityComponent; mSnapshot = snapshot; + mColorSpace = colorSpace.getId() < 0 + ? ColorSpace.get(ColorSpace.Named.SRGB) : colorSpace; mOrientation = orientation; mContentInsets = new Rect(contentInsets); mReducedResolution = reducedResolution; @@ -1811,6 +1811,10 @@ public class ActivityManager { private TaskSnapshot(Parcel source) { mTopActivityComponent = ComponentName.readFromParcel(source); mSnapshot = source.readParcelable(null /* classLoader */); + int colorSpaceId = source.readInt(); + mColorSpace = colorSpaceId >= 0 + ? ColorSpace.get(ColorSpace.Named.values()[colorSpaceId]) + : ColorSpace.get(ColorSpace.Named.SRGB); mOrientation = source.readInt(); mContentInsets = source.readParcelable(null /* classLoader */); mReducedResolution = source.readBoolean(); @@ -1917,6 +1921,7 @@ public class ActivityManager { public void writeToParcel(Parcel dest, int flags) { ComponentName.writeToParcel(mTopActivityComponent, dest); dest.writeParcelable(mSnapshot, 0); + dest.writeInt(mColorSpace.getId()); dest.writeInt(mOrientation); dest.writeParcelable(mContentInsets, 0); dest.writeBoolean(mReducedResolution); @@ -1934,6 +1939,7 @@ public class ActivityManager { return "TaskSnapshot{" + " mTopActivityComponent=" + mTopActivityComponent.flattenToShortString() + " mSnapshot=" + mSnapshot + " (" + width + "x" + height + ")" + + " mColorSpace=" + mColorSpace.toString() + " mOrientation=" + mOrientation + " mContentInsets=" + mContentInsets.toShortString() + " mReducedResolution=" + mReducedResolution + " mScale=" + mScale diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 79363edb0955..d34d19b60682 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -91,8 +91,8 @@ public final class SurfaceControl implements Parcelable { private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken, Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation, boolean captureSecureLayers); - private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder layerHandleToken, - Rect sourceCrop, float frameScale, IBinder[] excludeLayers); + private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder displayToken, + IBinder layerHandleToken, Rect sourceCrop, float frameScale, IBinder[] excludeLayers); private static native long nativeCreateTransaction(); private static native long nativeGetNativeTransactionFinalizer(); @@ -2001,7 +2001,8 @@ public final class SurfaceControl implements Parcelable { */ public static ScreenshotGraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop, float frameScale) { - return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale, null); + final IBinder displayToken = SurfaceControl.getInternalDisplayToken(); + return nativeCaptureLayers(displayToken, layerHandleToken, sourceCrop, frameScale, null); } /** @@ -2010,7 +2011,8 @@ public final class SurfaceControl implements Parcelable { */ public static ScreenshotGraphicBuffer captureLayersExcluding(IBinder layerHandleToken, Rect sourceCrop, float frameScale, IBinder[] exclude) { - return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale, exclude); + final IBinder displayToken = SurfaceControl.getInternalDisplayToken(); + return nativeCaptureLayers(displayToken, layerHandleToken, sourceCrop, frameScale, exclude); } /** diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 3135c62c9c61..c0b31e49960b 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -271,8 +271,9 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz, capturedSecureLayers); } -static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken, - jobject sourceCropObj, jfloat frameScale, jobjectArray excludeArray) { +static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTokenObj, + jobject layerHandleToken, jobject sourceCropObj, jfloat frameScale, + jobjectArray excludeArray) { sp<IBinder> layerHandle = ibinderForJavaObject(env, layerHandleToken); if (layerHandle == NULL) { @@ -301,7 +302,12 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandl } sp<GraphicBuffer> buffer; - const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB; + ui::Dataspace dataspace = ui::Dataspace::V0_SRGB; + sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); + if (displayToken != nullptr) { + const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken); + dataspace = pickDataspaceFromColorMode(colorMode); + } status_t res = ScreenshotClient::captureChildLayers(layerHandle, dataspace, ui::PixelFormat::RGBA_8888, sourceCrop, excludeHandles, frameScale, &buffer); @@ -1373,7 +1379,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;", (void*)nativeScreenshot }, {"nativeCaptureLayers", - "(Landroid/os/IBinder;Landroid/graphics/Rect;F[Landroid/os/IBinder;)" + "(Landroid/os/IBinder;Landroid/os/IBinder;Landroid/graphics/Rect;" + "F[Landroid/os/IBinder;)" "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;", (void*)nativeCaptureLayers }, {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V", diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index 6fe8b43db139..f559848c0499 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -292,9 +292,9 @@ class TaskSnapshotController { } final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE; return new TaskSnapshot(appWindowToken.mActivityComponent, buffer, - appWindowToken.getConfiguration().orientation, getInsets(mainWindow), - isLowRamDevice /* reduced */, scaleFraction /* scale */, true /* isRealSnapshot */, - task.getWindowingMode(), getSystemUiVisibility(task), + screenshotBuffer.getColorSpace(), appWindowToken.getConfiguration().orientation, + getInsets(mainWindow), isLowRamDevice /* reduced */, scaleFraction /* scale */, + true /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task), !appWindowToken.fillsParent() || isWindowTranslucent); } @@ -385,10 +385,10 @@ class TaskSnapshotController { // Note, the app theme snapshot is never translucent because we enforce a non-translucent // color above return new TaskSnapshot(topChild.mActivityComponent, hwBitmap.createGraphicBufferHandle(), - topChild.getConfiguration().orientation, mainWindow.getStableInsets(), - ActivityManager.isLowRamDeviceStatic() /* reduced */, 1.0f /* scale */, - false /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task), - false); + hwBitmap.getColorSpace(), topChild.getConfiguration().orientation, + mainWindow.getStableInsets(), ActivityManager.isLowRamDeviceStatic() /* reduced */, + 1.0f /* scale */, false /* isRealSnapshot */, task.getWindowingMode(), + getSystemUiVisibility(task), false); } /** diff --git a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java index d30843b9c589..f7b8945d9729 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java @@ -89,7 +89,8 @@ class TaskSnapshotLoader { } ComponentName topActivityComponent = ComponentName.unflattenFromString( proto.topActivityComponent); - return new TaskSnapshot(topActivityComponent, buffer, proto.orientation, + return new TaskSnapshot(topActivityComponent, buffer, bitmap.getColorSpace(), + proto.orientation, new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom), reducedResolution, reducedResolution ? mPersister.getReducedScale() : 1f, proto.isRealSnapshot, proto.windowingMode, proto.systemUiVisibility, diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java index d29e3fa6f546..c3b0a67e2ee1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java @@ -27,6 +27,7 @@ import android.app.ActivityManager.TaskSnapshot; import android.content.ComponentName; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.ColorSpace; import android.graphics.GraphicBuffer; import android.graphics.PixelFormat; import android.graphics.Rect; @@ -127,8 +128,9 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase { Canvas c = buffer.lockCanvas(); c.drawColor(Color.RED); buffer.unlockCanvasAndPost(c); - return new TaskSnapshot(new ComponentName("", ""), buffer, ORIENTATION_PORTRAIT, - TEST_INSETS, mScale < 1f /* reducedResolution */, mScale, mIsRealSnapshot, + return new TaskSnapshot(new ComponentName("", ""), buffer, + ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, TEST_INSETS, + mScale < 1f /* reducedResolution */, mScale, mIsRealSnapshot, mWindowingMode, mSystemUiVisibility, mIsTranslucent); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java index ca815eca9a1f..fc4545652a22 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java @@ -34,11 +34,11 @@ import android.app.ActivityManager.TaskSnapshot; import android.content.ComponentName; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.ColorSpace; import android.graphics.GraphicBuffer; import android.graphics.PixelFormat; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; -import android.view.Surface; import android.view.SurfaceControl; import androidx.test.filters.SmallTest; @@ -64,8 +64,9 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase { final GraphicBuffer buffer = GraphicBuffer.create(width, height, PixelFormat.RGBA_8888, GraphicBuffer.USAGE_SW_READ_RARELY | GraphicBuffer.USAGE_SW_WRITE_NEVER); final TaskSnapshot snapshot = new TaskSnapshot(new ComponentName("", ""), buffer, - ORIENTATION_PORTRAIT, contentInsets, false, 1.0f, true /* isRealSnapshot */, - WINDOWING_MODE_FULLSCREEN, 0 /* systemUiVisibility */, false /* isTranslucent */); + ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, contentInsets, false, + 1.0f, true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN, + 0 /* systemUiVisibility */, false /* isTranslucent */); mSurface = new TaskSnapshotSurface(mWm, new Window(), new SurfaceControl(), snapshot, "Test", Color.WHITE, Color.RED, Color.BLUE, sysuiVis, windowFlags, 0, taskBounds, ORIENTATION_PORTRAIT); |