diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 758609a541e2f..197b7b43be716 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -47,6 +47,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; +import android.graphics.Matrix; import android.hardware.biometrics.BiometricSourceType; import android.media.AudioAttributes; import android.media.AudioManager; @@ -236,6 +237,14 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, */ private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000; + private static final int UNOCCLUDE_ANIMATION_DURATION = 250; + + /** + * How far down to animate the unoccluding activity, in terms of percent of the activity's + * height. + */ + private static final float UNOCCLUDE_TRANSLATE_DISTANCE_PERCENT = 0.1f; + /** * Boolean option for doKeyguardLocked/doKeyguardTimeout which, when set to true, forces the * keyguard to show even if it is disabled for the current user. @@ -883,52 +892,89 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, } }; - /** - * Animation controller for activities that unocclude the keyguard. This will play the launch - * animation in reverse. - */ - private final ActivityLaunchAnimator.Controller mUnoccludeAnimationController = - new ActivityLaunchAnimator.Controller() { - @Override - public void onLaunchAnimationEnd(boolean isExpandingFullyAbove) { - setOccluded(false /* isOccluded */, false /* animate */); - } - - @Override - public void onLaunchAnimationCancelled() { - setOccluded(false /* isOccluded */, false /* animate */); - } - - @NonNull - @Override - public ViewGroup getLaunchContainer() { - return ((ViewGroup) mKeyguardViewControllerLazy.get() - .getViewRootImpl().getView()); - } - - @Override - public void setLaunchContainer(@NonNull ViewGroup launchContainer) { - // No-op, launch container is always the shade. - Log.wtf(TAG, "Someone tried to change the launch container for the " - + "ActivityLaunchAnimator, which should never happen."); - } - - @NonNull - @Override - public LaunchAnimator.State createAnimatorState() { - final int width = getLaunchContainer().getWidth(); - final int height = getLaunchContainer().getHeight(); - - // TODO(b/207399883): Unocclude animation. This currently ends instantly. - return new LaunchAnimator.State( - 0, height, 0, width, mWindowCornerRadius, mWindowCornerRadius); - } - }; - private IRemoteAnimationRunner mOccludeAnimationRunner = new ActivityLaunchRemoteAnimationRunner(mOccludeAnimationController); + + /** + * 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 + * or the power button. + */ private IRemoteAnimationRunner mUnoccludeAnimationRunner = - new ActivityLaunchRemoteAnimationRunner(mUnoccludeAnimationController); + new IRemoteAnimationRunner.Stub() { + + @Nullable private ValueAnimator mUnoccludeAnimator; + private final Matrix mUnoccludeMatrix = new Matrix(); + + @Override + public void onAnimationCancelled() { + if (mUnoccludeAnimator != null) { + mUnoccludeAnimator.cancel(); + } + } + + @Override + public void onAnimationStart(int transit, RemoteAnimationTarget[] apps, + RemoteAnimationTarget[] wallpapers, + RemoteAnimationTarget[] nonApps, + IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException { + final RemoteAnimationTarget primary = apps[0]; + + if (primary == null) { + finishedCallback.onAnimationFinished(); + return; + } + + final SyncRtSurfaceTransactionApplier applier = + new SyncRtSurfaceTransactionApplier( + mKeyguardViewControllerLazy.get().getViewRootImpl().getView()); + + + mContext.getMainExecutor().execute(() -> { + if (mUnoccludeAnimator != null) { + mUnoccludeAnimator.cancel(); + } + + mUnoccludeAnimator = ValueAnimator.ofFloat(1f, 0f); + mUnoccludeAnimator.setDuration(UNOCCLUDE_ANIMATION_DURATION); + mUnoccludeAnimator.setInterpolator(Interpolators.TOUCH_RESPONSE); + mUnoccludeAnimator.addUpdateListener( + animation -> { + final float animatedValue = + (float) animation.getAnimatedValue(); + + final float surfaceHeight = primary.screenSpaceBounds.height(); + + mUnoccludeMatrix.setTranslate( + 0f, + (1f - animatedValue) + * surfaceHeight + * UNOCCLUDE_TRANSLATE_DISTANCE_PERCENT); + + SyncRtSurfaceTransactionApplier.SurfaceParams params = + new SyncRtSurfaceTransactionApplier.SurfaceParams + .Builder(primary.leash) + .withMatrix(mUnoccludeMatrix) + .withCornerRadius(mWindowCornerRadius) + .withAlpha(animatedValue) + .build(); + applier.scheduleApply(params); + }); + mUnoccludeAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + try { + finishedCallback.onAnimationFinished(); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + }); + + mUnoccludeAnimator.start(); + }); + } + }; private DeviceConfigProxy mDeviceConfig; private DozeParameters mDozeParameters;