LauncherStateTransitionAnimation.java revision f3e35d93318190f995e6a0fc9d0441ac844b67e4
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
269645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            // Show the content view
270645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            contentView.setVisibility(View.VISIBLE);
271645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
272645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
273645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(fromView, animated, false);
274645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(fromView, animated, false);
275645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(toView, animated, false);
276645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(toView, animated, false);
277645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(toView, animated, false);
278645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            pCb.onTransitionComplete();
279191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            return;
280645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        }
281645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (animType == CIRCULAR_REVEAL) {
282b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the reveal view animation
2830ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View revealView = toView.getRevealView();
2840ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
285b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int width = revealView.getMeasuredWidth();
286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int height = revealView.getMeasuredHeight();
287f7a29e83f06909b378dba39c83a522375682710aSunny Goyal            float revealRadius = (float) Math.hypot(width / 2, height / 2);
288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setVisibility(View.VISIBLE);
289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setAlpha(0f);
290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationY(0f);
291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationX(0f);
292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Calculate the final animation values
294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToAlpha;
295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToXDrift;
296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToYDrift;
297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
2980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(
2990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        revealView, buttonView, null);
3000ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                revealViewToAlpha = pCb.materialRevealViewFinalAlpha;
30198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToYDrift = buttonViewToPanelDelta[1];
30298ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToXDrift = buttonViewToPanelDelta[0];
303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            } else {
304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToAlpha = 0f;
305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToYDrift = 2 * height / 3;
306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToXDrift = 0;
307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the animators
310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelAlpha =
3115d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f);
312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftY =
3135d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0);
314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftX =
3155d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0);
316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,
317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha, panelDriftY, panelDriftX);
318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setDuration(revealDuration);
319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the animation
322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(revealView, BUILD_AND_SET_LAYER);
323006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(panelAlphaAndDrift);
324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the animation for the content view
326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setAlpha(0f);
328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setTranslationY(revealViewToYDrift);
329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(contentView, BUILD_AND_SET_LAYER);
330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the individual animators
332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift, 0);
334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setDuration(revealDuration);
335b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setStartDelay(itemsAlphaStagger);
337006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(pageDrift);
338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f);
340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setDuration(revealDuration);
341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setStartDelay(itemsAlphaStagger);
343006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(itemsAlpha);
344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                float startRadius = pCb.getMaterialRevealViewStartFinalRadius();
347b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener(
34898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                        revealView, buttonView);
3498f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2,
3508f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                        startRadius, revealRadius).createRevealAnimator(revealView);
351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setDuration(revealDuration);
352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (listener != null) {
354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.addListener(listener);
355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
356006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(reveal);
357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
359006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, false);
364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Hide the reveal view
366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealView.setVisibility(View.INVISIBLE);
367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
376006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
37776648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Dispatch the prepare transition signal
383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
386006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
387b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
388b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
389006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
390b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
391006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
397b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
398b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
399b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
400b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
401756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
402b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
403b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
404b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Focus the new view
407b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toView.requestFocus();
408b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
409006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
410b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
412b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
413b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
414b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.post(startAnimRunnable);
415191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            mCurrentAnimation = animation;
416645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        } else if (animType == PULLUP) {
41761d9e78f23efcf43be1945d4233780ac89db99d9Winson            // We are animating the content view alpha, so ensure we have a layer for it
41861d9e78f23efcf43be1945d4233780ac89db99d9Winson            layerViews.put(contentView, BUILD_AND_SET_LAYER);
41961d9e78f23efcf43be1945d4233780ac89db99d9Winson
420645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            animation.addListener(new AnimatorListenerAdapter() {
421191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                @Override
422191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                public void onAnimationEnd(Animator animation) {
423191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
424191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    dispatchOnLauncherTransitionEnd(toView, animated, false);
425191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song
426191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    // Disable all necessary layers
427191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    for (View v : layerViews.keySet()) {
428191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
429191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                            v.setLayerType(View.LAYER_TYPE_NONE, null);
430191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                        }
431191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    }
432191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song
433191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    cleanupAnimation();
434191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                    pCb.onTransitionComplete();
435191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                }
436645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            });
437191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            boolean shouldPost = mAllAppsController.animateToAllApps(animation, revealDurationSlide);
438b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
439b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
440b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
441006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
442645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final AnimatorSet stateAnimation = animation;
443645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final Runnable startAnimRunnable = new Runnable() {
444645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                public void run() {
445645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Check that mCurrentAnimation hasn't changed while
446645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // we waited for a layout/draw pass
447645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    if (mCurrentAnimation != stateAnimation)
448645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                        return;
44961d9e78f23efcf43be1945d4233780ac89db99d9Winson
450645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(fromView, animated, false);
451645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(toView, animated, false);
452645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
45361d9e78f23efcf43be1945d4233780ac89db99d9Winson                    // Enable all necessary layers
45461d9e78f23efcf43be1945d4233780ac89db99d9Winson                    for (View v : layerViews.keySet()) {
45561d9e78f23efcf43be1945d4233780ac89db99d9Winson                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
45661d9e78f23efcf43be1945d4233780ac89db99d9Winson                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
45761d9e78f23efcf43be1945d4233780ac89db99d9Winson                        }
45861d9e78f23efcf43be1945d4233780ac89db99d9Winson                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
45961d9e78f23efcf43be1945d4233780ac89db99d9Winson                            v.buildLayer();
46061d9e78f23efcf43be1945d4233780ac89db99d9Winson                        }
46161d9e78f23efcf43be1945d4233780ac89db99d9Winson                    }
46261d9e78f23efcf43be1945d4233780ac89db99d9Winson
463645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    toView.requestFocus();
464645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    stateAnimation.start();
465645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
466645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            };
467191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            mCurrentAnimation = animation;
468191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            if (shouldPost) {
469191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                toView.post(startAnimRunnable);
470191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            } else {
471191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                startAnimRunnable.run();
472191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            }
473b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
474b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
475b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
476b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
477685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham     * Plays animations used by various transitions.
478685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham     */
4797c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal    private void playCommonTransitionAnimations(
4807c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal            Workspace.State toWorkspaceState, View fromView, View toView,
48161d9e78f23efcf43be1945d4233780ac89db99d9Winson            boolean animated, boolean initialized, AnimatorSet animation,
482685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            HashMap<View, Integer> layerViews) {
483685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // Create the workspace animation.
484685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // NOTE: this call apparently also sets the state for the workspace if !animated
485685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
486685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham                animated, layerViews);
487685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
488685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        if (animated && initialized) {
489685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            // Play the workspace animation
490685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            if (workspaceAnim != null) {
491685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham                animation.play(workspaceAnim);
492685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            }
493685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            // Dispatch onLauncherTransitionStep() as the animation interpolates.
494685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            animation.play(dispatchOnLauncherTransitionStepAnim(fromView, toView));
495685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        }
496685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham    }
497685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
498685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham    /**
4990bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on
5000bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * {@param fromView} and {@param toView} as the animation interpolates.
5010bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     *
5020bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener.
5030bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     */
5040bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) {
5050bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1);
5060bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
5070bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            @Override
5080bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            public void onAnimationUpdate(ValueAnimator animation) {
5090bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction());
5100bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction());
5110bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            }
5120bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        });
5130bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        return updateAnimator;
5140bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    }
5150bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
5160bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    /**
5176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the apps view.
518b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
519006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState,
520645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final Workspace.State toWorkspaceState, final boolean animated, int type,
5212a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
5225f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        AllAppsContainerView appsView = mLauncher.getAppsView();
5230ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        // No alpha anim from all apps
5240ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) {
525b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
526b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewStartFinalRadius() {
5272e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
528b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
529b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
530b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
531b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
532b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
533b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
534b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
535b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // We set the alpha instead of visibility to ensure that the focus does not
536b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // get taken from the all apps view
537b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
538b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(0f);
539b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
540b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
541b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
542b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
543b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
544b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Show the all apps button, and focus it
545b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(1f);
546b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
547b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
548b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
5498fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            @Override
5508fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            void onTransitionComplete() {
551aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song                mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
5528fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            }
553b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
554ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating to spring loaded mode from all apps
555191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song        startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState,
556bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal                mLauncher.getStartViewForAllAppsRevealAnimation(), appsView,
557645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                animated, type, onCompleteRunnable, cb);
558b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
559b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
560b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
5616d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the widgets view.
562b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
563006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState,
5646d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
5652a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
5664cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song        final WidgetsContainerView widgetsView = mLauncher.getWidgetsView();
5670ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb =
5680ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) {
569b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
570b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
57198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    final View revealView, final View widgetsButtonView) {
572b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
573b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
574b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
575b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
576b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
577b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
578b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
5798fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            @Override
5808fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            void onTransitionComplete() {
581aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song                mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
5828fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            }
583b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
584191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song        startAnimationToWorkspaceFromOverlay(
5850ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                fromWorkspaceState, toWorkspaceState,
5867c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                mLauncher.getWidgetsButton(), widgetsView,
587645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                animated, CIRCULAR_REVEAL, onCompleteRunnable, cb);
588b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
589b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
590b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
5916d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from another workspace state, e.g. normal to overview.
5926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     */
5936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState,
5946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
5956d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable onCompleteRunnable) {
5966d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final View fromWorkspace = mLauncher.getWorkspace();
5976d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final HashMap<View, Integer> layerViews = new HashMap<>();
5986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
5996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final int revealDuration = mLauncher.getResources()
6006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                .getInteger(R.integer.config_overlayRevealTime);
6016d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6026d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        // Cancel the current animation
6036d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        cancelAnimation();
6046d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
605f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham        boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages;
606f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham
6077c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null,
60861d9e78f23efcf43be1945d4233780ac89db99d9Winson                animated, animated, animation, layerViews);
6096d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
610f3e35d93318190f995e6a0fc9d0441ac844b67e4Jon Miranda        mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
611f3e35d93318190f995e6a0fc9d0441ac844b67e4Jon Miranda
6126d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        if (animated) {
613f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible);
6146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final AnimatorSet stateAnimation = animation;
6166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable startAnimRunnable = new Runnable() {
6176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
6186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void run() {
6196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Check that mCurrentAnimation hasn't changed while
6206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // we waited for a layout/draw pass
6216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (mCurrentAnimation != stateAnimation)
6226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        return;
6236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
6256d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6266d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Enable all necessary layers
6276d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
6286d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
6296d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
6306d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
6316d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
6326d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.buildLayer();
6336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
6346d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
6356d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    stateAnimation.start();
6366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
6376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            };
6386d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            animation.addListener(new AnimatorListenerAdapter() {
6396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @Override
6406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void onAnimationEnd(Animator animation) {
6416d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
6426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6436d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Run any queued runnables
6446d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (onCompleteRunnable != null) {
6456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        onCompleteRunnable.run();
6466d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
6476d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6486d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Disable all necessary layers
6496d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
6506d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
6516d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_NONE, null);
6526d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
6536d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
6546d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6556d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // This can hold unnecessary references to views.
6566d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    cleanupAnimation();
6576d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
6586d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            });
6596d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            fromWorkspace.post(startAnimRunnable);
6606d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = animation;
6616d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else /* if (!animated) */ {
662f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible);
6636d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
6646d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
6656d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6666d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            // Run any queued runnables
6676d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            if (onCompleteRunnable != null) {
6686d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                onCompleteRunnable.run();
6696d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            }
6706d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6716d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = null;
6726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        }
6736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    }
6746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6756d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    /**
676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to the workspace.
677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
678191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song    private void startAnimationToWorkspaceFromOverlay(
6790ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
6800ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View buttonView, final BaseContainerView fromView,
681645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final boolean animated, int animType, final Runnable onCompleteRunnable,
682006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final PrivateTransitionCallbacks pCb) {
683006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
684b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
6859fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
6865f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
687e3876e8dd0a6b6948c5365af9f88709301bbb536Hyunyoung Song        final int revealDurationSlide = res.getInteger(R.integer.config_overlaySlideRevealTime);
688b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
6895f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung                res.getInteger(R.integer.config_overlayItemsAlphaStagger);
690b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
691b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View toView = mLauncher.getWorkspace();
69261d9e78f23efcf43be1945d4233780ac89db99d9Winson        final View revealView = fromView.getRevealView();
69361d9e78f23efcf43be1945d4233780ac89db99d9Winson        final View contentView = fromView.getContentView();
694b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
695b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
697b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
69898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
699b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
700b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
702b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
703f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham        boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages;
704f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham
705a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song        playCommonTransitionAnimations(toWorkspaceState, fromView, toView,
70661d9e78f23efcf43be1945d4233780ac89db99d9Winson                animated, initialized, animation, layerViews);
70774b5af35291f620d2f09f313f2e9bd9f817b9d27Hyunyoung Song        if (!animated || !initialized) {
708ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song            if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP &&
709ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song                    fromWorkspaceState == Workspace.State.NORMAL_HIDDEN) {
7107ccc4625e38b8107cd1882272aec36967874a5ccHyunyoung Song                mAllAppsController.finishPullDown();
711b11ae50fcb2bb07ee77645fdacdf90f67f58dae4Hyunyoung Song            }
712645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            fromView.setVisibility(View.GONE);
713645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
714645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(fromView, animated, true);
715645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(fromView, animated, true);
716645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
717645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(toView, animated, true);
718645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(toView, animated, true);
719645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            pCb.onTransitionComplete();
7200bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
721645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            // Run any queued runnables
722645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            if (onCompleteRunnable != null) {
723645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                onCompleteRunnable.run();
724645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            }
725191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            return;
726645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        }
727645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (animType == CIRCULAR_REVEAL) {
728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // hideAppsCustomizeHelper is called in some cases when it is already hidden
729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // don't perform all these no-op animations. In particularly, this was causing
730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // the all-apps button to pop in and out.
731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (fromView.getVisibility() == View.VISIBLE) {
732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int width = revealView.getMeasuredWidth();
733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int height = revealView.getMeasuredHeight();
734f7a29e83f06909b378dba39c83a522375682710aSunny Goyal                float revealRadius = (float) Math.hypot(width / 2, height / 2);
735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setVisibility(View.VISIBLE);
736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setAlpha(1f);
737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setTranslationY(0);
738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(revealView, BUILD_AND_SET_LAYER);
739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Calculate the final animation values
741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToXDrift;
742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToYDrift;
743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
74498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
74598ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            buttonView, null);
74698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToYDrift = buttonViewToPanelDelta[1];
74798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToXDrift = buttonViewToPanelDelta[0];
748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                } else {
749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift = 2 * height / 3;
750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToXDrift = 0;
751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // The vertical motion of the apps panel should be delayed by one frame
754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // from the conceal animation in order to give the right feel. We correspondingly
755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // shorten the duration so that the slide and conceal end at the same time.
756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                TimeInterpolator decelerateInterpolator = material ?
757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new LogDecelerateInterpolator(100, 0) :
758b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new DecelerateInterpolator(1f);
7591558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY",
760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);
762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
763b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setInterpolator(decelerateInterpolator);
764006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftY);
765b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
7661558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX",
767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToXDrift);
768b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);
769b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setInterpolator(decelerateInterpolator);
771006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftX);
772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
773b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup animation for the reveal panel alpha
774b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToAlpha = !material ? 0f :
7750ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        pCb.materialRevealViewFinalAlpha;
776b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (revealViewToAlpha != 1f) {
7771558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha",
778b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            1f, revealViewToAlpha);
779b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setDuration(material ? revealDuration : 150);
780b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
781b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setInterpolator(decelerateInterpolator);
782006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(panelAlpha);
783b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
784b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
785b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup the animation for the content view
786b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(contentView, BUILD_AND_SET_LAYER);
787b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
788b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Create the individual animators
7891558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
790b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
791b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setTranslationY(0);
792b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);
793b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setInterpolator(decelerateInterpolator);
794b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
795006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(pageDrift);
796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
797b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setAlpha(1f);
7981558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f);
799b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setDuration(100);
800b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setInterpolator(decelerateInterpolator);
801006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(itemsAlpha);
802b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
8033f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                // Invalidate the scrim throughout the animation to ensure the highlight
8043f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                // cutout is correct throughout.
8053f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                ValueAnimator invalidateScrim = ValueAnimator.ofFloat(0f, 1f);
8063f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                invalidateScrim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
8073f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    @Override
8083f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    public void onAnimationUpdate(ValueAnimator animation) {
8093f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                        mLauncher.getDragLayer().invalidateScrim();
8103f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    }
8113f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                });
8123f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                animation.play(invalidateScrim);
8133f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham
814b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
815b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Animate the all apps button
816b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    float finalRadius = pCb.getMaterialRevealViewStartFinalRadius();
817b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    AnimatorListenerAdapter listener =
81898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView);
8198f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                    Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2,
8208f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                            revealRadius, finalRadius).createRevealAnimator(revealView);
821b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
822b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setDuration(revealDuration);
823b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setStartDelay(itemsAlphaStagger);
824b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (listener != null) {
825b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        reveal.addListener(listener);
826b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
827006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(reveal);
828b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
829b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
830b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
831f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
832f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
833a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham
834006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
835b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
836b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
837b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    fromView.setVisibility(View.GONE);
838b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
839b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, true);
840b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
841b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Run any queued runnables
842b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (onCompleteRunnable != null) {
843b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        onCompleteRunnable.run();
844b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
845b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
846b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
847b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
848b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
849b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
850b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
851b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
852b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
853b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Reset page transforms
854b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (contentView != null) {
855b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationX(0);
856b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationY(0);
857b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setAlpha(1);
858b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
859b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
860b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
861006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
86276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
863b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
864b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
865b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
866006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
867b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
868756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
869b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
870006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
871b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
872006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
873b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
874006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
875b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
876b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
877b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
878b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
879b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
880b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
881b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
882b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
883756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
884b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
885b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
886b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
887006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
888b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
889b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
890191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            mCurrentAnimation = animation;
891b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.post(startAnimRunnable);
892645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        } else if (animType == PULLUP) {
89361d9e78f23efcf43be1945d4233780ac89db99d9Winson            // We are animating the content view alpha, so ensure we have a layer for it
89461d9e78f23efcf43be1945d4233780ac89db99d9Winson            layerViews.put(contentView, BUILD_AND_SET_LAYER);
89561d9e78f23efcf43be1945d4233780ac89db99d9Winson
896645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            animation.addListener(new AnimatorListenerAdapter() {
897eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                boolean canceled = false;
898645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                @Override
899eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                public void onAnimationCancel(Animator animation) {
900eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                    canceled = true;
901645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
902b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
903645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                @Override
904645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                public void onAnimationEnd(Animator animation) {
905eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                    if (canceled) return;
9069dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
9079dcf0a3ef7595f58aedec7773e7bc3b9075fb3caHyunyoung Song                    dispatchOnLauncherTransitionEnd(toView, animated, true);
908645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Run any queued runnables
909645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    if (onCompleteRunnable != null) {
910645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                        onCompleteRunnable.run();
911645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    }
91261d9e78f23efcf43be1945d4233780ac89db99d9Winson
91361d9e78f23efcf43be1945d4233780ac89db99d9Winson                    // Disable all necessary layers
91461d9e78f23efcf43be1945d4233780ac89db99d9Winson                    for (View v : layerViews.keySet()) {
91561d9e78f23efcf43be1945d4233780ac89db99d9Winson                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
91661d9e78f23efcf43be1945d4233780ac89db99d9Winson                            v.setLayerType(View.LAYER_TYPE_NONE, null);
91761d9e78f23efcf43be1945d4233780ac89db99d9Winson                        }
91861d9e78f23efcf43be1945d4233780ac89db99d9Winson                    }
91961d9e78f23efcf43be1945d4233780ac89db99d9Winson
920645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    cleanupAnimation();
921645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    pCb.onTransitionComplete();
922645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
923eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song
924645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            });
925191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            boolean shouldPost = mAllAppsController.animateToWorkspace(animation, revealDurationSlide);
926eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song
927eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song            // Dispatch the prepare transition signal
9286f02f2ffb4b3cec91891bed9a0c179d2c913d27eSunny Goyal            dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
9296f02f2ffb4b3cec91891bed9a0c179d2c913d27eSunny Goyal            dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
930645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
931645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final AnimatorSet stateAnimation = animation;
932645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final Runnable startAnimRunnable = new Runnable() {
933645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                public void run() {
934645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Check that mCurrentAnimation hasn't changed while
935645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // we waited for a layout/draw pass
936645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    if (mCurrentAnimation != stateAnimation)
937645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                        return;
93861d9e78f23efcf43be1945d4233780ac89db99d9Winson
939645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(fromView, animated, false);
940645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(toView, animated, false);
941645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
94261d9e78f23efcf43be1945d4233780ac89db99d9Winson                    // Enable all necessary layers
94361d9e78f23efcf43be1945d4233780ac89db99d9Winson                    for (View v : layerViews.keySet()) {
94461d9e78f23efcf43be1945d4233780ac89db99d9Winson                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
94561d9e78f23efcf43be1945d4233780ac89db99d9Winson                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
94661d9e78f23efcf43be1945d4233780ac89db99d9Winson                        }
94761d9e78f23efcf43be1945d4233780ac89db99d9Winson                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
94861d9e78f23efcf43be1945d4233780ac89db99d9Winson                            v.buildLayer();
94961d9e78f23efcf43be1945d4233780ac89db99d9Winson                        }
95061d9e78f23efcf43be1945d4233780ac89db99d9Winson                    }
95161d9e78f23efcf43be1945d4233780ac89db99d9Winson
952645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Focus the new view
953645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    toView.requestFocus();
954645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    stateAnimation.start();
955645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
956645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            };
957191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            mCurrentAnimation = animation;
958191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            if (shouldPost) {
959191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                fromView.post(startAnimRunnable);
960191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            } else {
961191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song                startAnimRunnable.run();
962191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song            }
963b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
964191e9d1b297f3a5dd2953f00c9cf9eac364fcf69Hyunyoung Song        return;
965b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
966b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
967006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    /**
968b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the prepare-transition event to suitable views.
969b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
970f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham    void dispatchOnLauncherTransitionPrepare(View v, boolean animated,
971f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            boolean multiplePagesVisible) {
972b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
973b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated,
974f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham                    multiplePagesVisible);
975b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
976b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
977b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
978b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
979b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the start-transition event to suitable views.
980b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
981b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {
982b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
983b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated,
984b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
985b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
986b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
987b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
988b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 0f);
989b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
990b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
991b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
992b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the step-transition event to suitable views.
993b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
994b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStep(View v, float t) {
995b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
996b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t);
997b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
998b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
999b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
1000b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
1001b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the end-transition event to suitable views.
1002b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
1003b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {
1004b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
1005b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated,
1006b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
1007b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
1008b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
1009b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
1010b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 1f);
1011b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
1012b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
1013b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
1014b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Cancels the current animation.
1015b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
1016b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void cancelAnimation() {
1017006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (mCurrentAnimation != null) {
1018006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.setDuration(0);
1019006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.cancel();
1020006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation = null;
1021b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
1022b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
1023006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
1024d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal    @Thunk void cleanupAnimation() {
1025006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = null;
1026006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    }
10271558893b873cd55b2df779f594f1de3c370d3328Adam Cohen}
1028