diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java index a81439914ea17..b7de7b8d217b3 100644 --- a/core/java/android/window/TransitionInfo.java +++ b/core/java/android/window/TransitionInfo.java @@ -91,8 +91,11 @@ 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; + /** 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 << 6; + public static final int FLAG_FIRST_CUSTOM = 1 << 7; /** @hide */ @IntDef(prefix = { "FLAG_" }, value = { @@ -103,6 +106,7 @@ public final class TransitionInfo implements Parcelable { FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT, FLAG_IS_VOICE_INTERACTION, FLAG_IS_DISPLAY, + FLAG_OCCLUDES_KEYGUARD, FLAG_FIRST_CUSTOM }) public @interface ChangeFlags {} @@ -234,7 +238,7 @@ public final class TransitionInfo implements Parcelable { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("{t=" + transitTypeToString(mType) + " f=" + Integer.toHexString(mFlags) + sb.append("{t=" + transitTypeToString(mType) + " f=0x" + Integer.toHexString(mFlags) + " ro=" + mRootOffset + " c=["); for (int i = 0; i < mChanges.size(); ++i) { if (i > 0) { @@ -283,6 +287,9 @@ public final class TransitionInfo implements Parcelable { if ((flags & FLAG_IS_DISPLAY) != 0) { sb.append((sb.length() == 0 ? "" : "|") + "IS_DISPLAY"); } + if ((flags & FLAG_OCCLUDES_KEYGUARD) != 0) { + sb.append((sb.length() == 0 ? "" : "|") + "OCCLUDES_KEYGUARD"); + } if ((flags & FLAG_FIRST_CUSTOM) != 0) { sb.append((sb.length() == 0 ? "" : "|") + "FIRST_CUSTOM"); } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index 391e6defd7e88..f2e60e0531978 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -20,6 +20,8 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.RemoteAnimationTarget.MODE_OPENING; +import static android.view.WindowManager.TRANSIT_CLOSE; +import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED; 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; @@ -28,8 +30,12 @@ import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALL import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE; import static android.view.WindowManager.TRANSIT_OLD_NONE; +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.WindowManager.TransitionOldType; import static android.view.WindowManager.TransitionType; +import static android.window.TransitionInfo.FLAG_OCCLUDES_KEYGUARD; import android.app.ActivityManager; import android.app.ActivityTaskManager; @@ -231,9 +237,42 @@ public class KeyguardService extends Service { } if (sEnableRemoteKeyguardOccludeAnimation) { Slog.d(TAG, "KeyguardService registerRemote: TRANSIT_KEYGUARD_(UN)OCCLUDE"); + // Register for occluding TransitionFilter f = new TransitionFilter(); - f.mTypeSet = new int[]{TRANSIT_KEYGUARD_OCCLUDE, TRANSIT_KEYGUARD_UNOCCLUDE}; - shellTransitions.registerRemote(f, wrap(mOccludeAnimationRunner)); + f.mFlags = TRANSIT_FLAG_KEYGUARD_LOCKED; + f.mRequirements = new TransitionFilter.Requirement[]{ + new TransitionFilter.Requirement(), new TransitionFilter.Requirement()}; + // First require at-least one app showing that occludes. + f.mRequirements[0].mMustBeIndependent = false; + f.mRequirements[0].mFlags = FLAG_OCCLUDES_KEYGUARD; + f.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT}; + // Then require that we aren't closing any occludes (because this would mean a + // regular task->task or activity->activity animation not involving keyguard). + f.mRequirements[1].mNot = true; + f.mRequirements[1].mMustBeIndependent = false; + f.mRequirements[1].mFlags = FLAG_OCCLUDES_KEYGUARD; + f.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK}; + shellTransitions.registerRemote(f, mOccludeAnimation); + + // Now register for un-occlude. + f = new TransitionFilter(); + f.mFlags = TRANSIT_FLAG_KEYGUARD_LOCKED; + f.mRequirements = new TransitionFilter.Requirement[]{ + new TransitionFilter.Requirement(), new TransitionFilter.Requirement()}; + // First require at-least one app going-away (doesn't need occlude flag + // as that is implicit by it having been visible and we don't want to exclude + // cases where we are un-occluding because the app removed its showWhenLocked + // capability at runtime). + f.mRequirements[1].mMustBeIndependent = false; + f.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK}; + f.mRequirements[1].mMustBeTask = true; + // Then require that we aren't opening any occludes (otherwise we'd remain + // occluded). + f.mRequirements[0].mNot = true; + f.mRequirements[0].mMustBeIndependent = false; + f.mRequirements[0].mFlags = FLAG_OCCLUDES_KEYGUARD; + f.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT}; + shellTransitions.registerRemote(f, mUnoccludeAnimation); } } else { RemoteAnimationDefinition definition = new RemoteAnimationDefinition(); @@ -328,6 +367,40 @@ public class KeyguardService extends Service { } }; + final IRemoteTransition mOccludeAnimation = new IRemoteTransition.Stub() { + @Override + public void startAnimation(IBinder transition, TransitionInfo info, + SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback) + throws RemoteException { + t.apply(); + mBinder.setOccluded(true /* isOccluded */, true /* animate */); + finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */); + } + + @Override + public void mergeAnimation(IBinder transition, TransitionInfo info, + SurfaceControl.Transaction t, IBinder mergeTarget, + IRemoteTransitionFinishedCallback finishCallback) { + } + }; + + final IRemoteTransition mUnoccludeAnimation = new IRemoteTransition.Stub() { + @Override + public void startAnimation(IBinder transition, TransitionInfo info, + SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback) + throws RemoteException { + t.apply(); + mBinder.setOccluded(false /* isOccluded */, true /* animate */); + finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */); + } + + @Override + public void mergeAnimation(IBinder transition, TransitionInfo info, + SurfaceControl.Transaction t, IBinder mergeTarget, + IRemoteTransitionFinishedCallback finishCallback) { + } + }; + private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() { @Override // Binder interface diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 43165f82d9dec..6bfa611d7a98b 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -39,6 +39,7 @@ import static android.view.WindowManager.transitTypeToString; import static android.window.TransitionInfo.FLAG_IS_DISPLAY; import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; +import static android.window.TransitionInfo.FLAG_OCCLUDES_KEYGUARD; import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER; import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT; import static android.window.TransitionInfo.FLAG_TRANSLUCENT; @@ -705,6 +706,22 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe return wc.asWallpaperToken() != null; } + private static boolean occludesKeyguard(WindowContainer wc) { + final ActivityRecord ar = wc.asActivityRecord(); + if (ar != null) { + return ar.canShowWhenLocked(); + } + final Task t = wc.asTask(); + if (t != null) { + // Get the top activity which was visible (since this is going away, it will remain + // client visible until the transition is finished). + // skip hidden (or about to hide) apps + final ActivityRecord top = t.getActivity(WindowToken::isClientVisible); + return top != null && top.canShowWhenLocked(); + } + return false; + } + /** * Under some conditions (eg. all visible targets within a parent container are transitioning * the same way) the transition can be "promoted" to the parent container. This means an @@ -1153,6 +1170,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe if (isWallpaper(wc)) { flags |= FLAG_IS_WALLPAPER; } + if (occludesKeyguard(wc)) { + flags |= FLAG_OCCLUDES_KEYGUARD; + } return flags; }