diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 6714c393d64bb..a91781580ac4f 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -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.
+ *
+ *
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
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index a92ca8a4d3f26..59238b40e0c8e 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -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");
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
index 513638eeb9607..cef7e16663312 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
@@ -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 mStartedTransitions = new ArrayMap<>();
+ private final ArrayMap 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.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 64571e067a832..3ec433e55da96 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -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.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 10db9050caf50..94227bccfced5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -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 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();
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index fe804661914dd..57c7b09759a5f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -205,6 +205,12 @@ class KeyguardUnlockAnimationController @Inject constructor(
*/
var playingCannedUnlockAnimation = false
+ /**
+ * Whether we reached the swipe gesture threshold to dismiss keyguard, or restore it, once
+ * and should ignore any future changes to the dismiss amount before the animation finishes.
+ */
+ var dismissAmountThresholdsReached = false
+
/**
* Remote callback provided by Launcher that allows us to control the Launcher's unlock
* animation and smartspace.
@@ -649,6 +655,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
@VisibleForTesting
fun unlockToLauncherWithInWindowAnimations() {
+ surfaceBehindAlpha = 1f
setSurfaceBehindAppearAmount(1f, wallpapers = false)
try {
@@ -762,6 +769,10 @@ class KeyguardUnlockAnimationController @Inject constructor(
return
}
+ if (dismissAmountThresholdsReached) {
+ return
+ }
+
if (!keyguardStateController.isShowing) {
return
}
@@ -793,6 +804,11 @@ class KeyguardUnlockAnimationController @Inject constructor(
return
}
+ // no-op if we alreaddy reached a threshold.
+ if (dismissAmountThresholdsReached) {
+ return
+ }
+
// no-op if animation is not requested yet.
if (!keyguardViewMediator.get().requestedShowSurfaceBehindKeyguard() ||
!keyguardViewMediator.get().isAnimatingBetweenKeyguardAndSurfaceBehindOrWillBe) {
@@ -807,6 +823,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
!keyguardStateController.isFlingingToDismissKeyguardDuringSwipeGesture &&
dismissAmount >= DISMISS_AMOUNT_EXIT_KEYGUARD_THRESHOLD)) {
setSurfaceBehindAppearAmount(1f)
+ dismissAmountThresholdsReached = true
keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
false /* cancelled */)
}
@@ -941,6 +958,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
wallpaperTargets = null
playingCannedUnlockAnimation = false
+ dismissAmountThresholdsReached = false
willUnlockWithInWindowLauncherAnimations = false
willUnlockWithSmartspaceTransition = false
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 992add63e23ca..6680a431487e2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1352,12 +1352,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
setShowingLocked(false /* showing */, true /* forceCallbacks */);
}
- boolean isLockscreenLwpEnabled = getWallpaperManager().isLockscreenLiveWallpaperEnabled();
+ boolean isLLwpEnabled = getWallpaperManager().isLockscreenLiveWallpaperEnabled();
mKeyguardTransitions.register(
- KeyguardService.wrap(getExitAnimationRunner(), isLockscreenLwpEnabled),
- KeyguardService.wrap(getOccludeAnimationRunner(), isLockscreenLwpEnabled),
- KeyguardService.wrap(getOccludeByDreamAnimationRunner(), isLockscreenLwpEnabled),
- KeyguardService.wrap(getUnoccludeAnimationRunner(), isLockscreenLwpEnabled));
+ KeyguardService.wrap(this, getExitAnimationRunner(), isLLwpEnabled),
+ KeyguardService.wrap(this, getOccludeAnimationRunner(), isLLwpEnabled),
+ KeyguardService.wrap(this, getOccludeByDreamAnimationRunner(), isLLwpEnabled),
+ KeyguardService.wrap(this, getUnoccludeAnimationRunner(), isLLwpEnabled));
final ContentResolver cr = mContext.getContentResolver();
@@ -2906,6 +2906,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
// re-locking. We should just end the surface-behind animation without exiting the
// keyguard. The pending lock will be handled by onFinishedGoingToSleep().
finishSurfaceBehindRemoteAnimation(true);
+ maybeHandlePendingLock();
} else {
Log.d(TAG, "#handleCancelKeyguardExitAnimation: keyguard exit animation cancelled. "
+ "No pending lock, we should end up unlocked with the app/launcher visible.");
@@ -3261,8 +3262,6 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
/**
* Cancel the keyguard exit animation, usually because we were swiping to unlock but WM starts
* a new remote animation before finishing the keyguard exit animation.
- *
- * This will dismiss the keyguard.
*/
public void cancelKeyguardExitAnimation() {
Trace.beginSection("KeyguardViewMediator#cancelKeyguardExitAnimation");
@@ -3435,7 +3434,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
}
}
- private void setPendingLock(boolean hasPendingLock) {
+ public void setPendingLock(boolean hasPendingLock) {
mPendingLock = hasPendingLock;
Trace.traceCounter(Trace.TRACE_TAG_APP, "pendingLock", mPendingLock ? 1 : 0);
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 6aec96988a772..7fc86b0fdc016 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5602,17 +5602,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
*/
void requestTransitionAndLegacyPrepare(@WindowManager.TransitionType int transit,
@WindowManager.TransitionFlags int flags) {
- prepareAppTransition(transit, flags);
- mTransitionController.requestTransitionIfNeeded(transit, flags,
- null /* trigger */, this);
+ requestTransitionAndLegacyPrepare(transit, flags, null /* trigger */);
}
/** @see #requestTransitionAndLegacyPrepare(int, int) */
void requestTransitionAndLegacyPrepare(@WindowManager.TransitionType int transit,
- @Nullable WindowContainer trigger) {
- prepareAppTransition(transit);
- mTransitionController.requestTransitionIfNeeded(transit, 0 /* flags */,
- trigger, this);
+ @WindowManager.TransitionFlags int flags, @Nullable WindowContainer trigger) {
+ prepareAppTransition(transit, flags);
+ mTransitionController.requestTransitionIfNeeded(transit, flags, trigger, this);
}
void executeAppTransition() {
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 99878a3d0ffe5..ad9c3b2742673 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -19,17 +19,21 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
+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_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_OCCLUDING;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_UNOCCLUDING;
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;
@@ -171,10 +175,11 @@ class KeyguardController {
final KeyguardDisplayState state = getDisplayState(displayId);
final boolean aodChanged = aodShowing != state.mAodShowing;
final boolean aodRemoved = state.mAodShowing && !aodShowing;
+ final boolean goingAwayRemoved = state.mKeyguardGoingAway && keyguardShowing;
// If keyguard is going away, but SystemUI aborted the transition, need to reset state.
// Do not reset keyguardChanged status when only AOD is removed.
final boolean keyguardChanged = (keyguardShowing != state.mKeyguardShowing)
- || (state.mKeyguardGoingAway && keyguardShowing && !aodRemoved);
+ || (goingAwayRemoved && !aodRemoved);
if (aodRemoved) {
updateDeferTransitionForAod(false /* waiting */);
}
@@ -214,6 +219,15 @@ class KeyguardController {
if (keyguardShowing) {
state.mDismissalRequested = false;
}
+ if (goingAwayRemoved) {
+ // Keyguard dismiss is canceled. Send a transition to undo the changes and clean up
+ // before holding the sleep token again.
+ final DisplayContent dc = mRootWindowContainer.getDefaultDisplay();
+ dc.requestTransitionAndLegacyPrepare(
+ TRANSIT_TO_FRONT, TRANSIT_FLAG_KEYGUARD_APPEARING);
+ dc.mWallpaperController.showWallpaperInTransition(false /* showHome */);
+ mWindowManager.executeAppTransition();
+ }
}
// Update the sleep token first such that ensureActivitiesVisible has correct sleep token
@@ -269,7 +283,7 @@ class KeyguardController {
updateKeyguardSleepToken();
// Make the home wallpaper visible
- dc.mWallpaperController.showHomeWallpaperInTransition();
+ dc.mWallpaperController.showWallpaperInTransition(true /* showHome */);
// Some stack visibility might change (e.g. docked stack)
mRootWindowContainer.resumeFocusedTasksTopActivities();
mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
@@ -413,10 +427,12 @@ class KeyguardController {
if (isDisplayOccluded(DEFAULT_DISPLAY)) {
mRootWindowContainer.getDefaultDisplay().requestTransitionAndLegacyPrepare(
TRANSIT_KEYGUARD_OCCLUDE,
+ TRANSIT_FLAG_KEYGUARD_OCCLUDING,
topActivity != null ? topActivity.getRootTask() : null);
} else {
mRootWindowContainer.getDefaultDisplay().requestTransitionAndLegacyPrepare(
- TRANSIT_KEYGUARD_UNOCCLUDE, 0 /* flags */);
+ TRANSIT_KEYGUARD_UNOCCLUDE,
+ TRANSIT_FLAG_KEYGUARD_UNOCCLUDING);
}
updateKeyguardSleepToken(DEFAULT_DISPLAY);
mWindowManager.executeAppTransition();
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index b938b9e4ec51e..9a5f766989ca8 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -52,7 +52,6 @@ import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;
import static android.window.TransitionInfo.FLAG_NO_ANIMATION;
-import static android.window.TransitionInfo.FLAG_OCCLUDES_KEYGUARD;
import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
import static android.window.TransitionInfo.FLAG_TASK_LAUNCHING_BEHIND;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
@@ -2820,9 +2819,6 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
}
}
}
- if (occludesKeyguard(wc)) {
- flags |= FLAG_OCCLUDES_KEYGUARD;
- }
if ((mFlags & FLAG_CHANGE_NO_ANIMATION) != 0
&& (mFlags & FLAG_CHANGE_YES_ANIMATION) == 0) {
flags |= FLAG_NO_ANIMATION;
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 1c6a412e54503..0cb6f14b38f2c 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -16,10 +16,10 @@
package com.android.server.wm;
+import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_IS_RECENTS;
-import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
@@ -619,9 +619,9 @@ class TransitionController {
}
// Make the collecting transition wait until this request is ready.
mCollectingTransition.setReady(readyGroupRef, false);
- if ((flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0) {
- // Add keyguard flag to dismiss keyguard
- mCollectingTransition.addFlag(flags);
+ if ((flags & KEYGUARD_VISIBILITY_TRANSIT_FLAGS) != 0) {
+ // Add keyguard flags to affect keyguard visibility
+ mCollectingTransition.addFlag(flags & KEYGUARD_VISIBILITY_TRANSIT_FLAGS);
}
} else {
newTransition = requestStartTransition(createTransition(type, flags),
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 4616e6b2a6800..7f41ff1a3d9b7 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -339,12 +339,12 @@ class WallpaperController {
}
/**
- * Change the visibility if wallpaper is home screen only.
+ * Make one wallpaper visible, according to {@attr showHome}.
* This is called during the keyguard unlocking transition
- * (see {@link KeyguardController#keyguardGoingAway(int, int)}) and thus assumes that if the
- * system wallpaper is shared with lock, then it needs no animation.
+ * (see {@link KeyguardController#keyguardGoingAway(int, int)}),
+ * or when a keyguard unlock is cancelled (see {@link KeyguardController})
*/
- public void showHomeWallpaperInTransition() {
+ public void showWallpaperInTransition(boolean showHome) {
updateWallpaperWindowsTarget(mFindResults);
if (!mFindResults.hasTopShowWhenLockedWallpaper()) {
@@ -357,9 +357,9 @@ class WallpaperController {
// Shared wallpaper, ensure its visibility
showWhenLocked.mToken.asWallpaperToken().updateWallpaperWindows(true);
} else {
- // Separate lock and home wallpapers: show home wallpaper and hide lock
- hideWhenLocked.mToken.asWallpaperToken().updateWallpaperWindowsInTransition(true);
- showWhenLocked.mToken.asWallpaperToken().updateWallpaperWindowsInTransition(false);
+ // Separate lock and home wallpapers: show the correct wallpaper in transition
+ hideWhenLocked.mToken.asWallpaperToken().updateWallpaperWindowsInTransition(showHome);
+ showWhenLocked.mToken.asWallpaperToken().updateWallpaperWindowsInTransition(!showHome);
}
}