LauncherStateTransitionAnimation.java revision 0ac7ede56afebe4401c0636196f5844be573ad68
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
830ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private static final float FINAL_REVEAL_ALPHA_FOR_WIDGETS = 0.3f;
840ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
85b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
86b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Private callbacks made during transition setup.
87b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
880ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private static class PrivateTransitionCallbacks {
890ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        private final float materialRevealViewFinalAlpha;
900ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
910ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks(float revealAlpha) {
920ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            materialRevealViewFinalAlpha = revealAlpha;
93b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
940ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
95b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewStartFinalRadius() {
96b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
97b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
98b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView,
9998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                View buttonView) {
100b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return null;
101b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
10276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung        void onTransitionComplete() {}
103b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
104b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
1050ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    public static final String TAG = "LSTAnimation";
106b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
107b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    // Flags to determine how to set the layers on views before the transition animation
108b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_LAYER = 0;
109b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_AND_SET_LAYER = 1;
110b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int SINGLE_FRAME_DELAY = 16;
111b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
112091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk Launcher mLauncher;
113006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    @Thunk AnimatorSet mCurrentAnimation;
114b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
115006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public LauncherStateTransitionAnimation(Launcher l) {
116b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        mLauncher = l;
117b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
118b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
119b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
120b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the apps view.
12176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *
12276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     * @param startSearchAfterTransition Immediately starts app search after the transition to
12376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *                                   All Apps is completed.
124b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
125006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public void startAnimationToAllApps(final Workspace.State fromWorkspaceState,
126006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final boolean startSearchAfterTransition) {
1275f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final AllAppsContainerView toView = mLauncher.getAppsView();
12898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getAllAppsButton();
1290ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) {
130b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
131b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewStartFinalRadius() {
1322e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
133b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
134b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
135b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
136b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
137b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
138b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
139b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
140b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.INVISIBLE);
141b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
142b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
143b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
144b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
145b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
146b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
14776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            @Override
14876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            void onTransitionComplete() {
14976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                if (startSearchAfterTransition) {
15076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    toView.startAppsSearch();
15176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                }
15276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            }
153b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
154ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating from spring loaded mode back to all apps
155006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState,
1560ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                Workspace.State.NORMAL_HIDDEN, buttonView, toView, 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
167006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState,
1680ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, animated,
1690ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS));
170b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
171b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
172b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
173b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts and animation to the workspace from the current overlay view.
174b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
175b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public void startAnimationToWorkspace(final Launcher.State fromState,
176006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
177006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final int toWorkspacePage, final boolean animated, final Runnable onCompleteRunnable) {
178b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (toWorkspaceState != Workspace.State.NORMAL &&
179b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.SPRING_LOADED &&
180b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.OVERVIEW) {
181b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            Log.e(TAG, "Unexpected call to startAnimationToWorkspace");
182b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
183b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
184b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) {
185006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState, toWorkspacePage,
186dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
187b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
188006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState, toWorkspacePage,
189dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
190b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
191b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
192b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
193b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
194b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to a particular overlay view.
195b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
1967066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal    @SuppressLint("NewApi")
1970ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private AnimatorSet startAnimationToOverlay(
1980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
1990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View buttonView, final BaseContainerView toView,
200006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final PrivateTransitionCallbacks pCb) {
201006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
202b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
2039fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
2045f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
2050ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger);
206b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
207b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View fromView = mLauncher.getWorkspace();
208b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
209b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
210b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
211b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
21298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
213b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
214b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
215b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
216b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
217b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Create the workspace animation.
218b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // NOTE: this call apparently also sets the state for the workspace if !animated
219cd99cd3ed6a84b9dcd8f4c60b0941760f85a64ceWinson Chung        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState, -1,
220006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animated, layerViews);
221b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
222006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        // Animate the search bar
2230ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        startWorkspaceSearchBarAnimation(
2240ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                toWorkspaceState, animated ? revealDuration : 0, animation);
225b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
2260bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        Animator updateTransitionStepAnim = dispatchOnLauncherTransitionStepAnim(fromView, toView);
2270bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
2280ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        final View contentView = toView.getContentView();
2290ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
230006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (animated && initialized) {
231b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the reveal view animation
2320ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View revealView = toView.getRevealView();
2330ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
234b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int width = revealView.getMeasuredWidth();
235b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int height = revealView.getMeasuredHeight();
236f7a29e83f06909b378dba39c83a522375682710aSunny Goyal            float revealRadius = (float) Math.hypot(width / 2, height / 2);
237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setVisibility(View.VISIBLE);
238b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setAlpha(0f);
239b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationY(0f);
240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationX(0f);
241b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Calculate the final animation values
243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToAlpha;
244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToXDrift;
245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToYDrift;
246b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
2470ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(
2480ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        revealView, buttonView, null);
2490ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                revealViewToAlpha = pCb.materialRevealViewFinalAlpha;
25098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToYDrift = buttonViewToPanelDelta[1];
25198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToXDrift = buttonViewToPanelDelta[0];
252b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            } else {
253b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToAlpha = 0f;
254b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToYDrift = 2 * height / 3;
255b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToXDrift = 0;
256b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
257b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
258b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the animators
259b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelAlpha =
260b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    PropertyValuesHolder.ofFloat("alpha", revealViewToAlpha, 1f);
261b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftY =
262b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    PropertyValuesHolder.ofFloat("translationY", revealViewToYDrift, 0);
263b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftX =
264b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    PropertyValuesHolder.ofFloat("translationX", revealViewToXDrift, 0);
265b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,
266b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha, panelDriftY, panelDriftX);
267b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setDuration(revealDuration);
268b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
269b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
270b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the animation
271b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(revealView, BUILD_AND_SET_LAYER);
272006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(panelAlphaAndDrift);
273b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
274b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the animation for the content view
275b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
276b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setAlpha(0f);
277b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setTranslationY(revealViewToYDrift);
278b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(contentView, BUILD_AND_SET_LAYER);
279b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
280b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the individual animators
281b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
282b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift, 0);
283b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setDuration(revealDuration);
284b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
285b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setStartDelay(itemsAlphaStagger);
286006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(pageDrift);
287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f);
289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setDuration(revealDuration);
290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setStartDelay(itemsAlphaStagger);
292006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(itemsAlpha);
293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                float startRadius = pCb.getMaterialRevealViewStartFinalRadius();
296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener(
29798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                        revealView, buttonView);
2981558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
299b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        height / 2, startRadius, revealRadius);
300b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setDuration(revealDuration);
301b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (listener != null) {
303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.addListener(listener);
304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
305006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(reveal);
306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
308006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
311b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, false);
313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Hide the reveal view
315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealView.setVisibility(View.INVISIBLE);
316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
325006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
32676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the workspace animation
332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (workspaceAnim != null) {
333006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(workspaceAnim);
334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
335b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
3360bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            animation.play(updateTransitionStepAnim);
3370bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Dispatch the prepare transition signal
339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
342006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
345006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
347006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
349b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
3579fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && Utilities.isViewAttachedToWindow(v)) {
358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Focus the new view
363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toView.requestFocus();
364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
365006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.post(startAnimRunnable);
371006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
372006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationX(0.0f);
375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationY(0.0f);
376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleX(1.0f);
377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleY(1.0f);
378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Show the content view
382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, false);
386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, false);
387b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
388b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, false);
389b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, false);
39076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            pCb.onTransitionComplete();
391006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
392006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return null;
393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
3970bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on
3980bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * {@param fromView} and {@param toView} as the animation interpolates.
3990bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     *
4000bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener.
4010bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     */
4020bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) {
4030bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1);
4040bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
4050bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            @Override
4060bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            public void onAnimationUpdate(ValueAnimator animation) {
4070bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction());
4080bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction());
4090bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            }
4100bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        });
4110bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        return updateAnimator;
4120bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    }
4130bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
4140bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    /**
415b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts and animation to the workspace from the apps view.
416b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
417006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState,
418006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State toWorkspaceState, final int toWorkspacePage,
419006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final Runnable onCompleteRunnable) {
4205f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        AllAppsContainerView appsView = mLauncher.getAppsView();
4210ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        // No alpha anim from all apps
4220ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) {
423b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
424b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewStartFinalRadius() {
4252e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
426b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
427b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
428b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
429b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
430b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
431b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
432b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
433b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // We set the alpha instead of visibility to ensure that the focus does not
434b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // get taken from the all apps view
435b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
436b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(0f);
437b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
438b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
439b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
440b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
441b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
442b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Show the all apps button, and focus it
443b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(1f);
444b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
445b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
446b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
447b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
448ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating to spring loaded mode from all apps
449006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState,
4500ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                toWorkspacePage, mLauncher.getAllAppsButton(), appsView,
4510ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                animated, onCompleteRunnable, cb);
452b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
453b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
454b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
455b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts and animation to the workspace from the widgets view.
456b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
457006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState,
458006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State toWorkspaceState, final int toWorkspacePage,
459006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final Runnable onCompleteRunnable) {
4604cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song        final WidgetsContainerView widgetsView = mLauncher.getWidgetsView();
4610ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb =
4620ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) {
463b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
464b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
46598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    final View revealView, final View widgetsButtonView) {
466b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
467b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
468b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
469b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
470b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
471b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
472b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
473b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
4740ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(
4750ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                fromWorkspaceState, toWorkspaceState,
4760ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                toWorkspacePage, mLauncher.getWidgetsButton(), widgetsView,
4770ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                animated, onCompleteRunnable, cb);
478b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
479b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
480b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
481b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to the workspace.
482b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
4830ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private AnimatorSet startAnimationToWorkspaceFromOverlay(
4840ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
4850ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final int toWorkspacePage,
4860ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View buttonView, final BaseContainerView fromView,
4870ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final boolean animated, final Runnable onCompleteRunnable,
488006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final PrivateTransitionCallbacks pCb) {
489006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
490b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
4919fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
4925f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
493b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
4945f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung                res.getInteger(R.integer.config_overlayItemsAlphaStagger);
495b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
496b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View toView = mLauncher.getWorkspace();
497b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
498b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
499b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
500b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
50198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
502b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
503b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
504b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
505b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
506b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Create the workspace animation.
507b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // NOTE: this call apparently also sets the state for the workspace if !animated
508cd99cd3ed6a84b9dcd8f4c60b0941760f85a64ceWinson Chung        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
509006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                toWorkspacePage, animated, layerViews);
510b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
511006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        // Animate the search bar
5120ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        startWorkspaceSearchBarAnimation(
5130ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                toWorkspaceState, animated ? revealDuration : 0, animation);
514b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
5150bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        Animator updateTransitionStepAnim = dispatchOnLauncherTransitionStepAnim(fromView, toView);
5160bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
517006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (animated && initialized) {
518b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the workspace animation
519b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (workspaceAnim != null) {
520006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(workspaceAnim);
521b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
522b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
5230bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            animation.play(updateTransitionStepAnim);
5240ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View revealView = fromView.getRevealView();
5250ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View contentView = fromView.getContentView();
5260bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
527b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // hideAppsCustomizeHelper is called in some cases when it is already hidden
528b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // don't perform all these no-op animations. In particularly, this was causing
529b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // the all-apps button to pop in and out.
530b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (fromView.getVisibility() == View.VISIBLE) {
531b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int width = revealView.getMeasuredWidth();
532b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int height = revealView.getMeasuredHeight();
533f7a29e83f06909b378dba39c83a522375682710aSunny Goyal                float revealRadius = (float) Math.hypot(width / 2, height / 2);
534b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setVisibility(View.VISIBLE);
535b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setAlpha(1f);
536b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setTranslationY(0);
537b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(revealView, BUILD_AND_SET_LAYER);
538b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
539b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Calculate the final animation values
540b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToXDrift;
541b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToYDrift;
542b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
54398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
54498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            buttonView, null);
54598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToYDrift = buttonViewToPanelDelta[1];
54698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToXDrift = buttonViewToPanelDelta[0];
547b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                } else {
548b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift = 2 * height / 3;
549b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToXDrift = 0;
550b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
551b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
552b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // The vertical motion of the apps panel should be delayed by one frame
553b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // from the conceal animation in order to give the right feel. We correspondingly
554b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // shorten the duration so that the slide and conceal end at the same time.
555b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                TimeInterpolator decelerateInterpolator = material ?
556b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new LogDecelerateInterpolator(100, 0) :
557b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new DecelerateInterpolator(1f);
5581558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY",
559b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
560b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);
561b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
562b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setInterpolator(decelerateInterpolator);
563006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftY);
564b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
5651558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX",
566b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToXDrift);
567b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);
568b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
569b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setInterpolator(decelerateInterpolator);
570006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftX);
571b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
572b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup animation for the reveal panel alpha
573b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToAlpha = !material ? 0f :
5740ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        pCb.materialRevealViewFinalAlpha;
575b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (revealViewToAlpha != 1f) {
5761558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha",
577b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            1f, revealViewToAlpha);
578b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setDuration(material ? revealDuration : 150);
579b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
580b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setInterpolator(decelerateInterpolator);
581006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(panelAlpha);
582b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
583b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
584b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup the animation for the content view
585b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(contentView, BUILD_AND_SET_LAYER);
586b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
587b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Create the individual animators
5881558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
589b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
590b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setTranslationY(0);
591b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);
592b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setInterpolator(decelerateInterpolator);
593b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
594006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(pageDrift);
595b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
596b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setAlpha(1f);
5971558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f);
598b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setDuration(100);
599b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setInterpolator(decelerateInterpolator);
600006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(itemsAlpha);
601b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
602b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
603b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Animate the all apps button
604b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    float finalRadius = pCb.getMaterialRevealViewStartFinalRadius();
605b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    AnimatorListenerAdapter listener =
60698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView);
6071558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
6081558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                            height / 2, revealRadius, finalRadius);
609b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
610b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setDuration(revealDuration);
611b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setStartDelay(itemsAlphaStagger);
612b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (listener != null) {
613b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        reveal.addListener(listener);
614b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
615006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(reveal);
616b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
617b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
618b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
619a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham            dispatchOnLauncherTransitionPrepare(fromView, animated, true);
620a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham            dispatchOnLauncherTransitionPrepare(toView, animated, true);
621a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham
622006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
623b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
624b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
625b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    fromView.setVisibility(View.GONE);
626b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
627b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, true);
628b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
629b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Run any queued runnables
630b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (onCompleteRunnable != null) {
631b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        onCompleteRunnable.run();
632b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
633b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
634b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
635b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
636b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
637b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
638b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
639b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
640b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
641b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Reset page transforms
642b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (contentView != null) {
643b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationX(0);
644b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationY(0);
645b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setAlpha(1);
646b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
647b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
648b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
649006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
65076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
651b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
652b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
653b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
654006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
655b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
656b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
657006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
658b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
659006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
660b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
661006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
663b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
665b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
668b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
6709fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && Utilities.isViewAttachedToWindow(v)) {
671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
672b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
673b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
674006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.post(startAnimRunnable);
678006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
679006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
680b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
681b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.setVisibility(View.GONE);
682b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, true);
683b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, true);
684b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, true);
685b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, true);
686b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, true);
687b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, true);
68876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            pCb.onTransitionComplete();
689b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
690b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Run any queued runnables
691b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (onCompleteRunnable != null) {
692b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                onCompleteRunnable.run();
693b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
694006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
695006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return null;
696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
697b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
698b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
699006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    /**
700006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung     * Coordinates the workspace search bar animation along with the launcher state animation.
701006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung     */
7020ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private void startWorkspaceSearchBarAnimation(
7030ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State toWorkspaceState, int duration, AnimatorSet animation) {
704006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final SearchDropTargetBar.State toSearchBarState =
705006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                toWorkspaceState.getSearchDropTargetBarState();
7060ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState, duration, animation);
707006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    }
708b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
709b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
710b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the prepare-transition event to suitable views.
711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {
713b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated,
715b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
716b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
717b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
718b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
719b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
720b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the start-transition event to suitable views.
721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {
723b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
724b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated,
725b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
726b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 0f);
730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the step-transition event to suitable views.
734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStep(View v, float t) {
736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t);
738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the end-transition event to suitable views.
743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
744b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {
745b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
746b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated,
747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 1f);
752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Cancels the current animation.
756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void cancelAnimation() {
758006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (mCurrentAnimation != null) {
759006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.setDuration(0);
760006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.cancel();
761006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation = null;
762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
763b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
764006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
765d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal    @Thunk void cleanupAnimation() {
766006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = null;
767006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    }
7681558893b873cd55b2df779f594f1de3c370d3328Adam Cohen}
769