Use BLAST layer for snapshot starting windows
Test: Snapshot starting window uses blast and works Bug: 170765639 Change-Id: Iab1e5cf200e02509d3ab72cb3f04e788e1c1aa38
This commit is contained in:
@@ -38,6 +38,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
|
||||
|
||||
import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES;
|
||||
@@ -52,8 +53,10 @@ import android.app.ActivityThread;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.GraphicBuffer;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
@@ -68,7 +71,6 @@ import android.view.IWindowSession;
|
||||
import android.view.InputChannel;
|
||||
import android.view.InsetsSourceControl;
|
||||
import android.view.InsetsState;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceSession;
|
||||
import android.view.View;
|
||||
@@ -122,11 +124,9 @@ public class TaskSnapshotWindow {
|
||||
private static final Point TMP_SURFACE_SIZE = new Point();
|
||||
|
||||
private final Window mWindow;
|
||||
private final Surface mSurface;
|
||||
private final Runnable mClearWindowHandler;
|
||||
private final ShellExecutor mSplashScreenExecutor;
|
||||
private SurfaceControl mSurfaceControl;
|
||||
private SurfaceControl mChildSurfaceControl;
|
||||
private final SurfaceControl mSurfaceControl;
|
||||
private final IWindowSession mSession;
|
||||
private final Rect mTaskBounds;
|
||||
private final Rect mFrame = new Rect();
|
||||
@@ -179,7 +179,7 @@ public class TaskSnapshotWindow {
|
||||
// Setting as trusted overlay to let touches pass through. This is safe because this
|
||||
// window is controlled by the system.
|
||||
layoutParams.privateFlags = (windowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS)
|
||||
| PRIVATE_FLAG_TRUSTED_OVERLAY;
|
||||
| PRIVATE_FLAG_TRUSTED_OVERLAY | PRIVATE_FLAG_USE_BLAST;
|
||||
layoutParams.token = appToken;
|
||||
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
@@ -259,7 +259,6 @@ public class TaskSnapshotWindow {
|
||||
int currentOrientation, int activityType, InsetsState topWindowInsetsState,
|
||||
Runnable clearWindowHandler, ShellExecutor splashScreenExecutor) {
|
||||
mSplashScreenExecutor = splashScreenExecutor;
|
||||
mSurface = new Surface();
|
||||
mSession = WindowManagerGlobal.getWindowSession();
|
||||
mWindow = new Window();
|
||||
mWindow.setSession(mSession);
|
||||
@@ -336,7 +335,6 @@ public class TaskSnapshotWindow {
|
||||
}
|
||||
|
||||
private void drawSnapshot() {
|
||||
mSurface.copyFrom(mSurfaceControl);
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Drawing snapshot surface sizeMismatch= " + mSizeMismatch);
|
||||
}
|
||||
@@ -357,15 +355,14 @@ public class TaskSnapshotWindow {
|
||||
}
|
||||
|
||||
private void drawSizeMatchSnapshot() {
|
||||
mSurface.attachAndQueueBufferWithColorSpace(mSnapshot.getHardwareBuffer(),
|
||||
mSnapshot.getColorSpace());
|
||||
mSurface.release();
|
||||
GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(
|
||||
mSnapshot.getHardwareBuffer());
|
||||
mTransaction.setBuffer(mSurfaceControl, graphicBuffer)
|
||||
.setColorSpace(mSurfaceControl, mSnapshot.getColorSpace())
|
||||
.apply();
|
||||
}
|
||||
|
||||
private void drawSizeMismatchSnapshot() {
|
||||
if (!mSurface.isValid()) {
|
||||
throw new IllegalStateException("mSurface does not hold a valid surface.");
|
||||
}
|
||||
final HardwareBuffer buffer = mSnapshot.getHardwareBuffer();
|
||||
final SurfaceSession session = new SurfaceSession();
|
||||
|
||||
@@ -376,26 +373,24 @@ public class TaskSnapshotWindow {
|
||||
- ((float) mFrame.width() / mFrame.height())) > 0.01f;
|
||||
|
||||
// Keep a reference to it such that it doesn't get destroyed when finalized.
|
||||
mChildSurfaceControl = new SurfaceControl.Builder(session)
|
||||
SurfaceControl childSurfaceControl = new SurfaceControl.Builder(session)
|
||||
.setName(mTitle + " - task-snapshot-surface")
|
||||
.setBufferSize(buffer.getWidth(), buffer.getHeight())
|
||||
.setBLASTLayer()
|
||||
.setFormat(buffer.getFormat())
|
||||
.setParent(mSurfaceControl)
|
||||
.setCallsite("TaskSnapshotWindow.drawSizeMismatchSnapshot")
|
||||
.build();
|
||||
Surface surface = new Surface();
|
||||
surface.copyFrom(mChildSurfaceControl);
|
||||
|
||||
final Rect frame;
|
||||
// We can just show the surface here as it will still be hidden as the parent is
|
||||
// still hidden.
|
||||
mTransaction.show(mChildSurfaceControl);
|
||||
mTransaction.show(childSurfaceControl);
|
||||
if (aspectRatioMismatch) {
|
||||
// Clip off ugly navigation bar.
|
||||
final Rect crop = calculateSnapshotCrop();
|
||||
frame = calculateSnapshotFrame(crop);
|
||||
mTransaction.setWindowCrop(mChildSurfaceControl, crop);
|
||||
mTransaction.setPosition(mChildSurfaceControl, frame.left, frame.top);
|
||||
mTransaction.setWindowCrop(childSurfaceControl, crop);
|
||||
mTransaction.setPosition(childSurfaceControl, frame.left, frame.top);
|
||||
mTmpSnapshotSize.set(crop);
|
||||
mTmpDstFrame.set(frame);
|
||||
} else {
|
||||
@@ -407,18 +402,23 @@ public class TaskSnapshotWindow {
|
||||
|
||||
// Scale the mismatch dimensions to fill the task bounds
|
||||
mSnapshotMatrix.setRectToRect(mTmpSnapshotSize, mTmpDstFrame, Matrix.ScaleToFit.FILL);
|
||||
mTransaction.setMatrix(mChildSurfaceControl, mSnapshotMatrix, mTmpFloat9);
|
||||
|
||||
mTransaction.apply();
|
||||
surface.attachAndQueueBufferWithColorSpace(buffer, mSnapshot.getColorSpace());
|
||||
surface.release();
|
||||
mTransaction.setMatrix(childSurfaceControl, mSnapshotMatrix, mTmpFloat9);
|
||||
GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(
|
||||
mSnapshot.getHardwareBuffer());
|
||||
mTransaction.setColorSpace(childSurfaceControl, mSnapshot.getColorSpace());
|
||||
mTransaction.setBuffer(childSurfaceControl, graphicBuffer);
|
||||
|
||||
if (aspectRatioMismatch) {
|
||||
final Canvas c = mSurface.lockCanvas(null);
|
||||
GraphicBuffer background = GraphicBuffer.create(mFrame.width(), mFrame.height(),
|
||||
PixelFormat.RGBA_8888,
|
||||
GraphicBuffer.USAGE_HW_TEXTURE | GraphicBuffer.USAGE_HW_COMPOSER
|
||||
| GraphicBuffer.USAGE_SW_WRITE_RARELY);
|
||||
final Canvas c = background.lockCanvas();
|
||||
drawBackgroundAndBars(c, frame);
|
||||
mSurface.unlockCanvasAndPost(c);
|
||||
mSurface.release();
|
||||
background.unlockCanvasAndPost(c);
|
||||
mTransaction.setBuffer(mSurfaceControl, background);
|
||||
}
|
||||
mTransaction.apply();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,6 +37,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
|
||||
|
||||
import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES;
|
||||
@@ -53,8 +54,10 @@ import android.app.ActivityThread;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.GraphicBuffer;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
@@ -69,7 +72,6 @@ import android.util.Slog;
|
||||
import android.view.IWindowSession;
|
||||
import android.view.InsetsSourceControl;
|
||||
import android.view.InsetsState;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceSession;
|
||||
import android.view.View;
|
||||
@@ -124,9 +126,7 @@ class TaskSnapshotSurface implements StartingSurface {
|
||||
private static final Point sTmpSurfaceSize = new Point();
|
||||
|
||||
private final Window mWindow;
|
||||
private final Surface mSurface;
|
||||
private SurfaceControl mSurfaceControl;
|
||||
private SurfaceControl mChildSurfaceControl;
|
||||
private final SurfaceControl mSurfaceControl;
|
||||
private final IWindowSession mSession;
|
||||
private final WindowManagerService mService;
|
||||
private final int mDisplayId;
|
||||
@@ -200,7 +200,7 @@ class TaskSnapshotSurface implements StartingSurface {
|
||||
// Setting as trusted overlay to let touches pass through. This is safe because this
|
||||
// window is controlled by the system.
|
||||
layoutParams.privateFlags = (windowPrivateFlags & PRIVATE_FLAG_INHERITS)
|
||||
| PRIVATE_FLAG_TRUSTED_OVERLAY;
|
||||
| PRIVATE_FLAG_TRUSTED_OVERLAY | PRIVATE_FLAG_USE_BLAST;
|
||||
layoutParams.token = activity.token;
|
||||
layoutParams.width = LayoutParams.MATCH_PARENT;
|
||||
layoutParams.height = LayoutParams.MATCH_PARENT;
|
||||
@@ -262,7 +262,6 @@ class TaskSnapshotSurface implements StartingSurface {
|
||||
InsetsState insetsState) {
|
||||
mService = service;
|
||||
mDisplayId = displayId;
|
||||
mSurface = service.mSurfaceFactory.get();
|
||||
mHandler = new Handler(mService.mH.getLooper());
|
||||
mSession = WindowManagerGlobal.getWindowSession();
|
||||
mWindow = window;
|
||||
@@ -314,8 +313,6 @@ class TaskSnapshotSurface implements StartingSurface {
|
||||
}
|
||||
|
||||
private void drawSnapshot() {
|
||||
mSurface.copyFrom(mSurfaceControl);
|
||||
|
||||
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Drawing snapshot surface sizeMismatch=%b",
|
||||
mSizeMismatch);
|
||||
if (mSizeMismatch) {
|
||||
@@ -337,15 +334,14 @@ class TaskSnapshotSurface implements StartingSurface {
|
||||
}
|
||||
|
||||
private void drawSizeMatchSnapshot() {
|
||||
mSurface.attachAndQueueBufferWithColorSpace(mSnapshot.getHardwareBuffer(),
|
||||
mSnapshot.getColorSpace());
|
||||
mSurface.release();
|
||||
GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(
|
||||
mSnapshot.getHardwareBuffer());
|
||||
mTransaction.setBuffer(mSurfaceControl, graphicBuffer)
|
||||
.setColorSpace(mSurfaceControl, mSnapshot.getColorSpace())
|
||||
.apply();
|
||||
}
|
||||
|
||||
private void drawSizeMismatchSnapshot() {
|
||||
if (!mSurface.isValid()) {
|
||||
throw new IllegalStateException("mSurface does not hold a valid surface.");
|
||||
}
|
||||
final HardwareBuffer buffer = mSnapshot.getHardwareBuffer();
|
||||
final SurfaceSession session = new SurfaceSession();
|
||||
// We consider nearly matched dimensions as there can be rounding errors and the user won't
|
||||
@@ -356,26 +352,24 @@ class TaskSnapshotSurface implements StartingSurface {
|
||||
|
||||
// Keep a reference to it such that it doesn't get destroyed when finalized.
|
||||
final String name = mTitle + " - task-snapshot-surface";
|
||||
mChildSurfaceControl = mService.mSurfaceControlFactory.apply(session)
|
||||
SurfaceControl childSurfaceControl = mService.mSurfaceControlFactory.apply(session)
|
||||
.setName(name)
|
||||
.setBufferSize(buffer.getWidth(), buffer.getHeight())
|
||||
.setBLASTLayer()
|
||||
.setFormat(buffer.getFormat())
|
||||
.setParent(mSurfaceControl)
|
||||
.setCallsite("TaskSnapshotSurface.drawSizeMismatchSnapshot")
|
||||
.build();
|
||||
Surface surface = mService.mSurfaceFactory.get();
|
||||
surface.copyFrom(mChildSurfaceControl);
|
||||
|
||||
final Rect frame;
|
||||
// We can just show the surface here as it will still be hidden as the parent is
|
||||
// still hidden.
|
||||
mTransaction.show(mChildSurfaceControl);
|
||||
mTransaction.show(childSurfaceControl);
|
||||
if (aspectRatioMismatch) {
|
||||
// Clip off ugly navigation bar.
|
||||
final Rect crop = calculateSnapshotCrop();
|
||||
frame = calculateSnapshotFrame(crop);
|
||||
mTransaction.setWindowCrop(mChildSurfaceControl, crop);
|
||||
mTransaction.setPosition(mChildSurfaceControl, frame.left, frame.top);
|
||||
mTransaction.setWindowCrop(childSurfaceControl, crop);
|
||||
mTransaction.setPosition(childSurfaceControl, frame.left, frame.top);
|
||||
mTmpSnapshotSize.set(crop);
|
||||
mTmpDstFrame.set(frame);
|
||||
} else {
|
||||
@@ -387,23 +381,29 @@ class TaskSnapshotSurface implements StartingSurface {
|
||||
|
||||
// Scale the mismatch dimensions to fill the task bounds
|
||||
mSnapshotMatrix.setRectToRect(mTmpSnapshotSize, mTmpDstFrame, Matrix.ScaleToFit.FILL);
|
||||
mTransaction.setMatrix(mChildSurfaceControl, mSnapshotMatrix, mTmpFloat9);
|
||||
mTransaction.setMatrix(childSurfaceControl, mSnapshotMatrix, mTmpFloat9);
|
||||
|
||||
GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(
|
||||
mSnapshot.getHardwareBuffer());
|
||||
mTransaction.setColorSpace(childSurfaceControl, mSnapshot.getColorSpace());
|
||||
mTransaction.setBuffer(childSurfaceControl, graphicBuffer);
|
||||
// This is the way to tell the input system to exclude this surface from occlusion
|
||||
// detection since we don't have a window for it. We do this because this window is
|
||||
// generated by the system as well as its content (the snapshot of the app).
|
||||
InputMonitor.setTrustedOverlayInputInfo(mChildSurfaceControl, mTransaction, mDisplayId,
|
||||
InputMonitor.setTrustedOverlayInputInfo(childSurfaceControl, mTransaction, mDisplayId,
|
||||
name);
|
||||
mTransaction.apply();
|
||||
surface.attachAndQueueBufferWithColorSpace(buffer, mSnapshot.getColorSpace());
|
||||
surface.release();
|
||||
|
||||
if (aspectRatioMismatch) {
|
||||
final Canvas c = mSurface.lockCanvas(null);
|
||||
GraphicBuffer background = GraphicBuffer.create(mFrame.width(), mFrame.height(),
|
||||
PixelFormat.RGBA_8888,
|
||||
GraphicBuffer.USAGE_HW_TEXTURE | GraphicBuffer.USAGE_HW_COMPOSER
|
||||
| GraphicBuffer.USAGE_SW_WRITE_RARELY);
|
||||
final Canvas c = background.lockCanvas();
|
||||
drawBackgroundAndBars(c, frame);
|
||||
mSurface.unlockCanvasAndPost(c);
|
||||
mSurface.release();
|
||||
background.unlockCanvasAndPost(c);
|
||||
mTransaction.setBuffer(mSurfaceControl, background);
|
||||
}
|
||||
mTransaction.apply();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user