diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 2195b83933a56..218ca58dee548 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -285,11 +285,17 @@ public interface WindowManager extends ViewManager { int TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER = 21; /** - * Keyguard is being occluded. + * Keyguard is being occluded by non-Dream. * @hide */ int TRANSIT_OLD_KEYGUARD_OCCLUDE = 22; + /** + * Keyguard is being occluded by Dream. + * @hide + */ + int TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM = 33; + /** * Keyguard is being unoccluded. * @hide diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index 6dfbd426ef305..2da92326a7fd9 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -29,6 +29,7 @@ import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE; +import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE; import static android.view.WindowManager.TRANSIT_OLD_NONE; import static android.view.WindowManager.TRANSIT_OPEN; @@ -189,6 +190,9 @@ public class KeyguardService extends Service { return apps.length == 0 ? TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER : TRANSIT_OLD_KEYGUARD_GOING_AWAY; } else if (type == TRANSIT_KEYGUARD_OCCLUDE) { + boolean isOccludeByDream = apps.length > 0 && apps[0].taskInfo.topActivityType + == WindowConfiguration.ACTIVITY_TYPE_DREAM; + if (isOccludeByDream) return TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM; return TRANSIT_OLD_KEYGUARD_OCCLUDE; } else if (type == TRANSIT_KEYGUARD_UNOCCLUDE) { return TRANSIT_OLD_KEYGUARD_UNOCCLUDE; @@ -303,6 +307,12 @@ public class KeyguardService extends Service { definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_OCCLUDE, occludeAnimationAdapter); + final RemoteAnimationAdapter occludeByDreamAnimationAdapter = + new RemoteAnimationAdapter( + mKeyguardViewMediator.getOccludeByDreamAnimationRunner(), 0, 0); + definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM, + occludeByDreamAnimationAdapter); + final RemoteAnimationAdapter unoccludeAnimationAdapter = new RemoteAnimationAdapter( mKeyguardViewMediator.getUnoccludeAnimationRunner(), 0, 0); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index d4ef4675392d6..d4e0f061ba060 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -887,6 +887,86 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, private IRemoteAnimationRunner mOccludeAnimationRunner = new OccludeActivityLaunchRemoteAnimationRunner(mOccludeAnimationController); + private final IRemoteAnimationRunner mOccludeByDreamAnimationRunner = + new IRemoteAnimationRunner.Stub() { + @Nullable private ValueAnimator mOccludeByDreamAnimator; + + @Override + public void onAnimationCancelled(boolean isKeyguardOccluded) { + if (mOccludeByDreamAnimator != null) { + mOccludeByDreamAnimator.cancel(); + } + setOccluded(isKeyguardOccluded /* isOccluded */, false /* animate */); + if (DEBUG) { + Log.d(TAG, "Occlude by Dream animation cancelled. Occluded state is now: " + + mOccluded); + } + } + + @Override + public void onAnimationStart(int transit, RemoteAnimationTarget[] apps, + RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, + IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException { + setOccluded(true /* isOccluded */, true /* animate */); + + if (apps == null || apps.length == 0 || apps[0] == null) { + if (DEBUG) { + Log.d(TAG, "No apps provided to the OccludeByDream runner; " + + "skipping occluding animation."); + } + finishedCallback.onAnimationFinished(); + return; + } + + final RemoteAnimationTarget primary = apps[0]; + final boolean isDream = (apps[0].taskInfo.topActivityType + == WindowConfiguration.ACTIVITY_TYPE_DREAM); + if (!isDream) { + Log.w(TAG, "The occluding app isn't Dream; " + + "finishing up. Please check that the config is correct."); + finishedCallback.onAnimationFinished(); + return; + } + + final SyncRtSurfaceTransactionApplier applier = + new SyncRtSurfaceTransactionApplier( + mKeyguardViewControllerLazy.get().getViewRootImpl().getView()); + + mContext.getMainExecutor().execute(() -> { + if (mOccludeByDreamAnimator != null) { + mOccludeByDreamAnimator.cancel(); + } + + mOccludeByDreamAnimator = ValueAnimator.ofFloat(0f, 1f); + // Use the same duration as for the UNOCCLUDE. + mOccludeByDreamAnimator.setDuration(UNOCCLUDE_ANIMATION_DURATION); + mOccludeByDreamAnimator.setInterpolator(Interpolators.LINEAR); + mOccludeByDreamAnimator.addUpdateListener( + animation -> { + SyncRtSurfaceTransactionApplier.SurfaceParams.Builder + paramsBuilder = + new SyncRtSurfaceTransactionApplier.SurfaceParams + .Builder(primary.leash) + .withAlpha(animation.getAnimatedFraction()); + applier.scheduleApply(paramsBuilder.build()); + }); + mOccludeByDreamAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + try { + finishedCallback.onAnimationFinished(); + mOccludeByDreamAnimator = null; + } catch (RemoteException e) { + e.printStackTrace(); + } + } + }); + + mOccludeByDreamAnimator.start(); + }); + } + }; + /** * Animation controller for activities that unocclude the keyguard. This does not use the * ActivityLaunchAnimator since we're just translating down, rather than emerging from a view @@ -1682,6 +1762,10 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, return mOccludeAnimationRunner; } + public IRemoteAnimationRunner getOccludeByDreamAnimationRunner() { + return mOccludeByDreamAnimationRunner; + } + public IRemoteAnimationRunner getUnoccludeAnimationRunner() { return mUnoccludeAnimationRunner; } diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 53f2c71466562..5c1a877cc8652 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -39,6 +39,7 @@ import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_OPEN; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE; +import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE; import static android.view.WindowManager.TRANSIT_OLD_NONE; import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE; @@ -758,7 +759,8 @@ public class AppTransition implements Dump { if (isKeyguardGoingAwayTransitOld(transit) && enter) { a = mTransitionAnimation.loadKeyguardExitAnimation(mNextAppTransitionFlags, transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER); - } else if (transit == TRANSIT_OLD_KEYGUARD_OCCLUDE) { + } else if (transit == TRANSIT_OLD_KEYGUARD_OCCLUDE + || transit == TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM) { a = null; } else if (transit == TRANSIT_OLD_KEYGUARD_UNOCCLUDE && !enter) { a = mTransitionAnimation.loadKeyguardUnoccludeAnimation(); @@ -1170,6 +1172,9 @@ public class AppTransition implements Dump { case TRANSIT_OLD_KEYGUARD_OCCLUDE: { return "TRANSIT_OLD_KEYGUARD_OCCLUDE"; } + case TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM: { + return "TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM"; + } case TRANSIT_OLD_KEYGUARD_UNOCCLUDE: { return "TRANSIT_OLD_KEYGUARD_UNOCCLUDE"; } @@ -1425,6 +1430,7 @@ public class AppTransition implements Dump { static boolean isKeyguardOccludeTransitOld(@TransitionOldType int transit) { return transit == TRANSIT_OLD_KEYGUARD_OCCLUDE + || transit == TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM || transit == TRANSIT_OLD_KEYGUARD_UNOCCLUDE; } diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java index 5ac5f2e4bdaf8..5599f2cfc374f 100644 --- a/services/core/java/com/android/server/wm/AppTransitionController.java +++ b/services/core/java/com/android/server/wm/AppTransitionController.java @@ -38,6 +38,7 @@ import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_OPEN; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE; +import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE; import static android.view.WindowManager.TRANSIT_OLD_NONE; import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE; @@ -363,8 +364,14 @@ public class AppTransitionController { // When there is a closing app, the keyguard has already been occluded by an // activity, and another activity has started on top of that activity, so normal // app transition animation should be used. - return closingApps.isEmpty() ? TRANSIT_OLD_KEYGUARD_OCCLUDE - : TRANSIT_OLD_ACTIVITY_OPEN; + if (!closingApps.isEmpty()) { + return TRANSIT_OLD_ACTIVITY_OPEN; + } + if (!openingApps.isEmpty() && openingApps.valueAt(0).getActivityType() + == ACTIVITY_TYPE_DREAM) { + return TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM; + } + return TRANSIT_OLD_KEYGUARD_OCCLUDE; case TRANSIT_KEYGUARD_UNOCCLUDE: return TRANSIT_OLD_KEYGUARD_UNOCCLUDE; }