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

Commit 4e69814c authored by Robin Lee's avatar Robin Lee Committed by Automerger Merge Worker
Browse files

Transition flags for Keyguard un/occlude/cancel am: ee8da1ae

parents 4cc8e7aa ee8da1ae
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -435,11 +435,15 @@ public interface WindowManager extends ViewManager {
    int TRANSIT_KEYGUARD_GOING_AWAY = 7;
    /**
     * A window is appearing above a locked keyguard.
     * @deprecated use {@link #TRANSIT_TO_FRONT} + {@link #TRANSIT_FLAG_KEYGUARD_OCCLUDING} for
     *             keyguard occluding with Shell transition.
     * @hide
     */
    int TRANSIT_KEYGUARD_OCCLUDE = 8;
    /**
     * A window is made invisible revealing a locked keyguard.
     * @deprecated use {@link #TRANSIT_TO_BACK} + {@link #TRANSIT_FLAG_KEYGUARD_UNOCCLUDING} for
     *             keyguard occluding with Shell transition.
     * @hide
     */
    int TRANSIT_KEYGUARD_UNOCCLUDE = 9;
@@ -561,6 +565,25 @@ public interface WindowManager extends ViewManager {
     */
    int TRANSIT_FLAG_INVISIBLE = (1 << 10); // 0x400

    /**
     * Transition flag: Indicates that keyguard will be showing (locked) with this transition,
     * which is the opposite of {@link #TRANSIT_FLAG_KEYGUARD_GOING_AWAY}.
     * @hide
     */
    int TRANSIT_FLAG_KEYGUARD_APPEARING = (1 << 11); // 0x800

    /**
     * Transition flag: Indicates that keyguard is becoming hidden by an app
     * @hide
     */
    int TRANSIT_FLAG_KEYGUARD_OCCLUDING = (1 << 12); // 0x1000

    /**
     * Transition flag: Indicates that keyguard is being revealed after an app was occluding it.
     * @hide
     */
    int TRANSIT_FLAG_KEYGUARD_UNOCCLUDING = (1 << 13); // 0x2000

    /**
     * @hide
     */
@@ -576,10 +599,27 @@ public interface WindowManager extends ViewManager {
            TRANSIT_FLAG_KEYGUARD_GOING_AWAY,
            TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT,
            TRANSIT_FLAG_INVISIBLE,
            TRANSIT_FLAG_KEYGUARD_APPEARING,
            TRANSIT_FLAG_KEYGUARD_OCCLUDING,
            TRANSIT_FLAG_KEYGUARD_UNOCCLUDING
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface TransitionFlags {}

    /**
     * Transit flags used to signal keyguard visibility is changing for animations.
     *
     * <p>These roughly correspond to CLOSE, OPEN, TO_BACK, and TO_FRONT on a hypothetical Keyguard
     * container. Since Keyguard isn't a container we can't include it in changes and need to send
     * this information in its own channel.
     * @hide
     */
    int KEYGUARD_VISIBILITY_TRANSIT_FLAGS =
            (TRANSIT_FLAG_KEYGUARD_GOING_AWAY
            | TRANSIT_FLAG_KEYGUARD_APPEARING
            | TRANSIT_FLAG_KEYGUARD_OCCLUDING
            | TRANSIT_FLAG_KEYGUARD_UNOCCLUDING);

    /**
     * Remove content mode: Indicates remove content mode is currently not defined.
     * @hide
+0 −7
Original line number Diff line number Diff line
@@ -99,9 +99,6 @@ public final class TransitionInfo implements Parcelable {
    /** The container is the display. */
    public static final int FLAG_IS_DISPLAY = 1 << 5;

    /** The container can show on top of lock screen. */
    public static final int FLAG_OCCLUDES_KEYGUARD = 1 << 6;

    /**
     * Only for IS_DISPLAY containers. Is set if the display has system alert windows. This is
     * used to prevent seamless rotation.
@@ -175,7 +172,6 @@ public final class TransitionInfo implements Parcelable {
            FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT,
            FLAG_IS_VOICE_INTERACTION,
            FLAG_IS_DISPLAY,
            FLAG_OCCLUDES_KEYGUARD,
            FLAG_DISPLAY_HAS_ALERT_WINDOWS,
            FLAG_IS_INPUT_METHOD,
            FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY,
@@ -457,9 +453,6 @@ public final class TransitionInfo implements Parcelable {
        if ((flags & FLAG_IS_DISPLAY) != 0) {
            sb.append(sb.length() == 0 ? "" : "|").append("IS_DISPLAY");
        }
        if ((flags & FLAG_OCCLUDES_KEYGUARD) != 0) {
            sb.append(sb.length() == 0 ? "" : "|").append("OCCLUDES_KEYGUARD");
        }
        if ((flags & FLAG_DISPLAY_HAS_ALERT_WINDOWS) != 0) {
            sb.append(sb.length() == 0 ? "" : "|").append("DISPLAY_HAS_ALERT_WINDOWS");
        }
+63 −58
Original line number Diff line number Diff line
@@ -17,31 +17,25 @@
package com.android.wm.shell.keyguard;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_SLEEP;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED;
import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
import static android.window.TransitionInfo.FLAG_OCCLUDES_KEYGUARD;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_APPEARING;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_OCCLUDING;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_UNOCCLUDING;
import static android.view.WindowManager.TRANSIT_SLEEP;

import static com.android.wm.shell.util.TransitionUtil.isOpeningType;
import static com.android.wm.shell.util.TransitionUtil.isClosingType;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.RemoteException;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Log;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.IRemoteTransition;
import android.window.IRemoteTransitionFinishedCallback;
import android.window.TransitionInfo;
@@ -56,8 +50,6 @@ import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.transition.Transitions.TransitionFinishCallback;

import java.util.Map;

/**
 * The handler for Keyguard enter/exit and occlude/unocclude animations.
 *
@@ -70,7 +62,7 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
    private final Handler mMainHandler;
    private final ShellExecutor mMainExecutor;

    private final Map<IBinder, IRemoteTransition> mStartedTransitions = new ArrayMap<>();
    private final ArrayMap<IBinder, StartedTransition> mStartedTransitions = new ArrayMap<>();

    /**
     * Local IRemoteTransition implementations registered by the keyguard service.
@@ -81,6 +73,18 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
    private IRemoteTransition mOccludeByDreamTransition = null;
    private IRemoteTransition mUnoccludeTransition = null;

    private final class StartedTransition {
        final TransitionInfo mInfo;
        final SurfaceControl.Transaction mFinishT;
        final IRemoteTransition mPlayer;

        public StartedTransition(TransitionInfo info,
                SurfaceControl.Transaction finishT, IRemoteTransition player) {
            mInfo = info;
            mFinishT = finishT;
            mPlayer = player;
        }
    }
    public KeyguardTransitionHandler(
            @NonNull ShellInit shellInit,
            @NonNull Transitions transitions,
@@ -105,10 +109,7 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
    }

    public static boolean handles(TransitionInfo info) {
        return (info.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0
                || (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0
                || info.getType() == TRANSIT_KEYGUARD_OCCLUDE
                || info.getType() == TRANSIT_KEYGUARD_UNOCCLUDE;
        return (info.getFlags() & KEYGUARD_VISIBILITY_TRANSIT_FLAGS) != 0;
    }

    @Override
@@ -120,39 +121,14 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
            return false;
        }

        boolean hasOpeningOcclude = false;
        boolean hasClosingOcclude = false;
        boolean hasOpeningDream = false;
        boolean hasClosingApp = false;

        // Check for occluding/dream/closing apps
        for (int i = info.getChanges().size() - 1; i >= 0; i--) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            if ((change.getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0) {
                continue;
            } else if (isOpeningType(change.getMode())) {
                hasOpeningOcclude |= change.hasFlags(FLAG_OCCLUDES_KEYGUARD);
                hasOpeningDream |= (change.getTaskInfo() != null
                        && change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_DREAM);
            } else if (isClosingType(change.getMode())) {
                hasClosingOcclude |= change.hasFlags(FLAG_OCCLUDES_KEYGUARD);
                hasClosingApp = true;
            }
        }

        // Choose a transition applicable for the changes and keyguard state.
        if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0) {
            return startAnimation(mExitTransition,
                    "going-away",
                    transition, info, startTransaction, finishTransaction, finishCallback);
        }
        if (hasOpeningOcclude || info.getType() == TRANSIT_KEYGUARD_OCCLUDE) {
            if (hasClosingOcclude) {
                // Transitions between apps on top of the keyguard can use the default handler.
                // WM sends a final occlude status update after the transition is finished.
                return false;
            }
            if (hasOpeningDream) {
        if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_OCCLUDING) != 0) {
            if (hasOpeningDream(info)) {
                return startAnimation(mOccludeByDreamTransition,
                        "occlude-by-dream",
                        transition, info, startTransaction, finishTransaction, finishCallback);
@@ -161,12 +137,12 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
                        "occlude",
                        transition, info, startTransaction, finishTransaction, finishCallback);
            }
        } else if (hasClosingApp || info.getType() == TRANSIT_KEYGUARD_UNOCCLUDE) {
        } else if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_UNOCCLUDING) != 0) {
             return startAnimation(mUnoccludeTransition,
                    "unocclude",
                    transition, info, startTransaction, finishTransaction, finishCallback);
        } else {
            Log.w(TAG, "Failed to play: " + info);
            Log.i(TAG, "Refused to play keyguard transition: " + info);
            return false;
        }
    }
@@ -194,7 +170,8 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
                            });
                        }
                    });
            mStartedTransitions.put(transition, remoteHandler);
            mStartedTransitions.put(transition,
                    new StartedTransition(info, finishTransaction, remoteHandler));
        } catch (RemoteException e) {
            Log.wtf(TAG, "RemoteException thrown from local IRemoteTransition", e);
            return false;
@@ -207,20 +184,35 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
    public void mergeAnimation(@NonNull IBinder nextTransition, @NonNull TransitionInfo nextInfo,
            @NonNull SurfaceControl.Transaction nextT, @NonNull IBinder currentTransition,
            @NonNull TransitionFinishCallback nextFinishCallback) {
        final IRemoteTransition playing = mStartedTransitions.get(currentTransition);

        final StartedTransition playing = mStartedTransitions.get(currentTransition);
        if (playing == null) {
            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
                    "unknown keyguard transition %s", currentTransition);
            return;
        }

        if (nextInfo.getType() == TRANSIT_SLEEP) {
        if ((nextInfo.getFlags() & WindowManager.TRANSIT_FLAG_KEYGUARD_APPEARING) != 0
                && (playing.mInfo.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0) {
            // Keyguard unlocking has been canceled. Merge the unlock and re-lock transitions to
            // avoid a flicker where we flash one frame with the screen fully unlocked.
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
                    "canceling keyguard exit transition %s", currentTransition);
            playing.mFinishT.merge(nextT);
            try {
                playing.mPlayer.mergeAnimation(nextTransition, nextInfo, nextT, currentTransition,
                        new FakeFinishCallback());
            } catch (RemoteException e) {
                // There is no good reason for this to happen because the player is a local object
                // implementing an AIDL interface.
                Log.wtf(TAG, "RemoteException thrown from KeyguardService transition", e);
            }
            nextFinishCallback.onTransitionFinished(null, null);
        } else if (nextInfo.getType() == TRANSIT_SLEEP) {
            // An empty SLEEP transition comes in as a signal to abort transitions whenever a sleep
            // token is held. In cases where keyguard is showing, we are running the animation for
            // the device sleeping/waking, so it's best to ignore this and keep playing anyway.
            return;
        } else {
        } else if (handles(nextInfo)) {
            // In all other cases, fast-forward to let the next queued transition start playing.
            finishAnimationImmediately(currentTransition, playing);
        }
    }
@@ -228,7 +220,7 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
    @Override
    public void onTransitionConsumed(IBinder transition, boolean aborted,
            SurfaceControl.Transaction finishTransaction) {
        final IRemoteTransition playing = mStartedTransitions.remove(transition);
        final StartedTransition playing = mStartedTransitions.remove(transition);
        if (playing != null) {
            finishAnimationImmediately(transition, playing);
        }
@@ -241,13 +233,26 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
        return null;
    }

    private void finishAnimationImmediately(IBinder transition, IRemoteTransition playing) {
    private static boolean hasOpeningDream(@NonNull TransitionInfo info) {
        for (int i = info.getChanges().size() - 1; i >= 0; i--) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            if (isOpeningType(change.getMode())
                    && change.getTaskInfo() != null
                    && change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_DREAM) {
                return true;
            }
        }
        return false;
    }

    private void finishAnimationImmediately(IBinder transition, StartedTransition playing) {
        final IBinder fakeTransition = new Binder();
        final TransitionInfo fakeInfo = new TransitionInfo(TRANSIT_SLEEP, 0x0);
        final SurfaceControl.Transaction fakeT = new SurfaceControl.Transaction();
        final FakeFinishCallback fakeFinishCb = new FakeFinishCallback();
        try {
            playing.mergeAnimation(fakeTransition, fakeInfo, fakeT, transition, fakeFinishCb);
            playing.mPlayer.mergeAnimation(
                    fakeTransition, fakeInfo, fakeT, transition, fakeFinishCb);
        } catch (RemoteException e) {
            // There is no good reason for this to happen because the player is a local object
            // implementing an AIDL interface.
+11 −3
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static com.android.wm.shell.util.TransitionUtil.isOpeningType;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.IBinder;
import android.util.Log;
import android.util.Pair;
import android.view.SurfaceControl;
import android.view.WindowManager;
@@ -566,11 +567,18 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
            @NonNull SurfaceControl.Transaction startTransaction,
            @NonNull SurfaceControl.Transaction finishTransaction,
            @NonNull Transitions.TransitionFinishCallback finishCallback) {
        boolean consumed = mKeyguardHandler.startAnimation(
                mixed.mTransition, info, startTransaction, finishTransaction, finishCallback);
        if (!consumed) {
        final Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> {
            mixed.mInFlightSubAnimations--;
            if (mixed.mInFlightSubAnimations == 0) {
                mActiveTransitions.remove(mixed);
                finishCallback.onTransitionFinished(wct, wctCB);
            }
        };
        if (!mKeyguardHandler.startAnimation(
                mixed.mTransition, info, startTransaction, finishTransaction, finishCB)) {
            return false;
        }
        mixed.mInFlightSubAnimations++;
        // Sync pip state.
        if (mPipHandler != null) {
            // We don't know when to apply `startTransaction` so use a separate transaction here.
+9 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.keyguard;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
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_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
@@ -182,8 +183,8 @@ public class KeyguardService extends Service {

    // Wrap Keyguard going away animation.
    // Note: Also used for wrapping occlude by Dream animation. It works (with some redundancy).
    public static IRemoteTransition wrap(IRemoteAnimationRunner runner,
            boolean lockscreenLiveWallpaperEnabled) {
    public static IRemoteTransition wrap(final KeyguardViewMediator keyguardViewMediator,
        final IRemoteAnimationRunner runner, final boolean lockscreenLiveWallpaperEnabled) {
        return new IRemoteTransition.Stub() {

            private final ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = new ArrayMap<>();
@@ -239,6 +240,12 @@ public class KeyguardService extends Service {
                    SurfaceControl.Transaction candidateT, IBinder currentTransition,
                    IRemoteTransitionFinishedCallback candidateFinishCallback)
                    throws RemoteException {
                if ((candidateInfo.getFlags() & TRANSIT_FLAG_KEYGUARD_APPEARING) != 0) {
                    keyguardViewMediator.setPendingLock(true);
                    keyguardViewMediator.cancelKeyguardExitAnimation();
                    return;
                }

                try {
                    synchronized (mLeashMap) {
                        runner.onAnimationCancelled();
Loading