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

Commit efbc8c10 authored by Tony Huang's avatar Tony Huang
Browse files

Set stage outline layer to top

Outline do not set layer before so it will show behind tasks layer
then it will be invisible. Set its layer to top to ensure it's
visible.

Also fix context error message bug by replacing display context to
window context.

Fix: 192902371
Fix: 192527238
Test: Enable spilt and disable it many times and check outline display
Test: Check ContextImpl log
Change-Id: Ic1796965d7254d2276d4c05c662e940820c8d995
parent 85747f04
Loading
Loading
Loading
Loading
+33 −29
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMA
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
@@ -51,7 +52,8 @@ class OutlineManager extends WindowlessWindowManager {
    private final Rect mOutlineBounds = new Rect();
    private final Rect mTmpBounds = new Rect();
    private final Supplier<SurfaceControl> mOutlineSurfaceSupplier;
    private SurfaceControlViewHost mViewHost;
    private final SurfaceControlViewHost mViewHost;
    private final SurfaceControl mLeash;

    /**
     * Constructs {@link #OutlineManager} with indicated outline color for the provided root
@@ -60,9 +62,27 @@ class OutlineManager extends WindowlessWindowManager {
    OutlineManager(Context context, Configuration configuration,
            Supplier<SurfaceControl> outlineSurfaceSupplier, int color) {
        super(configuration, null /* rootSurface */, null /* hostInputToken */);
        mContext = context.createDisplayContext(context.getDisplay());
        mContext = context.createWindowContext(context.getDisplay(), TYPE_APPLICATION_OVERLAY,
                null /* options */);
        mOutlineSurfaceSupplier = outlineSurfaceSupplier;
        mOutlineColor = color;

        mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);
        final OutlineRoot rootView = (OutlineRoot) LayoutInflater.from(mContext)
                .inflate(R.layout.split_outline, null);
        rootView.updateOutlineBounds(mOutlineBounds, mOutlineColor);

        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                0 /* width */, 0 /* height */, TYPE_APPLICATION_OVERLAY,
                FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT);
        lp.token = new Binder();
        lp.setTitle(WINDOW_NAME);
        lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
        // TODO(b/189839391): Set INPUT_FEATURE_NO_INPUT_CHANNEL after WM supports
        //  TRUSTED_OVERLAY for windowless window without input channel.
        mViewHost.setView(rootView, lp);

        mLeash = getSurfaceControl(mViewHost.getWindowToken());
    }

    @Override
@@ -77,37 +97,21 @@ class OutlineManager extends WindowlessWindowManager {
        }
        mOutlineBounds.set(mTmpBounds);

        if (mViewHost == null) {
            mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);
        }
        if (mViewHost.getView() == null) {
            final OutlineRoot rootView = (OutlineRoot) LayoutInflater.from(mContext)
                    .inflate(R.layout.split_outline, null);
            rootView.updateOutlineBounds(mOutlineBounds, mOutlineColor);

            final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                    rootBounds.width(), rootBounds.height(),
                    TYPE_APPLICATION_OVERLAY,
                    FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCHABLE,
                    PixelFormat.TRANSLUCENT);
            lp.token = new Binder();
            lp.setTitle(WINDOW_NAME);
            lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
            // TODO(b/189839391): Set INPUT_FEATURE_NO_INPUT_CHANNEL after WM supports
            //  TRUSTED_OVERLAY for windowless window without input channel.
            mViewHost.setView(rootView, lp);
        } else {
        ((OutlineRoot) mViewHost.getView()).updateOutlineBounds(mOutlineBounds, mOutlineColor);
        final WindowManager.LayoutParams lp =
                (WindowManager.LayoutParams) mViewHost.getView().getLayoutParams();
        lp.width = rootBounds.width();
        lp.height = rootBounds.height();
        mViewHost.relayout(lp);
        }

        return true;
    }

    @Nullable
    SurfaceControl getLeash() {
        return mLeash;
    }

    private static void computeOutlineBounds(Context context, Rect rootBounds, Rect outBounds) {
        computeDisplayStableBounds(context, outBounds);
        outBounds.intersect(rootBounds);
+16 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.view.SurfaceSession;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;

import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.SyncTransactionQueue;

@@ -47,6 +48,14 @@ class SideStage extends StageTaskListener {
        mContext = context;
    }

    @VisibleForTesting
    SideStage(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
            StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
            SurfaceSession surfaceSession, OutlineManager outlineManager) {
        this(context, taskOrganizer, displayId, callbacks, syncQueue, surfaceSession);
        mOutlineManager = outlineManager;
    }

    void addTask(ActivityManager.RunningTaskInfo task, Rect rootBounds,
            WindowContainerTransaction wct) {
        final WindowContainerToken rootToken = mRootTaskInfo.token;
@@ -82,10 +91,16 @@ class SideStage extends StageTaskListener {
    @CallSuper
    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
        super.onTaskAppeared(taskInfo, leash);
        if (mRootTaskInfo != null && mRootTaskInfo.taskId == taskInfo.taskId) {
        if (mRootTaskInfo != null && mRootTaskInfo.taskId == taskInfo.taskId
                && mOutlineManager == null) {
            mOutlineManager = new OutlineManager(mContext, mRootTaskInfo.configuration,
                    () -> mRootLeash,
                    Color.YELLOW);
            if (mOutlineManager.getLeash() != null) {
                mSyncQueue.runInSync(t -> {
                    t.setLayer(mOutlineManager.getLeash(), Integer.MAX_VALUE);
                });
            }
        }
    }

+1 −1
Original line number Diff line number Diff line
@@ -71,8 +71,8 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
    }

    private final StageListenerCallbacks mCallbacks;
    private final SyncTransactionQueue mSyncQueue;
    private final SurfaceSession mSurfaceSession;
    protected final SyncTransactionQueue mSyncQueue;

    protected ActivityManager.RunningTaskInfo mRootTaskInfo;
    protected SurfaceControl mRootLeash;
+2 −1
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ public class SideStageTests extends ShellTestCase {
    @Mock private SyncTransactionQueue mSyncQueue;
    @Mock private ActivityManager.RunningTaskInfo mRootTask;
    @Mock private SurfaceControl mRootLeash;
    @Mock private OutlineManager mOutlineManager;
    @Spy private WindowContainerTransaction mWct;
    private SurfaceSession mSurfaceSession = new SurfaceSession();
    private SideStage mSideStage;
@@ -62,7 +63,7 @@ public class SideStageTests extends ShellTestCase {
        MockitoAnnotations.initMocks(this);
        mRootTask = new TestRunningTaskInfoBuilder().build();
        mSideStage = new SideStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mCallbacks,
                mSyncQueue, mSurfaceSession);
                mSyncQueue, mSurfaceSession, mOutlineManager);
        mSideStage.onTaskAppeared(mRootTask, mRootLeash);
    }

+3 −1
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ public class SplitTransitionTests extends ShellTestCase {
    @Mock private TransactionPool mTransactionPool;
    @Mock private Transitions mTransitions;
    @Mock private SurfaceSession mSurfaceSession;
    @Mock private OutlineManager mOutlineManager;
    private SplitLayout mSplitLayout;
    private MainStage mMainStage;
    private SideStage mSideStage;
@@ -103,7 +104,8 @@ public class SplitTransitionTests extends ShellTestCase {
                StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession);
        mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
        mSideStage = new SideStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
                StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession);
                StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession,
                mOutlineManager);
        mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
        mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
                    mSyncQueue, mRootTDAOrganizer, mTaskOrganizer, mMainStage, mSideStage,