1 /*
2  * Copyright (C) 2019 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.BACKGROUND_APP;
19 import static com.android.launcher3.LauncherState.OVERVIEW;
20 import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
21 import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_SHELF_ANIM;
22 
23 import android.animation.Animator;
24 import android.animation.AnimatorListenerAdapter;
25 import android.view.animation.Interpolator;
26 
27 import com.android.launcher3.Launcher;
28 import com.android.launcher3.config.FeatureFlags;
29 import com.android.launcher3.uioverrides.states.OverviewState;
30 
31 /**
32  * Animates the shelf between states HIDE, PEEK, and OVERVIEW.
33  */
34 public class ShelfPeekAnim {
35 
36     public static final Interpolator INTERPOLATOR = OVERSHOOT_1_2;
37     public static final long DURATION = 240;
38 
39     private final Launcher mLauncher;
40 
41     private ShelfAnimState mShelfState;
42     private boolean mIsPeeking;
43 
ShelfPeekAnim(Launcher launcher)44     public ShelfPeekAnim(Launcher launcher) {
45         mLauncher = launcher;
46     }
47 
48     /**
49      * Animates to the given state, canceling the previous animation if it was still running.
50      */
setShelfState(ShelfAnimState shelfState, Interpolator interpolator, long duration)51     public void setShelfState(ShelfAnimState shelfState, Interpolator interpolator, long duration) {
52         if (mShelfState == shelfState || FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get()) {
53             return;
54         }
55         mLauncher.getStateManager().cancelStateElementAnimation(INDEX_SHELF_ANIM);
56         mShelfState = shelfState;
57         mIsPeeking = mShelfState == ShelfAnimState.PEEK || mShelfState == ShelfAnimState.HIDE;
58         if (mShelfState == ShelfAnimState.CANCEL) {
59             return;
60         }
61         float shelfHiddenProgress = BACKGROUND_APP.getVerticalProgress(mLauncher);
62         float shelfOverviewProgress = OVERVIEW.getVerticalProgress(mLauncher);
63         // Peek based on default overview progress so we can see hotseat if we're showing
64         // that instead of predictions in overview.
65         float defaultOverviewProgress = OverviewState.getDefaultVerticalProgress(mLauncher);
66         float shelfPeekingProgress = shelfHiddenProgress
67                 - (shelfHiddenProgress - defaultOverviewProgress) * 0.25f;
68         float toProgress = mShelfState == ShelfAnimState.HIDE
69                 ? shelfHiddenProgress
70                 : mShelfState == ShelfAnimState.PEEK
71                         ? shelfPeekingProgress
72                         : shelfOverviewProgress;
73         Animator shelfAnim = mLauncher.getStateManager()
74                 .createStateElementAnimation(INDEX_SHELF_ANIM, toProgress);
75         shelfAnim.setInterpolator(interpolator);
76         shelfAnim.addListener(new AnimatorListenerAdapter() {
77             @Override
78             public void onAnimationCancel(Animator animation) {
79                 mShelfState = ShelfAnimState.CANCEL;
80             }
81 
82             @Override
83             public void onAnimationEnd(Animator animator) {
84                 mIsPeeking = mShelfState == ShelfAnimState.PEEK;
85             }
86         });
87         shelfAnim.setDuration(duration).start();
88     }
89 
90     /** @return Whether the shelf is currently peeking or animating to or from peeking. */
isPeeking()91     public boolean isPeeking() {
92         return mIsPeeking;
93     }
94 
95     /** The various shelf states we can animate to. */
96     public enum ShelfAnimState {
97         HIDE(true), PEEK(true), OVERVIEW(false), CANCEL(false);
98 
ShelfAnimState(boolean shouldPreformHaptic)99         ShelfAnimState(boolean shouldPreformHaptic) {
100             this.shouldPreformHaptic = shouldPreformHaptic;
101         }
102 
103         public final boolean shouldPreformHaptic;
104     }
105 }
106