LauncherStateTransitionAnimation.java revision 98ff38aa48b4c9d3e33c128fae2d5c851e49a3eb
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;
26b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.content.res.Resources;
27b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.util.Log;
28b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.View;
29b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.AccelerateInterpolator;
30b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.DecelerateInterpolator;
311558893b873cd55b2df779f594f1de3c370d3328Adam Cohen
325f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chungimport com.android.launcher3.allapps.AllAppsContainerView;
331558893b873cd55b2df779f594f1de3c370d3328Adam Cohenimport com.android.launcher3.util.UiThreadCircularReveal;
34091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
353f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.widget.WidgetsContainerView;
361558893b873cd55b2df779f594f1de3c370d3328Adam Cohen
37b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport java.util.HashMap;
38b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
39b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/**
40b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * TODO: figure out what kind of tests we can write for this
41b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
42b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Things to test when changing the following class.
43b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from workspace
44b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
45b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
46b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from all apps
47b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
48b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
49b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Back from all apps
50b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
51b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
52b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from workspace and quit
53b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
54b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
55b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from all apps and quit
56b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
57b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
58b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Go to a screen that's not the default, then all
59b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *     apps, and launch and app, and go back
60b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
61b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          -with home
62b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, long press power and go back
63b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
64b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
65b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, long press power and go back
66b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
67b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
68b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, power off
69b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, power off
70b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch an app and turn off the screen while in that app
71b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with home key
72b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with back key  TODO: make this not go to workspace
73b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
74b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From workspace
75b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Enter and exit car mode (becuase it causes an extra configuration changed)
76b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
77b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From the center workspace
78b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From another workspace
79b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */
80b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpublic class LauncherStateTransitionAnimation {
81b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
82b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
83b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Callbacks made during the state transition
84b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
85b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    interface Callbacks {
86b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        public void onStateTransitionHideSearchBar();
87b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
88b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
89b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
90b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Private callbacks made during transition setup.
91b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
92b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    static abstract class PrivateTransitionCallbacks {
93b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewFinalAlpha(View revealView) {
94b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
95b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
96b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewStartFinalRadius() {
97b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
98b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
99b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView,
10098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                View buttonView) {
101b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return null;
102b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
10376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung        void onTransitionComplete() {}
104b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
105b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
106b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final String TAG = "LauncherStateTransitionAnimation";
107b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
108b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    // Flags to determine how to set the layers on views before the transition animation
109b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_LAYER = 0;
110b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_AND_SET_LAYER = 1;
111b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int SINGLE_FRAME_DELAY = 16;
112b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
113091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk Launcher mLauncher;
114091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk Callbacks mCb;
115091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk AnimatorSet mStateAnimation;
116b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
117b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public LauncherStateTransitionAnimation(Launcher l, Callbacks cb) {
118b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        mLauncher = l;
119b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        mCb = cb;
120b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
121b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
122b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
123b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the apps view.
12476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *
12576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     * @param startSearchAfterTransition Immediately starts app search after the transition to
12676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *                                   All Apps is completed.
127b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
12876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung    public void startAnimationToAllApps(final boolean animated,
12976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            final boolean startSearchAfterTransition) {
1305f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final AllAppsContainerView toView = mLauncher.getAppsView();
13198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getAllAppsButton();
132b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
133b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
134b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewFinalAlpha(View revealView) {
135b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return 1f;
136b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
137b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
138b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewStartFinalRadius() {
1392e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
140b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
141b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
142b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
143b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
144b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
145b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
146b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
147b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.INVISIBLE);
148b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
149b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
150b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
151b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
152b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
153b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
15476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            @Override
15576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            void onTransitionComplete() {
15676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                if (startSearchAfterTransition) {
15776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    toView.startAppsSearch();
15876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                }
15976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            }
160b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
161ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating from spring loaded mode back to all apps
16298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        startAnimationToOverlay(Workspace.State.NORMAL_HIDDEN, buttonView, toView,
16398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                toView.getContentView(), toView.getRevealView(), toView.getSearchBarView(),
16498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                animated, true /* hideSearchBar */, cb);
165b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
166b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
167b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
168b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the widgets view.
169b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
170b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public void startAnimationToWidgets(final boolean animated) {
1713f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song        final WidgetsContainerView toView = mLauncher.getWidgetsView();
17298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getWidgetsButton();
17398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song
174b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
175b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
176b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewFinalAlpha(View revealView) {
177b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return 0.3f;
178b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
179b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
18098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        startAnimationToOverlay(Workspace.State.OVERVIEW_HIDDEN, buttonView, toView,
181ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                toView.getContentView(), toView.getRevealView(), null, animated,
182ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                true /* hideSearchBar */, cb);
183b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
184b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
185b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
186b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts and animation to the workspace from the current overlay view.
187b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
188b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public void startAnimationToWorkspace(final Launcher.State fromState,
189dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung              final Workspace.State toWorkspaceState, final int toWorkspacePage,
190dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung              final boolean animated, final Runnable onCompleteRunnable) {
191b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (toWorkspaceState != Workspace.State.NORMAL &&
192b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.SPRING_LOADED &&
193b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.OVERVIEW) {
194b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            Log.e(TAG, "Unexpected call to startAnimationToWorkspace");
195b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
196b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
197b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) {
198ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            startAnimationToWorkspaceFromAllApps(toWorkspaceState, toWorkspacePage,
199dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
200b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
201ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            startAnimationToWorkspaceFromWidgets(toWorkspaceState, toWorkspacePage,
202dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
203b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
204b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
205b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
206b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
207b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to a particular overlay view.
208b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
2097066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal    @SuppressLint("NewApi")
21098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song    private void startAnimationToOverlay(final Workspace.State toWorkspaceState,
21198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song            final View buttonView, final View toView, final View contentView, final View revealView,
21298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song            final View overlaySearchBarView, final boolean animated, final boolean hideSearchBar,
21398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song            final PrivateTransitionCallbacks pCb) {
214b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
215b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final boolean material = Utilities.isLmpOrAbove();
2165f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
217b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
2185f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung                res.getInteger(R.integer.config_overlayItemsAlphaStagger);
219b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
220b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View fromView = mLauncher.getWorkspace();
221b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
222b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
223b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
224b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
22598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
226b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
227b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
228b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
229b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
230b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Create the workspace animation.
231b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // NOTE: this call apparently also sets the state for the workspace if !animated
232cd99cd3ed6a84b9dcd8f4c60b0941760f85a64ceWinson Chung        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, -1,
233ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                animated, overlaySearchBarView != null /* hasOverlaySearchBar */, layerViews);
234b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
235b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (animated && initialized) {
236b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation = LauncherAnimUtils.createAnimatorSet();
237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
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 =
265b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    PropertyValuesHolder.ofFloat("alpha", revealViewToAlpha, 1f);
266b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftY =
267b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    PropertyValuesHolder.ofFloat("translationY", revealViewToYDrift, 0);
268b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftX =
269b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    PropertyValuesHolder.ofFloat("translationX", 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);
277b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.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);
285ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                mStateAnimation.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);
300b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.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);
306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.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                }
319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(reveal);
320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.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
3380f785720667ab8afe4b4620a6c333d382d8659edWinson Chung                    if (hideSearchBar) {
3390f785720667ab8afe4b4620a6c333d382d8659edWinson Chung                        mCb.onStateTransitionHideSearchBar();
3400f785720667ab8afe4b4620a6c333d382d8659edWinson Chung                    }
341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mStateAnimation = null;
34476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
347b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
349b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the workspace animation
350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (workspaceAnim != null) {
351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(workspaceAnim);
352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Dispatch the prepare transition signal
355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final AnimatorSet stateAnimation = mStateAnimation;
360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Check that mStateAnimation hasn't changed while
363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (mStateAnimation != stateAnimation)
365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
37011509ad61afb7424ce83057b0d2a4b09f853651fWinson Chung                    boolean isLmpOrAbove = Utilities.isLmpOrAbove();
371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
37511509ad61afb7424ce83057b0d2a4b09f853651fWinson Chung                        if (isLmpOrAbove && Utilities.isViewAttachedToWindow(v)) {
376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Focus the new view
381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toView.requestFocus();
382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mStateAnimation.start();
384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
387b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
388b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.post(startAnimRunnable);
389b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
390b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationX(0.0f);
391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationY(0.0f);
392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleX(1.0f);
393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleY(1.0f);
394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
397b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Show the content view
398b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
399b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
4000f785720667ab8afe4b4620a6c333d382d8659edWinson Chung            if (hideSearchBar) {
4010f785720667ab8afe4b4620a6c333d382d8659edWinson Chung                mCb.onStateTransitionHideSearchBar();
4020f785720667ab8afe4b4620a6c333d382d8659edWinson Chung            }
403b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
404b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, false);
406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, false);
407b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
408b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, false);
409b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, false);
41076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            pCb.onTransitionComplete();
411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
412b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
413b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
414b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
415b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts and animation to the workspace from the apps view.
416b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
417ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    private void startAnimationToWorkspaceFromAllApps(final Workspace.State toWorkspaceState,
418ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            final int toWorkspacePage, final boolean animated, final Runnable onCompleteRunnable) {
4195f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        AllAppsContainerView appsView = mLauncher.getAppsView();
420b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
421b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int[] mAllAppsToPanelDelta;
422b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
423b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
424b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewFinalAlpha(View revealView) {
425b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // No alpha anim from all apps
426b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return 1f;
427b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
428b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
429b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewStartFinalRadius() {
4302e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
431b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
432b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
433b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
434b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
435b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
436b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
437b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
438b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // We set the alpha instead of visibility to ensure that the focus does not
439b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // get taken from the all apps view
440b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
441b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(0f);
442b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
443b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
444b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
445b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
446b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
447b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Show the all apps button, and focus it
448b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(1f);
449b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
450b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
451b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
452b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
453ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating to spring loaded mode from all apps
45498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        startAnimationToWorkspaceFromOverlay(toWorkspaceState, toWorkspacePage,
45598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                mLauncher.getAllAppsButton(), appsView, appsView.getContentView(),
45698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                appsView.getRevealView(), appsView.getSearchBarView(), animated,
45798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                onCompleteRunnable, cb);
458b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
459b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
460b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
461b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts and animation to the workspace from the widgets view.
462b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
463ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    private void startAnimationToWorkspaceFromWidgets(final Workspace.State toWorkspaceState,
464ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung              final int toWorkspacePage, final boolean animated, final Runnable onCompleteRunnable) {
4654cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song        final WidgetsContainerView widgetsView = mLauncher.getWidgetsView();
466b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
467b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
468b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewFinalAlpha(View revealView) {
46998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                return 0.3f;
470b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
471b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
472b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
47398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    final View revealView, final View widgetsButtonView) {
474b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
475b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
476b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
477b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
478b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
479b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
480b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
481b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
48298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        startAnimationToWorkspaceFromOverlay(toWorkspaceState, toWorkspacePage,
48398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                mLauncher.getWidgetsButton(), widgetsView, widgetsView.getContentView(),
48498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                widgetsView.getRevealView(), null, animated, onCompleteRunnable, cb);
485b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
486b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
487b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
488b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to the workspace.
489b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
490b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void startAnimationToWorkspaceFromOverlay(final Workspace.State toWorkspaceState,
49198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song              final int toWorkspacePage, final View buttonView, final View fromView,
49298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song              final View contentView, final View revealView, final View overlaySearchBarView,
49398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song              final boolean animated, final Runnable onCompleteRunnable,
49498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song              final PrivateTransitionCallbacks pCb) {
495b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
496b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final boolean material = Utilities.isLmpOrAbove();
4975f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
498b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
4995f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung                res.getInteger(R.integer.config_overlayItemsAlphaStagger);
500b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
501b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View toView = mLauncher.getWorkspace();
502b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
503b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
504b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
505b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
50698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
507b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
508b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
509b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
510b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
511b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Create the workspace animation.
512b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // NOTE: this call apparently also sets the state for the workspace if !animated
513cd99cd3ed6a84b9dcd8f4c60b0941760f85a64ceWinson Chung        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
514ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                toWorkspacePage, animated, overlaySearchBarView != null /* hasOverlaySearchBar */,
515ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                layerViews);
516b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
517b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (animated && initialized) {
518b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation = LauncherAnimUtils.createAnimatorSet();
519b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
520b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the workspace animation
521b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (workspaceAnim != null) {
522b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(workspaceAnim);
523b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
524b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
525b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // hideAppsCustomizeHelper is called in some cases when it is already hidden
526b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // don't perform all these no-op animations. In particularly, this was causing
527b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // the all-apps button to pop in and out.
528b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (fromView.getVisibility() == View.VISIBLE) {
529b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int width = revealView.getMeasuredWidth();
530b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int height = revealView.getMeasuredHeight();
531f7a29e83f06909b378dba39c83a522375682710aSunny Goyal                float revealRadius = (float) Math.hypot(width / 2, height / 2);
532b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setVisibility(View.VISIBLE);
533b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setAlpha(1f);
534b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setTranslationY(0);
535b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(revealView, BUILD_AND_SET_LAYER);
536b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
537b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Calculate the final animation values
538b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToXDrift;
539b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToYDrift;
540b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
54198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
54298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            buttonView, null);
54398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToYDrift = buttonViewToPanelDelta[1];
54498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToXDrift = buttonViewToPanelDelta[0];
545b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                } else {
546b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift = 2 * height / 3;
547b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToXDrift = 0;
548b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
549b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
550b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // The vertical motion of the apps panel should be delayed by one frame
551b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // from the conceal animation in order to give the right feel. We correspondingly
552b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // shorten the duration so that the slide and conceal end at the same time.
553b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                TimeInterpolator decelerateInterpolator = material ?
554b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new LogDecelerateInterpolator(100, 0) :
555b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new DecelerateInterpolator(1f);
5561558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY",
557b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
558b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);
559b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
560b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setInterpolator(decelerateInterpolator);
561b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(panelDriftY);
562b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
5631558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX",
564b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToXDrift);
565b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);
566b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
567b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setInterpolator(decelerateInterpolator);
568b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(panelDriftX);
569b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
570b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup animation for the reveal panel alpha
571b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToAlpha = !material ? 0f :
572b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        pCb.getMaterialRevealViewFinalAlpha(revealView);
573b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (revealViewToAlpha != 1f) {
5741558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha",
575b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            1f, revealViewToAlpha);
576b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setDuration(material ? revealDuration : 150);
577b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
578b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setInterpolator(decelerateInterpolator);
579b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mStateAnimation.play(panelAlpha);
580b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
581b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
582b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup the animation for the content view
583b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(contentView, BUILD_AND_SET_LAYER);
584b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
585b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Create the individual animators
5861558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
587b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
588b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setTranslationY(0);
589b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);
590b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setInterpolator(decelerateInterpolator);
591b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
592b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(pageDrift);
593b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
594b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setAlpha(1f);
5951558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f);
596b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setDuration(100);
597b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setInterpolator(decelerateInterpolator);
598b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(itemsAlpha);
599b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
600ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                if (overlaySearchBarView != null) {
601ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    overlaySearchBarView.setAlpha(1f);
602ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    ObjectAnimator searchAlpha = ObjectAnimator.ofFloat(overlaySearchBarView, "alpha", 1f, 0f);
603ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    searchAlpha.setDuration(material ? 100 : 150);
604ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    searchAlpha.setInterpolator(decelerateInterpolator);
605ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    searchAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
606ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    layerViews.put(overlaySearchBarView, BUILD_AND_SET_LAYER);
607ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    mStateAnimation.play(searchAlpha);
608ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                }
609ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung
610b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
611b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Animate the all apps button
612b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    float finalRadius = pCb.getMaterialRevealViewStartFinalRadius();
613b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    AnimatorListenerAdapter listener =
61498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView);
6151558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
6161558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                            height / 2, revealRadius, finalRadius);
617b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
618b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setDuration(revealDuration);
619b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setStartDelay(itemsAlphaStagger);
620b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (listener != null) {
621b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        reveal.addListener(listener);
622b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
623b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mStateAnimation.play(reveal);
624b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
625b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
626b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                dispatchOnLauncherTransitionPrepare(fromView, animated, true);
627b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                dispatchOnLauncherTransitionPrepare(toView, animated, true);
628b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
629b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
630b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.addListener(new AnimatorListenerAdapter() {
631b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
632b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
633b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    fromView.setVisibility(View.GONE);
634b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
635b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, true);
636b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
637b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Run any queued runnables
638b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (onCompleteRunnable != null) {
639b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        onCompleteRunnable.run();
640b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
641b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
642b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
643b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
644b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
645b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
646b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
647b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
648b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
649b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Reset page transforms
650b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (contentView != null) {
651b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationX(0);
652b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationY(0);
653b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setAlpha(1);
654b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
655ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    if (overlaySearchBarView != null) {
656ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                        overlaySearchBarView.setAlpha(1f);
657ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    }
658b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
659b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
660b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mStateAnimation = null;
66176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
663b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
665b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final AnimatorSet stateAnimation = mStateAnimation;
666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
668b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Check that mStateAnimation hasn't changed while
669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (mStateAnimation != stateAnimation)
671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
672b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
673b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
674b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
67611509ad61afb7424ce83057b0d2a4b09f853651fWinson Chung                    boolean isLmpOrAbove = Utilities.isLmpOrAbove();
677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
678b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
679b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
680b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
68111509ad61afb7424ce83057b0d2a4b09f853651fWinson Chung                        if (isLmpOrAbove && Utilities.isViewAttachedToWindow(v)) {
682b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
683b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
684b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
685b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mStateAnimation.start();
686b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
687b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
688b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.post(startAnimRunnable);
689b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
690b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.setVisibility(View.GONE);
691b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, true);
692b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, true);
693b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, true);
694b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, true);
695b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, true);
696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, true);
69776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            pCb.onTransitionComplete();
698b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
699b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Run any queued runnables
700b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (onCompleteRunnable != null) {
701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                onCompleteRunnable.run();
702b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
703b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
704b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
705b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
706b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
707b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
708b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the prepare-transition event to suitable views.
709b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
710b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {
711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated,
713b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
715b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
716b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
717b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
718b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the start-transition event to suitable views.
719b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
720b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {
721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated,
723b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
724b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
725b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
726b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 0f);
728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the step-transition event to suitable views.
732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStep(View v, float t) {
734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t);
736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the end-transition event to suitable views.
741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {
743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
744b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated,
745b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
746b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 1f);
750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Cancels the current animation.
754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void cancelAnimation() {
756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (mStateAnimation != null) {
757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.setDuration(0);
758b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.cancel();
759b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation = null;
760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
7621558893b873cd55b2df779f594f1de3c370d3328Adam Cohen}
763