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

Commit 48bdf403 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Avoid showing/hiding task surfaces in window decor relayout" into main

parents 03d1207d 3567d3f6
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -180,12 +180,13 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
        // all other cases, it is expected that the transition handler positions and crops the task
        // in order to allow the handler time to animate before the task before the final
        // position and crop are set.
        final boolean shouldSetTaskPositionAndCrop = mTaskDragResizer.isResizingOrAnimating();
        final boolean shouldSetTaskVisibilityPositionAndCrop =
                mTaskDragResizer.isResizingOrAnimating();
        // Use |applyStartTransactionOnDraw| so that the transaction (that applies task crop) is
        // synced with the buffer transaction (that draws the View). Both will be shown on screen
        // at the same, whereas applying them independently causes flickering. See b/270202228.
        relayout(taskInfo, t, t, true /* applyStartTransactionOnDraw */,
                shouldSetTaskPositionAndCrop, hasGlobalFocus);
                shouldSetTaskVisibilityPositionAndCrop, hasGlobalFocus);
    }

    @VisibleForTesting
@@ -193,7 +194,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
            RelayoutParams relayoutParams,
            ActivityManager.RunningTaskInfo taskInfo,
            boolean applyStartTransactionOnDraw,
            boolean setTaskCropAndPosition,
            boolean shouldSetTaskVisibilityPositionAndCrop,
            boolean isStatusBarVisible,
            boolean isKeyguardVisibleAndOccluded,
            InsetsState displayInsetsState,
@@ -206,7 +207,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
                ? R.dimen.freeform_decor_shadow_focused_thickness
                : R.dimen.freeform_decor_shadow_unfocused_thickness;
        relayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
        relayoutParams.mSetTaskPositionAndCrop = setTaskCropAndPosition;
        relayoutParams.mSetTaskVisibilityPositionAndCrop = shouldSetTaskVisibilityPositionAndCrop;
        relayoutParams.mIsCaptionVisible = taskInfo.isFreeform()
                || (isStatusBarVisible && !isKeyguardVisibleAndOccluded);

@@ -234,7 +235,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
    @SuppressLint("MissingPermission")
    void relayout(RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean setTaskCropAndPosition,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
            boolean hasGlobalFocus) {
        final boolean isFreeform =
                taskInfo.getWindowingMode() == WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -246,7 +247,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
        final WindowContainerTransaction wct = new WindowContainerTransaction();

        updateRelayoutParams(mRelayoutParams, taskInfo, applyStartTransactionOnDraw,
                setTaskCropAndPosition, mIsStatusBarVisible, mIsKeyguardVisibleAndOccluded,
                shouldSetTaskVisibilityPositionAndCrop, mIsStatusBarVisible,
                mIsKeyguardVisibleAndOccluded,
                mDisplayController.getInsetsState(taskInfo.displayId), hasGlobalFocus);

        relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
+27 −20
Original line number Diff line number Diff line
@@ -390,18 +390,25 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    @Override
    void relayout(ActivityManager.RunningTaskInfo taskInfo, boolean hasGlobalFocus) {
        final SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
        // The crop and position of the task should only be set when a task is fluid resizing. In
        // all other cases, it is expected that the transition handler positions and crops the task
        // in order to allow the handler time to animate before the task before the final
        // position and crop are set.
        final boolean shouldSetTaskPositionAndCrop = !DesktopModeStatus.isVeiledResizeEnabled()
        // The visibility, crop and position of the task should only be set when a task is
        // fluid resizing. In all other cases, it is expected that the transition handler sets
        // those task properties to allow the handler time to animate with full control of the task
        // leash. In general, allowing the window decoration to set any of these is likely to cause
        // incorrect frames and flickering because relayouts from TaskListener#onTaskInfoChanged
        // aren't synchronized with shell transition callbacks, so if they come too early it
        // might show/hide or crop the task at a bad time.
        // Fluid resizing is exempt from this because it intentionally doesn't use shell
        // transitions to resize the task, so onTaskInfoChanged relayouts is the only way to make
        // sure the crop is set correctly.
        final boolean shouldSetTaskVisibilityPositionAndCrop =
                !DesktopModeStatus.isVeiledResizeEnabled()
                        && mTaskDragResizer.isResizingOrAnimating();
        // For headers only (i.e. in freeform): use |applyStartTransactionOnDraw| so that the
        // transaction (that applies task crop) is synced with the buffer transaction (that draws
        // the View). Both will be shown on screen at the same, whereas applying them independently
        // causes flickering. See b/270202228.
        final boolean applyTransactionOnDraw = taskInfo.isFreeform();
        relayout(taskInfo, t, t, applyTransactionOnDraw, shouldSetTaskPositionAndCrop,
        relayout(taskInfo, t, t, applyTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop,
                hasGlobalFocus);
        if (!applyTransactionOnDraw) {
            t.apply();
@@ -428,19 +435,19 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin

    void relayout(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
            boolean hasGlobalFocus) {
        Trace.beginSection("DesktopModeWindowDecoration#relayout");
        if (taskInfo.isFreeform()) {
            // The Task is in Freeform mode -> show its header in sync since it's an integral part
            // of the window itself - a delayed header might cause bad UX.
            relayoutInSync(taskInfo, startT, finishT, applyStartTransactionOnDraw,
                    shouldSetTaskPositionAndCrop, hasGlobalFocus);
                    shouldSetTaskVisibilityPositionAndCrop, hasGlobalFocus);
        } else {
            // The Task is outside Freeform mode -> allow the handle view to be delayed since the
            // handle is just a small addition to the window.
            relayoutWithDelayedViewHost(taskInfo, startT, finishT, applyStartTransactionOnDraw,
                    shouldSetTaskPositionAndCrop, hasGlobalFocus);
                    shouldSetTaskVisibilityPositionAndCrop, hasGlobalFocus);
        }
        Trace.endSection();
    }
@@ -448,12 +455,12 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    /** Run the whole relayout phase immediately without delay. */
    private void relayoutInSync(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
            boolean hasGlobalFocus) {
        // Clear the current ViewHost runnable as we will update the ViewHost here
        clearCurrentViewHostRunnable();
        updateRelayoutParamsAndSurfaces(taskInfo, startT, finishT, applyStartTransactionOnDraw,
                shouldSetTaskPositionAndCrop, hasGlobalFocus);
                shouldSetTaskVisibilityPositionAndCrop, hasGlobalFocus);
        if (mResult.mRootView != null) {
            updateViewHost(mRelayoutParams, startT, mResult);
        }
@@ -475,7 +482,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
     */
    private void relayoutWithDelayedViewHost(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
            boolean hasGlobalFocus) {
        if (applyStartTransactionOnDraw) {
            throw new IllegalArgumentException(
@@ -484,7 +491,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        // Clear the current ViewHost runnable as we will update the ViewHost here
        clearCurrentViewHostRunnable();
        updateRelayoutParamsAndSurfaces(taskInfo, startT, finishT,
                false /* applyStartTransactionOnDraw */, shouldSetTaskPositionAndCrop,
                false /* applyStartTransactionOnDraw */, shouldSetTaskVisibilityPositionAndCrop,
                hasGlobalFocus);
        if (mResult.mRootView == null) {
            // This means something blocks the window decor from showing, e.g. the task is hidden.
@@ -499,7 +506,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    @SuppressLint("MissingPermission")
    private void updateRelayoutParamsAndSurfaces(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
            boolean hasGlobalFocus) {
        Trace.beginSection("DesktopModeWindowDecoration#updateRelayoutParamsAndSurfaces");

@@ -524,9 +531,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        final boolean inFullImmersive = mDesktopRepository
                .isTaskInFullImmersiveState(taskInfo.taskId);
        updateRelayoutParams(mRelayoutParams, mContext, taskInfo, applyStartTransactionOnDraw,
                shouldSetTaskPositionAndCrop, mIsStatusBarVisible, mIsKeyguardVisibleAndOccluded,
                inFullImmersive, mDisplayController.getInsetsState(taskInfo.displayId),
                hasGlobalFocus);
                shouldSetTaskVisibilityPositionAndCrop, mIsStatusBarVisible,
                mIsKeyguardVisibleAndOccluded, inFullImmersive,
                mDisplayController.getInsetsState(taskInfo.displayId), hasGlobalFocus);

        final WindowDecorLinearLayout oldRootView = mResult.mRootView;
        final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
@@ -852,7 +859,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            Context context,
            ActivityManager.RunningTaskInfo taskInfo,
            boolean applyStartTransactionOnDraw,
            boolean shouldSetTaskPositionAndCrop,
            boolean shouldSetTaskVisibilityPositionAndCrop,
            boolean isStatusBarVisible,
            boolean isKeyguardVisibleAndOccluded,
            boolean inFullImmersiveMode,
@@ -948,7 +955,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                    : R.dimen.freeform_decor_shadow_unfocused_thickness;
        }
        relayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
        relayoutParams.mSetTaskPositionAndCrop = shouldSetTaskPositionAndCrop;
        relayoutParams.mSetTaskVisibilityPositionAndCrop = shouldSetTaskVisibilityPositionAndCrop;

        // The configuration used to layout the window decoration. A copy is made instead of using
        // the original reference so that the configuration isn't mutated on config changes and
+11 −5
Original line number Diff line number Diff line
@@ -249,7 +249,9 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>

        if (!mTaskInfo.isVisible) {
            releaseViews(wct);
            if (params.mSetTaskVisibilityPositionAndCrop) {
                finishT.hide(mTaskSurface);
            }
            return;
        }

@@ -422,7 +424,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>

    private void updateTaskSurface(RelayoutParams params, SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT, RelayoutResult<T> outResult) {
        if (params.mSetTaskPositionAndCrop) {
        if (params.mSetTaskVisibilityPositionAndCrop) {
            final Point taskPosition = mTaskInfo.positionInParent;
            startT.setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight);
            finishT.setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight)
@@ -437,9 +439,13 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
            shadowRadius =
                    loadDimension(mDecorWindowContext.getResources(), params.mShadowRadiusId);
        }
        startT.setShadowRadius(mTaskSurface, shadowRadius).show(mTaskSurface);
        startT.setShadowRadius(mTaskSurface, shadowRadius);
        finishT.setShadowRadius(mTaskSurface, shadowRadius);

        if (params.mSetTaskVisibilityPositionAndCrop) {
            startT.show(mTaskSurface);
        }

        if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
            if (!DesktopModeStatus.isVeiledResizeEnabled()) {
                // When fluid resize is enabled, add a background to freeform tasks
@@ -758,7 +764,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
        Configuration mWindowDecorConfig;

        boolean mApplyStartTransactionOnDraw;
        boolean mSetTaskPositionAndCrop;
        boolean mSetTaskVisibilityPositionAndCrop;
        boolean mHasGlobalFocus;

        void reset() {
@@ -777,7 +783,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
            mIsCaptionVisible = false;

            mApplyStartTransactionOnDraw = false;
            mSetTaskPositionAndCrop = false;
            mSetTaskVisibilityPositionAndCrop = false;
            mWindowDecorConfig = null;
            mHasGlobalFocus = false;
        }
+2 −6
Original line number Diff line number Diff line
@@ -218,8 +218,6 @@ public class WindowDecorationTests extends ShellTestCase {
        verify(captionContainerSurfaceBuilder, never()).build();
        verify(mMockSurfaceControlViewHostFactory, never()).create(any(), any(), any());

        verify(mMockSurfaceControlFinishT).hide(mMockTaskSurface);

        assertNull(mRelayoutResult.mRootView);
    }

@@ -281,8 +279,6 @@ public class WindowDecorationTests extends ShellTestCase {

        verify(mMockSurfaceControlStartT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
        verify(mMockSurfaceControlFinishT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
        verify(mMockSurfaceControlStartT)
                .show(mMockTaskSurface);
        verify(mMockSurfaceControlStartT).setShadowRadius(mMockTaskSurface, 10);

        assertEquals(300, mRelayoutResult.mWidth);
@@ -863,7 +859,7 @@ public class WindowDecorationTests extends ShellTestCase {
        final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo);


        mRelayoutParams.mSetTaskPositionAndCrop = false;
        mRelayoutParams.mSetTaskVisibilityPositionAndCrop = false;
        windowDecor.relayout(taskInfo, true /* hasGlobalFocus */);

        verify(mMockSurfaceControlStartT, never()).setWindowCrop(
@@ -891,7 +887,7 @@ public class WindowDecorationTests extends ShellTestCase {
        taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2;
        final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo);

        mRelayoutParams.mSetTaskPositionAndCrop = true;
        mRelayoutParams.mSetTaskVisibilityPositionAndCrop = true;
        windowDecor.relayout(taskInfo, true /* hasGlobalFocus */);

        verify(mMockSurfaceControlStartT).setWindowCrop(