From 6fe3eec95cfb153ed7c16c6381623b7e762452c3 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 15 Aug 2019 14:53:41 -0700 Subject: Moving various common executors to a single location Change-Id: I44bca49b8adb6fa22c3b48d10f674e42c28d792c --- .../android/quickstep/util/RecentsAnimationListenerSet.java | 12 ++++++------ .../com/android/quickstep/util/SwipeAnimationTargetSet.java | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'quickstep/recents_ui_overrides/src/com/android/quickstep/util') diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java index 14083dd95..b1999d716 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java @@ -15,11 +15,13 @@ */ package com.android.quickstep.util; -import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import android.graphics.Rect; import android.util.ArraySet; +import androidx.annotation.UiThread; + import com.android.launcher3.Utilities; import com.android.launcher3.util.Preconditions; import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; @@ -31,8 +33,6 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.util.Set; import java.util.function.Consumer; -import androidx.annotation.UiThread; - /** * Wrapper around {@link RecentsAnimationListener} which delegates callbacks to multiple listeners * on the main thread @@ -82,7 +82,7 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener { if (mCancelled) { targetSet.cancelAnimation(); } else { - Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> { + Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> { for (SwipeAnimationListener listener : getListeners()) { listener.onRecentsAnimationStart(targetSet); } @@ -92,14 +92,14 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener { @Override public final void onAnimationCanceled(ThumbnailData thumbnailData) { - Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> { + Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> { for (SwipeAnimationListener listener : getListeners()) { listener.onRecentsAnimationCanceled(); } }); // TODO: handle the transition better instead of simply using a transition delay. if (thumbnailData != null) { - MAIN_THREAD_EXECUTOR.getHandler().postDelayed(() -> mController.cleanupScreenshot(), + MAIN_EXECUTOR.getHandler().postDelayed(() -> mController.cleanupScreenshot(), TRANSITION_DELAY); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java index 381c27a28..3619d3a0e 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java @@ -15,8 +15,8 @@ */ package com.android.quickstep.util; -import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; -import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; import android.graphics.Rect; @@ -68,25 +68,25 @@ public class SwipeAnimationTargetSet extends RemoteAnimationTargetSet { public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) { mOnFinishListener.accept(this); - BACKGROUND_EXECUTOR.execute(() -> { + UI_HELPER_EXECUTOR.execute(() -> { controller.setInputConsumerEnabled(false); controller.finish(toRecents, sendUserLeaveHint); if (callback != null) { - MAIN_THREAD_EXECUTOR.execute(callback); + MAIN_EXECUTOR.execute(callback); } }); } public void enableInputConsumer() { - BACKGROUND_EXECUTOR.submit(() -> { + UI_HELPER_EXECUTOR.submit(() -> { controller.hideCurrentInputMethod(); controller.setInputConsumerEnabled(true); }); } public void setWindowThresholdCrossed(boolean thresholdCrossed) { - BACKGROUND_EXECUTOR.execute(() -> { + UI_HELPER_EXECUTOR.execute(() -> { controller.setAnimationTargetsBehindSystemBars(!thresholdCrossed); if (mShouldMinimizeSplitScreen && thresholdCrossed) { // NOTE: As a workaround for conflicting animations (Launcher animating the task -- cgit v1.2.3 From 13c1c2cd6505ca3103d4a2d315426e301a871337 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 6 Sep 2019 11:46:19 -0700 Subject: Migrate to using DefaultDisplay - Remove extra binder calls to get the default display Bug: 140633033 Change-Id: I532645deac101a6065d90484b87a67b67aa717f5 --- .../src/com/android/quickstep/util/NavBarPosition.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'quickstep/recents_ui_overrides/src/com/android/quickstep/util') diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java index 3ce341d8c..bbb318a02 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java @@ -21,9 +21,9 @@ import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import android.content.Context; import android.view.Surface; -import android.view.WindowManager; import com.android.launcher3.graphics.RotationMode; +import com.android.launcher3.util.DefaultDisplay; import com.android.quickstep.SysUINavigationMode; /** @@ -36,8 +36,7 @@ public class NavBarPosition { public NavBarPosition(Context context) { mMode = SysUINavigationMode.getMode(context); - mDisplayRotation = context.getSystemService(WindowManager.class) - .getDefaultDisplay().getRotation(); + mDisplayRotation = DefaultDisplay.INSTANCE.get(context).getInfo().rotation; } public boolean isRightEdge() { -- cgit v1.2.3 From fb578e4528855c8a82f0478b1eab9393c4711821 Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Tue, 24 Sep 2019 12:51:36 -0700 Subject: Fades out Assistant when entering Overview. This makes the transition smoother, since the Assistant goes away at the end of it. Note this only applies to the transition while an app other than Launcher is live. Before: https://drive.google.com/open?id=18SOWTtTUzt19TReAYnofQLIShJ2I-odP After: https://drive.google.com/open?id=1hqsikXSlCnSvNg0ZQYHxP-OIbS5yt9aW Bug: 136282913 Change-Id: Ia53c2407c82725c776f27b0d6e80a34554b4a303 Merged-In: Ia53c2407c82725c776f27b0d6e80a34554b4a303 Tested: Manually --- .../src/com/android/quickstep/util/ClipAnimationHelper.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'quickstep/recents_ui_overrides/src/com/android/quickstep/util') diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java index cae273a16..fa3be9c12 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java @@ -37,6 +37,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.LauncherState; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.anim.Interpolators; import com.android.launcher3.views.BaseDragLayer; import com.android.quickstep.RecentsModel; import com.android.quickstep.views.RecentsView; @@ -50,8 +51,6 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat. import com.android.systemui.shared.system.TransactionCompat; import com.android.systemui.shared.system.WindowManagerWrapper; -import java.util.function.BiFunction; - /** * Utility class to handle window clip animation */ @@ -213,6 +212,11 @@ public class ClipAnimationHelper { } mCurrentCornerRadius = cornerRadius; } + // Fade out Assistant overlay. + if (app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT + && app.isNotInRecents) { + alpha = 1 - Interpolators.DEACCEL_2_5.getInterpolation(progress); + } } else if (targetSet.hasRecents) { // If home has a different target then recents, reverse anim the // home target. -- cgit v1.2.3 From 42a9ef0e9f87230930127f25e0ce80b5ea1f603a Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Tue, 24 Sep 2019 16:05:54 -0700 Subject: Move shelf peeking anim code to ShelfPeekAnim class Bug: 126596417 Change-Id: I5ba501b04b3eaf12a20ba1312ef362f9734761c3 Merged-In: I5ba501b04b3eaf12a20ba1312ef362f9734761c3 --- .../com/android/quickstep/util/ShelfPeekAnim.java | 104 +++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/util/ShelfPeekAnim.java (limited to 'quickstep/recents_ui_overrides/src/com/android/quickstep/util') 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 000000000..41be6834f --- /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; + } +} -- cgit v1.2.3 From 2785a5996cebaae4df29c1f9e9efcaf2f7b0055f Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Mon, 12 Aug 2019 18:33:48 -0700 Subject: Improve quick switch from home by tracking both x and y motion - Add NoButtonQuickSwitchTouchController which uses BothAxesSwipeDetector to track horizontal and vertical motion. - Initially, we only detect swipe left to right to quick switch (like before), but then we allow swipe up to either go to overview (if you hold) or back home (if you don't hold). - xDisplacement transitions non-overview components out (e.g. shelf and workspace), and translates overview in. - yDisplacement translates overview up and scales it down Bug: 126596417 Change-Id: Id679ad84c08246e205c667a78ed5df00d7276258 Merged-In: Id679ad84c08246e205c667a78ed5df00d7276258 --- .../com/android/quickstep/util/ShelfPeekAnim.java | 1 + .../quickstep/util/StaggeredWorkspaceAnim.java | 30 ++++++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) (limited to 'quickstep/recents_ui_overrides/src/com/android/quickstep/util') 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 index 41be6834f..83bc41623 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ShelfPeekAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ShelfPeekAnim.java @@ -30,6 +30,7 @@ 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; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java index 1aa5365fd..5f02de2b9 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java @@ -18,6 +18,7 @@ package com.android.quickstep.util; import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y; import static com.android.launcher3.LauncherState.BACKGROUND_APP; import static com.android.launcher3.LauncherState.NORMAL; +import static com.android.launcher3.LauncherStateManager.ANIM_ALL; import static com.android.launcher3.anim.Interpolators.LINEAR; import android.animation.Animator; @@ -29,11 +30,11 @@ import android.view.ViewGroup; import androidx.annotation.Nullable; -import com.android.launcher3.BubbleTextView; import com.android.launcher3.CellLayout; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; +import com.android.launcher3.LauncherStateManager; import com.android.launcher3.LauncherStateManager.AnimationConfig; import com.android.launcher3.R; import com.android.launcher3.ShortcutAndWidgetContainer; @@ -41,9 +42,9 @@ import com.android.launcher3.Workspace; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.anim.SpringObjectAnimator; -import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.graphics.OverviewScrim; import com.android.launcher3.views.IconLabelDotView; +import com.android.quickstep.views.RecentsView; import java.util.ArrayList; import java.util.List; @@ -75,7 +76,9 @@ public class StaggeredWorkspaceAnim { * @param floatingViewOriginalView The FloatingIconView's original view. */ public StaggeredWorkspaceAnim(Launcher launcher, @Nullable View floatingViewOriginalView, - float velocity) { + float velocity, boolean animateOverviewScrim) { + prepareToAnimate(launcher); + mVelocity = velocity; mOriginalView = floatingViewOriginalView; @@ -133,8 +136,10 @@ public class StaggeredWorkspaceAnim { addStaggeredAnimationForView(qsb, grid.inv.numRows + 2, totalRows); } - addScrimAnimationForState(launcher, BACKGROUND_APP, 0); - addScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS); + if (animateOverviewScrim) { + addScrimAnimationForState(launcher, BACKGROUND_APP, 0); + addScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS); + } AnimatorListener resetClipListener = new AnimatorListenerAdapter() { int numAnimations = mAnimators.size(); @@ -160,6 +165,21 @@ public class StaggeredWorkspaceAnim { } } + /** + * Setup workspace with 0 duration to prepare for our staggered animation. + */ + private void prepareToAnimate(Launcher launcher) { + LauncherStateManager stateManager = launcher.getStateManager(); + AnimatorSetBuilder builder = new AnimatorSetBuilder(); + // setRecentsAttachedToAppWindow() will animate recents out. + builder.addFlag(AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW); + stateManager.createAtomicAnimation(BACKGROUND_APP, NORMAL, builder, ANIM_ALL, 0); + builder.build().start(); + + // Stop scrolling so that it doesn't interfere with the translation offscreen. + launcher.getOverviewPanel().getScroller().forceFinished(true); + } + /** * Starts the animation. */ -- cgit v1.2.3 From a3ea27de3941f2802361aff1d46547122f096c7d Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 20 Nov 2019 12:31:15 -0800 Subject: Fix bug where icon remains invisible after returning home. - The bug is caused by cancelling of the RectFSpringAnim before the StaggeredWorkspaceAnim has started. - Instead of having logic in StaggeredWorkspaceAnim control the visibility of the icon, we instead maintain all the visibility within the FloatingIconView class itself. Bug: 142120338 Change-Id: I94f3a066d395f9c3b97dc6ee9fc836e9401650a5 Merged-In: I082291ca9b288f57701cc00d61a9b3a84da8b084 --- .../quickstep/util/StaggeredWorkspaceAnim.java | 38 ++-------------------- 1 file changed, 2 insertions(+), 36 deletions(-) (limited to 'quickstep/recents_ui_overrides/src/com/android/quickstep/util') diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java index 5f02de2b9..958ef7d4f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java @@ -28,8 +28,6 @@ import android.animation.ObjectAnimator; import android.view.View; import android.view.ViewGroup; -import androidx.annotation.Nullable; - import com.android.launcher3.CellLayout; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; @@ -43,7 +41,6 @@ import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.anim.SpringObjectAnimator; import com.android.launcher3.graphics.OverviewScrim; -import com.android.launcher3.views.IconLabelDotView; import com.android.quickstep.views.RecentsView; import java.util.ArrayList; @@ -67,20 +64,12 @@ public class StaggeredWorkspaceAnim { private final float mVelocity; private final float mSpringTransY; - // The original view of the {@link FloatingIconView}. - private final View mOriginalView; - private final List mAnimators = new ArrayList<>(); - /** - * @param floatingViewOriginalView The FloatingIconView's original view. - */ - public StaggeredWorkspaceAnim(Launcher launcher, @Nullable View floatingViewOriginalView, - float velocity, boolean animateOverviewScrim) { + public StaggeredWorkspaceAnim(Launcher launcher, float velocity, boolean animateOverviewScrim) { prepareToAnimate(launcher); mVelocity = velocity; - mOriginalView = floatingViewOriginalView; // Scale the translationY based on the initial velocity to better sync the workspace items // with the floating view. @@ -212,35 +201,12 @@ public class StaggeredWorkspaceAnim { springTransY.setStartDelay(startDelay); mAnimators.add(springTransY); - ObjectAnimator alpha = getAlphaAnimator(v, startDelay); - if (v == mOriginalView) { - // For IconLabelDotViews, we just want the label to fade in. - // Icon, badge, and dots will animate in separately (controlled via FloatingIconView) - if (v instanceof IconLabelDotView) { - alpha.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - IconLabelDotView view = (IconLabelDotView) v; - view.setIconVisible(false); - view.setForceHideDot(true); - } - }); - } else { - return; - } - } - v.setAlpha(0); - mAnimators.add(alpha); - } - - private ObjectAnimator getAlphaAnimator(View v, long startDelay) { ObjectAnimator alpha = ObjectAnimator.ofFloat(v, View.ALPHA, 0f, 1f); alpha.setInterpolator(LINEAR); alpha.setDuration(ALPHA_DURATION_MS); alpha.setStartDelay(startDelay); - return alpha; - + mAnimators.add(alpha); } private void addScrimAnimationForState(Launcher launcher, LauncherState state, long duration) { -- cgit v1.2.3