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

Commit 646b0c13 authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

Merge "Skip ActivityEmbedding animation if it is behind an app starting window" into tm-qpr-dev

parents cac841b3 6a3dfb25
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -125,8 +125,15 @@ public final class TransitionInfo implements Parcelable {
    /** The container attaches work profile thumbnail for cross profile animation. */
    public static final int FLAG_CROSS_PROFILE_WORK_THUMBNAIL = 1 << 13;

    /**
     * Whether the window is covered by an app starting window. This is different from
     * {@link #FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT} which is only set on the Activity window
     * that contains the starting window.
     */
    public static final int FLAG_IS_BEHIND_STARTING_WINDOW = 1 << 14;

    /** The first unused bit. This can be used by remotes to attach custom flags to this change. */
    public static final int FLAG_FIRST_CUSTOM = 1 << 14;
    public static final int FLAG_FIRST_CUSTOM = 1 << 15;

    /** @hide */
    @IntDef(prefix = { "FLAG_" }, value = {
@@ -145,6 +152,7 @@ public final class TransitionInfo implements Parcelable {
            FLAG_WILL_IME_SHOWN,
            FLAG_CROSS_PROFILE_OWNER_THUMBNAIL,
            FLAG_CROSS_PROFILE_WORK_THUMBNAIL,
            FLAG_IS_BEHIND_STARTING_WINDOW,
            FLAG_FIRST_CUSTOM
    })
    public @interface ChangeFlags {}
@@ -351,6 +359,9 @@ public final class TransitionInfo implements Parcelable {
        if ((flags & FLAG_FILLS_TASK) != 0) {
            sb.append(sb.length() == 0 ? "" : "|").append("FILLS_TASK");
        }
        if ((flags & FLAG_IS_BEHIND_STARTING_WINDOW) != 0) {
            sb.append(sb.length() == 0 ? "" : "|").append("IS_BEHIND_STARTING_WINDOW");
        }
        if ((flags & FLAG_FIRST_CUSTOM) != 0) {
            sb.append(sb.length() == 0 ? "" : "|").append("FIRST_CUSTOM");
        }
+11 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.wm.shell.activityembedding;

import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET;
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;

import android.animation.Animator;
import android.animation.ValueAnimator;
@@ -129,12 +130,20 @@ class ActivityEmbeddingAnimationRunner {
    @NonNull
    private List<ActivityEmbeddingAnimationAdapter> createAnimationAdapters(
            @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction) {
        boolean isChangeTransition = false;
        for (TransitionInfo.Change change : info.getChanges()) {
            if (change.getMode() == TRANSIT_CHANGE
            if (change.hasFlags(FLAG_IS_BEHIND_STARTING_WINDOW)) {
                // Skip the animation if the windows are behind an app starting window.
                return new ArrayList<>();
            }
            if (!isChangeTransition && change.getMode() == TRANSIT_CHANGE
                    && !change.getStartAbsBounds().equals(change.getEndAbsBounds())) {
                return createChangeAnimationAdapters(info, startTransaction);
                isChangeTransition = true;
            }
        }
        if (isChangeTransition) {
            return createChangeAnimationAdapters(info, startTransaction);
        }
        if (Transitions.isClosingType(info.getType())) {
            return createCloseAnimationAdapters(info);
        }
+17 −0
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@ package com.android.wm.shell.activityembedding;

import static android.view.WindowManager.TRANSIT_OPEN;
import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;

import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
@@ -27,6 +29,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

import android.animation.Animator;
import android.window.TransitionInfo;

import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -76,4 +79,18 @@ public class ActivityEmbeddingAnimationRunnerTests extends ActivityEmbeddingAnim

        verify(mController).onAnimationFinished(mTransition);
    }

    @Test
    public void testChangesBehindStartingWindow() {
        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
        final TransitionInfo.Change embeddingChange = createChange();
        embeddingChange.setFlags(FLAG_IS_BEHIND_STARTING_WINDOW);
        info.addChange(embeddingChange);
        final Animator animator = mAnimRunner.createAnimator(
                info, mStartTransaction, mFinishTransaction,
                () -> mFinishCallback.onTransitionFinished(null /* wct */, null /* wctCB */));

        // The animation should be empty when it is behind starting window.
        assertEquals(0, animator.getDuration());
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import static android.view.WindowManager.transitTypeToString;
import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS;
import static android.window.TransitionInfo.FLAG_FILLS_TASK;
import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
import static android.window.TransitionInfo.FLAG_IS_INPUT_METHOD;
import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION;
@@ -1894,6 +1895,10 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
                    // Whether this is in a Task with embedded activity.
                    flags |= FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
                }
                if (parentTask.forAllActivities(ActivityRecord::hasStartingWindow)) {
                    // The starting window should cover all windows inside the leaf Task.
                    flags |= FLAG_IS_BEHIND_STARTING_WINDOW;
                }
                if (isWindowFillingTask(wc, parentTask)) {
                    // Whether the container fills its parent Task bounds.
                    flags |= FLAG_FILLS_TASK;
+34 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.window.TransitionInfo.FLAG_FILLS_TASK;
import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
@@ -1073,6 +1074,39 @@ public class TransitionTests extends WindowTestsBase {
        assertTrue(openTransition.allReady());
    }

    @Test
    public void testIsBehindStartingWindowChange() {
        final Transition transition = createTestTransition(TRANSIT_OPEN);
        final ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
        final ArraySet<WindowContainer> participants = transition.mParticipants;

        final Task task = createTask(mDisplayContent);
        final ActivityRecord activity0 = createActivityRecord(task);
        final ActivityRecord activity1 = createActivityRecord(task);
        doReturn(true).when(activity1).hasStartingWindow();

        // Start states.
        changes.put(activity0, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
        changes.put(activity1, new Transition.ChangeInfo(false /* vis */, false /* exChg */));
        // End states.
        activity0.mVisibleRequested = false;
        activity1.mVisibleRequested = true;

        participants.add(activity0);
        participants.add(activity1);
        final ArrayList<WindowContainer> targets = Transition.calculateTargets(
                participants, changes);
        final TransitionInfo info = Transition.calculateTransitionInfo(
                transition.mType, 0 /* flags */, targets, changes, mMockT);

        // All windows in the Task should have FLAG_IS_BEHIND_STARTING_WINDOW because the starting
        // window should cover the whole Task.
        assertEquals(2, info.getChanges().size());
        assertTrue(info.getChanges().get(0).hasFlags(FLAG_IS_BEHIND_STARTING_WINDOW));
        assertTrue(info.getChanges().get(1).hasFlags(FLAG_IS_BEHIND_STARTING_WINDOW));

    }

    @Test
    public void testFlagInTaskWithEmbeddedActivity() {
        final Transition transition = createTestTransition(TRANSIT_OPEN);