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

Commit bbc669b2 authored by wilsonshih's avatar wilsonshih
Browse files

Don't transfer snapshot starting window if bounds has changed.

The snapshot starting window could just remove itself when receive
resized request, so transfer it to a different size activity is
meanless but only cause flicker. So when the trampoline activity
finish and attemp to transfer the snapshot starting window to the
real activity, skip transfer starting window at that time, the
transaction will ready when app window drawn.
And in order to prevent the trampoline activity trigger an activity
transition animation, reuse the no_animation flag, so that transiton
won't merged into playing transition.

Bug: 278931413
Test: hot launch test app on large screen device, verify no flicker
from transfer snapshot starting window.

Change-Id: I285eccac8cea15846ca6c36d987d077bd0edde8d
parent 6e2b39c0
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import static android.view.WindowManager.TRANSIT_SLEEP;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.fixScale;
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
import static android.window.TransitionInfo.FLAG_IS_OCCLUDED;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;
@@ -728,11 +729,15 @@ public class Transitions implements RemoteCallable<Transitions>,
        final int changeSize = info.getChanges().size();
        boolean taskChange = false;
        boolean transferStartingWindow = false;
        int noAnimationBehindStartingWindow = 0;
        boolean allOccluded = changeSize > 0;
        for (int i = changeSize - 1; i >= 0; --i) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            taskChange |= change.getTaskInfo() != null;
            transferStartingWindow |= change.hasFlags(FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT);
            if (change.hasAllFlags(FLAG_IS_BEHIND_STARTING_WINDOW | FLAG_NO_ANIMATION)) {
                noAnimationBehindStartingWindow++;
            }
            if (!change.hasFlags(FLAG_IS_OCCLUDED)) {
                allOccluded = false;
            }
@@ -740,9 +745,11 @@ public class Transitions implements RemoteCallable<Transitions>,
        // There does not need animation when:
        // A. Transfer starting window. Apply transfer starting window directly if there is no other
        // task change. Since this is an activity->activity situation, we can detect it by selecting
        // transitions with only 2 changes where neither are tasks and one is a starting-window
        // recipient.
        if (!taskChange && transferStartingWindow && changeSize == 2
        // transitions with only 2 changes where
        // 1. neither are tasks, and
        // 2. one is a starting-window recipient, or all change is behind starting window.
        if (!taskChange && (transferStartingWindow || noAnimationBehindStartingWindow == changeSize)
                && changeSize == 2
                // B. It's visibility change if the TRANSIT_TO_BACK/TO_FRONT happened when all
                // changes are underneath another change.
                || ((info.getType() == TRANSIT_TO_BACK || info.getType() == TRANSIT_TO_FRONT)
+20 −0
Original line number Diff line number Diff line
@@ -4560,6 +4560,26 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        }
        task.forAllActivities(fromActivity -> {
            if (fromActivity == this) return true;
            // The snapshot starting window could remove itself when receive resized request without
            // redraw, so transfer it to a different size activity could only cause flicker.
            // By schedule remove snapshot starting window, the remove process will happen when
            // transition ready, transition ready means the app window is drawn.
            final StartingData tmpStartingData = fromActivity.mStartingData;
            if (tmpStartingData != null && tmpStartingData.mAssociatedTask == null
                    && mTransitionController.isCollecting(fromActivity)
                    && tmpStartingData instanceof SnapshotStartingData) {
                final Rect fromBounds = fromActivity.getBounds();
                final Rect myBounds = getBounds();
                if (!fromBounds.equals(myBounds)) {
                    // Mark as no animation, so these changes won't merge into playing transition.
                    if (mTransitionController.inPlayingTransition(fromActivity)) {
                        mTransitionController.setNoAnimation(this);
                        mTransitionController.setNoAnimation(fromActivity);
                    }
                    fromActivity.removeStartingWindow();
                    return true;
                }
            }
            return !fromActivity.isVisibleRequested() && transferStartingWindow(fromActivity);
        });
    }