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

Commit 490e264e authored by Xin Li's avatar Xin Li Committed by Android (Google) Code Review
Browse files

Merge "Merge UQ1A.231205.015" into aosp-main-future

parents 8adb71ff 5da189e0
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_APPEARING;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
@@ -360,6 +361,15 @@ public final class TransitionInfo implements Parcelable {
        mChanges.add(change);
    }

    /**
     * Whether this transition contains any changes to the window hierarchy,
     * including keyguard visibility.
     */
    public boolean hasChangesOrSideEffects() {
        return !mChanges.isEmpty() || isKeyguardGoingAway()
                || (mFlags & TRANSIT_FLAG_KEYGUARD_APPEARING) != 0;
    }

    /**
     * Whether this transition includes keyguard going away.
     */
+22 −4
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVIT
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
@@ -392,6 +393,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        return mMainStage.isActive();
    }

    /** @return whether this transition-request has the launch-adjacent flag. */
    public boolean requestHasLaunchAdjacentFlag(TransitionRequestInfo request) {
        final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask();
        return triggerTask != null && triggerTask.baseIntent != null
                && (triggerTask.baseIntent.getFlags() & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0;
    }

    /** @return whether the transition-request implies entering pip from split. */
    public boolean requestImpliesSplitToPip(TransitionRequestInfo request) {
        if (!isSplitActive() || !mMixedHandler.requestHasPipEnter(request)) {
@@ -2434,10 +2442,20 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                        EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP);
            }

            // When split in the background, it should be only opening/dismissing transition and
            // would keep out not empty. Prevent intercepting all transitions for split screen when
            // it is in the background and not identify to handle it.
            return (!out.isEmpty() || isSplitScreenVisible()) ? out : null;
            if (!out.isEmpty()) {
                // One of the cases above handled it
                return out;
            } else if (isSplitScreenVisible()) {
                // If split is visible, only defer handling this transition if it's launching
                // adjacent while there is already a split pair -- this may trigger PIP and
                // that should be handled by the mixed handler.
                final boolean deferTransition = requestHasLaunchAdjacentFlag(request)
                    && mMainStage.getChildCount() != 0 && mSideStage.getChildCount() != 0;
                return !deferTransition ? out : null;
            }
            // Don't intercept the transition if we are not handling it as a part of one of the
            // cases above and it is not already visible
            return null;
        } else {
            if (isOpening && getStageOfTask(triggerTask) != null) {
                // One task is appearing into split, prepare to enter split screen.
+9 −15
Original line number Diff line number Diff line
@@ -19,13 +19,12 @@ package com.android.wm.shell.transition;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.IBinder;
import android.util.Slog;
import android.view.SurfaceControl;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerTransaction;

import java.util.ArrayList;

/**
 * A Simple handler that tracks SLEEP transitions. We track them specially since we (ab)use these
 * as sentinels for fast-forwarding through animations when the screen is off.
@@ -34,30 +33,25 @@ import java.util.ArrayList;
 * don't register it like a normal handler.
 */
class SleepHandler implements Transitions.TransitionHandler {
    final ArrayList<IBinder> mSleepTransitions = new ArrayList<>();

    @Override
    public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
            @NonNull SurfaceControl.Transaction startTransaction,
            @NonNull SurfaceControl.Transaction finishTransaction,
            @NonNull Transitions.TransitionFinishCallback finishCallback) {
        mSleepTransitions.remove(transition);
        if (info.hasChangesOrSideEffects()) {
            Slog.e(Transitions.TAG, "Real changes included in a SLEEP transition");
            return false;
        } else {
            startTransaction.apply();
            finishCallback.onTransitionFinished(null);
            return true;
        }
    }

    @Override
    @Nullable
    public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
            @NonNull TransitionRequestInfo request) {
        mSleepTransitions.add(transition);
        return new WindowContainerTransaction();
    }

    @Override
    public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted,
            @Nullable SurfaceControl.Transaction finishTransaction) {
        mSleepTransitions.remove(transition);
    }
}
+60 −1
Original line number Diff line number Diff line
@@ -1152,7 +1152,7 @@ public class ShellTransitionTests extends ShellTestCase {
    }

    @Test
    public void testEmptyTransitionStillReportsKeyguardGoingAway() {
    public void testEmptyTransition_withKeyguardGoingAway_plays() {
        Transitions transitions = createTestTransitions();
        transitions.replaceDefaultHandlerForTest(mDefaultHandler);

@@ -1170,6 +1170,65 @@ public class ShellTransitionTests extends ShellTestCase {
        assertEquals(1, mDefaultHandler.activeCount());
    }

    @Test
    public void testSleepTransition_withKeyguardGoingAway_plays(){
        Transitions transitions = createTestTransitions();
        transitions.replaceDefaultHandlerForTest(mDefaultHandler);

        IBinder transitToken = new Binder();
        transitions.requestStartTransition(transitToken,
                new TransitionRequestInfo(TRANSIT_SLEEP, null /* trigger */, null /* remote */));

        // Make a no-op transition
        TransitionInfo info = new TransitionInfoBuilder(
                TRANSIT_SLEEP, TRANSIT_FLAG_KEYGUARD_GOING_AWAY, true /* noOp */).build();
        transitions.onTransitionReady(transitToken, info, new StubTransaction(),
                new StubTransaction());

        // If keyguard-going-away flag set, then it shouldn't be aborted.
        assertEquals(1, mDefaultHandler.activeCount());
    }

    @Test
    public void testSleepTransition_withChanges_plays(){
        Transitions transitions = createTestTransitions();
        transitions.replaceDefaultHandlerForTest(mDefaultHandler);

        IBinder transitToken = new Binder();
        transitions.requestStartTransition(transitToken,
                new TransitionRequestInfo(TRANSIT_SLEEP, null /* trigger */, null /* remote */));

        // Make a transition with some changes
        TransitionInfo info = new TransitionInfoBuilder(TRANSIT_SLEEP)
                .addChange(TRANSIT_OPEN).build();
        info.setTrack(0);
        transitions.onTransitionReady(transitToken, info, new StubTransaction(),
                new StubTransaction());

        // If there is an actual change, then it shouldn't be aborted.
        assertEquals(1, mDefaultHandler.activeCount());
    }


    @Test
    public void testSleepTransition_empty_SyncBySleepHandler() {
        Transitions transitions = createTestTransitions();
        transitions.replaceDefaultHandlerForTest(mDefaultHandler);

        IBinder transitToken = new Binder();
        transitions.requestStartTransition(transitToken,
                new TransitionRequestInfo(TRANSIT_SLEEP, null /* trigger */, null /* remote */));

        // Make a no-op transition
        TransitionInfo info = new TransitionInfoBuilder(
                TRANSIT_SLEEP, 0x0, true /* noOp */).build();
        transitions.onTransitionReady(transitToken, info, new StubTransaction(),
                new StubTransaction());

        // If there is nothing to actually play, it should not be offered to handlers.
        assertEquals(0, mDefaultHandler.activeCount());
    }

    @Test
    public void testMultipleTracks() {
        Transitions transitions = createTestTransitions();
+9 −1
Original line number Diff line number Diff line
@@ -554,6 +554,12 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
        if (shouldNotRunAnimation(tilesToReveal)) {
            return;
        }
        // This method has side effects (beings the fake drag, if it returns true). If we have
        // decided that we want to do a tile reveal, we do a last check to verify that we can
        // actually perform a fake drag.
        if (!beginFakeDrag()) {
            return;
        }

        final int lastPageNumber = mPages.size() - 1;
        final TileLayout lastPage = mPages.get(lastPageNumber);
@@ -588,8 +594,10 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
    }

    private boolean shouldNotRunAnimation(Set<String> tilesToReveal) {
        // None of these have side effects. That way, we don't need to rely on short-circuiting
        // behavior
        boolean noAnimationNeeded = tilesToReveal.isEmpty() || mPages.size() < 2;
        boolean scrollingInProgress = getScrollX() != 0 || !beginFakeDrag();
        boolean scrollingInProgress = getScrollX() != 0 || !isFakeDragging();
        // isRunningInTestHarness() to disable animation in functional testing as it caused
        // flakiness and is not needed there. Alternative solutions were more complex and would
        // still be either potentially flaky or modify internal data.
Loading