LauncherStateTransitionAnimation.java revision 3f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3
1b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/*
2b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Copyright (C) 2015 The Android Open Source Project
3b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
4b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Licensed under the Apache License, Version 2.0 (the "License");
5b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * you may not use this file except in compliance with the License.
6b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * You may obtain a copy of the License at
7b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
8b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *      http://www.apache.org/licenses/LICENSE-2.0
9b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
10b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Unless required by applicable law or agreed to in writing, software
11b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * distributed under the License is distributed on an "AS IS" BASIS,
12b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * See the License for the specific language governing permissions and
14b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * limitations under the License.
15b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */
16b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
17b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpackage com.android.launcher3;
18b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
19b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.Animator;
20b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.AnimatorListenerAdapter;
21b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.AnimatorSet;
22b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.ObjectAnimator;
23b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.PropertyValuesHolder;
24b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.TimeInterpolator;
250bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickhamimport android.animation.ValueAnimator;
267066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyalimport android.annotation.SuppressLint;
27756cd26592dee6b956becdc24d60995c64de9153Sunny Goyalimport android.annotation.TargetApi;
28b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.content.res.Resources;
29756cd26592dee6b956becdc24d60995c64de9153Sunny Goyalimport android.os.Build;
30b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.util.Log;
31b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.View;
32b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.AccelerateInterpolator;
33b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.DecelerateInterpolator;
341558893b873cd55b2df779f594f1de3c370d3328Adam Cohen
355f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chungimport com.android.launcher3.allapps.AllAppsContainerView;
36091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
375d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyalimport com.android.launcher3.util.UiThreadCircularReveal;
383f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.widget.WidgetsContainerView;
391558893b873cd55b2df779f594f1de3c370d3328Adam Cohen
40b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport java.util.HashMap;
41b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
42b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/**
43b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * TODO: figure out what kind of tests we can write for this
44b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
45b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Things to test when changing the following class.
46b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from workspace
47b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
48b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
49b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from all apps
50b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
51b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
52b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Back from all apps
53b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
54b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
55b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from workspace and quit
56b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
57b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
58b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from all apps and quit
59b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
60b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
61b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Go to a screen that's not the default, then all
62b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *     apps, and launch and app, and go back
63b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
64b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          -with home
65b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, long press power and go back
66b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
67b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
68b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, long press power and go back
69b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
70b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
71b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, power off
72b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, power off
73b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch an app and turn off the screen while in that app
74b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with home key
75b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with back key  TODO: make this not go to workspace
76b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
77b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From workspace
78b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Enter and exit car mode (becuase it causes an extra configuration changed)
79b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
80b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From the center workspace
81b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From another workspace
82b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */
83b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpublic class LauncherStateTransitionAnimation {
84b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
850ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private static final float FINAL_REVEAL_ALPHA_FOR_WIDGETS = 0.3f;
860ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
87b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
88b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Private callbacks made during transition setup.
89b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
900ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private static class PrivateTransitionCallbacks {
910ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        private final float materialRevealViewFinalAlpha;
920ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
930ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks(float revealAlpha) {
940ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            materialRevealViewFinalAlpha = revealAlpha;
95b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
960ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
97b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewStartFinalRadius() {
98b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
99b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
100b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView,
10198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                View buttonView) {
102b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return null;
103b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
10476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung        void onTransitionComplete() {}
105b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
106b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
1070ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    public static final String TAG = "LSTAnimation";
108b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
109b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    // Flags to determine how to set the layers on views before the transition animation
110b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_LAYER = 0;
111b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_AND_SET_LAYER = 1;
112b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int SINGLE_FRAME_DELAY = 16;
113b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
114091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk Launcher mLauncher;
115006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    @Thunk AnimatorSet mCurrentAnimation;
116b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
117006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public LauncherStateTransitionAnimation(Launcher l) {
118b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        mLauncher = l;
119b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
120b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
121b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
122b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the apps view.
12376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *
12476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     * @param startSearchAfterTransition Immediately starts app search after the transition to
12576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *                                   All Apps is completed.
126b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
127006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public void startAnimationToAllApps(final Workspace.State fromWorkspaceState,
128006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final boolean startSearchAfterTransition) {
1295f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final AllAppsContainerView toView = mLauncher.getAppsView();
13098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getAllAppsButton();
1310ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) {
132b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
133b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewStartFinalRadius() {
1342e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
135b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
136b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
137b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
138b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
139b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
140b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
141b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
142b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.INVISIBLE);
143b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
144b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
145b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
146b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
147b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
148b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
14976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            @Override
15076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            void onTransitionComplete() {
1518fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                mLauncher.getLogger().resetElapsedContainerMillis();
15276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                if (startSearchAfterTransition) {
15376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    toView.startAppsSearch();
15476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                }
15576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            }
156b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
157ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating from spring loaded mode back to all apps
158006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState,
1590ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                Workspace.State.NORMAL_HIDDEN, buttonView, toView, animated, cb);
160b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
161b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
162b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
163b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the widgets view.
164b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
165006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public void startAnimationToWidgets(final Workspace.State fromWorkspaceState,
166006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated) {
1673f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song        final WidgetsContainerView toView = mLauncher.getWidgetsView();
16898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getWidgetsButton();
169006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState,
1700ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, animated,
1718fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS){
1728fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                    @Override
1738fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                    void onTransitionComplete() {
1748fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                        mLauncher.getLogger().resetElapsedContainerMillis();
1758fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                    }
1768fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                });
177b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
178b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
179b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
1806d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the current overlay view.
181b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
182b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public void startAnimationToWorkspace(final Launcher.State fromState,
183006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
1842a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final boolean animated, final Runnable onCompleteRunnable) {
185b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (toWorkspaceState != Workspace.State.NORMAL &&
186b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.SPRING_LOADED &&
187b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.OVERVIEW) {
188b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            Log.e(TAG, "Unexpected call to startAnimationToWorkspace");
189b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
190b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
191b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) {
1922a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState,
193dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
1946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else if (fromState == Launcher.State.WIDGETS ||
1956d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                fromState == Launcher.State.WIDGETS_SPRING_LOADED) {
1962a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState,
197dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
1986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else {
1996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            startAnimationToNewWorkspaceState(fromWorkspaceState, toWorkspaceState,
2006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    animated, onCompleteRunnable);
201b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
202b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
203b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
204b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
205b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to a particular overlay view.
206b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
2077066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal    @SuppressLint("NewApi")
2080ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private AnimatorSet startAnimationToOverlay(
2090ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
2100ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View buttonView, final BaseContainerView toView,
211006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final PrivateTransitionCallbacks pCb) {
212006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
213b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
2149fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
2155f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
2160ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger);
217b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
218b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View fromView = mLauncher.getWorkspace();
219b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
220b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
221b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
222b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
22398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
224b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
225b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
226b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
227b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
2287c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        playCommonTransitionAnimations(toWorkspaceState, fromView, toView,
2297c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                animated, initialized, animation, revealDuration, layerViews);
2300bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
2310ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        final View contentView = toView.getContentView();
2320bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
233006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (animated && initialized) {
234b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the reveal view animation
2350ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View revealView = toView.getRevealView();
2360ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int width = revealView.getMeasuredWidth();
238b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int height = revealView.getMeasuredHeight();
239f7a29e83f06909b378dba39c83a522375682710aSunny Goyal            float revealRadius = (float) Math.hypot(width / 2, height / 2);
240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setVisibility(View.VISIBLE);
241b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setAlpha(0f);
242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationY(0f);
243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationX(0f);
244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Calculate the final animation values
246b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToAlpha;
247b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToXDrift;
248b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToYDrift;
249b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
2500ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(
2510ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        revealView, buttonView, null);
2520ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                revealViewToAlpha = pCb.materialRevealViewFinalAlpha;
25398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToYDrift = buttonViewToPanelDelta[1];
25498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToXDrift = buttonViewToPanelDelta[0];
255b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            } else {
256b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToAlpha = 0f;
257b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToYDrift = 2 * height / 3;
258b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToXDrift = 0;
259b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
260b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
261b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the animators
262b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelAlpha =
2635d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f);
264b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftY =
2655d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0);
266b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftX =
2675d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0);
268b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,
269b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha, panelDriftY, panelDriftX);
270b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setDuration(revealDuration);
271b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
272b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
273b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the animation
274b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(revealView, BUILD_AND_SET_LAYER);
275006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(panelAlphaAndDrift);
276b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
277b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the animation for the content view
278b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
279b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setAlpha(0f);
280b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setTranslationY(revealViewToYDrift);
281b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(contentView, BUILD_AND_SET_LAYER);
282b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
283b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the individual animators
284b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
285b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift, 0);
286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setDuration(revealDuration);
287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setStartDelay(itemsAlphaStagger);
289006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(pageDrift);
290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f);
292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setDuration(revealDuration);
293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setStartDelay(itemsAlphaStagger);
295006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(itemsAlpha);
296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
298b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                float startRadius = pCb.getMaterialRevealViewStartFinalRadius();
299b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener(
30098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                        revealView, buttonView);
3011558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        height / 2, startRadius, revealRadius);
303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setDuration(revealDuration);
304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (listener != null) {
306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.addListener(listener);
307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
308006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(reveal);
309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
311006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, false);
316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Hide the reveal view
318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealView.setVisibility(View.INVISIBLE);
319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
328006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
32976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Dispatch the prepare transition signal
335b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
337b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
338006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
341006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
343006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
347b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
349b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
353756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Focus the new view
359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toView.requestFocus();
360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
361006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.post(startAnimRunnable);
367006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
368006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationX(0.0f);
371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationY(0.0f);
372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleX(1.0f);
373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleY(1.0f);
374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Show the content view
378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, false);
382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, false);
383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, false);
385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, false);
38676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            pCb.onTransitionComplete();
387006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
388006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return null;
389b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
390b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
393685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham     * Plays animations used by various transitions.
394685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham     */
3957c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal    private void playCommonTransitionAnimations(
3967c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal            Workspace.State toWorkspaceState, View fromView, View toView,
397685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            boolean animated, boolean initialized, AnimatorSet animation, int revealDuration,
398685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            HashMap<View, Integer> layerViews) {
399685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // Create the workspace animation.
400685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // NOTE: this call apparently also sets the state for the workspace if !animated
401685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
402685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham                animated, layerViews);
403685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
404685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // Animate the search bar
4057c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        final SearchDropTargetBar.State toSearchBarState =
4062e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal                toWorkspaceState.searchDropTargetBarState;
4077c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState,
4087c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                animated ? revealDuration : 0, animation);
409685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
410685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        if (animated && initialized) {
411685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            // Play the workspace animation
412685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            if (workspaceAnim != null) {
413685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham                animation.play(workspaceAnim);
414685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            }
415685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            // Dispatch onLauncherTransitionStep() as the animation interpolates.
416685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            animation.play(dispatchOnLauncherTransitionStepAnim(fromView, toView));
417685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        }
418685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham    }
419685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
420685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham    /**
4210bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on
4220bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * {@param fromView} and {@param toView} as the animation interpolates.
4230bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     *
4240bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener.
4250bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     */
4260bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) {
4270bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1);
4280bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
4290bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            @Override
4300bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            public void onAnimationUpdate(ValueAnimator animation) {
4310bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction());
4320bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction());
4330bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            }
4340bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        });
4350bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        return updateAnimator;
4360bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    }
4370bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
4380bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    /**
4396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the apps view.
440b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
441006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState,
4422a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Workspace.State toWorkspaceState, final boolean animated,
4432a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
4445f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        AllAppsContainerView appsView = mLauncher.getAppsView();
4450ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        // No alpha anim from all apps
4460ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) {
447b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
448b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewStartFinalRadius() {
4492e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
450b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
451b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
452b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
453b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
454b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
455b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
456b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
457b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // We set the alpha instead of visibility to ensure that the focus does not
458b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // get taken from the all apps view
459b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
460b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(0f);
461b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
462b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
463b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
464b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
465b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
466b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Show the all apps button, and focus it
467b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(1f);
468b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
469b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
470b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
4718fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            @Override
4728fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            void onTransitionComplete() {
4738fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                mLauncher.getLogger().resetElapsedContainerMillis();
4748fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            }
475b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
476ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating to spring loaded mode from all apps
477006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState,
4787c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                mLauncher.getAllAppsButton(), appsView,
4790ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                animated, onCompleteRunnable, cb);
480b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
481b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
482b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
4836d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the widgets view.
484b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
485006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState,
4866d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
4872a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
4884cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song        final WidgetsContainerView widgetsView = mLauncher.getWidgetsView();
4890ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb =
4900ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) {
491b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
492b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
49398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    final View revealView, final View widgetsButtonView) {
494b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
495b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
496b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
497b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
498b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
499b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
500b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
5018fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            @Override
5028fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            void onTransitionComplete() {
5038fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                mLauncher.getLogger().resetElapsedContainerMillis();
5048fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            }
505b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
5060ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(
5070ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                fromWorkspaceState, toWorkspaceState,
5087c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                mLauncher.getWidgetsButton(), widgetsView,
5090ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                animated, onCompleteRunnable, cb);
510b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
511b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
512b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
5136d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from another workspace state, e.g. normal to overview.
5146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     */
5156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState,
5166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
5176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable onCompleteRunnable) {
5186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final View fromWorkspace = mLauncher.getWorkspace();
5196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final HashMap<View, Integer> layerViews = new HashMap<>();
5206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
5216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final int revealDuration = mLauncher.getResources()
5226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                .getInteger(R.integer.config_overlayRevealTime);
5236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        // Cancel the current animation
5256d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        cancelAnimation();
5266d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5277c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null,
5287c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                animated, animated, animation, revealDuration, layerViews);
5296d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5306d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        if (animated) {
5316d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, true);
5326d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final AnimatorSet stateAnimation = animation;
5346d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable startAnimRunnable = new Runnable() {
5356d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
5366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void run() {
5376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Check that mCurrentAnimation hasn't changed while
5386d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // we waited for a layout/draw pass
5396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (mCurrentAnimation != stateAnimation)
5406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        return;
5416d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
5436d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5446d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Enable all necessary layers
5456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
5466d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
5476d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
5486d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
5496d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
5506d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.buildLayer();
5516d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
5526d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
5536d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    stateAnimation.start();
5546d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
5556d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            };
5566d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            animation.addListener(new AnimatorListenerAdapter() {
5576d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @Override
5586d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void onAnimationEnd(Animator animation) {
5596d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
5606d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5616d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Run any queued runnables
5626d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (onCompleteRunnable != null) {
5636d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        onCompleteRunnable.run();
5646d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
5656d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5666d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Disable all necessary layers
5676d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
5686d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
5696d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_NONE, null);
5706d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
5716d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
5726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // This can hold unnecessary references to views.
5746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    cleanupAnimation();
5756d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
5766d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            });
5776d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            fromWorkspace.post(startAnimRunnable);
5786d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = animation;
5796d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else /* if (!animated) */ {
5806d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, true);
5816d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
5826d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
5836d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5846d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            // Run any queued runnables
5856d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            if (onCompleteRunnable != null) {
5866d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                onCompleteRunnable.run();
5876d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            }
5886d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5896d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = null;
5906d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        }
5916d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    }
5926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    /**
594b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to the workspace.
595b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
5960ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private AnimatorSet startAnimationToWorkspaceFromOverlay(
5970ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
5980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View buttonView, final BaseContainerView fromView,
5990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final boolean animated, final Runnable onCompleteRunnable,
600006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final PrivateTransitionCallbacks pCb) {
601006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
602b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
6039fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
6045f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
605b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
6065f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung                res.getInteger(R.integer.config_overlayItemsAlphaStagger);
607b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
608b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View toView = mLauncher.getWorkspace();
609b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
610b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
611b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
612b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
61398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
614b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
615b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
616b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
617b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
6187c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        playCommonTransitionAnimations(toWorkspaceState, fromView, toView,
6197c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                animated, initialized, animation, revealDuration, layerViews);
6200bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
621006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (animated && initialized) {
6220ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View revealView = fromView.getRevealView();
6230ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View contentView = fromView.getContentView();
6240bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
625b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // hideAppsCustomizeHelper is called in some cases when it is already hidden
626b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // don't perform all these no-op animations. In particularly, this was causing
627b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // the all-apps button to pop in and out.
628b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (fromView.getVisibility() == View.VISIBLE) {
629b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int width = revealView.getMeasuredWidth();
630b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int height = revealView.getMeasuredHeight();
631f7a29e83f06909b378dba39c83a522375682710aSunny Goyal                float revealRadius = (float) Math.hypot(width / 2, height / 2);
632b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setVisibility(View.VISIBLE);
633b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setAlpha(1f);
634b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setTranslationY(0);
635b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(revealView, BUILD_AND_SET_LAYER);
636b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
637b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Calculate the final animation values
638b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToXDrift;
639b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToYDrift;
640b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
64198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
64298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            buttonView, null);
64398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToYDrift = buttonViewToPanelDelta[1];
64498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToXDrift = buttonViewToPanelDelta[0];
645b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                } else {
646b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift = 2 * height / 3;
647b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToXDrift = 0;
648b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
649b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
650b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // The vertical motion of the apps panel should be delayed by one frame
651b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // from the conceal animation in order to give the right feel. We correspondingly
652b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // shorten the duration so that the slide and conceal end at the same time.
653b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                TimeInterpolator decelerateInterpolator = material ?
654b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new LogDecelerateInterpolator(100, 0) :
655b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new DecelerateInterpolator(1f);
6561558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY",
657b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
658b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);
659b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
660b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setInterpolator(decelerateInterpolator);
661006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftY);
662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
6631558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX",
664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToXDrift);
665b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);
666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setInterpolator(decelerateInterpolator);
668006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftX);
669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup animation for the reveal panel alpha
671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToAlpha = !material ? 0f :
6720ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        pCb.materialRevealViewFinalAlpha;
673b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (revealViewToAlpha != 1f) {
6741558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha",
675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            1f, revealViewToAlpha);
676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setDuration(material ? revealDuration : 150);
677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
678b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setInterpolator(decelerateInterpolator);
679006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(panelAlpha);
680b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
681b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
682b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup the animation for the content view
683b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(contentView, BUILD_AND_SET_LAYER);
684b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
685b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Create the individual animators
6861558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
687b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
688b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setTranslationY(0);
689b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);
690b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setInterpolator(decelerateInterpolator);
691b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
692006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(pageDrift);
693b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
694b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setAlpha(1f);
6951558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f);
696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setDuration(100);
697b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setInterpolator(decelerateInterpolator);
698006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(itemsAlpha);
699b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
7003f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                // Invalidate the scrim throughout the animation to ensure the highlight
7013f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                // cutout is correct throughout.
7023f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                ValueAnimator invalidateScrim = ValueAnimator.ofFloat(0f, 1f);
7033f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                invalidateScrim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
7043f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    @Override
7053f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    public void onAnimationUpdate(ValueAnimator animation) {
7063f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                        mLauncher.getDragLayer().invalidateScrim();
7073f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    }
7083f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                });
7093f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                animation.play(invalidateScrim);
7103f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham
711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Animate the all apps button
713b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    float finalRadius = pCb.getMaterialRevealViewStartFinalRadius();
714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    AnimatorListenerAdapter listener =
71598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView);
7161558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
7171558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                            height / 2, revealRadius, finalRadius);
718b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
719b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setDuration(revealDuration);
720b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setStartDelay(itemsAlphaStagger);
721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (listener != null) {
722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        reveal.addListener(listener);
723b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
724006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(reveal);
725b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
726b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
728a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham            dispatchOnLauncherTransitionPrepare(fromView, animated, true);
729a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham            dispatchOnLauncherTransitionPrepare(toView, animated, true);
730a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham
731006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    fromView.setVisibility(View.GONE);
735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, true);
737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Run any queued runnables
739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (onCompleteRunnable != null) {
740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        onCompleteRunnable.run();
741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
744b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
745b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
746b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Reset page transforms
751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (contentView != null) {
752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationX(0);
753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationY(0);
754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setAlpha(1);
755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
758006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
75976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
763006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
764b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
765756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
767006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
768b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
769006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
771006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
773b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
774b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
776b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
777b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
778b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
779b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
780756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
781b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
782b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
783b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
784006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
785b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
786b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
787b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.post(startAnimRunnable);
788006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
789006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
7906d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else /* if (!(animated && initialized)) */ {
791b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.setVisibility(View.GONE);
792b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, true);
793b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, true);
794b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, true);
795b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, true);
796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, true);
797b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, true);
79876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            pCb.onTransitionComplete();
799b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
800b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Run any queued runnables
801b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (onCompleteRunnable != null) {
802b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                onCompleteRunnable.run();
803b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
804006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
805006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return null;
806b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
807b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
808b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
809006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    /**
810b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the prepare-transition event to suitable views.
811b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
812b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {
813b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
814b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated,
815b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
816b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
817b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
818b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
819b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
820b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the start-transition event to suitable views.
821b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
822b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {
823b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
824b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated,
825b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
826b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
827b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
828b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
829b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 0f);
830b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
831b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
832b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
833b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the step-transition event to suitable views.
834b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
835b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStep(View v, float t) {
836b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
837b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t);
838b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
839b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
840b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
841b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
842b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the end-transition event to suitable views.
843b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
844b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {
845b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
846b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated,
847b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
848b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
849b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
850b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
851b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 1f);
852b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
853b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
854b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
855b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Cancels the current animation.
856b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
857b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void cancelAnimation() {
858006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (mCurrentAnimation != null) {
859006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.setDuration(0);
860006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.cancel();
861006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation = null;
862b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
863b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
864006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
865d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal    @Thunk void cleanupAnimation() {
866006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = null;
867006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    }
8681558893b873cd55b2df779f594f1de3c370d3328Adam Cohen}
869