LauncherStateTransitionAnimation.java revision 645764e3e5fa34d9adcddfc722d726b76f048306
1b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/*
2b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Copyright (C) 2015 The Android Open Source Project
3b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
4b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Licensed under the Apache License, Version 2.0 (the "License");
5b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * you may not use this file except in compliance with the License.
6b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * You may obtain a copy of the License at
7b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
8b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *      http://www.apache.org/licenses/LICENSE-2.0
9b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
10b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Unless required by applicable law or agreed to in writing, software
11b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * distributed under the License is distributed on an "AS IS" BASIS,
12b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * See the License for the specific language governing permissions and
14b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * limitations under the License.
15b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */
16b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
17b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpackage com.android.launcher3;
18b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
19b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.Animator;
20b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.AnimatorListenerAdapter;
21b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.AnimatorSet;
22b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.ObjectAnimator;
23b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.PropertyValuesHolder;
24b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.animation.TimeInterpolator;
250bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickhamimport android.animation.ValueAnimator;
267066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyalimport android.annotation.SuppressLint;
27756cd26592dee6b956becdc24d60995c64de9153Sunny Goyalimport android.annotation.TargetApi;
28b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.content.res.Resources;
29756cd26592dee6b956becdc24d60995c64de9153Sunny Goyalimport android.os.Build;
30b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.util.Log;
31b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.View;
32b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.AccelerateInterpolator;
33b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.DecelerateInterpolator;
341558893b873cd55b2df779f594f1de3c370d3328Adam Cohen
355f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chungimport com.android.launcher3.allapps.AllAppsContainerView;
36645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Songimport com.android.launcher3.allapps.AllAppsTransitionController;
37645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Songimport com.android.launcher3.config.FeatureFlags;
38091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
395d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyalimport com.android.launcher3.util.UiThreadCircularReveal;
403f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.widget.WidgetsContainerView;
411558893b873cd55b2df779f594f1de3c370d3328Adam Cohen
42b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport java.util.HashMap;
43b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
44b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/**
45b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * TODO: figure out what kind of tests we can write for this
46b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
47b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Things to test when changing the following class.
48b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from workspace
49b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
50b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
51b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from all apps
52b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
53b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
54b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Back from all apps
55b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
56b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
57b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from workspace and quit
58b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
59b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
60b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from all apps and quit
61b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
62b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
63b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Go to a screen that's not the default, then all
64b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *     apps, and launch and app, and go back
65b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
66b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          -with home
67b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, long press power and go back
68b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
69b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
70b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, long press power and go back
71b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
72b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
73b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, power off
74b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, power off
75b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch an app and turn off the screen while in that app
76b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with home key
77b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with back key  TODO: make this not go to workspace
78b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
79b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From workspace
80b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Enter and exit car mode (becuase it causes an extra configuration changed)
81b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
82b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From the center workspace
83b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From another workspace
84b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */
85b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpublic class LauncherStateTransitionAnimation {
86b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
87645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song    /**
88645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song     * animation used for all apps and widget tray when
89645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song     *{@link FeatureFlags#LAUNCHER3_ALL_APPS_PULL_UP} is {@code false}
90645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song     */
91645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song    public static final int CIRCULAR_REVEAL = 0;
92645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song    /**
93645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song     * animation used for all apps and not widget tray when
94645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song     *{@link FeatureFlags#LAUNCHER3_ALL_APPS_PULL_UP} is {@code true}
95645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song     */
96645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song    public static final int PULLUP = 1;
97645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private static final float FINAL_REVEAL_ALPHA_FOR_WIDGETS = 0.3f;
990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
100b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
101b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Private callbacks made during transition setup.
102b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
1030ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private static class PrivateTransitionCallbacks {
1040ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        private final float materialRevealViewFinalAlpha;
1050ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
1060ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks(float revealAlpha) {
1070ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            materialRevealViewFinalAlpha = revealAlpha;
108b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
1090ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
110b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewStartFinalRadius() {
111b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
112b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
113b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView,
11498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                View buttonView) {
115b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return null;
116b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
11776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung        void onTransitionComplete() {}
118b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
119b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
1200ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    public static final String TAG = "LSTAnimation";
121b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
122b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    // Flags to determine how to set the layers on views before the transition animation
123b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_LAYER = 0;
124b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_AND_SET_LAYER = 1;
125b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int SINGLE_FRAME_DELAY = 16;
126b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
127091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk Launcher mLauncher;
128006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    @Thunk AnimatorSet mCurrentAnimation;
129645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song    AllAppsTransitionController mAllAppsController;
130b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
131645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song    public LauncherStateTransitionAnimation(Launcher l, AllAppsTransitionController allAppsController) {
132b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        mLauncher = l;
133645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        mAllAppsController = allAppsController;
134b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
135b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
136b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
137b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the apps view.
13876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *
13976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     * @param startSearchAfterTransition Immediately starts app search after the transition to
14076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *                                   All Apps is completed.
141b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
142006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public void startAnimationToAllApps(final Workspace.State fromWorkspaceState,
143006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final boolean startSearchAfterTransition) {
1445f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final AllAppsContainerView toView = mLauncher.getAppsView();
14598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getAllAppsButton();
1460ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) {
147b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
148b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewStartFinalRadius() {
1492e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
150b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
151b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
152b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
153b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
154b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
155b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
156b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
157b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.INVISIBLE);
158b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
159b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
160b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
161b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
162b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
163b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
16476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            @Override
16576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            void onTransitionComplete() {
166aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song                mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
16776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                if (startSearchAfterTransition) {
16876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    toView.startAppsSearch();
16976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                }
17076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            }
171b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
172645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        int animType = CIRCULAR_REVEAL;
173645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) {
174645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            animType = PULLUP;
175645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        }
176ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating from spring loaded mode back to all apps
177006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState,
178645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                Workspace.State.NORMAL_HIDDEN, buttonView, toView, animated, animType, cb);
179b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
180b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
181b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
182b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the widgets view.
183b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
184006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public void startAnimationToWidgets(final Workspace.State fromWorkspaceState,
185006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated) {
1863f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song        final WidgetsContainerView toView = mLauncher.getWidgetsView();
18798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getWidgetsButton();
188006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState,
189645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, animated, CIRCULAR_REVEAL,
1908fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS){
1918fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                    @Override
1928fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                    void onTransitionComplete() {
193aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song                        mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
1948fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                    }
1958fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                });
196b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
197b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
198b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
1996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the current overlay view.
200b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
201b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public void startAnimationToWorkspace(final Launcher.State fromState,
202006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
2032a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final boolean animated, final Runnable onCompleteRunnable) {
204b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (toWorkspaceState != Workspace.State.NORMAL &&
205b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.SPRING_LOADED &&
206b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.OVERVIEW) {
207b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            Log.e(TAG, "Unexpected call to startAnimationToWorkspace");
208b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
209b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
210b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) {
211645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            int animType = CIRCULAR_REVEAL;
212645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) {
213645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                animType = PULLUP;
214645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            }
2152a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState,
216645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    animated, animType, onCompleteRunnable);
2176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else if (fromState == Launcher.State.WIDGETS ||
2186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                fromState == Launcher.State.WIDGETS_SPRING_LOADED) {
2192a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState,
220dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
2216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else {
2226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            startAnimationToNewWorkspaceState(fromWorkspaceState, toWorkspaceState,
2236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    animated, onCompleteRunnable);
224b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
225b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
226b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
227b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
228b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to a particular overlay view.
229b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
2307066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal    @SuppressLint("NewApi")
2310ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private AnimatorSet startAnimationToOverlay(
2320ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
2330ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View buttonView, final BaseContainerView toView,
234645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final boolean animated, int animType, final PrivateTransitionCallbacks pCb) {
235006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
236b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
2379fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
2385f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
2390ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger);
240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
241b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View fromView = mLauncher.getWorkspace();
242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
24698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
247b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
248b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
249b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
250b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
251645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (!FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) {
252645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            playCommonTransitionAnimations(toWorkspaceState, fromView, toView,
253645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    animated, initialized, animation, revealDuration, layerViews);
254645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        }
2550ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        final View contentView = toView.getContentView();
2560bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
257645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (!animated || !initialized) {
258645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setTranslationX(0.0f);
259645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setTranslationY(0.0f);
260645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setScaleX(1.0f);
261645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setScaleY(1.0f);
262645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setAlpha(1.0f);
263645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setVisibility(View.VISIBLE);
264645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.bringToFront();
265645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
266645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            // Show the content view
267645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            contentView.setVisibility(View.VISIBLE);
268645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
269645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
270645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(fromView, animated, false);
271645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(fromView, animated, false);
272645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(toView, animated, false);
273645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(toView, animated, false);
274645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(toView, animated, false);
275645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            pCb.onTransitionComplete();
276645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
277645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            return null;
278645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        }
279645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (animType == CIRCULAR_REVEAL) {
280b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the reveal view animation
2810ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View revealView = toView.getRevealView();
2820ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
283b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int width = revealView.getMeasuredWidth();
284b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int height = revealView.getMeasuredHeight();
285f7a29e83f06909b378dba39c83a522375682710aSunny Goyal            float revealRadius = (float) Math.hypot(width / 2, height / 2);
286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setVisibility(View.VISIBLE);
287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setAlpha(0f);
288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationY(0f);
289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationX(0f);
290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Calculate the final animation values
292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToAlpha;
293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToXDrift;
294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToYDrift;
295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
2960ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(
2970ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        revealView, buttonView, null);
2980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                revealViewToAlpha = pCb.materialRevealViewFinalAlpha;
29998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToYDrift = buttonViewToPanelDelta[1];
30098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToXDrift = buttonViewToPanelDelta[0];
301b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            } else {
302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToAlpha = 0f;
303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToYDrift = 2 * height / 3;
304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToXDrift = 0;
305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the animators
308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelAlpha =
3095d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f);
310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftY =
3115d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0);
312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftX =
3135d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0);
314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,
315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha, panelDriftY, panelDriftX);
316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setDuration(revealDuration);
317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the animation
320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(revealView, BUILD_AND_SET_LAYER);
321006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(panelAlphaAndDrift);
322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the animation for the content view
324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setAlpha(0f);
326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setTranslationY(revealViewToYDrift);
327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(contentView, BUILD_AND_SET_LAYER);
328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the individual animators
330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift, 0);
332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setDuration(revealDuration);
333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setStartDelay(itemsAlphaStagger);
335006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(pageDrift);
336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
337b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f);
338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setDuration(revealDuration);
339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setStartDelay(itemsAlphaStagger);
341006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(itemsAlpha);
342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                float startRadius = pCb.getMaterialRevealViewStartFinalRadius();
345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener(
34698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                        revealView, buttonView);
3471558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        height / 2, startRadius, revealRadius);
349b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setDuration(revealDuration);
350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (listener != null) {
352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.addListener(listener);
353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
354006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(reveal);
355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
357006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, false);
362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Hide the reveal view
364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealView.setVisibility(View.INVISIBLE);
365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
374006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
37576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Dispatch the prepare transition signal
381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
384006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
387006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
388b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
389006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
390b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
397b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
398b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
399756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
400b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
401b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
402b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
403b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
404b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Focus the new view
405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toView.requestFocus();
406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
407006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
408b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
409b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
410b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
412b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.post(startAnimRunnable);
413006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
414006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
415645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        } else if (animType == PULLUP) {
416645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            animation.addListener(new AnimatorListenerAdapter() {
417645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                  @Override
418645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                  public void onAnimationEnd(Animator animation) {
419645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                      dispatchOnLauncherTransitionEnd(fromView, animated, false);
420645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                      dispatchOnLauncherTransitionEnd(toView, animated, false);
421645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                      cleanupAnimation();
422645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                      pCb.onTransitionComplete();
423645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                  }
424b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
425645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            });
426645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            mAllAppsController.animateToAllApps(animation);
427b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
428b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
429b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
430006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
431645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final AnimatorSet stateAnimation = animation;
432645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final Runnable startAnimRunnable = new Runnable() {
433645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                public void run() {
434645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Check that mCurrentAnimation hasn't changed while
435645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // we waited for a layout/draw pass
436645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    if (mCurrentAnimation != stateAnimation)
437645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                        return;
438645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(fromView, animated, false);
439645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(toView, animated, false);
440645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
441645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    toView.requestFocus();
442645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    stateAnimation.start();
443645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
444645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            };
445645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.post(startAnimRunnable);
446645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            return animation;
447b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
448645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        return null;
449b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
450b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
451b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
452685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham     * Plays animations used by various transitions.
453685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham     */
4547c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal    private void playCommonTransitionAnimations(
4557c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal            Workspace.State toWorkspaceState, View fromView, View toView,
456685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            boolean animated, boolean initialized, AnimatorSet animation, int revealDuration,
457685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            HashMap<View, Integer> layerViews) {
458685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // Create the workspace animation.
459685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // NOTE: this call apparently also sets the state for the workspace if !animated
460685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
461685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham                animated, layerViews);
462685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
463685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // Animate the search bar
4647c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        final SearchDropTargetBar.State toSearchBarState =
4652e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal                toWorkspaceState.searchDropTargetBarState;
4667c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState,
4677c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                animated ? revealDuration : 0, animation);
468685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
469685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        if (animated && initialized) {
470685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            // Play the workspace animation
471685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            if (workspaceAnim != null) {
472685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham                animation.play(workspaceAnim);
473685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            }
474685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            // Dispatch onLauncherTransitionStep() as the animation interpolates.
475685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            animation.play(dispatchOnLauncherTransitionStepAnim(fromView, toView));
476685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        }
477685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham    }
478685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
479685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham    /**
4800bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on
4810bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * {@param fromView} and {@param toView} as the animation interpolates.
4820bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     *
4830bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener.
4840bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     */
4850bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) {
4860bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1);
4870bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
4880bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            @Override
4890bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            public void onAnimationUpdate(ValueAnimator animation) {
4900bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction());
4910bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction());
4920bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            }
4930bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        });
4940bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        return updateAnimator;
4950bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    }
4960bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
4970bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    /**
4986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the apps view.
499b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
500006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState,
501645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final Workspace.State toWorkspaceState, final boolean animated, int type,
5022a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
5035f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        AllAppsContainerView appsView = mLauncher.getAppsView();
5040ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        // No alpha anim from all apps
5050ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) {
506b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
507b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewStartFinalRadius() {
5082e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
509b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
510b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
511b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
512b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
513b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
514b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
515b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
516b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // We set the alpha instead of visibility to ensure that the focus does not
517b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // get taken from the all apps view
518b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
519b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(0f);
520b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
521b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
522b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
523b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
524b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
525b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Show the all apps button, and focus it
526b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(1f);
527b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
528b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
529b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
5308fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            @Override
5318fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            void onTransitionComplete() {
532aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song                mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
5338fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            }
534b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
535ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating to spring loaded mode from all apps
536006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState,
5377c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                mLauncher.getAllAppsButton(), appsView,
538645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                animated, type, onCompleteRunnable, cb);
539b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
540b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
541b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
5426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the widgets view.
543b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
544006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState,
5456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
5462a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
5474cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song        final WidgetsContainerView widgetsView = mLauncher.getWidgetsView();
5480ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb =
5490ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) {
550b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
551b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
55298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    final View revealView, final View widgetsButtonView) {
553b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
554b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
555b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
556b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
557b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
558b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
559b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
5608fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            @Override
5618fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            void onTransitionComplete() {
562aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song                mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
5638fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            }
564b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
5650ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(
5660ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                fromWorkspaceState, toWorkspaceState,
5677c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                mLauncher.getWidgetsButton(), widgetsView,
568645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                animated, CIRCULAR_REVEAL, onCompleteRunnable, cb);
569b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
570b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
571b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
5726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from another workspace state, e.g. normal to overview.
5736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     */
5746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState,
5756d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
5766d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable onCompleteRunnable) {
5776d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final View fromWorkspace = mLauncher.getWorkspace();
5786d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final HashMap<View, Integer> layerViews = new HashMap<>();
5796d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
5806d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final int revealDuration = mLauncher.getResources()
5816d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                .getInteger(R.integer.config_overlayRevealTime);
5826d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5836d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        // Cancel the current animation
5846d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        cancelAnimation();
5856d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
586f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham        boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages;
587f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham
5887c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null,
5897c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                animated, animated, animation, revealDuration, layerViews);
5906d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5916d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        if (animated) {
592f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible);
5936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final AnimatorSet stateAnimation = animation;
5956d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable startAnimRunnable = new Runnable() {
5966d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
5976d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void run() {
5986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Check that mCurrentAnimation hasn't changed while
5996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // we waited for a layout/draw pass
6006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (mCurrentAnimation != stateAnimation)
6016d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        return;
6026d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6036d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
6046d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6056d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Enable all necessary layers
6066d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
6076d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
6086d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
6096d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
6106d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
6116d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.buildLayer();
6126d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
6136d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
6146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    stateAnimation.start();
6156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
6166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            };
6176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            animation.addListener(new AnimatorListenerAdapter() {
6186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @Override
6196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void onAnimationEnd(Animator animation) {
6206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
6216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Run any queued runnables
6236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (onCompleteRunnable != null) {
6246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        onCompleteRunnable.run();
6256d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
6266d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6276d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Disable all necessary layers
6286d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
6296d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
6306d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_NONE, null);
6316d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
6326d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
6336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6346d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // This can hold unnecessary references to views.
6356d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    cleanupAnimation();
6366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
6376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            });
6386d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            fromWorkspace.post(startAnimRunnable);
6396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = animation;
6406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else /* if (!animated) */ {
641f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible);
6426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
6436d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
6446d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            // Run any queued runnables
6466d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            if (onCompleteRunnable != null) {
6476d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                onCompleteRunnable.run();
6486d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            }
6496d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6506d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = null;
6516d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        }
6526d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    }
6536d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6546d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    /**
655b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to the workspace.
656b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
6570ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private AnimatorSet startAnimationToWorkspaceFromOverlay(
6580ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
6590ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View buttonView, final BaseContainerView fromView,
660645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final boolean animated, int animType, final Runnable onCompleteRunnable,
661006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final PrivateTransitionCallbacks pCb) {
662006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
663b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
6649fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
6655f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
6675f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung                res.getInteger(R.integer.config_overlayItemsAlphaStagger);
668b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View toView = mLauncher.getWorkspace();
670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
672b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
673b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
67498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
678b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
679f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham        boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages;
680f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham
681645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (!FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) {
682645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            playCommonTransitionAnimations(toWorkspaceState, fromView, toView,
683645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    animated, initialized, animation, revealDuration, layerViews);
684645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        }
685645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (!animated || !initialized) {
686645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            mAllAppsController.finishPullDown();
687645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            fromView.setVisibility(View.GONE);
688645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
689645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(fromView, animated, true);
690645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(fromView, animated, true);
691645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
692645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(toView, animated, true);
693645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(toView, animated, true);
694645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            pCb.onTransitionComplete();
6950bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
696645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            // Run any queued runnables
697645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            if (onCompleteRunnable != null) {
698645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                onCompleteRunnable.run();
699645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            }
700645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
701645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            return null;
702645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        }
703645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (animType == CIRCULAR_REVEAL) {
7040ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View revealView = fromView.getRevealView();
7050ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View contentView = fromView.getContentView();
7060bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
707b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // hideAppsCustomizeHelper is called in some cases when it is already hidden
708b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // don't perform all these no-op animations. In particularly, this was causing
709b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // the all-apps button to pop in and out.
710b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (fromView.getVisibility() == View.VISIBLE) {
711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int width = revealView.getMeasuredWidth();
712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int height = revealView.getMeasuredHeight();
713f7a29e83f06909b378dba39c83a522375682710aSunny Goyal                float revealRadius = (float) Math.hypot(width / 2, height / 2);
714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setVisibility(View.VISIBLE);
715b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setAlpha(1f);
716b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setTranslationY(0);
717b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(revealView, BUILD_AND_SET_LAYER);
718b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
719b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Calculate the final animation values
720b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToXDrift;
721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToYDrift;
722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
72398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
72498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            buttonView, null);
72598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToYDrift = buttonViewToPanelDelta[1];
72698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToXDrift = buttonViewToPanelDelta[0];
727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                } else {
728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift = 2 * height / 3;
729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToXDrift = 0;
730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // The vertical motion of the apps panel should be delayed by one frame
733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // from the conceal animation in order to give the right feel. We correspondingly
734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // shorten the duration so that the slide and conceal end at the same time.
735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                TimeInterpolator decelerateInterpolator = material ?
736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new LogDecelerateInterpolator(100, 0) :
737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new DecelerateInterpolator(1f);
7381558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY",
739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);
741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setInterpolator(decelerateInterpolator);
743006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftY);
744b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
7451558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX",
746b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToXDrift);
747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);
748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setInterpolator(decelerateInterpolator);
750006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftX);
751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup animation for the reveal panel alpha
753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToAlpha = !material ? 0f :
7540ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        pCb.materialRevealViewFinalAlpha;
755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (revealViewToAlpha != 1f) {
7561558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha",
757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            1f, revealViewToAlpha);
758b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setDuration(material ? revealDuration : 150);
759b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setInterpolator(decelerateInterpolator);
761006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(panelAlpha);
762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
763b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
764b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup the animation for the content view
765b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(contentView, BUILD_AND_SET_LAYER);
766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Create the individual animators
7681558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
769b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setTranslationY(0);
771b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);
772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setInterpolator(decelerateInterpolator);
773b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
774006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(pageDrift);
775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
776b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setAlpha(1f);
7771558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f);
778b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setDuration(100);
779b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setInterpolator(decelerateInterpolator);
780006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(itemsAlpha);
781b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
7823f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                // Invalidate the scrim throughout the animation to ensure the highlight
7833f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                // cutout is correct throughout.
7843f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                ValueAnimator invalidateScrim = ValueAnimator.ofFloat(0f, 1f);
7853f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                invalidateScrim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
7863f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    @Override
7873f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    public void onAnimationUpdate(ValueAnimator animation) {
7883f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                        mLauncher.getDragLayer().invalidateScrim();
7893f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    }
7903f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                });
7913f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                animation.play(invalidateScrim);
7923f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham
793b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
794b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Animate the all apps button
795b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    float finalRadius = pCb.getMaterialRevealViewStartFinalRadius();
796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    AnimatorListenerAdapter listener =
79798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView);
7981558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
7991558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                            height / 2, revealRadius, finalRadius);
800b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
801b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setDuration(revealDuration);
802b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setStartDelay(itemsAlphaStagger);
803b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (listener != null) {
804b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        reveal.addListener(listener);
805b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
806006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(reveal);
807b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
808b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
809b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
810f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
811f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
812a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham
813006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
814b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
815b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
816b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    fromView.setVisibility(View.GONE);
817b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
818b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, true);
819b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
820b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Run any queued runnables
821b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (onCompleteRunnable != null) {
822b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        onCompleteRunnable.run();
823b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
824b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
825b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
826b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
827b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
828b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
829b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
830b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
831b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
832b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Reset page transforms
833b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (contentView != null) {
834b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationX(0);
835b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationY(0);
836b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setAlpha(1);
837b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
838b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
839b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
840006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
84176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
842b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
843b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
844b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
845006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
846b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
847756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
848b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
849006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
850b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
851006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
852b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
853006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
854b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
855b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
856b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
857b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
858b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
859b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
860b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
861b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
862756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
863b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
864b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
865b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
866006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
867b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
868b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
869b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.post(startAnimRunnable);
870006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
871006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
872645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        } else if (animType == PULLUP) {
873645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            animation.addListener(new AnimatorListenerAdapter() {
874645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                @Override
875645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                public void onAnimationEnd(Animator animation) {
876645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
877645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionEnd(toView, animated, false);
878645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    cleanupAnimation();
879645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    pCb.onTransitionComplete();
880645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
881b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
882645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            });
883645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            mAllAppsController.animateToWorkspace(animation);
884006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
885645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            // Dispatch the prepare transition signal
886645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
887645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(toView, animated, false);
888645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
889645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            animation.addListener(new AnimatorListenerAdapter() {
890645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                @Override
891645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                public void onAnimationEnd(Animator animation) {
892645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
893645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionEnd(toView, animated, true);
894645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
895645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Run any queued runnables
896645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    if (onCompleteRunnable != null) {
897645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                        onCompleteRunnable.run();
898645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    }
899645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
900645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // This can hold unnecessary references to views.
901645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    cleanupAnimation();
902645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    pCb.onTransitionComplete();
903645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
904645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            });
905645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
906645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final AnimatorSet stateAnimation = animation;
907645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final Runnable startAnimRunnable = new Runnable() {
908645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                public void run() {
909645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Check that mCurrentAnimation hasn't changed while
910645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // we waited for a layout/draw pass
911645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    if (mCurrentAnimation != stateAnimation)
912645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                        return;
913645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(fromView, animated, false);
914645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(toView, animated, false);
915645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
916645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Focus the new view
917645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    toView.requestFocus();
918645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    stateAnimation.start();
919645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
920645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            };
921645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            fromView.post(startAnimRunnable);
922645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            return animation;
923b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
924645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        return null;
925b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
926b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
927006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    /**
928b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the prepare-transition event to suitable views.
929b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
930f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham    void dispatchOnLauncherTransitionPrepare(View v, boolean animated,
931f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            boolean multiplePagesVisible) {
932b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
933b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated,
934f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham                    multiplePagesVisible);
935b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
936b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
937b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
938b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
939b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the start-transition event to suitable views.
940b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
941b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {
942b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
943b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated,
944b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
945b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
946b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
947b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
948b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 0f);
949b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
950b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
951b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
952b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the step-transition event to suitable views.
953b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
954b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStep(View v, float t) {
955b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
956b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t);
957b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
958b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
959b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
960b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
961b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the end-transition event to suitable views.
962b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
963b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {
964b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
965b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated,
966b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
967b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
968b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
969b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
970b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 1f);
971b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
972b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
973b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
974b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Cancels the current animation.
975b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
976b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void cancelAnimation() {
977006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (mCurrentAnimation != null) {
978006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.setDuration(0);
979006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.cancel();
980006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation = null;
981b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
982b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
983006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
984d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal    @Thunk void cleanupAnimation() {
985006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = null;
986006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    }
9871558893b873cd55b2df779f594f1de3c370d3328Adam Cohen}
988