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