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

Commit 3f7830ea authored by Charles Chen's avatar Charles Chen
Browse files

Introduce TaskFragment transition type

Previously AppTransitionController didn't recognize TaskFragment
transitions, so it uses Task opening/closing animation for
TaskFragment transitions.
This CL introduces and uses TaskFragment transition if the animation
target is TaskFragment. The new transition type can be used for registering
RemoteAnimation implemented by TaskFragmentOrganizer as well.
This CL also provides a fallback mechanism for TaskFragment transitions
if the RemoteAnimation fails or one of opening/closing animation target
is not a pure organized TaskFragment.

Bug: 194649929
Test: manual - the reproducible step in b/194649929#comment1
Test: atest WmTests:AppTransitionTests AppTransitionControllerTest
Change-Id: I0094694fa5cd95d8bbb7da94d2aaf7aac6e1fe09
parent a6a85a9b
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -319,6 +319,19 @@ public interface WindowManager extends ViewManager {
     */
    int TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE = 27;

    /**
     * A window in a new task fragment is being opened.
     * @hide
     */
    int TRANSIT_OLD_TASK_FRAGMENT_OPEN = 28;

    /**
     * A window in the top-most activity of task fragment is being closed to reveal the activity
     * below.
     * @hide
     */
    int TRANSIT_OLD_TASK_FRAGMENT_CLOSE = 29;

    /**
     * @hide
     */
@@ -344,7 +357,9 @@ public interface WindowManager extends ViewManager {
            TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN,
            TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE,
            TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE,
            TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE
            TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE,
            TRANSIT_OLD_TASK_FRAGMENT_OPEN,
            TRANSIT_OLD_TASK_FRAGMENT_CLOSE
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface TransitionOldType {}
+1 −0
Original line number Diff line number Diff line
@@ -756,6 +756,7 @@ final class AccessibilityController {
            if (magnifying) {
                switch (transition) {
                    case WindowManager.TRANSIT_OLD_ACTIVITY_OPEN:
                    case WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN:
                    case WindowManager.TRANSIT_OLD_TASK_OPEN:
                    case WindowManager.TRANSIT_OLD_TASK_TO_FRONT:
                    case WindowManager.TRANSIT_OLD_WALLPAPER_OPEN:
+23 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_OLD_NONE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN_BEHIND;
import static android.view.WindowManager.TRANSIT_OLD_TASK_TO_BACK;
@@ -1005,6 +1007,21 @@ public class AppTransition implements Dump {
                    animAttr = enter
                            ? WindowAnimation_launchTaskBehindSourceAnimation
                            : WindowAnimation_launchTaskBehindTargetAnimation;
                    break;
                // TODO(b/189386466): Use activity transition as the fallback. Investigate if we
                //  need new TaskFragment transition.
                case TRANSIT_OLD_TASK_FRAGMENT_OPEN:
                    animAttr = enter
                            ? WindowAnimation_activityOpenEnterAnimation
                            : WindowAnimation_activityOpenExitAnimation;
                    break;
                // TODO(b/189386466): Use activity transition as the fallback. Investigate if we
                //  need new TaskFragment transition.
                case TRANSIT_OLD_TASK_FRAGMENT_CLOSE:
                    animAttr = enter
                            ? WindowAnimation_activityCloseEnterAnimation
                            : WindowAnimation_activityCloseExitAnimation;
                    break;
            }
            a = animAttr != 0 ? loadAnimationAttr(lp, animAttr, transit) : null;
            ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
@@ -1315,6 +1332,12 @@ public class AppTransition implements Dump {
            case TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE: {
                return "TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE";
            }
            case TRANSIT_OLD_TASK_FRAGMENT_OPEN: {
                return "TRANSIT_OLD_TASK_FRAGMENT_OPEN";
            }
            case TRANSIT_OLD_TASK_FRAGMENT_CLOSE: {
                return "TRANSIT_OLD_TASK_FRAGMENT_CLOSE";
            }
            default: {
                return "<UNKNOWN: " + transition + ">";
            }
+54 −13
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_OLD_NONE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN_BEHIND;
import static android.view.WindowManager.TRANSIT_OLD_TASK_TO_BACK;
@@ -68,6 +70,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACT
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.os.Trace;
import android.util.ArrayMap;
@@ -86,6 +89,8 @@ import android.view.animation.Animation;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.function.Predicate;
@@ -102,6 +107,20 @@ public class AppTransitionController {
    private RemoteAnimationDefinition mRemoteAnimationDefinition = null;
    private static final int KEYGUARD_GOING_AWAY_ANIMATION_DURATION = 400;

    private static final int TYPE_NONE = 0;
    private static final int TYPE_ACTIVITY = 1;
    private static final int TYPE_TASK_FRAGMENT = 2;
    private static final int TYPE_TASK = 3;

    @IntDef(prefix = { "TYPE_" }, value = {
            TYPE_NONE,
            TYPE_ACTIVITY,
            TYPE_TASK_FRAGMENT,
            TYPE_TASK
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface TransitContainerType {}

    private final ArrayMap<WindowContainer, Integer> mTempTransitionReasons = new ArrayMap<>();

    AppTransitionController(WindowManagerService service, DisplayContent displayContent) {
@@ -387,33 +406,38 @@ public class AppTransitionController {
                openingApps, closingApps, true /* visible */);
        final ArraySet<WindowContainer> closingWcs = getAnimationTargets(
                openingApps, closingApps, false /* visible */);
        final boolean isActivityOpening = !openingWcs.isEmpty()
                && openingWcs.valueAt(0).asActivityRecord() != null;
        final boolean isActivityClosing = !closingWcs.isEmpty()
                && closingWcs.valueAt(0).asActivityRecord() != null;
        final boolean isTaskOpening = !openingWcs.isEmpty() && !isActivityOpening;
        final boolean isTaskClosing = !closingWcs.isEmpty() && !isActivityClosing;

        if (appTransition.containsTransitRequest(TRANSIT_TO_FRONT) && isTaskOpening) {
        final WindowContainer<?> openingContainer = !openingWcs.isEmpty()
                ? openingWcs.valueAt(0) : null;
        final WindowContainer<?> closingContainer = !closingWcs.isEmpty()
                ? closingWcs.valueAt(0) : null;
        @TransitContainerType int openingType = getTransitContainerType(openingContainer);
        @TransitContainerType int closingType = getTransitContainerType(closingContainer);
        if (appTransition.containsTransitRequest(TRANSIT_TO_FRONT) && openingType == TYPE_TASK) {
            return TRANSIT_OLD_TASK_TO_FRONT;
        }
        if (appTransition.containsTransitRequest(TRANSIT_TO_BACK) && isTaskClosing) {
        if (appTransition.containsTransitRequest(TRANSIT_TO_BACK) && closingType == TYPE_TASK) {
            return TRANSIT_OLD_TASK_TO_BACK;
        }
        if (appTransition.containsTransitRequest(TRANSIT_OPEN)) {
            if (isTaskOpening) {
            if (openingType == TYPE_TASK) {
                return (appTransition.getTransitFlags() & TRANSIT_FLAG_OPEN_BEHIND) != 0
                        ? TRANSIT_OLD_TASK_OPEN_BEHIND : TRANSIT_OLD_TASK_OPEN;
            }
            if (isActivityOpening) {
            if (openingType == TYPE_ACTIVITY) {
                return TRANSIT_OLD_ACTIVITY_OPEN;
            }
            if (openingType == TYPE_TASK_FRAGMENT) {
                return TRANSIT_OLD_TASK_FRAGMENT_OPEN;
            }
        }
        if (appTransition.containsTransitRequest(TRANSIT_CLOSE)) {
            if (isTaskClosing) {
            if (closingType == TYPE_TASK) {
                return TRANSIT_OLD_TASK_CLOSE;
            }
            if (isActivityClosing) {
            if (closingType == TYPE_TASK_FRAGMENT) {
                return TRANSIT_OLD_TASK_FRAGMENT_CLOSE;
            }
            if (closingType == TYPE_ACTIVITY) {
                for (int i = closingApps.size() - 1; i >= 0; i--) {
                    if (closingApps.valueAt(i).visibleIgnoringKeyguard) {
                        return TRANSIT_OLD_ACTIVITY_CLOSE;
@@ -430,6 +454,23 @@ public class AppTransitionController {
        return TRANSIT_OLD_NONE;
    }

    @TransitContainerType
    private static int getTransitContainerType(@Nullable WindowContainer<?> container) {
        if (container == null) {
            return TYPE_NONE;
        }
        if (container.asTask() != null) {
            return TYPE_TASK;
        }
        if (container.asTaskFragment() != null) {
            return TYPE_TASK_FRAGMENT;
        }
        if (container.asActivityRecord() != null) {
            return TYPE_ACTIVITY;
        }
        return TYPE_NONE;
    }

    private static WindowManager.LayoutParams getAnimLp(ActivityRecord activity) {
        final WindowState mainWindow = activity != null ? activity.findMainWindow() : null;
        return mainWindow != null ? mainWindow.mAttrs : null;
+1 −1
Original line number Diff line number Diff line
@@ -218,7 +218,7 @@ public class ActivityRecordTests extends WindowTestsBase {
    public void testNoCleanupMovingActivityInSameStack() {
        final ActivityRecord activity = createActivityWith2LevelTask();
        final Task rootTask = activity.getRootTask();
        final Task newTask = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(rootTask).build();
        final Task newTask = createTaskInRootTask(rootTask, 0 /* userId */);
        activity.reparent(newTask, 0, null /*reason*/);
        verify(rootTask, times(0)).cleanUpActivityReferences(any());
    }
Loading