1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.quickstep.util;
17 
18 import static com.android.launcher3.LauncherState.NORMAL;
19 import static com.android.launcher3.LauncherState.OVERVIEW;
20 
21 import android.animation.Animator;
22 import android.animation.AnimatorSet;
23 import android.util.Log;
24 
25 import com.android.launcher3.Launcher;
26 import com.android.launcher3.LauncherState;
27 import com.android.launcher3.anim.AnimationSuccessListener;
28 import com.android.launcher3.statemanager.StateManager;
29 import com.android.launcher3.states.StateAnimationConfig;
30 
31 /**
32  * Runs an animation from overview to home. Currently, this animation is just a wrapper around the
33  * normal state transition and may play a {@link WorkspaceRevealAnim} if we're starting from an
34  * upward fling.
35  */
36 public class OverviewToHomeAnim {
37 
38     private static final String TAG = "OverviewToHomeAnim";
39 
40     private final Launcher mLauncher;
41     private final Runnable mOnReachedHome;
42 
43     // Only run mOnReachedHome when both of these are true.
44     private boolean mIsHomeStaggeredAnimFinished;
45     private boolean mIsOverviewHidden;
46 
OverviewToHomeAnim(Launcher launcher, Runnable onReachedHome)47     public OverviewToHomeAnim(Launcher launcher, Runnable onReachedHome) {
48         mLauncher = launcher;
49         mOnReachedHome = onReachedHome;
50     }
51 
52     /**
53      * Starts the animation. If velocity < 0 (i.e. upwards), also plays a
54      * {@link WorkspaceRevealAnim}.
55      */
animateWithVelocity(float velocity)56     public void animateWithVelocity(float velocity) {
57         StateManager<LauncherState> stateManager = mLauncher.getStateManager();
58         LauncherState startState = stateManager.getState();
59         if (startState != OVERVIEW) {
60             Log.e(TAG, "animateFromOverviewToHome: unexpected start state " + startState);
61         }
62         AnimatorSet anim = new AnimatorSet();
63 
64         boolean playWorkspaceRevealAnim = velocity < 0;
65         if (playWorkspaceRevealAnim) {
66             WorkspaceRevealAnim workspaceRevealAnim = new WorkspaceRevealAnim(mLauncher,
67                     false /* animateOverviewScrim */);
68             workspaceRevealAnim.addAnimatorListener(new AnimationSuccessListener() {
69                 @Override
70                 public void onAnimationSuccess(Animator animator) {
71                     mIsHomeStaggeredAnimFinished = true;
72                     maybeOverviewToHomeAnimComplete();
73                 }
74             });
75             anim.play(workspaceRevealAnim.getAnimators());
76         } else {
77             mIsHomeStaggeredAnimFinished = true;
78         }
79 
80         StateAnimationConfig config = new StateAnimationConfig();
81         if (playWorkspaceRevealAnim) {
82             // WorkspaceRevealAnim handles the depth, so don't interfere.
83             config.animFlags |= StateAnimationConfig.SKIP_DEPTH_CONTROLLER;
84         }
85         config.duration = startState.getTransitionDuration(mLauncher);
86         AnimatorSet stateAnim = stateManager.createAtomicAnimation(
87                 startState, NORMAL, config);
88         stateAnim.addListener(new AnimationSuccessListener() {
89             @Override
90             public void onAnimationSuccess(Animator animator) {
91                 mIsOverviewHidden = true;
92                 maybeOverviewToHomeAnimComplete();
93             }
94         });
95         anim.play(stateAnim);
96         stateManager.setCurrentAnimation(anim, NORMAL);
97         anim.start();
98     }
99 
100     private void maybeOverviewToHomeAnimComplete() {
101         if (mIsHomeStaggeredAnimFinished && mIsOverviewHidden) {
102             mOnReachedHome.run();
103         }
104     }
105 }
106