Loading core/java/android/view/SurfaceControl.java +14 −0 Original line number Diff line number Diff line Loading @@ -653,12 +653,14 @@ public final class SurfaceControl implements Parcelable { private final Rect mSourceCrop = new Rect(); private final float mFrameScale; private final boolean mCaptureSecureLayers; private final boolean mAllowProtected; private CaptureArgs(Builder<? extends Builder<?>> builder) { mPixelFormat = builder.mPixelFormat; mSourceCrop.set(builder.mSourceCrop); mFrameScale = builder.mFrameScale; mCaptureSecureLayers = builder.mCaptureSecureLayers; mAllowProtected = builder.mAllowProtected; } /** Loading @@ -671,6 +673,7 @@ public final class SurfaceControl implements Parcelable { private final Rect mSourceCrop = new Rect(); private float mFrameScale = 1; private boolean mCaptureSecureLayers; private boolean mAllowProtected; /** * The desired pixel format of the returned buffer. Loading Loading @@ -708,6 +711,17 @@ public final class SurfaceControl implements Parcelable { return getThis(); } /** * Whether to allow the screenshot of protected (DRM) content. Warning: The screenshot * cannot be read in unprotected space. * * @see HardwareBuffer#USAGE_PROTECTED_CONTENT */ public T setAllowProtected(boolean allowProtected) { mAllowProtected = allowProtected; return getThis(); } /** * Each sub class should return itself to allow the builder to chain properly */ Loading core/jni/android_view_SurfaceControl.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ static struct { jfieldID sourceCrop; jfieldID frameScale; jfieldID captureSecureLayers; jfieldID allowProtected; } gCaptureArgsClassInfo; static struct { Loading Loading @@ -368,6 +369,8 @@ static void getCaptureArgs(JNIEnv* env, jobject captureArgsObject, CaptureArgs& env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScale); captureArgs.captureSecureLayers = env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.captureSecureLayers); captureArgs.allowProtected = env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.allowProtected); } static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env, Loading Loading @@ -1890,6 +1893,8 @@ int register_android_view_SurfaceControl(JNIEnv* env) gCaptureArgsClassInfo.frameScale = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScale", "F"); gCaptureArgsClassInfo.captureSecureLayers = GetFieldIDOrDie(env, captureArgsClazz, "mCaptureSecureLayers", "Z"); gCaptureArgsClassInfo.allowProtected = GetFieldIDOrDie(env, captureArgsClazz, "mAllowProtected", "Z"); jclass displayCaptureArgsClazz = FindClassOrDie(env, "android/view/SurfaceControl$DisplayCaptureArgs"); Loading services/core/java/com/android/server/display/ColorFade.java +109 −66 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.display; import static com.android.server.wm.utils.RotationAnimationUtils.hasProtectedContent; import android.content.Context; import android.graphics.SurfaceTexture; import android.hardware.display.DisplayManagerInternal; Loading @@ -35,7 +37,6 @@ import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import android.view.SurfaceSession; import com.android.server.LocalServices; import com.android.server.policy.WindowManagerPolicy; Loading Loading @@ -75,6 +76,7 @@ final class ColorFade { private static final int EGL_GL_COLORSPACE_KHR = 0x309D; private static final int EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT = 0x3490; private static final int EGL_PROTECTED_CONTENT_EXT = 0x32C0; private final int mDisplayId; Loading @@ -87,7 +89,6 @@ final class ColorFade { private int mDisplayLayerStack; // layer stack associated with primary display private int mDisplayWidth; // real width, not rotated private int mDisplayHeight; // real height, not rotated private SurfaceSession mSurfaceSession; private SurfaceControl mSurfaceControl; private Surface mSurface; private NaturalSurfaceLayout mSurfaceLayout; Loading @@ -97,7 +98,8 @@ final class ColorFade { private EGLSurface mEglSurface; private boolean mSurfaceVisible; private float mSurfaceAlpha; private boolean mIsWideColor; private boolean mLastWasWideColor; private boolean mLastWasProtectedContent; // Texture names. We only use one texture, which contains the screenshot. private final int[] mTexNames = new int[1]; Loading Loading @@ -157,9 +159,28 @@ final class ColorFade { mDisplayWidth = displayInfo.getNaturalWidth(); mDisplayHeight = displayInfo.getNaturalHeight(); // Prepare the surface for drawing. if (!(createSurface() && createEglContext() && createEglSurface() && captureScreenshotTextureAndSetViewport())) { final IBinder token = SurfaceControl.getInternalDisplayToken(); if (token == null) { Slog.e(TAG, "Failed to take screenshot because internal display is disconnected"); return false; } boolean isWideColor = SurfaceControl.getActiveColorMode(token) == Display.COLOR_MODE_DISPLAY_P3; // Set mPrepared here so if initialization fails, resources can be cleaned up. mPrepared = true; SurfaceControl.ScreenshotHardwareBuffer hardwareBuffer = captureScreen(); if (hardwareBuffer == null) { dismiss(); return false; } boolean isProtected = hasProtectedContent(hardwareBuffer.getHardwareBuffer()); if (!(createSurfaceControl(hardwareBuffer.containsSecureLayers()) && createEglContext(isProtected) && createEglSurface(isProtected, isWideColor) && setScreenshotTextureAndSetViewport(hardwareBuffer))) { dismiss(); return false; } Loading @@ -180,7 +201,8 @@ final class ColorFade { // Done. mCreatedResources = true; mPrepared = true; mLastWasProtectedContent = isProtected; mLastWasWideColor = isWideColor; // Dejanking optimization. // Some GL drivers can introduce a lot of lag in the first few frames as they Loading Loading @@ -466,7 +488,8 @@ final class ColorFade { mProjMatrix[15] = 1f; } private boolean captureScreenshotTextureAndSetViewport() { private boolean setScreenshotTextureAndSetViewport( SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer) { if (!attachEglContext()) { return false; } Loading @@ -482,27 +505,9 @@ final class ColorFade { final SurfaceTexture st = new SurfaceTexture(mTexNames[0]); final Surface s = new Surface(st); try { final IBinder token = SurfaceControl.getInternalDisplayToken(); if (token == null) { Slog.e(TAG, "Failed to take screenshot because internal display is disconnected"); return false; } mIsWideColor = SurfaceControl.getActiveColorMode(token) == Display.COLOR_MODE_DISPLAY_P3; SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = mDisplayManagerInternal.systemScreenshot(mDisplayId); if (screenshotBuffer == null) { Slog.e(TAG, "Failed to take screenshot. Buffer is null"); return false; } s.attachAndQueueBufferWithColorSpace(screenshotBuffer.getHardwareBuffer(), screenshotBuffer.getColorSpace()); if (screenshotBuffer.containsSecureLayers()) { mTransaction.setSecure(mSurfaceControl, true).apply(); } st.updateTexImage(); st.getTransformMatrix(mTexMatrix); } finally { Loading Loading @@ -535,7 +540,52 @@ final class ColorFade { } } private boolean createEglContext() { private SurfaceControl.ScreenshotHardwareBuffer captureScreen() { SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = mDisplayManagerInternal.systemScreenshot(mDisplayId); if (screenshotBuffer == null) { Slog.e(TAG, "Failed to take screenshot. Buffer is null"); return null; } return screenshotBuffer; } private boolean createSurfaceControl(boolean isSecure) { if (mSurfaceControl != null) { mTransaction.setSecure(mSurfaceControl, isSecure).apply(); return true; } try { final SurfaceControl.Builder builder = new SurfaceControl.Builder() .setName("ColorFade") .setSecure(isSecure) .setCallsite("ColorFade.createSurface"); if (mMode == MODE_FADE) { builder.setColorLayer(); } else { builder.setBufferSize(mDisplayWidth, mDisplayHeight); } mSurfaceControl = builder.build(); } catch (OutOfResourcesException ex) { Slog.e(TAG, "Unable to create surface.", ex); return false; } mTransaction.setLayerStack(mSurfaceControl, mDisplayLayerStack); mTransaction.setWindowCrop(mSurfaceControl, mDisplayWidth, mDisplayHeight); mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal, mDisplayId, mSurfaceControl); mSurfaceLayout.onDisplayTransaction(mTransaction); mTransaction.apply(); mSurface = new Surface(); mSurface.copyFrom(mSurfaceControl); return true; } private boolean createEglContext(boolean isProtected) { if (mEglDisplay == null) { mEglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); if (mEglDisplay == EGL14.EGL_NO_DISPLAY) { Loading Loading @@ -576,13 +626,25 @@ final class ColorFade { mEglConfig = eglConfigs[0]; } // The old context needs to be destroyed if the protected flag has changed. The context will // be recreated based on the protected flag if (mEglContext != null && isProtected != mLastWasProtectedContent) { EGL14.eglDestroyContext(mEglDisplay, mEglContext); mEglContext = null; } if (mEglContext == null) { int[] eglContextAttribList = new int[] { EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE, EGL14.EGL_NONE, EGL14.EGL_NONE }; mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig, EGL14.EGL_NO_CONTEXT, eglContextAttribList, 0); if (isProtected) { eglContextAttribList[2] = EGL_PROTECTED_CONTENT_EXT; eglContextAttribList[3] = EGL14.EGL_TRUE; } mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig, EGL14.EGL_NO_CONTEXT, eglContextAttribList, 0); if (mEglContext == null) { logEglError("eglCreateContext"); return false; Loading @@ -591,53 +653,34 @@ final class ColorFade { return true; } private boolean createSurface() { if (mSurfaceSession == null) { mSurfaceSession = new SurfaceSession(); } if (mSurfaceControl == null) { try { final SurfaceControl.Builder builder = new SurfaceControl.Builder(mSurfaceSession) .setName("ColorFade") .setCallsite("ColorFade.createSurface"); if (mMode == MODE_FADE) { builder.setColorLayer(); } else { builder.setBufferSize(mDisplayWidth, mDisplayHeight); } mSurfaceControl = builder.build(); } catch (OutOfResourcesException ex) { Slog.e(TAG, "Unable to create surface.", ex); return false; } mTransaction.setLayerStack(mSurfaceControl, mDisplayLayerStack); mTransaction.setWindowCrop(mSurfaceControl, mDisplayWidth, mDisplayHeight); mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal, mDisplayId, mSurfaceControl); mSurfaceLayout.onDisplayTransaction(mTransaction); mTransaction.apply(); mSurface = new Surface(); mSurface.copyFrom(mSurfaceControl); } return true; private boolean createEglSurface(boolean isProtected, boolean isWideColor) { // The old surface needs to be destroyed if either the protected flag or wide color flag has // changed. The surface will be recreated based on the new flags. boolean didContentAttributesChange = isProtected != mLastWasProtectedContent || isWideColor != mLastWasWideColor; if (mEglSurface != null && didContentAttributesChange) { EGL14.eglDestroySurface(mEglDisplay, mEglSurface); mEglSurface = null; } private boolean createEglSurface() { if (mEglSurface == null) { int[] eglSurfaceAttribList = new int[] { EGL14.EGL_NONE, EGL14.EGL_NONE, EGL14.EGL_NONE, EGL14.EGL_NONE, EGL14.EGL_NONE }; int index = 0; // If the current display is in wide color, then so is the screenshot. if (mIsWideColor) { eglSurfaceAttribList[0] = EGL_GL_COLORSPACE_KHR; eglSurfaceAttribList[1] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT; if (isWideColor) { eglSurfaceAttribList[index++] = EGL_GL_COLORSPACE_KHR; eglSurfaceAttribList[index++] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT; } if (isProtected) { eglSurfaceAttribList[index++] = EGL_PROTECTED_CONTENT_EXT; eglSurfaceAttribList[index] = EGL14.EGL_TRUE; } // turn our SurfaceControl into a Surface mEglSurface = EGL14.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, Loading services/core/java/com/android/server/display/DisplayManagerService.java +1 −0 Original line number Diff line number Diff line Loading @@ -1293,6 +1293,7 @@ public final class DisplayManagerService extends SystemService { .setSize(displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight()) .setUseIdentityTransform(true) .setCaptureSecureLayers(true) .setAllowProtected(true) .build(); return SurfaceControl.captureDisplay(captureArgs); } Loading services/core/java/com/android/server/wm/ScreenRotationAnimation.java +39 −35 Original line number Diff line number Diff line Loading @@ -181,9 +181,25 @@ class ScreenRotationAnimation { mSurfaceRotationAnimationController = new SurfaceRotationAnimationController(); // Check whether the current screen contains any secure content. final boolean isSecure = displayContent.hasSecureWindowOnScreen(); boolean isSecure = displayContent.hasSecureWindowOnScreen(); final int displayId = displayContent.getDisplayId(); final SurfaceControl.Transaction t = mService.mTransactionFactory.get(); try { SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = mService.mDisplayManagerInternal.systemScreenshot(displayId); if (screenshotBuffer == null) { Slog.w(TAG, "Unable to take screenshot of display " + displayId); return; } // If the screenshot contains secure layers, we have to make sure the // screenshot surface we display it in also has FLAG_SECURE so that // the user can not screenshot secure layers via the screenshot surface. if (screenshotBuffer.containsSecureLayers()) { isSecure = true; } mBackColorSurface = displayContent.makeChildSurface(null) .setName("BackColorSurface") .setColorLayer() Loading @@ -203,17 +219,12 @@ class ScreenRotationAnimation { .setCallsite("ScreenRotationAnimation") .build(); // Capture a screenshot into the surface we just created. final int displayId = displayContent.getDisplayId(); final Surface surface = mService.mSurfaceFactory.get(); // In case display bounds change, screenshot buffer and surface may mismatch so set a // scaling mode. // In case display bounds change, screenshot buffer and surface may mismatch so // set a scaling mode. surface.copyFrom(mScreenshotLayer); surface.setScalingMode(Surface.SCALING_MODE_SCALE_TO_WINDOW); SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = mService.mDisplayManagerInternal.systemScreenshot(displayId); if (screenshotBuffer != null) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "ScreenRotationAnimation#getMedianBorderLuma"); mStartLuma = RotationAnimationUtils.getMedianBorderLuma( Loading @@ -225,12 +236,7 @@ class ScreenRotationAnimation { } catch (RuntimeException e) { Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage()); } // If the screenshot contains secure layers, we have to make sure the // screenshot surface we display it in also has FLAG_SECURE so that // the user can not screenshot secure layers via the screenshot surface. if (screenshotBuffer.containsSecureLayers()) { t.setSecure(mScreenshotLayer, true); } t.setLayer(mScreenshotLayer, SCREEN_FREEZE_LAYER_BASE); t.reparent(mBackColorSurface, displayContent.getSurfaceControl()); t.setLayer(mBackColorSurface, -1); Loading @@ -238,10 +244,8 @@ class ScreenRotationAnimation { t.setAlpha(mBackColorSurface, 1); t.show(mScreenshotLayer); t.show(mBackColorSurface); } else { Slog.w(TAG, "Unable to take screenshot of display " + displayId); } surface.destroy(); } catch (OutOfResourcesException e) { Slog.w(TAG, "Unable to allocate freeze surface", e); } Loading Loading
core/java/android/view/SurfaceControl.java +14 −0 Original line number Diff line number Diff line Loading @@ -653,12 +653,14 @@ public final class SurfaceControl implements Parcelable { private final Rect mSourceCrop = new Rect(); private final float mFrameScale; private final boolean mCaptureSecureLayers; private final boolean mAllowProtected; private CaptureArgs(Builder<? extends Builder<?>> builder) { mPixelFormat = builder.mPixelFormat; mSourceCrop.set(builder.mSourceCrop); mFrameScale = builder.mFrameScale; mCaptureSecureLayers = builder.mCaptureSecureLayers; mAllowProtected = builder.mAllowProtected; } /** Loading @@ -671,6 +673,7 @@ public final class SurfaceControl implements Parcelable { private final Rect mSourceCrop = new Rect(); private float mFrameScale = 1; private boolean mCaptureSecureLayers; private boolean mAllowProtected; /** * The desired pixel format of the returned buffer. Loading Loading @@ -708,6 +711,17 @@ public final class SurfaceControl implements Parcelable { return getThis(); } /** * Whether to allow the screenshot of protected (DRM) content. Warning: The screenshot * cannot be read in unprotected space. * * @see HardwareBuffer#USAGE_PROTECTED_CONTENT */ public T setAllowProtected(boolean allowProtected) { mAllowProtected = allowProtected; return getThis(); } /** * Each sub class should return itself to allow the builder to chain properly */ Loading
core/jni/android_view_SurfaceControl.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ static struct { jfieldID sourceCrop; jfieldID frameScale; jfieldID captureSecureLayers; jfieldID allowProtected; } gCaptureArgsClassInfo; static struct { Loading Loading @@ -368,6 +369,8 @@ static void getCaptureArgs(JNIEnv* env, jobject captureArgsObject, CaptureArgs& env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScale); captureArgs.captureSecureLayers = env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.captureSecureLayers); captureArgs.allowProtected = env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.allowProtected); } static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env, Loading Loading @@ -1890,6 +1893,8 @@ int register_android_view_SurfaceControl(JNIEnv* env) gCaptureArgsClassInfo.frameScale = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScale", "F"); gCaptureArgsClassInfo.captureSecureLayers = GetFieldIDOrDie(env, captureArgsClazz, "mCaptureSecureLayers", "Z"); gCaptureArgsClassInfo.allowProtected = GetFieldIDOrDie(env, captureArgsClazz, "mAllowProtected", "Z"); jclass displayCaptureArgsClazz = FindClassOrDie(env, "android/view/SurfaceControl$DisplayCaptureArgs"); Loading
services/core/java/com/android/server/display/ColorFade.java +109 −66 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.display; import static com.android.server.wm.utils.RotationAnimationUtils.hasProtectedContent; import android.content.Context; import android.graphics.SurfaceTexture; import android.hardware.display.DisplayManagerInternal; Loading @@ -35,7 +37,6 @@ import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import android.view.SurfaceSession; import com.android.server.LocalServices; import com.android.server.policy.WindowManagerPolicy; Loading Loading @@ -75,6 +76,7 @@ final class ColorFade { private static final int EGL_GL_COLORSPACE_KHR = 0x309D; private static final int EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT = 0x3490; private static final int EGL_PROTECTED_CONTENT_EXT = 0x32C0; private final int mDisplayId; Loading @@ -87,7 +89,6 @@ final class ColorFade { private int mDisplayLayerStack; // layer stack associated with primary display private int mDisplayWidth; // real width, not rotated private int mDisplayHeight; // real height, not rotated private SurfaceSession mSurfaceSession; private SurfaceControl mSurfaceControl; private Surface mSurface; private NaturalSurfaceLayout mSurfaceLayout; Loading @@ -97,7 +98,8 @@ final class ColorFade { private EGLSurface mEglSurface; private boolean mSurfaceVisible; private float mSurfaceAlpha; private boolean mIsWideColor; private boolean mLastWasWideColor; private boolean mLastWasProtectedContent; // Texture names. We only use one texture, which contains the screenshot. private final int[] mTexNames = new int[1]; Loading Loading @@ -157,9 +159,28 @@ final class ColorFade { mDisplayWidth = displayInfo.getNaturalWidth(); mDisplayHeight = displayInfo.getNaturalHeight(); // Prepare the surface for drawing. if (!(createSurface() && createEglContext() && createEglSurface() && captureScreenshotTextureAndSetViewport())) { final IBinder token = SurfaceControl.getInternalDisplayToken(); if (token == null) { Slog.e(TAG, "Failed to take screenshot because internal display is disconnected"); return false; } boolean isWideColor = SurfaceControl.getActiveColorMode(token) == Display.COLOR_MODE_DISPLAY_P3; // Set mPrepared here so if initialization fails, resources can be cleaned up. mPrepared = true; SurfaceControl.ScreenshotHardwareBuffer hardwareBuffer = captureScreen(); if (hardwareBuffer == null) { dismiss(); return false; } boolean isProtected = hasProtectedContent(hardwareBuffer.getHardwareBuffer()); if (!(createSurfaceControl(hardwareBuffer.containsSecureLayers()) && createEglContext(isProtected) && createEglSurface(isProtected, isWideColor) && setScreenshotTextureAndSetViewport(hardwareBuffer))) { dismiss(); return false; } Loading @@ -180,7 +201,8 @@ final class ColorFade { // Done. mCreatedResources = true; mPrepared = true; mLastWasProtectedContent = isProtected; mLastWasWideColor = isWideColor; // Dejanking optimization. // Some GL drivers can introduce a lot of lag in the first few frames as they Loading Loading @@ -466,7 +488,8 @@ final class ColorFade { mProjMatrix[15] = 1f; } private boolean captureScreenshotTextureAndSetViewport() { private boolean setScreenshotTextureAndSetViewport( SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer) { if (!attachEglContext()) { return false; } Loading @@ -482,27 +505,9 @@ final class ColorFade { final SurfaceTexture st = new SurfaceTexture(mTexNames[0]); final Surface s = new Surface(st); try { final IBinder token = SurfaceControl.getInternalDisplayToken(); if (token == null) { Slog.e(TAG, "Failed to take screenshot because internal display is disconnected"); return false; } mIsWideColor = SurfaceControl.getActiveColorMode(token) == Display.COLOR_MODE_DISPLAY_P3; SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = mDisplayManagerInternal.systemScreenshot(mDisplayId); if (screenshotBuffer == null) { Slog.e(TAG, "Failed to take screenshot. Buffer is null"); return false; } s.attachAndQueueBufferWithColorSpace(screenshotBuffer.getHardwareBuffer(), screenshotBuffer.getColorSpace()); if (screenshotBuffer.containsSecureLayers()) { mTransaction.setSecure(mSurfaceControl, true).apply(); } st.updateTexImage(); st.getTransformMatrix(mTexMatrix); } finally { Loading Loading @@ -535,7 +540,52 @@ final class ColorFade { } } private boolean createEglContext() { private SurfaceControl.ScreenshotHardwareBuffer captureScreen() { SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = mDisplayManagerInternal.systemScreenshot(mDisplayId); if (screenshotBuffer == null) { Slog.e(TAG, "Failed to take screenshot. Buffer is null"); return null; } return screenshotBuffer; } private boolean createSurfaceControl(boolean isSecure) { if (mSurfaceControl != null) { mTransaction.setSecure(mSurfaceControl, isSecure).apply(); return true; } try { final SurfaceControl.Builder builder = new SurfaceControl.Builder() .setName("ColorFade") .setSecure(isSecure) .setCallsite("ColorFade.createSurface"); if (mMode == MODE_FADE) { builder.setColorLayer(); } else { builder.setBufferSize(mDisplayWidth, mDisplayHeight); } mSurfaceControl = builder.build(); } catch (OutOfResourcesException ex) { Slog.e(TAG, "Unable to create surface.", ex); return false; } mTransaction.setLayerStack(mSurfaceControl, mDisplayLayerStack); mTransaction.setWindowCrop(mSurfaceControl, mDisplayWidth, mDisplayHeight); mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal, mDisplayId, mSurfaceControl); mSurfaceLayout.onDisplayTransaction(mTransaction); mTransaction.apply(); mSurface = new Surface(); mSurface.copyFrom(mSurfaceControl); return true; } private boolean createEglContext(boolean isProtected) { if (mEglDisplay == null) { mEglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); if (mEglDisplay == EGL14.EGL_NO_DISPLAY) { Loading Loading @@ -576,13 +626,25 @@ final class ColorFade { mEglConfig = eglConfigs[0]; } // The old context needs to be destroyed if the protected flag has changed. The context will // be recreated based on the protected flag if (mEglContext != null && isProtected != mLastWasProtectedContent) { EGL14.eglDestroyContext(mEglDisplay, mEglContext); mEglContext = null; } if (mEglContext == null) { int[] eglContextAttribList = new int[] { EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE, EGL14.EGL_NONE, EGL14.EGL_NONE }; mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig, EGL14.EGL_NO_CONTEXT, eglContextAttribList, 0); if (isProtected) { eglContextAttribList[2] = EGL_PROTECTED_CONTENT_EXT; eglContextAttribList[3] = EGL14.EGL_TRUE; } mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig, EGL14.EGL_NO_CONTEXT, eglContextAttribList, 0); if (mEglContext == null) { logEglError("eglCreateContext"); return false; Loading @@ -591,53 +653,34 @@ final class ColorFade { return true; } private boolean createSurface() { if (mSurfaceSession == null) { mSurfaceSession = new SurfaceSession(); } if (mSurfaceControl == null) { try { final SurfaceControl.Builder builder = new SurfaceControl.Builder(mSurfaceSession) .setName("ColorFade") .setCallsite("ColorFade.createSurface"); if (mMode == MODE_FADE) { builder.setColorLayer(); } else { builder.setBufferSize(mDisplayWidth, mDisplayHeight); } mSurfaceControl = builder.build(); } catch (OutOfResourcesException ex) { Slog.e(TAG, "Unable to create surface.", ex); return false; } mTransaction.setLayerStack(mSurfaceControl, mDisplayLayerStack); mTransaction.setWindowCrop(mSurfaceControl, mDisplayWidth, mDisplayHeight); mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal, mDisplayId, mSurfaceControl); mSurfaceLayout.onDisplayTransaction(mTransaction); mTransaction.apply(); mSurface = new Surface(); mSurface.copyFrom(mSurfaceControl); } return true; private boolean createEglSurface(boolean isProtected, boolean isWideColor) { // The old surface needs to be destroyed if either the protected flag or wide color flag has // changed. The surface will be recreated based on the new flags. boolean didContentAttributesChange = isProtected != mLastWasProtectedContent || isWideColor != mLastWasWideColor; if (mEglSurface != null && didContentAttributesChange) { EGL14.eglDestroySurface(mEglDisplay, mEglSurface); mEglSurface = null; } private boolean createEglSurface() { if (mEglSurface == null) { int[] eglSurfaceAttribList = new int[] { EGL14.EGL_NONE, EGL14.EGL_NONE, EGL14.EGL_NONE, EGL14.EGL_NONE, EGL14.EGL_NONE }; int index = 0; // If the current display is in wide color, then so is the screenshot. if (mIsWideColor) { eglSurfaceAttribList[0] = EGL_GL_COLORSPACE_KHR; eglSurfaceAttribList[1] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT; if (isWideColor) { eglSurfaceAttribList[index++] = EGL_GL_COLORSPACE_KHR; eglSurfaceAttribList[index++] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT; } if (isProtected) { eglSurfaceAttribList[index++] = EGL_PROTECTED_CONTENT_EXT; eglSurfaceAttribList[index] = EGL14.EGL_TRUE; } // turn our SurfaceControl into a Surface mEglSurface = EGL14.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, Loading
services/core/java/com/android/server/display/DisplayManagerService.java +1 −0 Original line number Diff line number Diff line Loading @@ -1293,6 +1293,7 @@ public final class DisplayManagerService extends SystemService { .setSize(displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight()) .setUseIdentityTransform(true) .setCaptureSecureLayers(true) .setAllowProtected(true) .build(); return SurfaceControl.captureDisplay(captureArgs); } Loading
services/core/java/com/android/server/wm/ScreenRotationAnimation.java +39 −35 Original line number Diff line number Diff line Loading @@ -181,9 +181,25 @@ class ScreenRotationAnimation { mSurfaceRotationAnimationController = new SurfaceRotationAnimationController(); // Check whether the current screen contains any secure content. final boolean isSecure = displayContent.hasSecureWindowOnScreen(); boolean isSecure = displayContent.hasSecureWindowOnScreen(); final int displayId = displayContent.getDisplayId(); final SurfaceControl.Transaction t = mService.mTransactionFactory.get(); try { SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = mService.mDisplayManagerInternal.systemScreenshot(displayId); if (screenshotBuffer == null) { Slog.w(TAG, "Unable to take screenshot of display " + displayId); return; } // If the screenshot contains secure layers, we have to make sure the // screenshot surface we display it in also has FLAG_SECURE so that // the user can not screenshot secure layers via the screenshot surface. if (screenshotBuffer.containsSecureLayers()) { isSecure = true; } mBackColorSurface = displayContent.makeChildSurface(null) .setName("BackColorSurface") .setColorLayer() Loading @@ -203,17 +219,12 @@ class ScreenRotationAnimation { .setCallsite("ScreenRotationAnimation") .build(); // Capture a screenshot into the surface we just created. final int displayId = displayContent.getDisplayId(); final Surface surface = mService.mSurfaceFactory.get(); // In case display bounds change, screenshot buffer and surface may mismatch so set a // scaling mode. // In case display bounds change, screenshot buffer and surface may mismatch so // set a scaling mode. surface.copyFrom(mScreenshotLayer); surface.setScalingMode(Surface.SCALING_MODE_SCALE_TO_WINDOW); SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = mService.mDisplayManagerInternal.systemScreenshot(displayId); if (screenshotBuffer != null) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "ScreenRotationAnimation#getMedianBorderLuma"); mStartLuma = RotationAnimationUtils.getMedianBorderLuma( Loading @@ -225,12 +236,7 @@ class ScreenRotationAnimation { } catch (RuntimeException e) { Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage()); } // If the screenshot contains secure layers, we have to make sure the // screenshot surface we display it in also has FLAG_SECURE so that // the user can not screenshot secure layers via the screenshot surface. if (screenshotBuffer.containsSecureLayers()) { t.setSecure(mScreenshotLayer, true); } t.setLayer(mScreenshotLayer, SCREEN_FREEZE_LAYER_BASE); t.reparent(mBackColorSurface, displayContent.getSurfaceControl()); t.setLayer(mBackColorSurface, -1); Loading @@ -238,10 +244,8 @@ class ScreenRotationAnimation { t.setAlpha(mBackColorSurface, 1); t.show(mScreenshotLayer); t.show(mBackColorSurface); } else { Slog.w(TAG, "Unable to take screenshot of display " + displayId); } surface.destroy(); } catch (OutOfResourcesException e) { Slog.w(TAG, "Unable to allocate freeze surface", e); } Loading