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

Commit d35959f0 authored by Nick Chameyev's avatar Nick Chameyev
Browse files

[Unfold transition] Take over only physical display changes

Updates UnfoldTransitionHandler to start unfold
animation only if physical display has changed.
We should not start unfold transition when display
resizes without underlying display change.

Bug: 314252763
Test: manual unfolds => check that unfold animation plays
Test: atest UnfoldTransitionHandlerTest
Test: atest CompatChangeTests
Change-Id: I46c7859ff042ee7aa9193757e5df8269f4892362
parent c2f9bed1
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -591,6 +591,13 @@ public interface WindowManager extends ViewManager {
     */
    int TRANSIT_FLAG_KEYGUARD_UNOCCLUDING = (1 << 13); // 0x2000

    /**
     * Transition flag: Indicates that there is a physical display switch
     * TODO(b/316112906) remove after defer_display_updates flag roll out
     * @hide
     */
    int TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH = (1 << 14); // 0x4000

    /**
     * @hide
     */
@@ -608,7 +615,8 @@ public interface WindowManager extends ViewManager {
            TRANSIT_FLAG_INVISIBLE,
            TRANSIT_FLAG_KEYGUARD_APPEARING,
            TRANSIT_FLAG_KEYGUARD_OCCLUDING,
            TRANSIT_FLAG_KEYGUARD_UNOCCLUDING
            TRANSIT_FLAG_KEYGUARD_UNOCCLUDING,
            TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH,
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface TransitionFlags {}
+19 −12
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.wm.shell.unfold;

import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH;

import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TRANSITIONS;

@@ -245,15 +246,22 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene
    public boolean shouldPlayUnfoldAnimation(@NonNull TransitionInfo transitionInfo) {
        // Unfold animation won't play when animations are disabled
        if (!ValueAnimator.areAnimatorsEnabled()) return false;
        // Only handle transitions that are marked as physical display switch
        // See PhysicalDisplaySwitchTransitionLauncher for the conditions
        if ((transitionInfo.getFlags() & TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH) == 0) return false;

        for (int i = 0; i < transitionInfo.getChanges().size(); i++) {
            final TransitionInfo.Change change = transitionInfo.getChanges().get(i);
            if ((change.getFlags() & TransitionInfo.FLAG_IS_DISPLAY) != 0) {
                if (change.getEndAbsBounds() == null || change.getStartAbsBounds() == null) {
            // We are interested only in display container changes
            if ((change.getFlags() & TransitionInfo.FLAG_IS_DISPLAY) == 0) {
                continue;
            }

            // Handle only unfolding, currently we don't have an animation when folding
            if (change.getEndAbsBounds() == null || change.getStartAbsBounds() == null) {
                continue;
            }

            final int afterArea =
                    change.getEndAbsBounds().width() * change.getEndAbsBounds().height();
            final int beforeArea = change.getStartAbsBounds().width()
@@ -263,7 +271,6 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene
                return true;
            }
        }
        }

        return false;
    }
+28 −24
Original line number Diff line number Diff line
@@ -18,12 +18,11 @@ package com.android.wm.shell.unfold;

import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH;
import static android.view.WindowManager.TRANSIT_NONE;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
@@ -40,22 +39,17 @@ import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerTransaction;

import com.android.window.flags.FakeFeatureFlagsImpl;
import com.android.window.flags.FeatureFlags;
import com.android.window.flags.Flags;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.transition.TransitionInfoBuilder;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.transition.Transitions.TransitionFinishCallback;
import com.android.wm.shell.unfold.animation.FullscreenUnfoldTaskAnimator;
import com.android.wm.shell.unfold.animation.SplitTaskUnfoldAnimator;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.util.ArrayList;
import java.util.List;
@@ -195,6 +189,22 @@ public class UnfoldTransitionHandlerTest {
        assertThat(animationStarted).isTrue();
    }

    @Test
    public void startAnimation_differentTransitionFromRequestWithResize_doesNotStartAnimation() {
        mUnfoldTransitionHandler.handleRequest(new Binder(), createNoneTransitionInfo());
        TransitionFinishCallback finishCallback = mock(TransitionFinishCallback.class);

        boolean animationStarted = mUnfoldTransitionHandler.startAnimation(
                mTransition,
                createDisplayResizeTransitionInfo(),
                mock(SurfaceControl.Transaction.class),
                mock(SurfaceControl.Transaction.class),
                finishCallback
        );

        assertThat(animationStarted).isFalse();
    }

    @Test
    public void startAnimation_differentTransitionFromRequestWithoutUnfold_doesNotStart() {
        mUnfoldTransitionHandler.handleRequest(new Binder(), createNoneTransitionInfo());
@@ -403,24 +413,18 @@ public class UnfoldTransitionHandlerTest {
        }
    }

    static class TestCase {
        private final boolean mShouldHandleMixedUnfold;

        public TestCase(boolean shouldHandleMixedUnfold) {
            mShouldHandleMixedUnfold = shouldHandleMixedUnfold;
        }

        public boolean mixedUnfoldFlagEnabled() {
            return mShouldHandleMixedUnfold;
        }

        @Override
        public String toString() {
            return "shouldHandleMixedUnfold flag = " + mShouldHandleMixedUnfold;
        }
    private TransitionInfo createUnfoldTransitionInfo() {
        TransitionInfo transitionInfo = new TransitionInfo(TRANSIT_CHANGE, /* flags= */ 0);
        TransitionInfo.Change change = new TransitionInfo.Change(null, mock(SurfaceControl.class));
        change.setStartAbsBounds(new Rect(0, 0, 10, 10));
        change.setEndAbsBounds(new Rect(0, 0, 100, 100));
        change.setFlags(TransitionInfo.FLAG_IS_DISPLAY);
        transitionInfo.addChange(change);
        transitionInfo.setFlags(TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH);
        return transitionInfo;
    }

    private TransitionInfo createUnfoldTransitionInfo() {
    private TransitionInfo createDisplayResizeTransitionInfo() {
        TransitionInfo transitionInfo = new TransitionInfo(TRANSIT_CHANGE, /* flags= */ 0);
        TransitionInfo.Change change = new TransitionInfo.Change(null, mock(SurfaceControl.class));
        change.setStartAbsBounds(new Rect(0, 0, 10, 10));
+11 −9
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.wm;

import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH;

import static com.android.internal.R.bool.config_unfoldTransitionEnabled;
import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY;
@@ -110,15 +111,6 @@ public class PhysicalDisplaySwitchTransitionLauncher {
            return;
        }

        final TransitionRequestInfo.DisplayChange displayChange =
                new TransitionRequestInfo.DisplayChange(displayId);

        final Rect startAbsBounds = new Rect(0, 0, oldDisplayWidth, oldDisplayHeight);
        displayChange.setStartAbsBounds(startAbsBounds);
        final Rect endAbsBounds = new Rect(0, 0, newDisplayWidth, newDisplayHeight);
        displayChange.setEndAbsBounds(endAbsBounds);
        displayChange.setPhysicalDisplayChanged(true);

        mTransition = null;

        if (mTransitionController.isCollecting()) {
@@ -128,10 +120,20 @@ public class PhysicalDisplaySwitchTransitionLauncher {

            // Make sure that transition is not ready until we finish the remote display change
            mTransition.setReady(mDisplayContent, false);
            mTransition.addFlag(TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH);

            ProtoLog.d(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
                    "Adding display switch to existing collecting transition");
        } else {
            final TransitionRequestInfo.DisplayChange displayChange =
                    new TransitionRequestInfo.DisplayChange(displayId);

            final Rect startAbsBounds = new Rect(0, 0, oldDisplayWidth, oldDisplayHeight);
            displayChange.setStartAbsBounds(startAbsBounds);
            final Rect endAbsBounds = new Rect(0, 0, newDisplayWidth, newDisplayHeight);
            displayChange.setEndAbsBounds(endAbsBounds);
            displayChange.setPhysicalDisplayChanged(true);

            mTransition = mTransitionController.requestTransitionIfNeeded(TRANSIT_CHANGE,
                    0 /* flags */,
                    mDisplayContent, mDisplayContent, null /* remoteTransition */,