LauncherStateTransitionAnimation.java revision 191e9d1b297f3a5dd2953f00c9cf9eac364fcf69
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;
388f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhamimport com.android.launcher3.util.CircleRevealOutlineProvider;
39091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
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();
145bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal        final View buttonView = mLauncher.getStartViewForAllAppsRevealAnimation();
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
177191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song        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();
188191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song        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
2109dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song        if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED
2119dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song                || mAllAppsController.isTransitioning()) {
212645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            int animType = CIRCULAR_REVEAL;
213645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) {
214645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                animType = PULLUP;
215645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            }
2162a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState,
217645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    animated, animType, onCompleteRunnable);
2186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else if (fromState == Launcher.State.WIDGETS ||
2196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                fromState == Launcher.State.WIDGETS_SPRING_LOADED) {
2202a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState,
221dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
2226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else {
2236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            startAnimationToNewWorkspaceState(fromWorkspaceState, toWorkspaceState,
2246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    animated, onCompleteRunnable);
225b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
226b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
227b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
228b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
229b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to a particular overlay view.
230b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
2317066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal    @SuppressLint("NewApi")
232191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song    private void startAnimationToOverlay(
2330ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
2340ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View buttonView, final BaseContainerView toView,
235645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final boolean animated, int animType, final PrivateTransitionCallbacks pCb) {
236006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
2389fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
2395f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
240e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song        final int revealDurationSlide = res.getInteger(R.integer.config_overlaySlideRevealTime);
241e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song
2420ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger);
243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View fromView = mLauncher.getWorkspace();
245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
246b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
247b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
248b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
24998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
250b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
251b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
252b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
253b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
2540ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        final View contentView = toView.getContentView();
255a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song        playCommonTransitionAnimations(toWorkspaceState, fromView, toView,
25661d9e78f23efcf43be1945d4233780ac89db99d9Winson                animated, initialized, animation, layerViews);
257645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (!animated || !initialized) {
258ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song            if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP &&
259ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song                    toWorkspaceState == Workspace.State.NORMAL_HIDDEN) {
260ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song                mAllAppsController.finishPullUp();
261ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song            }
262645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setTranslationX(0.0f);
263645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setTranslationY(0.0f);
264645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setScaleX(1.0f);
265645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setScaleY(1.0f);
266645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setAlpha(1.0f);
267645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setVisibility(View.VISIBLE);
268645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.bringToFront();
269645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
270645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            // Show the content view
271645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            contentView.setVisibility(View.VISIBLE);
272645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
273645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
274645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(fromView, animated, false);
275645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(fromView, animated, false);
276645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(toView, animated, false);
277645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(toView, animated, false);
278645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(toView, animated, false);
279645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            pCb.onTransitionComplete();
280191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            return;
281645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        }
282645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (animType == CIRCULAR_REVEAL) {
283b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the reveal view animation
2840ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View revealView = toView.getRevealView();
2850ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int width = revealView.getMeasuredWidth();
287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int height = revealView.getMeasuredHeight();
288f7a29e83f06909b378dba39c83a522375682710aSunny Goyal            float revealRadius = (float) Math.hypot(width / 2, height / 2);
289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setVisibility(View.VISIBLE);
290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setAlpha(0f);
291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationY(0f);
292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationX(0f);
293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Calculate the final animation values
295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToAlpha;
296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToXDrift;
297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToYDrift;
298b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
2990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(
3000ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        revealView, buttonView, null);
3010ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                revealViewToAlpha = pCb.materialRevealViewFinalAlpha;
30298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToYDrift = buttonViewToPanelDelta[1];
30398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToXDrift = buttonViewToPanelDelta[0];
304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            } else {
305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToAlpha = 0f;
306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToYDrift = 2 * height / 3;
307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToXDrift = 0;
308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the animators
311b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelAlpha =
3125d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f);
313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftY =
3145d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0);
315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftX =
3165d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0);
317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,
318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha, panelDriftY, panelDriftX);
319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setDuration(revealDuration);
320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the animation
323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(revealView, BUILD_AND_SET_LAYER);
324006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(panelAlphaAndDrift);
325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the animation for the content view
327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setAlpha(0f);
329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setTranslationY(revealViewToYDrift);
330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(contentView, BUILD_AND_SET_LAYER);
331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the individual animators
333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift, 0);
335b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setDuration(revealDuration);
336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
337b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setStartDelay(itemsAlphaStagger);
338006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(pageDrift);
339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f);
341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setDuration(revealDuration);
342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setStartDelay(itemsAlphaStagger);
344006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(itemsAlpha);
345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
347b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                float startRadius = pCb.getMaterialRevealViewStartFinalRadius();
348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener(
34998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                        revealView, buttonView);
3508f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2,
3518f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                        startRadius, revealRadius).createRevealAnimator(revealView);
352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setDuration(revealDuration);
353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (listener != null) {
355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.addListener(listener);
356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
357006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(reveal);
358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
360006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, false);
365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Hide the reveal view
367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealView.setVisibility(View.INVISIBLE);
368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
377006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
37876648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Dispatch the prepare transition signal
384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
387006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
388b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
389b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
390006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
392006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
397b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
398b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
399b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
400b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
401b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
402756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
403b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
404b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
407b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Focus the new view
408b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toView.requestFocus();
409b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
410006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
412b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
413b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
414b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
415b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.post(startAnimRunnable);
416191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            mCurrentAnimation = animation;
417645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        } else if (animType == PULLUP) {
41861d9e78f23efcf43be1945d4233780ac89db99d9Winson            // We are animating the content view alpha, so ensure we have a layer for it
41961d9e78f23efcf43be1945d4233780ac89db99d9Winson            layerViews.put(contentView, BUILD_AND_SET_LAYER);
42061d9e78f23efcf43be1945d4233780ac89db99d9Winson
421645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            animation.addListener(new AnimatorListenerAdapter() {
422191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                @Override
423191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                public void onAnimationEnd(Animator animation) {
424191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
425191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    dispatchOnLauncherTransitionEnd(toView, animated, false);
426191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song
427191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    // Disable all necessary layers
428191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    for (View v : layerViews.keySet()) {
429191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
430191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                            v.setLayerType(View.LAYER_TYPE_NONE, null);
431191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                        }
432191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    }
433191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song
434191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    cleanupAnimation();
435191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    pCb.onTransitionComplete();
436191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                }
437645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            });
438191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            boolean shouldPost = mAllAppsController.animateToAllApps(animation, revealDurationSlide);
439b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
440b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
441b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
442006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
443645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final AnimatorSet stateAnimation = animation;
444645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final Runnable startAnimRunnable = new Runnable() {
445645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                public void run() {
446645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Check that mCurrentAnimation hasn't changed while
447645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // we waited for a layout/draw pass
448645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    if (mCurrentAnimation != stateAnimation)
449645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                        return;
45061d9e78f23efcf43be1945d4233780ac89db99d9Winson
451645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(fromView, animated, false);
452645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(toView, animated, false);
453645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
45461d9e78f23efcf43be1945d4233780ac89db99d9Winson                    // Enable all necessary layers
45561d9e78f23efcf43be1945d4233780ac89db99d9Winson                    for (View v : layerViews.keySet()) {
45661d9e78f23efcf43be1945d4233780ac89db99d9Winson                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
45761d9e78f23efcf43be1945d4233780ac89db99d9Winson                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
45861d9e78f23efcf43be1945d4233780ac89db99d9Winson                        }
45961d9e78f23efcf43be1945d4233780ac89db99d9Winson                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
46061d9e78f23efcf43be1945d4233780ac89db99d9Winson                            v.buildLayer();
46161d9e78f23efcf43be1945d4233780ac89db99d9Winson                        }
46261d9e78f23efcf43be1945d4233780ac89db99d9Winson                    }
46361d9e78f23efcf43be1945d4233780ac89db99d9Winson
464645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    toView.requestFocus();
465645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    stateAnimation.start();
466645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
467645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            };
468191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            mCurrentAnimation = animation;
469191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            if (shouldPost) {
470191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                toView.post(startAnimRunnable);
471191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            } else {
472191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                startAnimRunnable.run();
473191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            }
474b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
475b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
476b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
477b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
478685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham     * Plays animations used by various transitions.
479685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham     */
4807c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal    private void playCommonTransitionAnimations(
4817c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal            Workspace.State toWorkspaceState, View fromView, View toView,
48261d9e78f23efcf43be1945d4233780ac89db99d9Winson            boolean animated, boolean initialized, AnimatorSet animation,
483685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            HashMap<View, Integer> layerViews) {
484685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // Create the workspace animation.
485685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // NOTE: this call apparently also sets the state for the workspace if !animated
486685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
487685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham                animated, layerViews);
488685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
489685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        if (animated && initialized) {
490685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            // Play the workspace animation
491685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            if (workspaceAnim != null) {
492685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham                animation.play(workspaceAnim);
493685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            }
494685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            // Dispatch onLauncherTransitionStep() as the animation interpolates.
495685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            animation.play(dispatchOnLauncherTransitionStepAnim(fromView, toView));
496685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        }
497685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham    }
498685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
499685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham    /**
5000bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on
5010bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * {@param fromView} and {@param toView} as the animation interpolates.
5020bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     *
5030bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener.
5040bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     */
5050bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) {
5060bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1);
5070bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
5080bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            @Override
5090bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            public void onAnimationUpdate(ValueAnimator animation) {
5100bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction());
5110bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction());
5120bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            }
5130bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        });
5140bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        return updateAnimator;
5150bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    }
5160bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
5170bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    /**
5186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the apps view.
519b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
520006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState,
521645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final Workspace.State toWorkspaceState, final boolean animated, int type,
5222a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
5235f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        AllAppsContainerView appsView = mLauncher.getAppsView();
5240ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        // No alpha anim from all apps
5250ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) {
526b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
527b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewStartFinalRadius() {
5282e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
529b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
530b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
531b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
532b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
533b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
534b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
535b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
536b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // We set the alpha instead of visibility to ensure that the focus does not
537b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // get taken from the all apps view
538b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
539b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(0f);
540b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
541b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
542b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
543b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
544b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
545b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Show the all apps button, and focus it
546b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(1f);
547b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
548b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
549b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
5508fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            @Override
5518fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            void onTransitionComplete() {
552aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song                mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
5538fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            }
554b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
555ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating to spring loaded mode from all apps
556191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song        startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState,
557bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal                mLauncher.getStartViewForAllAppsRevealAnimation(), appsView,
558645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                animated, type, onCompleteRunnable, cb);
559b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
560b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
561b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
5626d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the widgets view.
563b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
564006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState,
5656d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
5662a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
5674cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song        final WidgetsContainerView widgetsView = mLauncher.getWidgetsView();
5680ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb =
5690ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) {
570b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
571b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
57298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    final View revealView, final View widgetsButtonView) {
573b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
574b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
575b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
576b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
577b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
578b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
579b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
5808fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            @Override
5818fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            void onTransitionComplete() {
582aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song                mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
5838fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            }
584b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
585191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song        startAnimationToWorkspaceFromOverlay(
5860ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                fromWorkspaceState, toWorkspaceState,
5877c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                mLauncher.getWidgetsButton(), widgetsView,
588645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                animated, CIRCULAR_REVEAL, onCompleteRunnable, cb);
589b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
590b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
591b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
5926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from another workspace state, e.g. normal to overview.
5936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     */
5946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState,
5956d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
5966d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable onCompleteRunnable) {
5976d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final View fromWorkspace = mLauncher.getWorkspace();
5986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final HashMap<View, Integer> layerViews = new HashMap<>();
5996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
6006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final int revealDuration = mLauncher.getResources()
6016d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                .getInteger(R.integer.config_overlayRevealTime);
6026d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6036d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        // Cancel the current animation
6046d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        cancelAnimation();
6056d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
606f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham        boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages;
607f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham
6087c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null,
60961d9e78f23efcf43be1945d4233780ac89db99d9Winson                animated, animated, animation, layerViews);
6106d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6116d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        if (animated) {
612f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible);
6136d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final AnimatorSet stateAnimation = animation;
6156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable startAnimRunnable = new Runnable() {
6166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
6176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void run() {
6186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Check that mCurrentAnimation hasn't changed while
6196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // we waited for a layout/draw pass
6206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (mCurrentAnimation != stateAnimation)
6216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        return;
6226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
6246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6256d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Enable all necessary layers
6266d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
6276d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
6286d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
6296d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
6306d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
6316d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.buildLayer();
6326d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
6336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
6346d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    stateAnimation.start();
6356d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
6366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            };
6376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            animation.addListener(new AnimatorListenerAdapter() {
6386d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @Override
6396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void onAnimationEnd(Animator animation) {
6406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
6416d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Run any queued runnables
6436d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (onCompleteRunnable != null) {
6446d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        onCompleteRunnable.run();
6456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
6466d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6476d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Disable all necessary layers
6486d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
6496d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
6506d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_NONE, null);
6516d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
6526d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
6536d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6546d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // This can hold unnecessary references to views.
6556d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    cleanupAnimation();
6566d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
6576d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            });
6586d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            fromWorkspace.post(startAnimRunnable);
6596d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = animation;
6606d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else /* if (!animated) */ {
661f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible);
6626d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
6636d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
6646d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6656d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            // Run any queued runnables
6666d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            if (onCompleteRunnable != null) {
6676d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                onCompleteRunnable.run();
6686d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            }
6696d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6706d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = null;
6716d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        }
6726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    }
6736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    /**
675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to the workspace.
676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
677191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song    private void startAnimationToWorkspaceFromOverlay(
6780ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
6790ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View buttonView, final BaseContainerView fromView,
680645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final boolean animated, int animType, final Runnable onCompleteRunnable,
681006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final PrivateTransitionCallbacks pCb) {
682006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
683b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
6849fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
6855f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
686e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song        final int revealDurationSlide = res.getInteger(R.integer.config_overlaySlideRevealTime);
687b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
6885f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung                res.getInteger(R.integer.config_overlayItemsAlphaStagger);
689b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
690b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View toView = mLauncher.getWorkspace();
69161d9e78f23efcf43be1945d4233780ac89db99d9Winson        final View revealView = fromView.getRevealView();
69261d9e78f23efcf43be1945d4233780ac89db99d9Winson        final View contentView = fromView.getContentView();
693b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
694b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
695b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
69798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
698b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
699b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
700b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
702f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham        boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages;
703f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham
704a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song        playCommonTransitionAnimations(toWorkspaceState, fromView, toView,
70561d9e78f23efcf43be1945d4233780ac89db99d9Winson                animated, initialized, animation, layerViews);
70674b5af35291f620d2f09f313f2e9bd9f817b9d27Hyunyoung Song        if (!animated || !initialized) {
707ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song            if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP &&
708ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song                    fromWorkspaceState == Workspace.State.NORMAL_HIDDEN) {
7097ccc4625e38b8107cd1882272aec36967874a5ccHyunyoung Song                mAllAppsController.finishPullDown();
710b11ae50fcb2bb07ee77645fdacdf90f67f58dae4Hyunyoung Song            }
711645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            fromView.setVisibility(View.GONE);
712645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
713645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(fromView, animated, true);
714645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(fromView, animated, true);
715645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
716645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(toView, animated, true);
717645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(toView, animated, true);
718645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            pCb.onTransitionComplete();
7190bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
720645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            // Run any queued runnables
721645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            if (onCompleteRunnable != null) {
722645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                onCompleteRunnable.run();
723645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            }
724191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            return;
725645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        }
726645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (animType == CIRCULAR_REVEAL) {
727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // hideAppsCustomizeHelper is called in some cases when it is already hidden
728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // don't perform all these no-op animations. In particularly, this was causing
729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // the all-apps button to pop in and out.
730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (fromView.getVisibility() == View.VISIBLE) {
731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int width = revealView.getMeasuredWidth();
732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int height = revealView.getMeasuredHeight();
733f7a29e83f06909b378dba39c83a522375682710aSunny Goyal                float revealRadius = (float) Math.hypot(width / 2, height / 2);
734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setVisibility(View.VISIBLE);
735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setAlpha(1f);
736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setTranslationY(0);
737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(revealView, BUILD_AND_SET_LAYER);
738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Calculate the final animation values
740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToXDrift;
741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToYDrift;
742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
74398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
74498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            buttonView, null);
74598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToYDrift = buttonViewToPanelDelta[1];
74698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToXDrift = buttonViewToPanelDelta[0];
747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                } else {
748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift = 2 * height / 3;
749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToXDrift = 0;
750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // The vertical motion of the apps panel should be delayed by one frame
753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // from the conceal animation in order to give the right feel. We correspondingly
754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // shorten the duration so that the slide and conceal end at the same time.
755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                TimeInterpolator decelerateInterpolator = material ?
756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new LogDecelerateInterpolator(100, 0) :
757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new DecelerateInterpolator(1f);
7581558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY",
759b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);
761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setInterpolator(decelerateInterpolator);
763006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftY);
764b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
7651558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX",
766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToXDrift);
767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);
768b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
769b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setInterpolator(decelerateInterpolator);
770006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftX);
771b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup animation for the reveal panel alpha
773b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToAlpha = !material ? 0f :
7740ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        pCb.materialRevealViewFinalAlpha;
775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (revealViewToAlpha != 1f) {
7761558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha",
777b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            1f, revealViewToAlpha);
778b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setDuration(material ? revealDuration : 150);
779b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
780b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setInterpolator(decelerateInterpolator);
781006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(panelAlpha);
782b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
783b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
784b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup the animation for the content view
785b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(contentView, BUILD_AND_SET_LAYER);
786b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
787b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Create the individual animators
7881558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
789b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
790b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setTranslationY(0);
791b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);
792b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setInterpolator(decelerateInterpolator);
793b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
794006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(pageDrift);
795b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setAlpha(1f);
7971558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f);
798b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setDuration(100);
799b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setInterpolator(decelerateInterpolator);
800006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(itemsAlpha);
801b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
8023f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                // Invalidate the scrim throughout the animation to ensure the highlight
8033f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                // cutout is correct throughout.
8043f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                ValueAnimator invalidateScrim = ValueAnimator.ofFloat(0f, 1f);
8053f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                invalidateScrim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
8063f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    @Override
8073f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    public void onAnimationUpdate(ValueAnimator animation) {
8083f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                        mLauncher.getDragLayer().invalidateScrim();
8093f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    }
8103f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                });
8113f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                animation.play(invalidateScrim);
8123f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham
813b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
814b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Animate the all apps button
815b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    float finalRadius = pCb.getMaterialRevealViewStartFinalRadius();
816b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    AnimatorListenerAdapter listener =
81798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView);
8188f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                    Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2,
8198f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                            revealRadius, finalRadius).createRevealAnimator(revealView);
820b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
821b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setDuration(revealDuration);
822b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setStartDelay(itemsAlphaStagger);
823b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (listener != null) {
824b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        reveal.addListener(listener);
825b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
826006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(reveal);
827b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
828b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
829b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
830f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
831f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
832a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham
833006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
834b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
835b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
836b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    fromView.setVisibility(View.GONE);
837b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
838b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, true);
839b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
840b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Run any queued runnables
841b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (onCompleteRunnable != null) {
842b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        onCompleteRunnable.run();
843b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
844b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
845b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
846b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
847b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
848b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
849b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
850b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
851b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
852b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Reset page transforms
853b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (contentView != null) {
854b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationX(0);
855b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationY(0);
856b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setAlpha(1);
857b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
858b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
859b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
860006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
86176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
862b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
863b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
864b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
865006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
866b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
867756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
868b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
869006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
870b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
871006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
872b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
873006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
874b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
875b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
876b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
877b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
878b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
879b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
880b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
881b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
882756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
883b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
884b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
885b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
886006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
887b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
888b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
889191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            mCurrentAnimation = animation;
890b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.post(startAnimRunnable);
891645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        } else if (animType == PULLUP) {
89261d9e78f23efcf43be1945d4233780ac89db99d9Winson            // We are animating the content view alpha, so ensure we have a layer for it
89361d9e78f23efcf43be1945d4233780ac89db99d9Winson            layerViews.put(contentView, BUILD_AND_SET_LAYER);
89461d9e78f23efcf43be1945d4233780ac89db99d9Winson
895645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            animation.addListener(new AnimatorListenerAdapter() {
896eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                boolean canceled = false;
897645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                @Override
898eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                public void onAnimationCancel(Animator animation) {
899eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                    canceled = true;
900645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
901b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
902645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                @Override
903645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                public void onAnimationEnd(Animator animation) {
904eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                    if (canceled) return;
9059dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
9069dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song                    dispatchOnLauncherTransitionEnd(toView, animated, true);
907645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Run any queued runnables
908645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    if (onCompleteRunnable != null) {
909645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                        onCompleteRunnable.run();
910645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    }
91161d9e78f23efcf43be1945d4233780ac89db99d9Winson
91261d9e78f23efcf43be1945d4233780ac89db99d9Winson                    // Disable all necessary layers
91361d9e78f23efcf43be1945d4233780ac89db99d9Winson                    for (View v : layerViews.keySet()) {
91461d9e78f23efcf43be1945d4233780ac89db99d9Winson                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
91561d9e78f23efcf43be1945d4233780ac89db99d9Winson                            v.setLayerType(View.LAYER_TYPE_NONE, null);
91661d9e78f23efcf43be1945d4233780ac89db99d9Winson                        }
91761d9e78f23efcf43be1945d4233780ac89db99d9Winson                    }
91861d9e78f23efcf43be1945d4233780ac89db99d9Winson
919645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    cleanupAnimation();
920645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    pCb.onTransitionComplete();
921645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
922eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song
923645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            });
924191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            boolean shouldPost = mAllAppsController.animateToWorkspace(animation, revealDurationSlide);
925eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song
926eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song            // Dispatch the prepare transition signal
9276f02f2ffb4b3cec91891bed9a0c179d2c913d27eSunny Goyal            dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
9286f02f2ffb4b3cec91891bed9a0c179d2c913d27eSunny Goyal            dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
929645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
930645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final AnimatorSet stateAnimation = animation;
931645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final Runnable startAnimRunnable = new Runnable() {
932645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                public void run() {
933645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Check that mCurrentAnimation hasn't changed while
934645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // we waited for a layout/draw pass
935645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    if (mCurrentAnimation != stateAnimation)
936645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                        return;
93761d9e78f23efcf43be1945d4233780ac89db99d9Winson
938645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(fromView, animated, false);
939645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(toView, animated, false);
940645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
94161d9e78f23efcf43be1945d4233780ac89db99d9Winson                    // Enable all necessary layers
94261d9e78f23efcf43be1945d4233780ac89db99d9Winson                    for (View v : layerViews.keySet()) {
94361d9e78f23efcf43be1945d4233780ac89db99d9Winson                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
94461d9e78f23efcf43be1945d4233780ac89db99d9Winson                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
94561d9e78f23efcf43be1945d4233780ac89db99d9Winson                        }
94661d9e78f23efcf43be1945d4233780ac89db99d9Winson                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
94761d9e78f23efcf43be1945d4233780ac89db99d9Winson                            v.buildLayer();
94861d9e78f23efcf43be1945d4233780ac89db99d9Winson                        }
94961d9e78f23efcf43be1945d4233780ac89db99d9Winson                    }
95061d9e78f23efcf43be1945d4233780ac89db99d9Winson
951645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Focus the new view
952645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    toView.requestFocus();
953645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    stateAnimation.start();
954645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
955645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            };
956191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            mCurrentAnimation = animation;
957191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            if (shouldPost) {
958191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                fromView.post(startAnimRunnable);
959191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            } else {
960191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                startAnimRunnable.run();
961191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            }
962b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
963191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song        return;
964b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
965b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
966006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    /**
967b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the prepare-transition event to suitable views.
968b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
969f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham    void dispatchOnLauncherTransitionPrepare(View v, boolean animated,
970f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            boolean multiplePagesVisible) {
971b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
972b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated,
973f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham                    multiplePagesVisible);
974b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
975b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
976b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
977b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
978b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the start-transition event to suitable views.
979b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
980b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {
981b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
982b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated,
983b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
984b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
985b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
986b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
987b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 0f);
988b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
989b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
990b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
991b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the step-transition event to suitable views.
992b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
993b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStep(View v, float t) {
994b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
995b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t);
996b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
997b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
998b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
999b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
1000b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the end-transition event to suitable views.
1001b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
1002b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {
1003b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
1004b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated,
1005b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
1006b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
1007b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
1008b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
1009b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 1f);
1010b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
1011b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
1012b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
1013b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Cancels the current animation.
1014b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
1015b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void cancelAnimation() {
1016006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (mCurrentAnimation != null) {
1017006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.setDuration(0);
1018006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.cancel();
1019006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation = null;
1020b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
1021b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
1022006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
1023d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal    @Thunk void cleanupAnimation() {
1024006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = null;
1025006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    }
10261558893b873cd55b2df779f594f1de3c370d3328Adam Cohen}
1027