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

Commit ffb976c4 authored by shawnlin's avatar shawnlin Committed by Shawn Lin
Browse files

Attached the navigation bar to app for launching from Launcher

- Play the nav bar fade-out animation at the same time when the app
  launching animation starts and make the fade-in animation ends at the
  same time when app launching animation ends.
- To make the nav bar fade-in animation looks like it's attached to the
  app, apply crop rect and translation that the app targets apply to the
  nav target.

Bug: 181638132
Test: manual: click app icon on launcher to launch an activity and
observe the navigation bar animation.

Change-Id: If7e610eca5fccbb747a76c87335a600b018195a6
parent 12eeecc3
Loading
Loading
Loading
Loading
+43 −9
Original line number Diff line number Diff line
@@ -61,6 +61,8 @@ import android.os.Looper;
import android.os.SystemProperties;
import android.util.Pair;
import android.view.View;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -137,6 +139,15 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
    private static final long APP_LAUNCH_ALPHA_DOWN_DURATION =
            (long) (APP_LAUNCH_ALPHA_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR);

    public static final int ANIMATION_NAV_FADE_IN_DURATION = 266;
    public static final int ANIMATION_NAV_FADE_OUT_DURATION = 133;
    public static final long ANIMATION_DELAY_NAV_FADE_IN =
            APP_LAUNCH_DURATION - ANIMATION_NAV_FADE_IN_DURATION;
    public static final Interpolator NAV_FADE_IN_INTERPOLATOR =
            new PathInterpolator(0f, 0f, 0f, 1f);
    public static final Interpolator NAV_FADE_OUT_INTERPOLATOR =
            new PathInterpolator(0.2f, 0f, 1f, 1f);

    private static final long CROP_DURATION = 375;
    private static final long RADIUS_DURATION = 375;

@@ -276,10 +287,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
     */
    protected void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v,
            @NonNull RemoteAnimationTargetCompat[] appTargets,
            @NonNull RemoteAnimationTargetCompat[] wallpaperTargets, boolean launcherClosing) {
            @NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
            @NonNull RemoteAnimationTargetCompat[] nonAppTargets, boolean launcherClosing) {
        TaskViewUtils.composeRecentsLaunchAnimator(anim, v, appTargets, wallpaperTargets,
                launcherClosing, mLauncher.getStateManager(), mLauncher.getOverviewPanel(),
                mLauncher.getDepthController());
                nonAppTargets, launcherClosing, mLauncher.getStateManager(),
                mLauncher.getOverviewPanel(), mLauncher.getDepthController());
    }

    private boolean areAllTargetsTranslucent(@NonNull RemoteAnimationTargetCompat[] targets) {
@@ -305,6 +317,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
    private void composeIconLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v,
            @NonNull RemoteAnimationTargetCompat[] appTargets,
            @NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
            @NonNull RemoteAnimationTargetCompat[] nonAppTargets,
            boolean launcherClosing) {
        // Set the state animation first so that any state listeners are called
        // before our internal listeners.
@@ -313,8 +326,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
        final int rotationChange = getRotationChange(appTargets);
        // Note: the targetBounds are relative to the launcher
        Rect windowTargetBounds = getWindowTargetBounds(appTargets, rotationChange);
        anim.play(getOpeningWindowAnimators(v, appTargets, wallpaperTargets, windowTargetBounds,
                areAllTargetsTranslucent(appTargets), rotationChange));
        anim.play(getOpeningWindowAnimators(v, appTargets, wallpaperTargets, nonAppTargets,
                windowTargetBounds, areAllTargetsTranslucent(appTargets), rotationChange));
        if (launcherClosing) {
            Pair<AnimatorSet, Runnable> launcherContentAnimator =
                    getLauncherContentAnimator(true /* isAppOpening */,
@@ -515,6 +528,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
    private Animator getOpeningWindowAnimators(View v,
            RemoteAnimationTargetCompat[] appTargets,
            RemoteAnimationTargetCompat[] wallpaperTargets,
            RemoteAnimationTargetCompat[] nonAppTargets,
            Rect windowTargetBounds, boolean appTargetsAreTranslucent, int rotationChange) {
        RectF launcherIconBounds = new RectF();
        FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v,
@@ -523,10 +537,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
        Matrix matrix = new Matrix();

        RemoteAnimationTargets openingTargets = new RemoteAnimationTargets(appTargets,
                wallpaperTargets, MODE_OPENING);
                wallpaperTargets, nonAppTargets, MODE_OPENING);
        SurfaceTransactionApplier surfaceApplier =
                new SurfaceTransactionApplier(floatingView);
        openingTargets.addReleaseCheck(surfaceApplier);
        RemoteAnimationTargetCompat navBarTarget = openingTargets.getNavBarRemoteAnimationTarget();

        int[] dragLayerBounds = new int[2];
        mDragLayer.getLocationOnScreen(dragLayerBounds);
@@ -601,6 +616,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
            FloatProp mCropRectHeight = new FloatProp(prop.cropHeightStart, prop.cropHeightEnd, 0,
                    CROP_DURATION, EXAGGERATED_EASE);

            FloatProp mNavFadeOut = new FloatProp(1f, 0f, 0, ANIMATION_NAV_FADE_OUT_DURATION,
                    NAV_FADE_OUT_INTERPOLATOR);
            FloatProp mNavFadeIn = new FloatProp(0f, 1f, ANIMATION_DELAY_NAV_FADE_IN,
                    ANIMATION_NAV_FADE_IN_DURATION, NAV_FADE_IN_INTERPOLATOR);

            @Override
            public void onUpdate(float percent) {
                // Calculate the size of the scaled icon.
@@ -706,6 +726,21 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
                    params[i] = builder.build();
                }
                surfaceApplier.scheduleApply(params);

                if (navBarTarget != null) {
                    final SurfaceParams.Builder navBuilder =
                            new SurfaceParams.Builder(navBarTarget.leash);
                    if (mNavFadeIn.value > mNavFadeIn.getStartValue()) {
                        matrix.setScale(scale, scale);
                        matrix.postTranslate(windowTransX0, windowTransY0);
                        navBuilder.withMatrix(matrix)
                                .withWindowCrop(crop)
                                .withAlpha(mNavFadeIn.value);
                    } else {
                        navBuilder.withAlpha(mNavFadeOut.value);
                    }
                    surfaceApplier.scheduleApply(navBuilder.build());
                }
            }
        });

@@ -1088,19 +1123,18 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
                RemoteAnimationTargetCompat[] nonAppTargets,
                LauncherAnimationRunner.AnimationResult result) {
            AnimatorSet anim = new AnimatorSet();

            boolean launcherClosing =
                    launcherIsATargetWithMode(appTargets, MODE_CLOSING);

            final boolean launchingFromRecents = isLaunchingFromRecents(mV, appTargets);
            final boolean launchingFromTaskbar = mLauncher.isViewInTaskbar(mV);
            if (launchingFromRecents) {
                composeRecentsLaunchAnimator(anim, mV, appTargets, wallpaperTargets,
                composeRecentsLaunchAnimator(anim, mV, appTargets, wallpaperTargets, nonAppTargets,
                        launcherClosing);
            } else if (launchingFromTaskbar) {
                // TODO
            } else {
                composeIconLaunchAnimator(anim, mV, appTargets, wallpaperTargets,
                composeIconLaunchAnimator(anim, mV, appTargets, wallpaperTargets, nonAppTargets,
                        launcherClosing);
            }

+2 −1
Original line number Diff line number Diff line
@@ -247,7 +247,8 @@ public class FallbackSwipeHandler extends
            if (appearedTaskTarget.activityType == ACTIVITY_TYPE_HOME) {
                RemoteAnimationTargets targets = new RemoteAnimationTargets(
                        new RemoteAnimationTargetCompat[] {appearedTaskTarget},
                        new RemoteAnimationTargetCompat[0], appearedTaskTarget.mode);
                        new RemoteAnimationTargetCompat[0], new RemoteAnimationTargetCompat[0],
                        appearedTaskTarget.mode);
                mHomeAlphaParams.setTargetSet(targets);
                updateHomeAlpha();
                return true;
+4 −3
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
                    RemoteAnimationTargetCompat[] nonAppTargets,
                    AnimationResult result) -> {
            AnimatorSet anim = composeRecentsLaunchAnimator(taskView, appTargets,
                    wallpaperTargets);
                    wallpaperTargets, nonAppTargets);
            anim.addListener(resetStateListener());
            result.setAnimation(anim, RecentsActivity.this, onEndCallback::executeAllAndDestroy);
        };
@@ -213,12 +213,13 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
     */
    private AnimatorSet  composeRecentsLaunchAnimator(TaskView taskView,
            RemoteAnimationTargetCompat[] appTargets,
            RemoteAnimationTargetCompat[] wallpaperTargets) {
            RemoteAnimationTargetCompat[] wallpaperTargets,
            RemoteAnimationTargetCompat[] nonAppTargets) {
        AnimatorSet target = new AnimatorSet();
        boolean activityClosing = taskIsATargetWithMode(appTargets, getTaskId(), MODE_CLOSING);
        PendingAnimation pa = new PendingAnimation(RECENTS_LAUNCH_DURATION);
        createRecentsWindowAnimator(taskView, !activityClosing, appTargets,
                wallpaperTargets, null /* depthController */, pa);
                wallpaperTargets, nonAppTargets, null /* depthController */, pa);
        target.play(pa.buildAnim());

        // Found a visible recents task that matches the opening app, lets launch the app from there
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ public class RecentsAnimationTargets extends RemoteAnimationTargets {
    public RecentsAnimationTargets(RemoteAnimationTargetCompat[] apps,
            RemoteAnimationTargetCompat[] wallpapers, Rect homeContentInsets,
            Rect minimizedHomeBounds) {
        super(apps, wallpapers, MODE_CLOSING);
        super(apps, wallpapers, new RemoteAnimationTargetCompat[0], MODE_CLOSING);
        this.homeContentInsets = homeContentInsets;
        this.minimizedHomeBounds = minimizedHomeBounds;
    }
+21 −1
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package com.android.quickstep;

import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;

import com.android.systemui.shared.system.RemoteAnimationTargetCompat;

import java.util.ArrayList;
@@ -30,13 +32,15 @@ public class RemoteAnimationTargets {
    public final RemoteAnimationTargetCompat[] unfilteredApps;
    public final RemoteAnimationTargetCompat[] apps;
    public final RemoteAnimationTargetCompat[] wallpapers;
    public final RemoteAnimationTargetCompat[] nonApps;
    public final int targetMode;
    public final boolean hasRecents;

    private boolean mReleased = false;

    public RemoteAnimationTargets(RemoteAnimationTargetCompat[] apps,
            RemoteAnimationTargetCompat[] wallpapers, int targetMode) {
            RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps,
            int targetMode) {
        ArrayList<RemoteAnimationTargetCompat> filteredApps = new ArrayList<>();
        boolean hasRecents = false;
        if (apps != null) {
@@ -55,6 +59,7 @@ public class RemoteAnimationTargets {
        this.wallpapers = wallpapers;
        this.targetMode = targetMode;
        this.hasRecents = hasRecents;
        this.nonApps = nonApps;
    }

    public RemoteAnimationTargetCompat findTask(int taskId) {
@@ -66,6 +71,18 @@ public class RemoteAnimationTargets {
        return null;
    }

    /**
     * Gets the navigation bar remote animation target if exists.
     */
    public RemoteAnimationTargetCompat getNavBarRemoteAnimationTarget() {
        for (RemoteAnimationTargetCompat target : nonApps) {
            if (target.windowType == TYPE_NAVIGATION_BAR) {
                return target;
            }
        }
        return null;
    }

    public boolean isAnimatingHome() {
        for (RemoteAnimationTargetCompat target : unfilteredApps) {
            if (target.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
@@ -98,6 +115,9 @@ public class RemoteAnimationTargets {
        for (RemoteAnimationTargetCompat target : wallpapers) {
            target.release();
        }
        for (RemoteAnimationTargetCompat target : nonApps) {
            target.release();
        }
    }

    /**
Loading