Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0498394f authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Android (Google) Code Review
Browse files

Merge "Use BLAST layer for snapshot starting windows" into sc-dev

parents 7645d476 cc6cdbc9
Loading
Loading
Loading
Loading
+28 −28
Original line number Diff line number Diff line
@@ -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();
    }

    /**
+29 −29
Original line number Diff line number Diff line
@@ -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();
    }

    /**