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

Commit a77179bc authored by wilsonshih's avatar wilsonshih
Browse files

[PB] Find same change target by surface control

When comparing transitions for identical changes, relying on the
activity's component name is unreliable due to potential multiple
instances. Identifying the same object via its surface control
provides a more reliable approach.

Flag: EXEMPT bugfix
Bug: 376020378
Test: atest BackAnimationControllerTest
Test: launch different instance activity from same Component, verify
the close animation won't get bypassed.

Change-Id: I477a58f6a20455d8f38766337715f7e530be972a
parent 428aef40
Loading
Loading
Loading
Loading
+10 −34
Original line number Diff line number Diff line
@@ -1300,7 +1300,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            final TransitionInfo init = mOpenTransitionInfo;
            // Find prepare open target
            boolean openShowWallpaper = false;
            final ArrayList<OpenChangeInfo> targets = new ArrayList<>();
            final ArrayList<SurfaceControl> openSurfaces = new ArrayList<>();
            int tmpSize;
            for (int j = init.getChanges().size() - 1; j >= 0; --j) {
                final TransitionInfo.Change change = init.getChanges().get(j);
@@ -1313,13 +1313,13 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
                            && openToken == null) {
                        continue;
                    }
                    targets.add(new OpenChangeInfo(openComponent, openTaskId, openToken));
                    openSurfaces.add(change.getLeash());
                    if (change.hasFlags(FLAG_SHOW_WALLPAPER)) {
                        openShowWallpaper = true;
                    }
                }
            }
            if (targets.isEmpty()) {
            if (openSurfaces.isEmpty()) {
                // This shouldn't happen, but if that happen, consume the initial transition anyway.
                Log.e(TAG, "Unable to merge following transition, cannot find the gesture "
                        + "animated target from the open transition=" + mOpenTransitionInfo);
@@ -1331,7 +1331,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            tmpSize = info.getChanges().size();
            for (int j = 0; j < tmpSize; ++j) {
                final TransitionInfo.Change change = info.getChanges().get(j);
                if (isOpenChangeMatched(targets, change)) {
                if (isOpenSurfaceMatched(openSurfaces, change)) {
                    // This is original close target, potential be close, but cannot determine
                    // from it.
                    if (change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)) {
@@ -1352,7 +1352,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
                boolean mergePredictive = false;
                for (int j = info.getChanges().size() - 1; j >= 0; --j) {
                    final TransitionInfo.Change change = info.getChanges().get(j);
                    if (isOpenChangeMatched(targets, change)) {
                    if (isOpenSurfaceMatched(openSurfaces, change)) {
                        if (TransitionUtil.isClosingMode(change.getMode())) {
                            excludeOpenTarget = true;
                        }
@@ -1373,7 +1373,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
                        if (change.hasFlags(FLAG_IS_WALLPAPER)) {
                            continue;
                        }
                        if (isOpenChangeMatched(targets, change)) {
                        if (isOpenSurfaceMatched(openSurfaces, change)) {
                            if (excludeOpenTarget) {
                                // App has triggered another change during predictive back
                                // transition, filter out predictive back target.
@@ -1408,7 +1408,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
                if (nonBackClose && nonBackOpen) {
                    for (int j = info.getChanges().size() - 1; j >= 0; --j) {
                        final TransitionInfo.Change change = info.getChanges().get(j);
                        if (isOpenChangeMatched(targets, change)) {
                        if (isOpenSurfaceMatched(openSurfaces, change)) {
                            info.getChanges().remove(j);
                        } else if ((openShowWallpaper && change.hasFlags(FLAG_IS_WALLPAPER))) {
                            info.getChanges().remove(j);
@@ -1692,22 +1692,10 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        return INVALID_TASK_ID;
    }

    private static boolean isSameChangeTarget(ComponentName topActivity, int taskId,
            WindowContainerToken token, TransitionInfo.Change change) {
        final ComponentName openChange = findComponentName(change);
        final int firstTaskId = findTaskId(change);
        final WindowContainerToken openToken = findToken(change);
        return (openChange != null && openChange.equals(topActivity))
                || (firstTaskId != INVALID_TASK_ID && firstTaskId == taskId)
                || (openToken != null && openToken.equals(token));
    }

    static boolean isOpenChangeMatched(@NonNull ArrayList<OpenChangeInfo> targets,
    static boolean isOpenSurfaceMatched(@NonNull ArrayList<SurfaceControl> openSurfaces,
            TransitionInfo.Change change) {
        for (int i = targets.size() - 1; i >= 0; --i) {
            final OpenChangeInfo next = targets.get(i);
            if (isSameChangeTarget(next.mOpenComponent, next.mOpenTaskId, next.mOpenToken,
                    change)) {
        for (int i = openSurfaces.size() - 1; i >= 0; --i) {
            if (openSurfaces.get(i).isSameSurface(change.getLeash())) {
                return true;
            }
        }
@@ -1771,16 +1759,4 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            }
        }
    }

    static class OpenChangeInfo {
        final ComponentName mOpenComponent;
        final int mOpenTaskId;
        final WindowContainerToken mOpenToken;
        OpenChangeInfo(ComponentName openComponent, int openTaskId,
                WindowContainerToken openToken) {
            mOpenComponent = openComponent;
            mOpenTaskId = openTaskId;
            mOpenToken = openToken;
        }
    }
}
+11 −1
Original line number Diff line number Diff line
@@ -700,7 +700,7 @@ public class BackAnimationControllerTest extends ShellTestCase {
                eq(tInfo), eq(st), eq(ft), eq(callback));

        mBackTransitionHandler.onAnimationFinished();
        final TransitionInfo.Change openToClose = createAppChange(openTaskId, TRANSIT_CLOSE,
        final TransitionInfo.Change openToClose = createAppChangeFromChange(open, TRANSIT_CLOSE,
                FLAG_BACK_GESTURE_ANIMATED);
        tInfo2 = createTransitionInfo(TRANSIT_CLOSE_PREPARE_BACK_NAVIGATION, openToClose);
        mBackTransitionHandler.mClosePrepareTransition = mock(IBinder.class);
@@ -830,6 +830,16 @@ public class BackAnimationControllerTest extends ShellTestCase {
        return change;
    }

    private TransitionInfo.Change createAppChangeFromChange(
            TransitionInfo.Change originalChange, @TransitionInfo.TransitionMode int mode,
            @TransitionInfo.ChangeFlags int flags) {
        final TransitionInfo.Change change = new TransitionInfo.Change(
                originalChange.getTaskInfo().token, originalChange.getLeash());
        change.setMode(mode);
        change.setFlags(flags);
        return change;
    }

    private static TransitionInfo createTransitionInfo(
            @WindowManager.TransitionType int type, TransitionInfo.Change ... changes) {
        final TransitionInfo info = new TransitionInfo(type, 0);