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

Commit 69347c2f authored by Wei Sheng Shih's avatar Wei Sheng Shih Committed by Android (Google) Code Review
Browse files

Merge "[PB] Filter out activity transition under TaskFragment" into main

parents 73d7ec8b bbeaa71b
Loading
Loading
Loading
Loading
+61 −25
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;

@@ -1277,42 +1278,42 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            }
            // Copy initial changes to final transition
            final TransitionInfo init = mOpenTransitionInfo;
            // find prepare open target
            // Find prepare open target
            boolean openShowWallpaper = false;
            ComponentName openComponent = null;
            final ArrayList<OpenChangeInfo> targets = new ArrayList<>();
            int tmpSize;
            int openTaskId = INVALID_TASK_ID;
            WindowContainerToken openToken = null;
            for (int j = init.getChanges().size() - 1; j >= 0; --j) {
                final TransitionInfo.Change change = init.getChanges().get(j);
                if (change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)) {
                    openComponent = findComponentName(change);
                    openTaskId = findTaskId(change);
                    openToken = findToken(change);
                if (change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)
                        && TransitionUtil.isOpeningMode(change.getMode())) {
                    final ComponentName openComponent = findComponentName(change);
                    final int openTaskId = findTaskId(change);
                    final WindowContainerToken openToken = findToken(change);
                    if (openComponent == null && openTaskId == INVALID_TASK_ID
                            && openToken == null) {
                        continue;
                    }
                    targets.add(new OpenChangeInfo(openComponent, openTaskId, openToken));
                    if (change.hasFlags(FLAG_SHOW_WALLPAPER)) {
                        openShowWallpaper = true;
                    }
                    break;
                }
            }
            if (openComponent == null && openTaskId == INVALID_TASK_ID && openToken == null) {
            if (targets.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);
                mOpenTransitionInfo = null;
                return;
            }
            // find first non-prepare open target
            // Find first non-prepare open target
            boolean isOpen = false;
            tmpSize = info.getChanges().size();
            for (int j = 0; j < tmpSize; ++j) {
                final TransitionInfo.Change change = info.getChanges().get(j);
                final ComponentName firstNonOpen = findComponentName(change);
                final int firstTaskId = findTaskId(change);
                if ((firstNonOpen != null && firstNonOpen != openComponent)
                        || (firstTaskId != INVALID_TASK_ID && firstTaskId != openTaskId)) {
                    // this is original close target, potential be close, but cannot determine from
                    // it
                if (isOpenChangeMatched(targets, change)) {
                    // This is original close target, potential be close, but cannot determine
                    // from it.
                    if (change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)) {
                        isOpen = !TransitionUtil.isClosingMode(change.getMode());
                    } else {
@@ -1321,33 +1322,44 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
                    }
                }
            }

            if (!isOpen) {
                // Close transition, the transition info should be:
                // init info(open A & wallpaper)
                // current info(close B target)
                // remove init info(open/change A target & wallpaper)
                boolean moveToTop = false;
                boolean excludeOpenTarget = false;
                boolean mergePredictive = false;
                for (int j = info.getChanges().size() - 1; j >= 0; --j) {
                    final TransitionInfo.Change change = info.getChanges().get(j);
                    if (isSameChangeTarget(openComponent, openTaskId, openToken, change)) {
                    if (isOpenChangeMatched(targets, change)) {
                        if (TransitionUtil.isClosingMode(change.getMode())) {
                            excludeOpenTarget = true;
                        }
                        moveToTop = change.hasFlags(FLAG_MOVED_TO_TOP);
                        info.getChanges().remove(j);
                    } else if ((openShowWallpaper && change.hasFlags(FLAG_IS_WALLPAPER))
                            || !change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)) {
                        info.getChanges().remove(j);
                    } else if (!mergePredictive && TransitionUtil.isClosingMode(change.getMode())) {
                        mergePredictive = true;
                    }
                }
                // Ignore merge if there is no close target
                if (!info.getChanges().isEmpty()) {
                if (!info.getChanges().isEmpty() && mergePredictive) {
                    tmpSize = init.getChanges().size();
                    for (int i = 0; i < tmpSize; ++i) {
                        final TransitionInfo.Change change = init.getChanges().get(i);
                        if (change.hasFlags(FLAG_IS_WALLPAPER)) {
                            continue;
                        }
                        if (isOpenChangeMatched(targets, change)) {
                            if (excludeOpenTarget) {
                                // App has triggered another change during predictive back
                                // transition, filter out predictive back target.
                                continue;
                            }
                            if (moveToTop) {
                            if (isSameChangeTarget(openComponent, openTaskId, openToken, change)) {
                                change.setFlags(change.getFlags() | FLAG_MOVED_TO_TOP);
                            }
                        }
@@ -1376,7 +1388,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 (isSameChangeTarget(openComponent, openTaskId, openToken, change)) {
                        if (isOpenChangeMatched(targets, change)) {
                            info.getChanges().remove(j);
                        } else if ((openShowWallpaper && change.hasFlags(FLAG_IS_WALLPAPER))) {
                            info.getChanges().remove(j);
@@ -1659,9 +1671,21 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        final ComponentName openChange = findComponentName(change);
        final int firstTaskId = findTaskId(change);
        final WindowContainerToken openToken = findToken(change);
        return (openChange != null && openChange == topActivity)
        return (openChange != null && openChange.equals(topActivity))
                || (firstTaskId != INVALID_TASK_ID && firstTaskId == taskId)
                || (openToken != null && token == openToken);
                || (openToken != null && openToken.equals(token));
    }

    static boolean isOpenChangeMatched(@NonNull ArrayList<OpenChangeInfo> targets,
            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)) {
                return true;
            }
        }
        return false;
    }

    private static boolean canBeTransitionTarget(TransitionInfo.Change change) {
@@ -1721,4 +1745,16 @@ 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;
        }
    }
}
+5 −1
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import android.content.pm.ApplicationInfo;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.input.InputManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -812,7 +813,10 @@ public class BackAnimationControllerTest extends ShellTestCase {
        if (taskId != INVALID_TASK_ID) {
            final ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
            taskInfo.taskId = taskId;
            taskInfo.token = new WindowContainerToken(mock(IWindowContainerToken.class));
            final IWindowContainerToken mockT = mock(IWindowContainerToken.class);
            Binder binder = new Binder();
            doReturn(binder).when(mockT).asBinder();
            taskInfo.token = new WindowContainerToken(mockT);
            change = new TransitionInfo.Change(
                    taskInfo.token, b.build());
            change.setTaskInfo(taskInfo);