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

Commit ccf3121e authored by Josh Tsuji's avatar Josh Tsuji
Browse files

Add unocclude animation.

This is a simple downward translate/alpha animation to match
the shade's current unocclude animation. We use this rather
than activity lauch animator since we're not launching from
a view/from the power button, so it's not needed.

Bug: 202963722
Test: unocclude camera
Test: unocclude home controls
Test: unocclude google maps navigation
Change-Id: Id62fcb75d9215d8b12d06fb8c2e7e6e884e457b9
parent 017c695c
Loading
Loading
Loading
Loading
+80 −34
Original line number Diff line number Diff line
@@ -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,53 +892,90 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
                }
            };

    private IRemoteAnimationRunner mOccludeAnimationRunner =
            new ActivityLaunchRemoteAnimationRunner(mOccludeAnimationController);

    /**
     * Animation controller for activities that unocclude the keyguard. This will play the launch
     * animation in reverse.
     * 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 final ActivityLaunchAnimator.Controller mUnoccludeAnimationController =
            new ActivityLaunchAnimator.Controller() {
                @Override
                public void onLaunchAnimationEnd(boolean isExpandingFullyAbove) {
                    setOccluded(false /* isOccluded */, false /* animate */);
                }
    private IRemoteAnimationRunner mUnoccludeAnimationRunner =
            new IRemoteAnimationRunner.Stub() {

                @Nullable private ValueAnimator mUnoccludeAnimator;
                private final Matrix mUnoccludeMatrix = new Matrix();

                @Override
                public void onLaunchAnimationCancelled() {
                    setOccluded(false /* isOccluded */, false /* animate */);
                public void onAnimationCancelled() {
                    if (mUnoccludeAnimator != null) {
                        mUnoccludeAnimator.cancel();
                    }
                }

                @NonNull
                @Override
                public ViewGroup getLaunchContainer() {
                    return ((ViewGroup) mKeyguardViewControllerLazy.get()
                            .getViewRootImpl().getView());
                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;
                    }

                @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.");
                    final SyncRtSurfaceTransactionApplier applier =
                            new SyncRtSurfaceTransactionApplier(
                                    mKeyguardViewControllerLazy.get().getViewRootImpl().getView());


                    mContext.getMainExecutor().execute(() -> {
                        if (mUnoccludeAnimator != null) {
                            mUnoccludeAnimator.cancel();
                        }

                @NonNull
                        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 LaunchAnimator.State createAnimatorState() {
                    final int width = getLaunchContainer().getWidth();
                    final int height = getLaunchContainer().getHeight();
                            public void onAnimationEnd(Animator animation) {
                                try {
                                    finishedCallback.onAnimationFinished();
                                } catch (RemoteException e) {
                                    e.printStackTrace();
                                }
                            }
                        });

                    // TODO(b/207399883): Unocclude animation. This currently ends instantly.
                    return new LaunchAnimator.State(
                            0, height, 0, width, mWindowCornerRadius, mWindowCornerRadius);
                        mUnoccludeAnimator.start();
                    });
                }
            };

    private IRemoteAnimationRunner mOccludeAnimationRunner =
            new ActivityLaunchRemoteAnimationRunner(mOccludeAnimationController);
    private IRemoteAnimationRunner mUnoccludeAnimationRunner =
            new ActivityLaunchRemoteAnimationRunner(mUnoccludeAnimationController);

    private DeviceConfigProxy mDeviceConfig;
    private DozeParameters mDozeParameters;