Loading core/java/android/hardware/display/DisplayManagerInternal.java +20 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.view.SurfaceControl; import android.view.SurfaceControl.RefreshRateRange; import android.view.SurfaceControl.Transaction; import android.window.DisplayWindowPolicyController; import android.window.ScreenCapture; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -110,6 +111,25 @@ public abstract class DisplayManagerInternal { */ public abstract void unregisterDisplayGroupListener(DisplayGroupListener listener); /** * Screenshot for internal system-only use such as rotation, etc. This method includes * secure layers and the result should never be exposed to non-system applications. * This method does not apply any rotation and provides the output in natural orientation. * * @param displayId The display id to take the screenshot of. * @return The buffer or null if we have failed. */ public abstract ScreenCapture.ScreenshotHardwareBuffer systemScreenshot(int displayId); /** * General screenshot functionality that excludes secure layers and applies appropriate * rotation that the device is currently in. * * @param displayId The display id to take the screenshot of. * @return The buffer or null if we have failed. */ public abstract ScreenCapture.ScreenshotHardwareBuffer userScreenshot(int displayId); /** * Returns information about the specified logical display. * Loading services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +29 −34 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ import android.graphics.ParcelableColorSpace; import android.graphics.Region; import android.hardware.HardwareBuffer; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerInternal; import android.os.Binder; import android.os.Build; import android.os.Bundle; Loading Loading @@ -97,6 +98,7 @@ import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection; import com.android.internal.os.SomeArgs; import com.android.internal.util.DumpUtils; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection; import com.android.server.accessibility.magnification.MagnificationProcessor; import com.android.server.inputmethod.InputMethodManagerInternal; Loading Loading @@ -1439,24 +1441,19 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, callback); return; } final long identity = Binder.clearCallingIdentity(); try { ScreenCapture.ScreenCaptureListener screenCaptureListener = new ScreenCapture.ScreenCaptureListener( (screenshotBuffer, result) -> { if (screenshotBuffer != null && result == 0) { mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> { final ScreenshotHardwareBuffer screenshotBuffer = LocalServices .getService(DisplayManagerInternal.class).userScreenshot(displayId); if (screenshotBuffer != null) { sendScreenshotSuccess(screenshotBuffer, callback); } else { sendScreenshotFailure( AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, callback); } AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, callback); } ); mWindowManagerService.captureDisplay(displayId, null, screenCaptureListener); } catch (Exception e) { sendScreenshotFailure(AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, callback); }, null).recycleOnUse()); } finally { Binder.restoreCallingIdentity(identity); } Loading @@ -1464,7 +1461,6 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ private void sendScreenshotSuccess(ScreenshotHardwareBuffer screenshotBuffer, RemoteCallback callback) { mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> { final HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer(); final ParcelableColorSpace colorSpace = new ParcelableColorSpace(screenshotBuffer.getColorSpace()); Loading @@ -1481,7 +1477,6 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ // Send back the result. callback.sendResult(payload); hardwareBuffer.close(); }, null).recycleOnUse()); } private void sendScreenshotFailure(@AccessibilityService.ScreenshotErrorCode int errorCode, Loading services/core/java/com/android/server/display/ColorFade.java +2 −16 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ import android.window.ScreenCapture; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import com.android.server.policy.WindowManagerPolicy; import com.android.server.wm.WindowManagerInternal; import libcore.io.Streams; Loading Loading @@ -568,21 +567,8 @@ final class ColorFade { } private ScreenCapture.ScreenshotHardwareBuffer captureScreen() { WindowManagerInternal windowManagerService = LocalServices.getService( WindowManagerInternal.class); ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer; ScreenCapture.SynchronousScreenCaptureListener screenCaptureListener = ScreenCapture.createSyncCaptureListener(); ScreenCapture.CaptureArgs captureArgs = new ScreenCapture.CaptureArgs.Builder<>() .setCaptureSecureLayers(true) .setAllowProtected(true) .build(); try { windowManagerService.captureDisplay(mDisplayId, captureArgs, screenCaptureListener); screenshotBuffer = screenCaptureListener.getBuffer(); } catch (Exception e) { screenshotBuffer = null; } ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer = mDisplayManagerInternal.systemScreenshot(mDisplayId); if (screenshotBuffer == null) { Slog.e(TAG, "Failed to take screenshot. Buffer is null"); return null; Loading services/core/java/com/android/server/display/DisplayManagerService.java +47 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,7 @@ import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceControl.RefreshRateRange; import android.window.DisplayWindowPolicyController; import android.window.ScreenCapture; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -2673,6 +2674,42 @@ public final class DisplayManagerService extends SystemService { return null; } private ScreenCapture.ScreenshotHardwareBuffer systemScreenshotInternal(int displayId) { final ScreenCapture.DisplayCaptureArgs captureArgs; synchronized (mSyncRoot) { final IBinder token = getDisplayToken(displayId); if (token == null) { return null; } final LogicalDisplay logicalDisplay = mLogicalDisplayMapper.getDisplayLocked(displayId); if (logicalDisplay == null) { return null; } final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked(); captureArgs = new ScreenCapture.DisplayCaptureArgs.Builder(token) .setSize(displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight()) .setCaptureSecureLayers(true) .setAllowProtected(true) .build(); } return ScreenCapture.captureDisplay(captureArgs); } private ScreenCapture.ScreenshotHardwareBuffer userScreenshotInternal(int displayId) { synchronized (mSyncRoot) { final IBinder token = getDisplayToken(displayId); if (token == null) { return null; } final ScreenCapture.DisplayCaptureArgs captureArgs = new ScreenCapture.DisplayCaptureArgs.Builder(token) .build(); return ScreenCapture.captureDisplay(captureArgs); } } @VisibleForTesting DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributesInternal( int displayId) { Loading Loading @@ -4440,6 +4477,16 @@ public final class DisplayManagerService extends SystemService { mDisplayGroupListeners.remove(listener); } @Override public ScreenCapture.ScreenshotHardwareBuffer systemScreenshot(int displayId) { return systemScreenshotInternal(displayId); } @Override public ScreenCapture.ScreenshotHardwareBuffer userScreenshot(int displayId) { return userScreenshotInternal(displayId); } @Override public DisplayInfo getDisplayInfo(int displayId) { return getDisplayInfoInternal(displayId, Process.myUid()); Loading services/core/java/com/android/server/wm/ScreenRotationAnimation.java +27 −1 Original line number Diff line number Diff line Loading @@ -40,9 +40,11 @@ import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.os.IBinder; import android.os.Trace; import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.DisplayAddress; import android.view.DisplayInfo; import android.view.Surface; import android.view.Surface.OutOfResourcesException; Loading @@ -55,6 +57,7 @@ import android.window.ScreenCapture; import com.android.internal.R; import com.android.internal.policy.TransitionAnimation; import com.android.internal.protolog.common.ProtoLog; import com.android.server.display.DisplayControl; import com.android.server.wm.SurfaceAnimator.AnimationType; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; Loading Loading @@ -168,10 +171,32 @@ class ScreenRotationAnimation { try { final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer; if (isSizeChanged) { final DisplayAddress address = displayInfo.address; if (!(address instanceof DisplayAddress.Physical)) { Slog.e(TAG, "Display does not have a physical address: " + displayId); return; } final DisplayAddress.Physical physicalAddress = (DisplayAddress.Physical) address; final IBinder displayToken = DisplayControl.getPhysicalDisplayToken( physicalAddress.getPhysicalDisplayId()); if (displayToken == null) { Slog.e(TAG, "Display token is null."); return; } // Temporarily not skip screenshot for the rounded corner overlays and screenshot // the whole display to include the rounded corner overlays. setSkipScreenshotForRoundedCornerOverlays(false, t); } mRoundedCornerOverlay = displayContent.findRoundedCornerOverlays(); final ScreenCapture.DisplayCaptureArgs captureArgs = new ScreenCapture.DisplayCaptureArgs.Builder(displayToken) .setSourceCrop(new Rect(0, 0, width, height)) .setAllowProtected(true) .setCaptureSecureLayers(true) .setHintForSeamlessTransition(true) .build(); screenshotBuffer = ScreenCapture.captureDisplay(captureArgs); } else { ScreenCapture.LayerCaptureArgs captureArgs = new ScreenCapture.LayerCaptureArgs.Builder( displayContent.getSurfaceControl()) Loading @@ -181,6 +206,7 @@ class ScreenRotationAnimation { .setHintForSeamlessTransition(true) .build(); screenshotBuffer = ScreenCapture.captureLayers(captureArgs); } if (screenshotBuffer == null) { Slog.w(TAG, "Unable to take screenshot of display " + displayId); Loading Loading
core/java/android/hardware/display/DisplayManagerInternal.java +20 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.view.SurfaceControl; import android.view.SurfaceControl.RefreshRateRange; import android.view.SurfaceControl.Transaction; import android.window.DisplayWindowPolicyController; import android.window.ScreenCapture; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -110,6 +111,25 @@ public abstract class DisplayManagerInternal { */ public abstract void unregisterDisplayGroupListener(DisplayGroupListener listener); /** * Screenshot for internal system-only use such as rotation, etc. This method includes * secure layers and the result should never be exposed to non-system applications. * This method does not apply any rotation and provides the output in natural orientation. * * @param displayId The display id to take the screenshot of. * @return The buffer or null if we have failed. */ public abstract ScreenCapture.ScreenshotHardwareBuffer systemScreenshot(int displayId); /** * General screenshot functionality that excludes secure layers and applies appropriate * rotation that the device is currently in. * * @param displayId The display id to take the screenshot of. * @return The buffer or null if we have failed. */ public abstract ScreenCapture.ScreenshotHardwareBuffer userScreenshot(int displayId); /** * Returns information about the specified logical display. * Loading
services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +29 −34 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ import android.graphics.ParcelableColorSpace; import android.graphics.Region; import android.hardware.HardwareBuffer; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerInternal; import android.os.Binder; import android.os.Build; import android.os.Bundle; Loading Loading @@ -97,6 +98,7 @@ import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection; import com.android.internal.os.SomeArgs; import com.android.internal.util.DumpUtils; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection; import com.android.server.accessibility.magnification.MagnificationProcessor; import com.android.server.inputmethod.InputMethodManagerInternal; Loading Loading @@ -1439,24 +1441,19 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, callback); return; } final long identity = Binder.clearCallingIdentity(); try { ScreenCapture.ScreenCaptureListener screenCaptureListener = new ScreenCapture.ScreenCaptureListener( (screenshotBuffer, result) -> { if (screenshotBuffer != null && result == 0) { mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> { final ScreenshotHardwareBuffer screenshotBuffer = LocalServices .getService(DisplayManagerInternal.class).userScreenshot(displayId); if (screenshotBuffer != null) { sendScreenshotSuccess(screenshotBuffer, callback); } else { sendScreenshotFailure( AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, callback); } AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, callback); } ); mWindowManagerService.captureDisplay(displayId, null, screenCaptureListener); } catch (Exception e) { sendScreenshotFailure(AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, callback); }, null).recycleOnUse()); } finally { Binder.restoreCallingIdentity(identity); } Loading @@ -1464,7 +1461,6 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ private void sendScreenshotSuccess(ScreenshotHardwareBuffer screenshotBuffer, RemoteCallback callback) { mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> { final HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer(); final ParcelableColorSpace colorSpace = new ParcelableColorSpace(screenshotBuffer.getColorSpace()); Loading @@ -1481,7 +1477,6 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ // Send back the result. callback.sendResult(payload); hardwareBuffer.close(); }, null).recycleOnUse()); } private void sendScreenshotFailure(@AccessibilityService.ScreenshotErrorCode int errorCode, Loading
services/core/java/com/android/server/display/ColorFade.java +2 −16 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ import android.window.ScreenCapture; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import com.android.server.policy.WindowManagerPolicy; import com.android.server.wm.WindowManagerInternal; import libcore.io.Streams; Loading Loading @@ -568,21 +567,8 @@ final class ColorFade { } private ScreenCapture.ScreenshotHardwareBuffer captureScreen() { WindowManagerInternal windowManagerService = LocalServices.getService( WindowManagerInternal.class); ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer; ScreenCapture.SynchronousScreenCaptureListener screenCaptureListener = ScreenCapture.createSyncCaptureListener(); ScreenCapture.CaptureArgs captureArgs = new ScreenCapture.CaptureArgs.Builder<>() .setCaptureSecureLayers(true) .setAllowProtected(true) .build(); try { windowManagerService.captureDisplay(mDisplayId, captureArgs, screenCaptureListener); screenshotBuffer = screenCaptureListener.getBuffer(); } catch (Exception e) { screenshotBuffer = null; } ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer = mDisplayManagerInternal.systemScreenshot(mDisplayId); if (screenshotBuffer == null) { Slog.e(TAG, "Failed to take screenshot. Buffer is null"); return null; Loading
services/core/java/com/android/server/display/DisplayManagerService.java +47 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,7 @@ import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceControl.RefreshRateRange; import android.window.DisplayWindowPolicyController; import android.window.ScreenCapture; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -2673,6 +2674,42 @@ public final class DisplayManagerService extends SystemService { return null; } private ScreenCapture.ScreenshotHardwareBuffer systemScreenshotInternal(int displayId) { final ScreenCapture.DisplayCaptureArgs captureArgs; synchronized (mSyncRoot) { final IBinder token = getDisplayToken(displayId); if (token == null) { return null; } final LogicalDisplay logicalDisplay = mLogicalDisplayMapper.getDisplayLocked(displayId); if (logicalDisplay == null) { return null; } final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked(); captureArgs = new ScreenCapture.DisplayCaptureArgs.Builder(token) .setSize(displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight()) .setCaptureSecureLayers(true) .setAllowProtected(true) .build(); } return ScreenCapture.captureDisplay(captureArgs); } private ScreenCapture.ScreenshotHardwareBuffer userScreenshotInternal(int displayId) { synchronized (mSyncRoot) { final IBinder token = getDisplayToken(displayId); if (token == null) { return null; } final ScreenCapture.DisplayCaptureArgs captureArgs = new ScreenCapture.DisplayCaptureArgs.Builder(token) .build(); return ScreenCapture.captureDisplay(captureArgs); } } @VisibleForTesting DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributesInternal( int displayId) { Loading Loading @@ -4440,6 +4477,16 @@ public final class DisplayManagerService extends SystemService { mDisplayGroupListeners.remove(listener); } @Override public ScreenCapture.ScreenshotHardwareBuffer systemScreenshot(int displayId) { return systemScreenshotInternal(displayId); } @Override public ScreenCapture.ScreenshotHardwareBuffer userScreenshot(int displayId) { return userScreenshotInternal(displayId); } @Override public DisplayInfo getDisplayInfo(int displayId) { return getDisplayInfoInternal(displayId, Process.myUid()); Loading
services/core/java/com/android/server/wm/ScreenRotationAnimation.java +27 −1 Original line number Diff line number Diff line Loading @@ -40,9 +40,11 @@ import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.os.IBinder; import android.os.Trace; import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.DisplayAddress; import android.view.DisplayInfo; import android.view.Surface; import android.view.Surface.OutOfResourcesException; Loading @@ -55,6 +57,7 @@ import android.window.ScreenCapture; import com.android.internal.R; import com.android.internal.policy.TransitionAnimation; import com.android.internal.protolog.common.ProtoLog; import com.android.server.display.DisplayControl; import com.android.server.wm.SurfaceAnimator.AnimationType; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; Loading Loading @@ -168,10 +171,32 @@ class ScreenRotationAnimation { try { final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer; if (isSizeChanged) { final DisplayAddress address = displayInfo.address; if (!(address instanceof DisplayAddress.Physical)) { Slog.e(TAG, "Display does not have a physical address: " + displayId); return; } final DisplayAddress.Physical physicalAddress = (DisplayAddress.Physical) address; final IBinder displayToken = DisplayControl.getPhysicalDisplayToken( physicalAddress.getPhysicalDisplayId()); if (displayToken == null) { Slog.e(TAG, "Display token is null."); return; } // Temporarily not skip screenshot for the rounded corner overlays and screenshot // the whole display to include the rounded corner overlays. setSkipScreenshotForRoundedCornerOverlays(false, t); } mRoundedCornerOverlay = displayContent.findRoundedCornerOverlays(); final ScreenCapture.DisplayCaptureArgs captureArgs = new ScreenCapture.DisplayCaptureArgs.Builder(displayToken) .setSourceCrop(new Rect(0, 0, width, height)) .setAllowProtected(true) .setCaptureSecureLayers(true) .setHintForSeamlessTransition(true) .build(); screenshotBuffer = ScreenCapture.captureDisplay(captureArgs); } else { ScreenCapture.LayerCaptureArgs captureArgs = new ScreenCapture.LayerCaptureArgs.Builder( displayContent.getSurfaceControl()) Loading @@ -181,6 +206,7 @@ class ScreenRotationAnimation { .setHintForSeamlessTransition(true) .build(); screenshotBuffer = ScreenCapture.captureLayers(captureArgs); } if (screenshotBuffer == null) { Slog.w(TAG, "Unable to take screenshot of display " + displayId); Loading