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

Commit 9f37d8cb authored by Biswarup Pal's avatar Biswarup Pal
Browse files

Disable window and transition animations on computercontrol displays

Introduce a method in WindowManagerInternal to enable/disable window
and transiton animations for a display, and store a boolean in
DisplayContent to indicate on/off state of animations. VDM service
calls this method for every display created for computercontrol (this
will also be called when a ComputerControlSession is attached/detached
to a MirrorView to re-enable animations). WMCore notifies WMShell using
a new method in IDisplayWindowListener about animations turned on/off
for a display, to play transitions accordingly.

Test: atest WindowManagerServiceTests
Test: atest ComputerControlSessionTest
Bug: 427437362
Flag: android.companion.virtualdevice.flags.enable_animations_per_display
Change-Id: Ie4835c1107d33556c04ace1a59d7c7341b510e77
parent a45e410c
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -256,3 +256,13 @@ flag {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "enable_animations_per_display"
    namespace: "virtual_devices"
    description: "Enable/disable window and transition animations per display"
    bug: "427437362"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -79,4 +79,9 @@ oneway interface IDisplayWindowListener {
     * Called when the system decorations should be removed from the display.
     */
    void onDisplayRemoveSystemDecorations(int displayId);

    /**
     * Called when animations are disabled or enabled for a display.
     */
    void onDisplayAnimationsDisabledChanged(int displayId, boolean disabled);
}
+25 −0
Original line number Diff line number Diff line
@@ -172,6 +172,14 @@ public class DisplayController {
        return r != null ? r.mInsetsState : null;
    }

    /**
     * Returns whether animations are disabled for the given displayId.
     */
    public boolean isAnimationsDisabled(int displayId) {
        final DisplayRecord r = mDisplays.get(displayId);
        return r == null || r.mAnimationsDisabled;
    }

    /**
     * Updates the insets for a given display.
     */
@@ -411,6 +419,15 @@ public class DisplayController {
        }
    }

    private void onAnimationsDisabled(int displayId, boolean disabled) {
        synchronized (mDisplays) {
            DisplayRecord r = mDisplays.get(displayId);
            if (r != null) {
                r.mAnimationsDisabled = disabled;
            }
        }
    }

    private class DisplayRecord {
        private final int mDisplayId;
        private String mUniqueId;
@@ -418,10 +435,12 @@ public class DisplayController {
        private DisplayLayout mDisplayLayout;
        private InsetsState mInsetsState = new InsetsState();
        private boolean mHasStatusAndNavBars;
        private boolean mAnimationsDisabled;

        private DisplayRecord(int displayId, boolean hasStatusAndNavBars) {
            mDisplayId = displayId;
            mHasStatusAndNavBars = hasStatusAndNavBars;
            mAnimationsDisabled = false;
        }

        private DisplayLayout createLayout(Context context, Display display) {
@@ -527,6 +546,12 @@ public class DisplayController {

        @Override
        public void onDisplayRemoveSystemDecorations(int displayId) { }

        @Override
        public void onDisplayAnimationsDisabledChanged(int displayId, boolean disabled) {
            mMainExecutor.execute(
                    () -> DisplayController.this.onAnimationsDisabled(displayId, disabled));
        }
    }

    /**
+12 −2
Original line number Diff line number Diff line
@@ -347,7 +347,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
        }

        // Early check if the transition doesn't warrant an animation.
        if (TransitionUtil.isAllNoAnimation(info) || TransitionUtil.isAllOrderOnly(info)
        if (isAnimationsDisabledForAnyDisplay(info) || TransitionUtil.isAllNoAnimation(info)
                || TransitionUtil.isAllOrderOnly(info)
                || (info.getFlags() & WindowManager.TRANSIT_FLAG_INVISIBLE) != 0) {
            startTransaction.apply();
            // As a contract, finishTransaction should only be applied in Transitions#onFinish
@@ -666,6 +667,15 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
        return true;
    }

    private boolean isAnimationsDisabledForAnyDisplay(@NonNull TransitionInfo info) {
        boolean disabled = false;
        int rootCount = info.getRootCount();
        for (int i = 0; i < rootCount; i++) {
            disabled |= mDisplayController.isAnimationsDisabled(info.getRoot(i).getDisplayId());
        }
        return disabled;
    }

    private void addBackgroundColor(@NonNull TransitionInfo info,
            @ColorInt int color, @NonNull SurfaceControl.Transaction startTransaction,
            @NonNull SurfaceControl.Transaction finishTransaction) {
@@ -1032,7 +1042,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {

    /**
     * Returns {@code true} if the default transition handler can run the override animation.
     * @see #loadAnimation(TransitionInfo, TransitionInfo.Change, int, boolean)
     * @see #loadAnimation(int, TransitionInfo, TransitionInfo.Change, int, boolean)
     */
    public static boolean isSupportedOverrideAnimation(
            @NonNull TransitionInfo.AnimationOptions options) {
+12 −2
Original line number Diff line number Diff line
@@ -274,7 +274,12 @@ public class DefaultTransitionHandlerTest extends ShellTestCase {

    @Test
    public void startAnimation_neverFindsErrors_animationMode() {
        final TransitionInfo info = mock(TransitionInfo.class);
        final TransitionInfo.Change open = new ChangeBuilder(TRANSIT_OPEN).build();
        final TransitionInfo.Change close = new ChangeBuilder(TRANSIT_TO_BACK).build();
        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
                .addChange(open)
                .addChange(close)
                .build();
        final IBinder token = mock(Binder.class);

        TransitionDispatchState dispatchState = new TransitionDispatchState(token, info);
@@ -291,7 +296,12 @@ public class DefaultTransitionHandlerTest extends ShellTestCase {

    @Test
    public void startAnimation_neverFindsErrors_dataCollectionMode() {
        final TransitionInfo info = mock(TransitionInfo.class);
        final TransitionInfo.Change open = new ChangeBuilder(TRANSIT_OPEN).build();
        final TransitionInfo.Change close = new ChangeBuilder(TRANSIT_TO_BACK).build();
        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
                .addChange(open)
                .addChange(close)
                .build();
        final IBinder token = mock(Binder.class);

        TransitionDispatchState dispatchState = new TransitionDispatchState(token, info);
Loading