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

Commit aa8a9b71 authored by Wale Ogunwale's avatar Wale Ogunwale
Browse files

Fixed issue with focused stack frame not displaying in multi-window.

Problem was caused by getting the canvas from the surface while
within a transaction.

Also, cleaned up code a little so it is clearer what is happening.

Bug: 19249857
Change-Id: I9ff1f612bc8a58a0e0c7939dbb400d083d8a7039
parent b1193ade
Loading
Loading
Loading
Loading
+64 −60
Original line number Diff line number Diff line
@@ -16,14 +16,14 @@

package com.android.server.wm;

import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.Slog;
import android.view.Display;
import android.view.Surface.OutOfResourcesException;
@@ -35,14 +35,17 @@ import com.android.server.wm.WindowStateAnimator.SurfaceTrace;

class FocusedStackFrame {
    private static final String TAG = "FocusedStackFrame";
    private static final int THICKNESS = 10;
    private static final boolean DEBUG = false;
    private static final int THICKNESS = 2;
    private static final float ALPHA = 0.3f;

    private final SurfaceControl mSurfaceControl;
    private final Surface mSurface = new Surface();
    private final Paint mInnerPaint = new Paint();
    private final Paint mOuterPaint = new Paint();
    private final Rect mBounds = new Rect();
    private final Rect mLastBounds = new Rect();
    final Rect mBounds = new Rect();
    private final Rect mTmpDrawRect = new Rect();
    private int mLayer = -1;

    public FocusedStackFrame(Display display, SurfaceSession session) {
        SurfaceControl ctrl = null;
@@ -60,83 +63,84 @@ class FocusedStackFrame {
        } catch (OutOfResourcesException e) {
        }
        mSurfaceControl = ctrl;

        mInnerPaint.setStyle(Paint.Style.STROKE);
        mInnerPaint.setStrokeWidth(THICKNESS);
        mInnerPaint.setColor(Color.WHITE);
        mOuterPaint.setStyle(Paint.Style.STROKE);
        mOuterPaint.setStrokeWidth(THICKNESS);
        mOuterPaint.setColor(Color.BLACK);
    }

    private void draw() {
        if (mLastBounds.isEmpty()) {
            // Currently unset. Set it.
            mLastBounds.set(mBounds);
        }

    private void draw(Rect bounds, int color) {
        if (false && DEBUG_STACK) Slog.i(TAG, "draw: bounds=" + bounds.toShortString() +
                " color=" + Integer.toHexString(color));
        mTmpDrawRect.set(bounds);
        if (DEBUG) Slog.i(TAG, "draw: mBounds=" + mBounds + " mLastBounds=" + mLastBounds);

        Canvas c = null;
        try {
            c = mSurface.lockCanvas(mTmpDrawRect);
            c = mSurface.lockCanvas(mLastBounds);
        } catch (IllegalArgumentException e) {
            Slog.e(TAG, "Unable to lock canvas", e);
        } catch (Surface.OutOfResourcesException e) {
            Slog.e(TAG, "Unable to lock canvas", e);
        }
        if (c == null) {
            if (DEBUG) Slog.w(TAG, "Canvas is null...");
            return;
        }

        final int w = bounds.width();
        final int h = bounds.height();

        // Top
        mTmpDrawRect.set(0, 0, w, THICKNESS);
        c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
        c.drawColor(color);
        // Left (not including Top or Bottom stripe).
        mTmpDrawRect.set(0, THICKNESS, THICKNESS, h - THICKNESS);
        c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
        c.drawColor(color);
        // Right (not including Top or Bottom stripe).
        mTmpDrawRect.set(w - THICKNESS, THICKNESS, w, h - THICKNESS);
        c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
        c.drawColor(color);
        // Bottom
        mTmpDrawRect.set(0, h - THICKNESS, w, h);
        c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
        c.drawColor(color);

        c.drawRect(0, 0, mBounds.width(), mBounds.height(), mOuterPaint);
        c.drawRect(THICKNESS, THICKNESS, mBounds.width() - THICKNESS, mBounds.height() - THICKNESS,
                mInnerPaint);
        if (DEBUG) Slog.w(TAG, "c.width=" + c.getWidth() + " c.height=" + c.getHeight()
                + " c.clip=" + c .getClipBounds());
        mSurface.unlockCanvasAndPost(c);
        mLastBounds.set(mBounds);
    }

    private void positionSurface(Rect bounds) {
        if (false && DEBUG_STACK) Slog.i(TAG, "positionSurface: bounds=" + bounds.toShortString());
        mSurfaceControl.setSize(bounds.width(), bounds.height());
        mSurfaceControl.setPosition(bounds.left, bounds.top);
    }

    // Note: caller responsible for being inside
    // Surface.openTransaction() / closeTransaction()
    public void setVisibility(boolean on) {
        if (false && DEBUG_STACK) Slog.i(TAG, "setVisibility: on=" + on +
                " mLastBounds=" + mLastBounds.toShortString() +
                " mBounds=" + mBounds.toShortString());
    private void setupSurface(boolean visible) {
        if (mSurfaceControl == null) {
            return;
        }
        if (on) {
            if (!mLastBounds.equals(mBounds)) {
                // Erase the previous rectangle.
                positionSurface(mLastBounds);
                draw(mLastBounds, Color.TRANSPARENT);
                // Draw the latest rectangle.
                positionSurface(mBounds);
                draw(mBounds, Color.WHITE);
                // Update the history.
                mLastBounds.set(mBounds);
            }
        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setupSurface");
        SurfaceControl.openTransaction();
        try {
            if (visible) {
                mSurfaceControl.setPosition(mBounds.left, mBounds.top);
                mSurfaceControl.setSize(mBounds.width(), mBounds.height());
                mSurfaceControl.show();
            } else {
                mSurfaceControl.hide();
            }
        } finally {
            SurfaceControl.closeTransaction();
            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setupSurface");
        }
    }

    public void setBounds(TaskStack stack) {
    void setVisibility(TaskStack stack) {
        if (stack == null || stack.isFullscreen()) {
            setupSurface(false);
        } else {
            stack.getBounds(mBounds);
        if (false && DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + mBounds);
            setupSurface(true);
            if (!mBounds.equals(mLastBounds)) {
                draw();
            }
        }
    }

    public void setLayer(int layer) {
        mSurfaceControl.setLayer(layer);
    // Note: caller responsible for being inside
    // Surface.openTransaction() / closeTransaction()
    void setLayer(int layer) {
        if (mLayer == layer) {
            return;
        }
        mLayer = layer;
        mSurfaceControl.setLayer(mLayer);
    }
}
+1 −19
Original line number Diff line number Diff line
@@ -64,11 +64,9 @@ import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerInternal;
@@ -127,7 +125,6 @@ import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicy;
@@ -136,7 +133,6 @@ import android.view.WindowManagerPolicy.FakeWindow;
import android.view.WindowManagerPolicy.PointerEventListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;

import java.io.BufferedWriter;
import java.io.DataInputStream;
@@ -181,7 +177,6 @@ public class WindowManagerService extends IWindowManager.Stub
    static final boolean DEBUG_CONFIGURATION = false;
    static final boolean DEBUG_APP_TRANSITIONS = false;
    static final boolean DEBUG_STARTING_WINDOW = false;
    static final boolean DEBUG_REORDER = false;
    static final boolean DEBUG_WALLPAPER = false;
    static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
    static final boolean DEBUG_DRAG = false;
@@ -3940,20 +3935,7 @@ public class WindowManagerService extends IWindowManager.Stub
        } else {
            stack = null;
        }
        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setFocusedStackFrame");
        SurfaceControl.openTransaction();
        try {
            if (stack == null) {
                mFocusedStackFrame.setVisibility(false);
            } else {
                mFocusedStackFrame.setBounds(stack);
                final boolean multipleStacks = !stack.isFullscreen();
                mFocusedStackFrame.setVisibility(multipleStacks);
            }
        } finally {
            SurfaceControl.closeTransaction();
            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setFocusedStackFrame");
        }
        mFocusedStackFrame.setVisibility(stack);
    }

    @Override