diff --git a/go/quickstep/src/com/android/quickstep/util/ShelfPeekAnim.java b/go/quickstep/src/com/android/quickstep/util/ShelfPeekAnim.java new file mode 100644 index 0000000000..e7099ec1c9 --- /dev/null +++ b/go/quickstep/src/com/android/quickstep/util/ShelfPeekAnim.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.quickstep.util; + +import com.android.launcher3.Launcher; + +/** Empty class, only exists so that lowRamWithQuickstepIconRecentsDebug compiles. */ +public class ShelfPeekAnim { + public ShelfPeekAnim(Launcher launcher) { + } + + public enum ShelfAnimState { + } +} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java index 01cf4bbe7b..d2225de07e 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java @@ -47,6 +47,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiThread; +import com.android.launcher3.BaseQuickstepLauncher; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherInitListener; @@ -56,12 +57,13 @@ import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.appprediction.PredictionUiStateManager; -import com.android.launcher3.uioverrides.states.OverviewState; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.views.FloatingIconView; import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.util.ActivityInitListener; import com.android.quickstep.util.LayoutUtils; +import com.android.quickstep.util.ShelfPeekAnim; +import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState; import com.android.quickstep.util.StaggeredWorkspaceAnim; import com.android.quickstep.views.LauncherRecentsView; import com.android.quickstep.views.RecentsView; @@ -227,7 +229,8 @@ public final class LauncherActivityInterface implements BaseActivityInterface Math.min(1 / MIN_PROGRESS_FOR_OVERVIEW, 1 / (1 - MIN_PROGRESS_FOR_OVERVIEW)); private static final String SCREENSHOT_CAPTURED_EVT = "ScreenshotCaptured"; - private static final long SHELF_ANIM_DURATION = 240; public static final long RECENTS_ATTACH_DURATION = 300; /** @@ -432,7 +432,7 @@ public class LauncherSwipeHandler @Override public void onMotionPauseChanged(boolean isPaused) { - setShelfState(isPaused ? PEEK : HIDE, OVERSHOOT_1_2, SHELF_ANIM_DURATION); + setShelfState(isPaused ? PEEK : HIDE, ShelfPeekAnim.INTERPOLATOR, ShelfPeekAnim.DURATION); if (mDeviceState.isFullyGesturalNavMode() && isPaused) { // In fully gestural nav mode, switch to overview predictions once the user has paused diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ShelfPeekAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ShelfPeekAnim.java new file mode 100644 index 0000000000..41be6834f7 --- /dev/null +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ShelfPeekAnim.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.quickstep.util; + +import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_SHELF_ANIM; +import static com.android.launcher3.LauncherState.BACKGROUND_APP; +import static com.android.launcher3.LauncherState.OVERVIEW; +import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.view.animation.Interpolator; + +import com.android.launcher3.Launcher; +import com.android.launcher3.uioverrides.states.OverviewState; + +/** + * Animates the shelf between states HIDE, PEEK, and OVERVIEW. + */ +public class ShelfPeekAnim { + + public static final Interpolator INTERPOLATOR = OVERSHOOT_1_2; + public static final long DURATION = 240; + + private final Launcher mLauncher; + + private ShelfAnimState mShelfState; + private boolean mIsPeeking; + + public ShelfPeekAnim(Launcher launcher) { + mLauncher = launcher; + } + + /** + * Animates to the given state, canceling the previous animation if it was still running. + */ + public void setShelfState(ShelfAnimState shelfState, Interpolator interpolator, long duration) { + if (mShelfState == shelfState) { + return; + } + mLauncher.getStateManager().cancelStateElementAnimation(INDEX_SHELF_ANIM); + mShelfState = shelfState; + mIsPeeking = mShelfState == ShelfAnimState.PEEK || mShelfState == ShelfAnimState.HIDE; + if (mShelfState == ShelfAnimState.CANCEL) { + return; + } + float shelfHiddenProgress = BACKGROUND_APP.getVerticalProgress(mLauncher); + float shelfOverviewProgress = OVERVIEW.getVerticalProgress(mLauncher); + // Peek based on default overview progress so we can see hotseat if we're showing + // that instead of predictions in overview. + float defaultOverviewProgress = OverviewState.getDefaultVerticalProgress(mLauncher); + float shelfPeekingProgress = shelfHiddenProgress + - (shelfHiddenProgress - defaultOverviewProgress) * 0.25f; + float toProgress = mShelfState == ShelfAnimState.HIDE + ? shelfHiddenProgress + : mShelfState == ShelfAnimState.PEEK + ? shelfPeekingProgress + : shelfOverviewProgress; + Animator shelfAnim = mLauncher.getStateManager() + .createStateElementAnimation(INDEX_SHELF_ANIM, toProgress); + shelfAnim.setInterpolator(interpolator); + shelfAnim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationCancel(Animator animation) { + mShelfState = ShelfAnimState.CANCEL; + } + + @Override + public void onAnimationEnd(Animator animator) { + mIsPeeking = mShelfState == ShelfAnimState.PEEK; + } + }); + shelfAnim.setDuration(duration).start(); + } + + /** @return Whether the shelf is currently peeking or animating to or from peeking. */ + public boolean isPeeking() { + return mIsPeeking; + } + + /** The various shelf states we can animate to. */ + public enum ShelfAnimState { + HIDE(true), PEEK(true), OVERVIEW(false), CANCEL(false); + + ShelfAnimState(boolean shouldPreformHaptic) { + this.shouldPreformHaptic = shouldPreformHaptic; + } + + public final boolean shouldPreformHaptic; + } +} diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index fc9cfcd7fa..9ea13c640c 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -48,6 +48,7 @@ import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.util.RemoteFadeOutAnimationListener; +import com.android.quickstep.util.ShelfPeekAnim; import java.util.stream.Stream; @@ -64,6 +65,8 @@ public abstract class BaseQuickstepLauncher extends Launcher (context, arg1, arg2) -> SystemUiProxy.INSTANCE.get(context).setBackButtonAlpha( Float.intBitsToFloat(arg1), arg2 != 0); + private final ShelfPeekAnim mShelfPeekAnim = new ShelfPeekAnim(this); + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -270,4 +273,8 @@ public abstract class BaseQuickstepLauncher extends Launcher return Stream.concat(super.getSupportedShortcuts(), Stream.of(WellbeingModel.SHORTCUT_FACTORY)); } + + public ShelfPeekAnim getShelfPeekAnim() { + return mShelfPeekAnim; + } } diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index 86ffd227ca..fd55e077fd 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -32,6 +32,7 @@ import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.quickstep.util.ActivityInitListener; +import com.android.quickstep.util.ShelfPeekAnim; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; @@ -113,16 +114,6 @@ public interface BaseActivityInterface { interface AnimationFactory { - enum ShelfAnimState { - HIDE(true), PEEK(true), OVERVIEW(false), CANCEL(false); - - ShelfAnimState(boolean shouldPreformHaptic) { - this.shouldPreformHaptic = shouldPreformHaptic; - } - - public final boolean shouldPreformHaptic; - } - default void onRemoteAnimationReceived(RemoteAnimationTargets targets) { } void createActivityInterface(long transitionLength); @@ -131,8 +122,8 @@ public interface BaseActivityInterface { default void onTransitionCancelled() { } - default void setShelfState(ShelfAnimState animState, Interpolator interpolator, - long duration) { } + default void setShelfState(ShelfPeekAnim.ShelfAnimState animState, + Interpolator interpolator, long duration) { } /** * @param attached Whether to show RecentsView alongside the app window. If false, recents