LauncherStateTransitionAnimation.java revision a5209e33fcce5cd429086971ef1b57bcfc106c23
1b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/*
2b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Copyright (C) 2015 The Android Open Source Project
3b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
4b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Licensed under the Apache License, Version 2.0 (the "License");
5b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * you may not use this file except in compliance with the License.
6b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * You may obtain a copy of the License at
7b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
8b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *      http://www.apache.org/licenses/LICENSE-2.0
9b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
10b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Unless required by applicable law or agreed to in writing, software
11b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * distributed under the License is distributed on an "AS IS" BASIS,
12b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * See the License for the specific language governing permissions and
14b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * limitations under the License.
15b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */
16b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
17b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpackage com.android.launcher3;
18b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
19b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.Animator;
20b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.AnimatorListenerAdapter;
21b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.AnimatorSet;
22b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.ObjectAnimator;
23b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.PropertyValuesHolder;
24b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.TimeInterpolator;
250bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickhamimport android.animation.ValueAnimator;
267066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyalimport android.annotation.SuppressLint;
27b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.content.res.Resources;
28b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.util.Log;
29b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.View;
30b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.AccelerateInterpolator;
31b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.DecelerateInterpolator;
321558893b873cd55b2df779f594f1de3c370d3328Adam Cohen
335f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chungimport com.android.launcher3.allapps.AllAppsContainerView;
341558893b873cd55b2df779f594f1de3c370d3328Adam Cohenimport com.android.launcher3.util.UiThreadCircularReveal;
35091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
363f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.widget.WidgetsContainerView;
371558893b873cd55b2df779f594f1de3c370d3328Adam Cohen
38b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport java.util.HashMap;
39b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
40b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/**
41b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * TODO: figure out what kind of tests we can write for this
42b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
43b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Things to test when changing the following class.
44b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from workspace
45b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
46b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
47b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from all apps
48b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
49b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
50b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Back from all apps
51b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
52b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
53b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from workspace and quit
54b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
55b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
56b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from all apps and quit
57b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
58b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
59b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Go to a screen that's not the default, then all
60b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *     apps, and launch and app, and go back
61b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
62b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          -with home
63b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, long press power and go back
64b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
65b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
66b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, long press power and go back
67b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
68b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
69b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, power off
70b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, power off
71b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch an app and turn off the screen while in that app
72b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with home key
73b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with back key  TODO: make this not go to workspace
74b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
75b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From workspace
76b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Enter and exit car mode (becuase it causes an extra configuration changed)
77b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
78b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From the center workspace
79b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From another workspace
80b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */
81b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpublic class LauncherStateTransitionAnimation {
82b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
83b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
84b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Private callbacks made during transition setup.
85b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
86b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    static abstract class PrivateTransitionCallbacks {
87b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewFinalAlpha(View revealView) {
88b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
89b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
90b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewStartFinalRadius() {
91b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
92b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
93b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView,
9498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                View buttonView) {
95b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return null;
96b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
9776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung        void onTransitionComplete() {}
98b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
99b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
100b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final String TAG = "LauncherStateTransitionAnimation";
101b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
102b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    // Flags to determine how to set the layers on views before the transition animation
103b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_LAYER = 0;
104b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_AND_SET_LAYER = 1;
105b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int SINGLE_FRAME_DELAY = 16;
106b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
107091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk Launcher mLauncher;
108006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    @Thunk AnimatorSet mCurrentAnimation;
109b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
110006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public LauncherStateTransitionAnimation(Launcher l) {
111b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        mLauncher = l;
112b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
113b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
114b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
115b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the apps view.
11676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *
11776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     * @param startSearchAfterTransition Immediately starts app search after the transition to
11876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *                                   All Apps is completed.
119b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
120006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public void startAnimationToAllApps(final Workspace.State fromWorkspaceState,
121006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final boolean startSearchAfterTransition) {
1225f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final AllAppsContainerView toView = mLauncher.getAppsView();
12398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getAllAppsButton();
124b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
125b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
126b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewFinalAlpha(View revealView) {
127b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return 1f;
128b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
129b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
130b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewStartFinalRadius() {
1312e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
132b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
133b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
134b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
135b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
136b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
137b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
138b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
139b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.INVISIBLE);
140b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
141b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
142b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
143b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
144b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
145b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
14676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            @Override
14776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            void onTransitionComplete() {
14876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                if (startSearchAfterTransition) {
14976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    toView.startAppsSearch();
15076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                }
15176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            }
152b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
153ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating from spring loaded mode back to all apps
154006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState,
155006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                Workspace.State.NORMAL_HIDDEN, buttonView, toView, toView.getContentView(),
156006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                toView.getRevealView(), toView.getSearchBarView(), animated, cb);
157b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
158b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
159b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
160b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the widgets view.
161b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
162006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public void startAnimationToWidgets(final Workspace.State fromWorkspaceState,
163006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated) {
1643f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song        final WidgetsContainerView toView = mLauncher.getWidgetsView();
16598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getWidgetsButton();
16698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song
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    /**
179b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts and 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,
183006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final int toWorkspacePage, 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) {
191006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState, toWorkspacePage,
192dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
193b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
194006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState, toWorkspacePage,
195dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
196b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
197b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
198b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
199b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
200b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to a particular overlay view.
201b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
2027066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal    @SuppressLint("NewApi")
203006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private AnimatorSet startAnimationToOverlay(final Workspace.State fromWorkspaceState,
204006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State toWorkspaceState, final View buttonView, final View toView,
205006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final View contentView, final View revealView, final View overlaySearchBarView,
206006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final PrivateTransitionCallbacks pCb) {
207006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
208b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
2099fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
2105f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
211b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
2125f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung                res.getInteger(R.integer.config_overlayItemsAlphaStagger);
213b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
214b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View fromView = mLauncher.getWorkspace();
215b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
216b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
217b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
218b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
21998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
220b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
221b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
222b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
223b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
224b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Create the workspace animation.
225b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // NOTE: this call apparently also sets the state for the workspace if !animated
226cd99cd3ed6a84b9dcd8f4c60b0941760f85a64ceWinson Chung        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, -1,
227006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animated, layerViews);
228b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
229006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        // Animate the search bar
230006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        startWorkspaceSearchBarAnimation(animation, fromWorkspaceState, toWorkspaceState,
231006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animated ? revealDuration : 0, overlaySearchBarView);
232b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
2330bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        Animator updateTransitionStepAnim = dispatchOnLauncherTransitionStepAnim(fromView, toView);
2340bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
235006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (animated && initialized) {
236b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the reveal view animation
237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int width = revealView.getMeasuredWidth();
238b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int height = revealView.getMeasuredHeight();
239f7a29e83f06909b378dba39c83a522375682710aSunny Goyal            float revealRadius = (float) Math.hypot(width / 2, height / 2);
240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setVisibility(View.VISIBLE);
241b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setAlpha(0f);
242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationY(0f);
243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationX(0f);
244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Calculate the final animation values
246b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToAlpha;
247b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToXDrift;
248b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToYDrift;
249b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
25098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
25198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                        buttonView, null);
252b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToAlpha = pCb.getMaterialRevealViewFinalAlpha(revealView);
25398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToYDrift = buttonViewToPanelDelta[1];
25498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToXDrift = buttonViewToPanelDelta[0];
255b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            } else {
256b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToAlpha = 0f;
257b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToYDrift = 2 * height / 3;
258b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToXDrift = 0;
259b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
260b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
261b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the animators
262b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelAlpha =
263b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    PropertyValuesHolder.ofFloat("alpha", revealViewToAlpha, 1f);
264b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftY =
265b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    PropertyValuesHolder.ofFloat("translationY", revealViewToYDrift, 0);
266b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftX =
267b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    PropertyValuesHolder.ofFloat("translationX", revealViewToXDrift, 0);
268b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,
269b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha, panelDriftY, panelDriftX);
270b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setDuration(revealDuration);
271b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
272b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
273b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the animation
274b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(revealView, BUILD_AND_SET_LAYER);
275006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(panelAlphaAndDrift);
276b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
277ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            if (overlaySearchBarView != null) {
278ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                overlaySearchBarView.setAlpha(0f);
279ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                ObjectAnimator searchBarAlpha = ObjectAnimator.ofFloat(overlaySearchBarView, "alpha", 0f, 1f);
280a2dc7c351d1455f578bf424b13dbf033344799eaWinson                searchBarAlpha.setDuration(revealDuration / 2);
281ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                searchBarAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
282ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                layerViews.put(overlaySearchBarView, BUILD_AND_SET_LAYER);
283006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(searchBarAlpha);
284ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            }
285ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung
286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the animation for the content view
287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setAlpha(0f);
289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setTranslationY(revealViewToYDrift);
290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(contentView, BUILD_AND_SET_LAYER);
291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the individual animators
293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift, 0);
295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setDuration(revealDuration);
296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setStartDelay(itemsAlphaStagger);
298006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(pageDrift);
299b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
300b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f);
301b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setDuration(revealDuration);
302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setStartDelay(itemsAlphaStagger);
304006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(itemsAlpha);
305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                float startRadius = pCb.getMaterialRevealViewStartFinalRadius();
308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener(
30998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                        revealView, buttonView);
3101558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
311b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        height / 2, startRadius, revealRadius);
312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setDuration(revealDuration);
313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (listener != null) {
315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.addListener(listener);
316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
317006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(reveal);
318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
320006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, false);
325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Hide the reveal view
327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealView.setVisibility(View.INVISIBLE);
328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
335b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
337006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
33876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the workspace animation
344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (workspaceAnim != null) {
345006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(workspaceAnim);
346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
347b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
3480bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            animation.play(updateTransitionStepAnim);
3490bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Dispatch the prepare transition signal
351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
354006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
357006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
359006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
3699fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && Utilities.isViewAttachedToWindow(v)) {
370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Focus the new view
375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toView.requestFocus();
376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
377006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.post(startAnimRunnable);
383006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
384006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationX(0.0f);
387b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationY(0.0f);
388b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleX(1.0f);
389b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleY(1.0f);
390b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Show the content view
394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
397b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, false);
398b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, false);
399b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
400b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, false);
401b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, false);
40276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            pCb.onTransitionComplete();
403006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
404006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return null;
405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
407b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
408b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
4090bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on
4100bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * {@param fromView} and {@param toView} as the animation interpolates.
4110bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     *
4120bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener.
4130bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     */
4140bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) {
4150bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1);
4160bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
4170bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            @Override
4180bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            public void onAnimationUpdate(ValueAnimator animation) {
4190bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction());
4200bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction());
4210bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            }
4220bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        });
4230bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        return updateAnimator;
4240bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    }
4250bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
4260bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    /**
427b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts and animation to the workspace from the apps view.
428b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
429006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState,
430006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State toWorkspaceState, final int toWorkspacePage,
431006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final Runnable onCompleteRunnable) {
4325f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        AllAppsContainerView appsView = mLauncher.getAppsView();
433b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
434b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
435b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewFinalAlpha(View revealView) {
436b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // No alpha anim from all apps
437b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return 1f;
438b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
439b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
440b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewStartFinalRadius() {
4412e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
442b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
443b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
444b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
445b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
446b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
447b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
448b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
449b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // We set the alpha instead of visibility to ensure that the focus does not
450b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // get taken from the all apps view
451b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
452b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(0f);
453b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
454b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
455b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
456b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
457b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
458b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Show the all apps button, and focus it
459b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(1f);
460b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
461b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
462b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
463b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
464ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating to spring loaded mode from all apps
465006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState,
466006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                toWorkspacePage, mLauncher.getAllAppsButton(), appsView, appsView.getContentView(),
46798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                appsView.getRevealView(), appsView.getSearchBarView(), animated,
46898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                onCompleteRunnable, cb);
469b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
470b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
471b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
472b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts and animation to the workspace from the widgets view.
473b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
474006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState,
475006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State toWorkspaceState, final int toWorkspacePage,
476006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final Runnable onCompleteRunnable) {
4774cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song        final WidgetsContainerView widgetsView = mLauncher.getWidgetsView();
478b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
479b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
480b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewFinalAlpha(View revealView) {
48198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                return 0.3f;
482b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
483b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
484b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
48598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    final View revealView, final View widgetsButtonView) {
486b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
487b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
488b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
489b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
490b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
491b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
492b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
493b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
494006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState,
495006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                toWorkspaceState, toWorkspacePage, mLauncher.getWidgetsButton(), widgetsView,
496006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                widgetsView.getContentView(), widgetsView.getRevealView(), null, animated,
497006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                onCompleteRunnable, cb);
498b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
499b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
500b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
501b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to the workspace.
502b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
503006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private AnimatorSet startAnimationToWorkspaceFromOverlay(final Workspace.State fromWorkspaceState,
504006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State toWorkspaceState, final int toWorkspacePage, final View buttonView,
505006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final View fromView, final View contentView, final View revealView,
506006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final View overlaySearchBarView, final boolean animated, final Runnable onCompleteRunnable,
507006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final PrivateTransitionCallbacks pCb) {
508006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
509b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
5109fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
5115f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
512b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
5135f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung                res.getInteger(R.integer.config_overlayItemsAlphaStagger);
514b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
515b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View toView = mLauncher.getWorkspace();
516b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
517b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
518b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
519b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
52098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
521b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
522b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
523b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
524b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
525b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Create the workspace animation.
526b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // NOTE: this call apparently also sets the state for the workspace if !animated
527cd99cd3ed6a84b9dcd8f4c60b0941760f85a64ceWinson Chung        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
528006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                toWorkspacePage, animated, layerViews);
529b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
530006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        // Animate the search bar
531006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        startWorkspaceSearchBarAnimation(animation, fromWorkspaceState, toWorkspaceState,
532006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animated ? revealDuration : 0, overlaySearchBarView);
533b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
5340bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        Animator updateTransitionStepAnim = dispatchOnLauncherTransitionStepAnim(fromView, toView);
5350bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
536006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (animated && initialized) {
537b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the workspace animation
538b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (workspaceAnim != null) {
539006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(workspaceAnim);
540b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
541b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
5420bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            animation.play(updateTransitionStepAnim);
5430bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
544b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // hideAppsCustomizeHelper is called in some cases when it is already hidden
545b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // don't perform all these no-op animations. In particularly, this was causing
546b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // the all-apps button to pop in and out.
547b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (fromView.getVisibility() == View.VISIBLE) {
548b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int width = revealView.getMeasuredWidth();
549b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int height = revealView.getMeasuredHeight();
550f7a29e83f06909b378dba39c83a522375682710aSunny Goyal                float revealRadius = (float) Math.hypot(width / 2, height / 2);
551b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setVisibility(View.VISIBLE);
552b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setAlpha(1f);
553b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setTranslationY(0);
554b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(revealView, BUILD_AND_SET_LAYER);
555b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
556b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Calculate the final animation values
557b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToXDrift;
558b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToYDrift;
559b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
56098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
56198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            buttonView, null);
56298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToYDrift = buttonViewToPanelDelta[1];
56398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToXDrift = buttonViewToPanelDelta[0];
564b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                } else {
565b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift = 2 * height / 3;
566b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToXDrift = 0;
567b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
568b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
569b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // The vertical motion of the apps panel should be delayed by one frame
570b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // from the conceal animation in order to give the right feel. We correspondingly
571b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // shorten the duration so that the slide and conceal end at the same time.
572b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                TimeInterpolator decelerateInterpolator = material ?
573b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new LogDecelerateInterpolator(100, 0) :
574b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new DecelerateInterpolator(1f);
5751558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY",
576b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
577b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);
578b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
579b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setInterpolator(decelerateInterpolator);
580006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftY);
581b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
5821558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX",
583b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToXDrift);
584b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);
585b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
586b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setInterpolator(decelerateInterpolator);
587006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftX);
588b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
589b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup animation for the reveal panel alpha
590b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToAlpha = !material ? 0f :
591b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        pCb.getMaterialRevealViewFinalAlpha(revealView);
592b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (revealViewToAlpha != 1f) {
5931558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha",
594b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            1f, revealViewToAlpha);
595b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setDuration(material ? revealDuration : 150);
596b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
597b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setInterpolator(decelerateInterpolator);
598006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(panelAlpha);
599b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
600b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
601b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup the animation for the content view
602b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(contentView, BUILD_AND_SET_LAYER);
603b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
604b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Create the individual animators
6051558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
606b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
607b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setTranslationY(0);
608b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);
609b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setInterpolator(decelerateInterpolator);
610b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
611006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(pageDrift);
612b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
613b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setAlpha(1f);
6141558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f);
615b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setDuration(100);
616b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setInterpolator(decelerateInterpolator);
617006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(itemsAlpha);
618b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
619ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                if (overlaySearchBarView != null) {
620ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    overlaySearchBarView.setAlpha(1f);
621ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    ObjectAnimator searchAlpha = ObjectAnimator.ofFloat(overlaySearchBarView, "alpha", 1f, 0f);
622a2dc7c351d1455f578bf424b13dbf033344799eaWinson                    searchAlpha.setDuration(revealDuration / 2);
623a2dc7c351d1455f578bf424b13dbf033344799eaWinson                    searchAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
624ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    searchAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
625ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    layerViews.put(overlaySearchBarView, BUILD_AND_SET_LAYER);
626006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(searchAlpha);
627ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                }
628ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung
629b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
630b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Animate the all apps button
631b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    float finalRadius = pCb.getMaterialRevealViewStartFinalRadius();
632b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    AnimatorListenerAdapter listener =
63398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView);
6341558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
6351558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                            height / 2, revealRadius, finalRadius);
636b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
637b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setDuration(revealDuration);
638b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setStartDelay(itemsAlphaStagger);
639b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (listener != null) {
640b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        reveal.addListener(listener);
641b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
642006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(reveal);
643b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
644b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
645b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
646a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham            dispatchOnLauncherTransitionPrepare(fromView, animated, true);
647a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham            dispatchOnLauncherTransitionPrepare(toView, animated, true);
648a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham
649006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
650b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
651b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
652b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    fromView.setVisibility(View.GONE);
653b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
654b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, true);
655b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
656b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Run any queued runnables
657b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (onCompleteRunnable != null) {
658b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        onCompleteRunnable.run();
659b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
660b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
661b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
663b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
665b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
668b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Reset page transforms
669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (contentView != null) {
670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationX(0);
671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationY(0);
672b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setAlpha(1);
673b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
674ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    if (overlaySearchBarView != null) {
675ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                        overlaySearchBarView.setAlpha(1f);
676ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    }
677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
678b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
679006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
68076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
681b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
682b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
683b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
684006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
685b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
686b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
687006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
688b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
689006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
690b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
691006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
692b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
693b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
694b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
695b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
697b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
698b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
699b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
7009fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && Utilities.isViewAttachedToWindow(v)) {
701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
702b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
703b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
704006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
705b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
706b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
707b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.post(startAnimRunnable);
708006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
709006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
710b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.setVisibility(View.GONE);
712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, true);
713b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, true);
714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, true);
715b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, true);
716b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, true);
717b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, true);
71876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            pCb.onTransitionComplete();
719b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
720b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Run any queued runnables
721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (onCompleteRunnable != null) {
722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                onCompleteRunnable.run();
723b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
724006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
725006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return null;
726b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
729006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    /**
730006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung     * Coordinates the workspace search bar animation along with the launcher state animation.
731006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung     */
732006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startWorkspaceSearchBarAnimation(AnimatorSet animation,
733006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, int duration,
734006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            View overlaySearchBar) {
735006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final SearchDropTargetBar.State toSearchBarState =
736006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                toWorkspaceState.getSearchDropTargetBarState();
737006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
738006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (overlaySearchBar != null) {
739f768d934682ba80da89d454543928e629a44103dWinson            if (mLauncher.launcherCallbacksProvidesSearch()) {
740f768d934682ba80da89d454543928e629a44103dWinson                if ((toWorkspaceState == Workspace.State.NORMAL) &&
741f768d934682ba80da89d454543928e629a44103dWinson                        (fromWorkspaceState == Workspace.State.NORMAL_HIDDEN)) {
742f768d934682ba80da89d454543928e629a44103dWinson                    // If we are transitioning from the overlay to the workspace, then show the
743f768d934682ba80da89d454543928e629a44103dWinson                    // workspace search bar immediately and let the overlay search bar fade out on
744f768d934682ba80da89d454543928e629a44103dWinson                    // top
745f768d934682ba80da89d454543928e629a44103dWinson                    mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, 0);
746f768d934682ba80da89d454543928e629a44103dWinson                    return;
747f768d934682ba80da89d454543928e629a44103dWinson                } else if (fromWorkspaceState == Workspace.State.NORMAL) {
748f768d934682ba80da89d454543928e629a44103dWinson                    // If we are transitioning from the workspace to the overlay, then keep the
749f768d934682ba80da89d454543928e629a44103dWinson                    // workspace search bar visible until the overlay search bar fades in on top
750f768d934682ba80da89d454543928e629a44103dWinson                    animation.addListener(new AnimatorListenerAdapter() {
751f768d934682ba80da89d454543928e629a44103dWinson                        @Override
752f768d934682ba80da89d454543928e629a44103dWinson                        public void onAnimationEnd(Animator animation) {
753f768d934682ba80da89d454543928e629a44103dWinson                            mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, 0);
754f768d934682ba80da89d454543928e629a44103dWinson                        }
755f768d934682ba80da89d454543928e629a44103dWinson                    });
756f768d934682ba80da89d454543928e629a44103dWinson                    return;
757f768d934682ba80da89d454543928e629a44103dWinson                }
758006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            }
759006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        }
760a2dc7c351d1455f578bf424b13dbf033344799eaWinson        // Fallback to the default search bar animation otherwise
761a2dc7c351d1455f578bf424b13dbf033344799eaWinson        mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, duration);
762006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    }
763b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
764b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
765b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the prepare-transition event to suitable views.
766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {
768b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
769b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated,
770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
771b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
773b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
774b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the start-transition event to suitable views.
776b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
777b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {
778b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
779b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated,
780b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
781b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
782b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
783b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
784b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 0f);
785b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
786b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
787b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
788b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the step-transition event to suitable views.
789b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
790b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStep(View v, float t) {
791b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
792b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t);
793b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
794b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
795b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
797b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the end-transition event to suitable views.
798b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
799b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {
800b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
801b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated,
802b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
803b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
804b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
805b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
806b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 1f);
807b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
808b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
809b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
810b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Cancels the current animation.
811b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
812b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void cancelAnimation() {
813006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (mCurrentAnimation != null) {
814006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.setDuration(0);
815006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.cancel();
816006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation = null;
817b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
818b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
819006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
820d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal    @Thunk void cleanupAnimation() {
821006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = null;
822006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    }
8231558893b873cd55b2df779f594f1de3c370d3328Adam Cohen}
824