LauncherStateTransitionAnimation.java revision 6d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dc
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;
257066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyalimport android.annotation.SuppressLint;
26756cd26592dee6b956becdc24d60995c64de9153Sunny Goyalimport android.annotation.TargetApi;
27b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.content.res.Resources;
28756cd26592dee6b956becdc24d60995c64de9153Sunny Goyalimport android.os.Build;
29b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.util.Log;
30b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.View;
31b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.AccelerateInterpolator;
32b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.DecelerateInterpolator;
331558893b873cd55b2df779f594f1de3c370d3328Adam Cohen
345f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chungimport com.android.launcher3.allapps.AllAppsContainerView;
35091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
365d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyalimport com.android.launcher3.util.UiThreadCircularReveal;
373f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.widget.WidgetsContainerView;
381558893b873cd55b2df779f594f1de3c370d3328Adam Cohen
39b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport java.util.HashMap;
40b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
41b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/**
42b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * TODO: figure out what kind of tests we can write for this
43b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
44b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Things to test when changing the following class.
45b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from workspace
46b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
47b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
48b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from all apps
49b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
50b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
51b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Back from all apps
52b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
53b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
54b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from workspace and quit
55b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
56b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
57b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from all apps and quit
58b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
59b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
60b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Go to a screen that's not the default, then all
61b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *     apps, and launch and app, and go back
62b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
63b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          -with home
64b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, long press power and go back
65b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
66b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
67b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, long press power and go back
68b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
69b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
70b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, power off
71b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, power off
72b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch an app and turn off the screen while in that app
73b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with home key
74b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with back key  TODO: make this not go to workspace
75b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
76b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From workspace
77b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Enter and exit car mode (becuase it causes an extra configuration changed)
78b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
79b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From the center workspace
80b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From another workspace
81b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */
82b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpublic class LauncherStateTransitionAnimation {
83b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
84b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
85b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Private callbacks made during transition setup.
86b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
87b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    static abstract class PrivateTransitionCallbacks {
88b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewFinalAlpha(View revealView) {
89b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
90b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
91b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewStartFinalRadius() {
92b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
93b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
94b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView,
9598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                View buttonView) {
96b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return null;
97b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
9876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung        void onTransitionComplete() {}
99b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
100b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
101b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final String TAG = "LauncherStateTransitionAnimation";
102b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
103b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    // Flags to determine how to set the layers on views before the transition animation
104b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_LAYER = 0;
105b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_AND_SET_LAYER = 1;
106b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int SINGLE_FRAME_DELAY = 16;
107b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
108091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk Launcher mLauncher;
109006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    @Thunk AnimatorSet mCurrentAnimation;
110b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
111006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public LauncherStateTransitionAnimation(Launcher l) {
112b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        mLauncher = l;
113b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
114b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
115b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
116b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the apps view.
11776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *
11876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     * @param startSearchAfterTransition Immediately starts app search after the transition to
11976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *                                   All Apps is completed.
120b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
121006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public void startAnimationToAllApps(final Workspace.State fromWorkspaceState,
122006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final boolean startSearchAfterTransition) {
1235f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final AllAppsContainerView toView = mLauncher.getAppsView();
12498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getAllAppsButton();
125b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
126b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
127b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewFinalAlpha(View revealView) {
128b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return 1f;
129b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
130b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
131b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewStartFinalRadius() {
1322e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
133b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
134b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
135b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
136b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
137b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
138b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
139b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
140b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.INVISIBLE);
141b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
142b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
143b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
144b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
145b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
146b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
14776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            @Override
14876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            void onTransitionComplete() {
14976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                if (startSearchAfterTransition) {
15076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    toView.startAppsSearch();
15176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                }
15276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            }
153b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
154ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating from spring loaded mode back to all apps
155006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState,
156006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                Workspace.State.NORMAL_HIDDEN, buttonView, toView, toView.getContentView(),
157006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                toView.getRevealView(), toView.getSearchBarView(), animated, cb);
158b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
159b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
160b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
161b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the widgets view.
162b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
163006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public void startAnimationToWidgets(final Workspace.State fromWorkspaceState,
164006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated) {
1653f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song        final WidgetsContainerView toView = mLauncher.getWidgetsView();
16698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getWidgetsButton();
167b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
168b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
169b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewFinalAlpha(View revealView) {
170b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return 0.3f;
171b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
172b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
173006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState,
174006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, toView.getContentView(),
175006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                toView.getRevealView(), null, animated, cb);
176b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
177b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
178b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
1796d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the current overlay view.
180b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
181b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public void startAnimationToWorkspace(final Launcher.State fromState,
182006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
1832a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final boolean animated, final Runnable onCompleteRunnable) {
184b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (toWorkspaceState != Workspace.State.NORMAL &&
185b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.SPRING_LOADED &&
186b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.OVERVIEW) {
187b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            Log.e(TAG, "Unexpected call to startAnimationToWorkspace");
188b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
189b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
190b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) {
1912a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState,
192dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
1936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else if (fromState == Launcher.State.WIDGETS ||
1946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                fromState == Launcher.State.WIDGETS_SPRING_LOADED) {
1952a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState,
196dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
1976d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else {
1986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            startAnimationToNewWorkspaceState(fromWorkspaceState, toWorkspaceState,
1996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    animated, onCompleteRunnable);
200b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
201b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
202b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
203b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
204b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to a particular overlay view.
205b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
2067066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal    @SuppressLint("NewApi")
207006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private AnimatorSet startAnimationToOverlay(final Workspace.State fromWorkspaceState,
208006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State toWorkspaceState, final View buttonView, final View toView,
209006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final View contentView, final View revealView, final View overlaySearchBarView,
210006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final PrivateTransitionCallbacks pCb) {
211006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
212b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
2139fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
2145f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
215b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
2165f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung                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
228b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Create the workspace animation.
229b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // NOTE: this call apparently also sets the state for the workspace if !animated
230ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
231006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animated, layerViews);
232b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
233006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        // Animate the search bar
234006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        startWorkspaceSearchBarAnimation(animation, fromWorkspaceState, toWorkspaceState,
235006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animated ? revealDuration : 0, overlaySearchBarView);
236b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
237006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (animated && initialized) {
238b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the reveal view animation
239b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int width = revealView.getMeasuredWidth();
240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int height = revealView.getMeasuredHeight();
241f7a29e83f06909b378dba39c83a522375682710aSunny Goyal            float revealRadius = (float) Math.hypot(width / 2, height / 2);
242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setVisibility(View.VISIBLE);
243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setAlpha(0f);
244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationY(0f);
245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationX(0f);
246b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
247b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Calculate the final animation values
248b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToAlpha;
249b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToXDrift;
250b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToYDrift;
251b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
25298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
25398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                        buttonView, null);
254b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToAlpha = pCb.getMaterialRevealViewFinalAlpha(revealView);
25598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToYDrift = buttonViewToPanelDelta[1];
25698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToXDrift = buttonViewToPanelDelta[0];
257b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            } else {
258b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToAlpha = 0f;
259b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToYDrift = 2 * height / 3;
260b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToXDrift = 0;
261b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
262b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
263b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the animators
264b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelAlpha =
2655d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f);
266b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftY =
2675d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0);
268b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftX =
2695d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0);
270b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,
271b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha, panelDriftY, panelDriftX);
272b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setDuration(revealDuration);
273b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
274b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
275b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the animation
276b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(revealView, BUILD_AND_SET_LAYER);
277006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(panelAlphaAndDrift);
278b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
279ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            if (overlaySearchBarView != null) {
280ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                overlaySearchBarView.setAlpha(0f);
281ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                ObjectAnimator searchBarAlpha = ObjectAnimator.ofFloat(overlaySearchBarView, "alpha", 0f, 1f);
282ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                searchBarAlpha.setDuration(100);
283ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                searchBarAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
284ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                layerViews.put(overlaySearchBarView, BUILD_AND_SET_LAYER);
285006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(searchBarAlpha);
286ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            }
287ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung
288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the animation for the content view
289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setAlpha(0f);
291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setTranslationY(revealViewToYDrift);
292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(contentView, BUILD_AND_SET_LAYER);
293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the individual animators
295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift, 0);
297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setDuration(revealDuration);
298b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
299b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setStartDelay(itemsAlphaStagger);
300006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(pageDrift);
301b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f);
303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setDuration(revealDuration);
304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setStartDelay(itemsAlphaStagger);
306006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(itemsAlpha);
307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                float startRadius = pCb.getMaterialRevealViewStartFinalRadius();
310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener(
31198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                        revealView, buttonView);
3121558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        height / 2, startRadius, revealRadius);
314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setDuration(revealDuration);
315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (listener != null) {
317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.addListener(listener);
318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
319006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(reveal);
320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
322006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, false);
327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Hide the reveal view
329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealView.setVisibility(View.INVISIBLE);
330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
335b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
337b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
339006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
34076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the workspace animation
346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (workspaceAnim != null) {
347006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(workspaceAnim);
348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
349b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Dispatch the prepare transition signal
351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
355006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
358006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
360006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
370756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Focus the new view
376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toView.requestFocus();
377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
378006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.post(startAnimRunnable);
384006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
385006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
387b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationX(0.0f);
388b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationY(0.0f);
389b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleX(1.0f);
390b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleY(1.0f);
391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Show the content view
395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
397b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
398b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, false);
399b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, false);
400b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
401b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, false);
402b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, false);
40376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            pCb.onTransitionComplete();
404006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
405006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return null;
406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
407b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
408b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
409b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
4106d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the apps view.
411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
412006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState,
4132a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Workspace.State toWorkspaceState, final boolean animated,
4142a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
4155f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        AllAppsContainerView appsView = mLauncher.getAppsView();
416b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
417b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
418b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewFinalAlpha(View revealView) {
419b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // No alpha anim from all apps
420b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return 1f;
421b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
422b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
423b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewStartFinalRadius() {
4242e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
425b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
426b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
427b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
428b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
429b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
430b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
431b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
432b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // We set the alpha instead of visibility to ensure that the focus does not
433b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // get taken from the all apps view
434b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
435b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(0f);
436b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
437b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
438b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
439b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
440b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
441b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Show the all apps button, and focus it
442b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(1f);
443b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
444b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
445b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
446b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
447ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating to spring loaded mode from all apps
448006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState,
4492a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson                mLauncher.getAllAppsButton(), appsView, appsView.getContentView(),
45098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                appsView.getRevealView(), appsView.getSearchBarView(), animated,
45198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                onCompleteRunnable, cb);
452b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
453b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
454b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
4556d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the widgets view.
456b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
457006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState,
4586d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
4592a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
4604cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song        final WidgetsContainerView widgetsView = mLauncher.getWidgetsView();
461b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
462b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
463b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewFinalAlpha(View revealView) {
46498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                return 0.3f;
465b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
466b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
467b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
46898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    final View revealView, final View widgetsButtonView) {
469b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
470b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
471b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
472b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
473b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
474b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
475b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
476b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
477006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState,
4782a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson                toWorkspaceState, mLauncher.getWidgetsButton(), widgetsView,
479006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                widgetsView.getContentView(), widgetsView.getRevealView(), null, animated,
480006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                onCompleteRunnable, cb);
481b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
482b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
483b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
4846d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from another workspace state, e.g. normal to overview.
4856d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     */
4866d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState,
4876d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
4886d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable onCompleteRunnable) {
4896d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final View fromWorkspace = mLauncher.getWorkspace();
4906d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final HashMap<View, Integer> layerViews = new HashMap<>();
4916d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
4926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final int revealDuration = mLauncher.getResources()
4936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                .getInteger(R.integer.config_overlayRevealTime);
4946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
4956d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        // Cancel the current animation
4966d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        cancelAnimation();
4976d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
4986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        // Create the workspace animation.
4996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        // NOTE: this call apparently also sets the state for the workspace if !animated
5006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
5016d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                animated, layerViews);
5026d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5036d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        startWorkspaceSearchBarAnimation(animation, fromWorkspaceState, toWorkspaceState,
5046d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                animated ? revealDuration : 0, null);
5056d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5066d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        if (animated) {
5076d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            if (workspaceAnim != null) {
5086d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                animation.play(workspaceAnim);
5096d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            }
5106d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, true);
5116d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5126d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final AnimatorSet stateAnimation = animation;
5136d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable startAnimRunnable = new Runnable() {
5146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
5156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void run() {
5166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Check that mCurrentAnimation hasn't changed while
5176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // we waited for a layout/draw pass
5186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (mCurrentAnimation != stateAnimation)
5196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        return;
5206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
5226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Enable all necessary layers
5246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
5256d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
5266d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
5276d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
5286d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
5296d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.buildLayer();
5306d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
5316d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
5326d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    stateAnimation.start();
5336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
5346d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            };
5356d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            animation.addListener(new AnimatorListenerAdapter() {
5366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @Override
5376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void onAnimationEnd(Animator animation) {
5386d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
5396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Run any queued runnables
5416d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (onCompleteRunnable != null) {
5426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        onCompleteRunnable.run();
5436d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
5446d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Disable all necessary layers
5466d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
5476d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
5486d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_NONE, null);
5496d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
5506d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
5516d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5526d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // This can hold unnecessary references to views.
5536d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    cleanupAnimation();
5546d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
5556d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            });
5566d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            fromWorkspace.post(startAnimRunnable);
5576d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = animation;
5586d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else /* if (!animated) */ {
5596d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, true);
5606d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
5616d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
5626d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5636d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            // Run any queued runnables
5646d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            if (onCompleteRunnable != null) {
5656d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                onCompleteRunnable.run();
5666d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            }
5676d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5686d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = null;
5696d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        }
5706d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    }
5716d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    /**
573b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to the workspace.
574b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
575006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private AnimatorSet startAnimationToWorkspaceFromOverlay(final Workspace.State fromWorkspaceState,
5762a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Workspace.State toWorkspaceState, final View buttonView,
577006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final View fromView, final View contentView, final View revealView,
578006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final View overlaySearchBarView, final boolean animated, final Runnable onCompleteRunnable,
579006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final PrivateTransitionCallbacks pCb) {
580006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
581b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
5829fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
5835f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
584b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
5855f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung                res.getInteger(R.integer.config_overlayItemsAlphaStagger);
586b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
587b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View toView = mLauncher.getWorkspace();
588b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
589b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
590b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
591b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
59298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
593b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
594b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
595b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
596b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
597b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Create the workspace animation.
598b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // NOTE: this call apparently also sets the state for the workspace if !animated
599cd99cd3ed6a84b9dcd8f4c60b0941760f85a64ceWinson Chung        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
6002a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson                animated, layerViews);
601b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
602006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        // Animate the search bar
603006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        startWorkspaceSearchBarAnimation(animation, fromWorkspaceState, toWorkspaceState,
604006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animated ? revealDuration : 0, overlaySearchBarView);
605b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
606006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (animated && initialized) {
607b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the workspace animation
608b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (workspaceAnim != null) {
609006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(workspaceAnim);
610b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
611b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
612b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // hideAppsCustomizeHelper is called in some cases when it is already hidden
613b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // don't perform all these no-op animations. In particularly, this was causing
614b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // the all-apps button to pop in and out.
615b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (fromView.getVisibility() == View.VISIBLE) {
616b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int width = revealView.getMeasuredWidth();
617b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int height = revealView.getMeasuredHeight();
618f7a29e83f06909b378dba39c83a522375682710aSunny Goyal                float revealRadius = (float) Math.hypot(width / 2, height / 2);
619b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setVisibility(View.VISIBLE);
620b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setAlpha(1f);
621b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setTranslationY(0);
622b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(revealView, BUILD_AND_SET_LAYER);
623b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
624b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Calculate the final animation values
625b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToXDrift;
626b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToYDrift;
627b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
62898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
62998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            buttonView, null);
63098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToYDrift = buttonViewToPanelDelta[1];
63198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToXDrift = buttonViewToPanelDelta[0];
632b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                } else {
633b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift = 2 * height / 3;
634b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToXDrift = 0;
635b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
636b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
637b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // The vertical motion of the apps panel should be delayed by one frame
638b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // from the conceal animation in order to give the right feel. We correspondingly
639b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // shorten the duration so that the slide and conceal end at the same time.
640b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                TimeInterpolator decelerateInterpolator = material ?
641b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new LogDecelerateInterpolator(100, 0) :
642b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new DecelerateInterpolator(1f);
6431558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY",
644b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
645b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);
646b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
647b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setInterpolator(decelerateInterpolator);
648006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftY);
649b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
6501558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX",
651b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToXDrift);
652b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);
653b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
654b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setInterpolator(decelerateInterpolator);
655006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftX);
656b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
657b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup animation for the reveal panel alpha
658b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToAlpha = !material ? 0f :
659b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        pCb.getMaterialRevealViewFinalAlpha(revealView);
660b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (revealViewToAlpha != 1f) {
6611558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha",
662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            1f, revealViewToAlpha);
663b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setDuration(material ? revealDuration : 150);
664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
665b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setInterpolator(decelerateInterpolator);
666006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(panelAlpha);
667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
668b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup the animation for the content view
670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(contentView, BUILD_AND_SET_LAYER);
671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
672b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Create the individual animators
6731558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
674b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setTranslationY(0);
676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);
677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setInterpolator(decelerateInterpolator);
678b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
679006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(pageDrift);
680b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
681b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setAlpha(1f);
6821558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f);
683b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setDuration(100);
684b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setInterpolator(decelerateInterpolator);
685006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(itemsAlpha);
686b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
687ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                if (overlaySearchBarView != null) {
688ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    overlaySearchBarView.setAlpha(1f);
689ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    ObjectAnimator searchAlpha = ObjectAnimator.ofFloat(overlaySearchBarView, "alpha", 1f, 0f);
690ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    searchAlpha.setDuration(material ? 100 : 150);
691ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    searchAlpha.setInterpolator(decelerateInterpolator);
692ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    searchAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
693ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    layerViews.put(overlaySearchBarView, BUILD_AND_SET_LAYER);
694006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(searchAlpha);
695ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                }
696ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung
697b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
698b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Animate the all apps button
699b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    float finalRadius = pCb.getMaterialRevealViewStartFinalRadius();
700b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    AnimatorListenerAdapter listener =
70198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView);
7021558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
7031558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                            height / 2, revealRadius, finalRadius);
704b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
705b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setDuration(revealDuration);
706b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setStartDelay(itemsAlphaStagger);
707b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (listener != null) {
708b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        reveal.addListener(listener);
709b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
710006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(reveal);
711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
713b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                dispatchOnLauncherTransitionPrepare(fromView, animated, true);
714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                dispatchOnLauncherTransitionPrepare(toView, animated, true);
715b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
716b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
717006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
718b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
719b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
720b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    fromView.setVisibility(View.GONE);
721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, true);
723b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
724b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Run any queued runnables
725b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (onCompleteRunnable != null) {
726b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        onCompleteRunnable.run();
727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Reset page transforms
737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (contentView != null) {
738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationX(0);
739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationY(0);
740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setAlpha(1);
741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
742ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    if (overlaySearchBarView != null) {
743ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                        overlaySearchBarView.setAlpha(1f);
744ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    }
745b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
746b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
747006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
74876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
752006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
754756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
756006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
758006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
759b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
760006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
763b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
764b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
765b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
768b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
769756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
771b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
773006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
774b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
776b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.post(startAnimRunnable);
777006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
778006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
7796d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else /* if (!(animated && initialized)) */ {
780b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.setVisibility(View.GONE);
781b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, true);
782b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, true);
783b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, true);
784b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, true);
785b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, true);
786b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, true);
78776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            pCb.onTransitionComplete();
788b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
789b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Run any queued runnables
790b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (onCompleteRunnable != null) {
791b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                onCompleteRunnable.run();
792b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
793006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
794006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return null;
795b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
797b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
798006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    /**
799006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung     * Coordinates the workspace search bar animation along with the launcher state animation.
800006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung     */
801006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startWorkspaceSearchBarAnimation(AnimatorSet animation,
802006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, int duration,
803006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            View overlaySearchBar) {
804006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final SearchDropTargetBar.State toSearchBarState =
805006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                toWorkspaceState.getSearchDropTargetBarState();
806006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
807006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (overlaySearchBar != null) {
808006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            if ((toWorkspaceState == Workspace.State.NORMAL) &&
809006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    (fromWorkspaceState == Workspace.State.NORMAL_HIDDEN)) {
810006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                // If we are transitioning from the overlay to the workspace, then show the
811006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                // workspace search bar immediately and let the overlay search bar fade out on top
812006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, 0);
813006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            } else if (fromWorkspaceState == Workspace.State.NORMAL) {
814006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                // If we are transitioning from the workspace to the overlay, then keep the
815006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                // workspace search bar visible until the overlay search bar fades in on top
816006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.addListener(new AnimatorListenerAdapter() {
817006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    @Override
818006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    public void onAnimationEnd(Animator animation) {
819006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                        mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, 0);
820006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    }
821006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                });
822006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            } else {
823006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                // Otherwise, then just animate the workspace search bar normally
824006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, duration);
825006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            }
826006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        } else {
827006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            // If there is no overlay search bar, then just animate the workspace search bar
828006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, duration);
829006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        }
830006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    }
831b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
832b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
833b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the prepare-transition event to suitable views.
834b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
835b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {
836b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
837b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated,
838b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
839b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
840b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
841b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
842b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
843b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the start-transition event to suitable views.
844b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
845b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {
846b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
847b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated,
848b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
849b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
850b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
851b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
852b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 0f);
853b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
854b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
855b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
856b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the step-transition event to suitable views.
857b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
858b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStep(View v, float t) {
859b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
860b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t);
861b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
862b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
863b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
864b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
865b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the end-transition event to suitable views.
866b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
867b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {
868b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
869b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated,
870b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
871b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
872b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
873b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
874b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 1f);
875b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
876b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
877b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
878b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Cancels the current animation.
879b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
880b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void cancelAnimation() {
881006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (mCurrentAnimation != null) {
882006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.setDuration(0);
883006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.cancel();
884006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation = null;
885b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
886b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
887006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
888d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal    @Thunk void cleanupAnimation() {
889006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = null;
890006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    }
8911558893b873cd55b2df779f594f1de3c370d3328Adam Cohen}
892