LauncherStateTransitionAnimation.java revision 8f58e61d02fcb0ca90a2803e76a8792ec2c1f99a
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
177006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState,
178645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                Workspace.State.NORMAL_HIDDEN, buttonView, toView, animated, animType, cb);
179b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
180b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
181b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
182b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the widgets view.
183b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
184006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public void startAnimationToWidgets(final Workspace.State fromWorkspaceState,
185006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated) {
1863f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song        final WidgetsContainerView toView = mLauncher.getWidgetsView();
18798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getWidgetsButton();
188006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState,
189645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, animated, CIRCULAR_REVEAL,
1908fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS){
1918fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                    @Override
1928fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                    void onTransitionComplete() {
193aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song                        mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
1948fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                    }
1958fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song                });
196b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
197b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
198b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
1996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the current overlay view.
200b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
201b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public void startAnimationToWorkspace(final Launcher.State fromState,
202006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
2032a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final boolean animated, final Runnable onCompleteRunnable) {
204b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (toWorkspaceState != Workspace.State.NORMAL &&
205b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.SPRING_LOADED &&
206b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.OVERVIEW) {
207b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            Log.e(TAG, "Unexpected call to startAnimationToWorkspace");
208b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
209b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
210b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) {
211645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            int animType = CIRCULAR_REVEAL;
212645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) {
213645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                animType = PULLUP;
214645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            }
2152a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState,
216645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    animated, animType, onCompleteRunnable);
2176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else if (fromState == Launcher.State.WIDGETS ||
2186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                fromState == Launcher.State.WIDGETS_SPRING_LOADED) {
2192a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState,
220dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
2216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else {
2226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            startAnimationToNewWorkspaceState(fromWorkspaceState, toWorkspaceState,
2236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    animated, onCompleteRunnable);
224b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
225b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
226b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
227b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
228b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to a particular overlay view.
229b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
2307066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal    @SuppressLint("NewApi")
2310ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private AnimatorSet startAnimationToOverlay(
2320ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
2330ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View buttonView, final BaseContainerView toView,
234645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final boolean animated, int animType, final PrivateTransitionCallbacks pCb) {
235006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
236b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
2379fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
2385f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
2390ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger);
240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
241b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View fromView = mLauncher.getWorkspace();
242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
24698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
247b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
248b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
249b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
250b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
2510ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        final View contentView = toView.getContentView();
252a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song        playCommonTransitionAnimations(toWorkspaceState, fromView, toView,
253a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song                animated, initialized, animation, revealDuration, layerViews);
254645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (!animated || !initialized) {
255ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song            if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP &&
256ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song                    toWorkspaceState == Workspace.State.NORMAL_HIDDEN) {
257ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song                mAllAppsController.finishPullUp();
258ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song            }
259645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setTranslationX(0.0f);
260645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setTranslationY(0.0f);
261645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setScaleX(1.0f);
262645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setScaleY(1.0f);
263645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setAlpha(1.0f);
264645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.setVisibility(View.VISIBLE);
265645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.bringToFront();
266645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
267645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            // Show the content view
268645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            contentView.setVisibility(View.VISIBLE);
269645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
270645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
271645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(fromView, animated, false);
272645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(fromView, animated, false);
273645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(toView, animated, false);
274645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(toView, animated, false);
275645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(toView, animated, false);
276645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            pCb.onTransitionComplete();
277645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
278645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            return null;
279645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        }
280645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (animType == CIRCULAR_REVEAL) {
281b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the reveal view animation
2820ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View revealView = toView.getRevealView();
2830ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
284b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int width = revealView.getMeasuredWidth();
285b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int height = revealView.getMeasuredHeight();
286f7a29e83f06909b378dba39c83a522375682710aSunny Goyal            float revealRadius = (float) Math.hypot(width / 2, height / 2);
287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setVisibility(View.VISIBLE);
288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setAlpha(0f);
289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationY(0f);
290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationX(0f);
291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Calculate the final animation values
293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToAlpha;
294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToXDrift;
295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToYDrift;
296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
2970ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(
2980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        revealView, buttonView, null);
2990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                revealViewToAlpha = pCb.materialRevealViewFinalAlpha;
30098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToYDrift = buttonViewToPanelDelta[1];
30198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToXDrift = buttonViewToPanelDelta[0];
302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            } else {
303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToAlpha = 0f;
304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToYDrift = 2 * height / 3;
305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToXDrift = 0;
306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the animators
309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelAlpha =
3105d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f);
311b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftY =
3125d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0);
313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftX =
3145d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0);
315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,
316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha, panelDriftY, panelDriftX);
317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setDuration(revealDuration);
318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the animation
321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(revealView, BUILD_AND_SET_LAYER);
322006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(panelAlphaAndDrift);
323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the animation for the content view
325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setAlpha(0f);
327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setTranslationY(revealViewToYDrift);
328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(contentView, BUILD_AND_SET_LAYER);
329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the individual animators
331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift, 0);
333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setDuration(revealDuration);
334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
335b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setStartDelay(itemsAlphaStagger);
336006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(pageDrift);
337b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f);
339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setDuration(revealDuration);
340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setStartDelay(itemsAlphaStagger);
342006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(itemsAlpha);
343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                float startRadius = pCb.getMaterialRevealViewStartFinalRadius();
346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener(
34798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                        revealView, buttonView);
3488f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2,
3498f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                        startRadius, revealRadius).createRevealAnimator(revealView);
350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setDuration(revealDuration);
351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (listener != null) {
353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.addListener(listener);
354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
355006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(reveal);
356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
358006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, false);
363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Hide the reveal view
365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealView.setVisibility(View.INVISIBLE);
366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
375006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
37676648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Dispatch the prepare transition signal
382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
385006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
387b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
388006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
389b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
390006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
397b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
398b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
399b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
400756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
401b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
402b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
403b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
404b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Focus the new view
406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toView.requestFocus();
407b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
408006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
409b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
410b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
412b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
413b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.post(startAnimRunnable);
414006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
415006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
416645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        } else if (animType == PULLUP) {
417645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            animation.addListener(new AnimatorListenerAdapter() {
418645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                  @Override
419645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                  public void onAnimationEnd(Animator animation) {
420645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                      dispatchOnLauncherTransitionEnd(fromView, animated, false);
421645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                      dispatchOnLauncherTransitionEnd(toView, animated, false);
422645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                      cleanupAnimation();
423645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                      pCb.onTransitionComplete();
424645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                  }
425645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            });
426eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song            mAllAppsController.animateToAllApps(animation, revealDuration, false);
427b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
428b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
429b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
430006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
431645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final AnimatorSet stateAnimation = animation;
432645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final Runnable startAnimRunnable = new Runnable() {
433645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                public void run() {
434645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Check that mCurrentAnimation hasn't changed while
435645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // we waited for a layout/draw pass
436645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    if (mCurrentAnimation != stateAnimation)
437645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                        return;
438645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(fromView, animated, false);
439645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(toView, animated, false);
440645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
441645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    toView.requestFocus();
442645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    stateAnimation.start();
443645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
444645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            };
445645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            toView.post(startAnimRunnable);
446645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            return animation;
447b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
448645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        return null;
449b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
450b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
451b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
452685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham     * Plays animations used by various transitions.
453685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham     */
4547c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal    private void playCommonTransitionAnimations(
4557c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal            Workspace.State toWorkspaceState, View fromView, View toView,
456685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            boolean animated, boolean initialized, AnimatorSet animation, int revealDuration,
457685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            HashMap<View, Integer> layerViews) {
458685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // Create the workspace animation.
459685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // NOTE: this call apparently also sets the state for the workspace if !animated
460685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
461685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham                animated, layerViews);
462685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
463685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        if (animated && initialized) {
464685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            // Play the workspace animation
465685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            if (workspaceAnim != null) {
466685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham                animation.play(workspaceAnim);
467685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            }
468685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            // Dispatch onLauncherTransitionStep() as the animation interpolates.
469685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            animation.play(dispatchOnLauncherTransitionStepAnim(fromView, toView));
470685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        }
471685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham    }
472685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
473685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham    /**
4740bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on
4750bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * {@param fromView} and {@param toView} as the animation interpolates.
4760bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     *
4770bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener.
4780bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     */
4790bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) {
4800bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1);
4810bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
4820bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            @Override
4830bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            public void onAnimationUpdate(ValueAnimator animation) {
4840bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction());
4850bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction());
4860bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            }
4870bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        });
4880bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        return updateAnimator;
4890bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    }
4900bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
4910bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    /**
4926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the apps view.
493b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
494006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState,
495645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final Workspace.State toWorkspaceState, final boolean animated, int type,
4962a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
4975f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        AllAppsContainerView appsView = mLauncher.getAppsView();
4980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        // No alpha anim from all apps
4990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) {
500b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
501b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewStartFinalRadius() {
5022e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
503b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
504b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
505b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
506b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
507b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
508b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
509b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
510b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // We set the alpha instead of visibility to ensure that the focus does not
511b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // get taken from the all apps view
512b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
513b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(0f);
514b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
515b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
516b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
517b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
518b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
519b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Show the all apps button, and focus it
520b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(1f);
521b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
522b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
523b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
5248fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            @Override
5258fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            void onTransitionComplete() {
526aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song                mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
5278fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            }
528b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
529ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating to spring loaded mode from all apps
530006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState,
531bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal                mLauncher.getStartViewForAllAppsRevealAnimation(), appsView,
532645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                animated, type, onCompleteRunnable, cb);
533b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
534b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
535b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
5366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the widgets view.
537b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
538006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState,
5396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
5402a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
5414cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song        final WidgetsContainerView widgetsView = mLauncher.getWidgetsView();
5420ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb =
5430ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) {
544b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
545b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
54698ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    final View revealView, final View widgetsButtonView) {
547b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
548b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
549b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
550b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
551b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
552b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
553b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
5548fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            @Override
5558fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            void onTransitionComplete() {
556aa953654279d7cca29682d85111e398ea1f20390Hyunyoung Song                mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
5578fd5e938d34ee84d076b5c5d2575cc6c46c254ceHyunyoung Song            }
558b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
5590ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(
5600ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                fromWorkspaceState, toWorkspaceState,
5617c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                mLauncher.getWidgetsButton(), widgetsView,
562645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                animated, CIRCULAR_REVEAL, onCompleteRunnable, cb);
563b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
564b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
565b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
5666d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from another workspace state, e.g. normal to overview.
5676d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     */
5686d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState,
5696d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
5706d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable onCompleteRunnable) {
5716d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final View fromWorkspace = mLauncher.getWorkspace();
5726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final HashMap<View, Integer> layerViews = new HashMap<>();
5736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
5746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final int revealDuration = mLauncher.getResources()
5756d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                .getInteger(R.integer.config_overlayRevealTime);
5766d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5776d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        // Cancel the current animation
5786d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        cancelAnimation();
5796d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
580f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham        boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages;
581f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham
5827c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null,
5837c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                animated, animated, animation, revealDuration, layerViews);
5846d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5856d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        if (animated) {
586f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible);
5876d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5886d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final AnimatorSet stateAnimation = animation;
5896d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable startAnimRunnable = new Runnable() {
5906d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
5916d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void run() {
5926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Check that mCurrentAnimation hasn't changed while
5936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // we waited for a layout/draw pass
5946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (mCurrentAnimation != stateAnimation)
5956d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        return;
5966d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5976d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
5986d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Enable all necessary layers
6006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
6016d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
6026d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
6036d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
6046d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
6056d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.buildLayer();
6066d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
6076d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
6086d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    stateAnimation.start();
6096d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
6106d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            };
6116d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            animation.addListener(new AnimatorListenerAdapter() {
6126d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @Override
6136d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void onAnimationEnd(Animator animation) {
6146d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
6156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Run any queued runnables
6176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (onCompleteRunnable != null) {
6186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        onCompleteRunnable.run();
6196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
6206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Disable all necessary layers
6226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
6236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
6246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_NONE, null);
6256d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
6266d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
6276d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6286d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // This can hold unnecessary references to views.
6296d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    cleanupAnimation();
6306d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
6316d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            });
6326d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            fromWorkspace.post(startAnimRunnable);
6336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = animation;
6346d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else /* if (!animated) */ {
635f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible);
6366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
6376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
6386d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            // Run any queued runnables
6406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            if (onCompleteRunnable != null) {
6416d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                onCompleteRunnable.run();
6426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            }
6436d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6446d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = null;
6456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        }
6466d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    }
6476d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
6486d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    /**
649b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to the workspace.
650b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
6510ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private AnimatorSet startAnimationToWorkspaceFromOverlay(
6520ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
6530ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View buttonView, final BaseContainerView fromView,
654645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final boolean animated, int animType, final Runnable onCompleteRunnable,
655006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final PrivateTransitionCallbacks pCb) {
656006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
657b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
6589fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
6595f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
660b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
6615f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung                res.getInteger(R.integer.config_overlayItemsAlphaStagger);
662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
663b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View toView = mLauncher.getWorkspace();
664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
665b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
66898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
672b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
673f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham        boolean multiplePagesVisible = toWorkspaceState.hasMultipleVisiblePages;
674f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham
675a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song        playCommonTransitionAnimations(toWorkspaceState, fromView, toView,
676a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song                animated, initialized, animation, revealDuration, layerViews);
67774b5af35291f620d2f09f313f2e9bd9f817b9d27Hyunyoung Song        if (!animated || !initialized) {
678ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song            if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP &&
679ca7f30f7cfdbea155cbef701485718fa5dd86f46Hyunyoung Song                    fromWorkspaceState == Workspace.State.NORMAL_HIDDEN) {
680a30b51ceb29e179caf7f441763ffeb6bfd336998Peter Schiller                mAllAppsController.finishPullDown(false);
681b11ae50fcb2bb07ee77645fdacdf90f67f58dae4Hyunyoung Song            }
682645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            fromView.setVisibility(View.GONE);
683645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
684645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(fromView, animated, true);
685645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(fromView, animated, true);
686645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
687645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionStart(toView, animated, true);
688645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            dispatchOnLauncherTransitionEnd(toView, animated, true);
689645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            pCb.onTransitionComplete();
6900bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
691645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            // Run any queued runnables
692645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            if (onCompleteRunnable != null) {
693645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                onCompleteRunnable.run();
694645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            }
695645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            return null;
696645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        }
697645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        if (animType == CIRCULAR_REVEAL) {
6980ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View revealView = fromView.getRevealView();
6990ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View contentView = fromView.getContentView();
7000bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // hideAppsCustomizeHelper is called in some cases when it is already hidden
702b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // don't perform all these no-op animations. In particularly, this was causing
703b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // the all-apps button to pop in and out.
704b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (fromView.getVisibility() == View.VISIBLE) {
705b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int width = revealView.getMeasuredWidth();
706b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int height = revealView.getMeasuredHeight();
707f7a29e83f06909b378dba39c83a522375682710aSunny Goyal                float revealRadius = (float) Math.hypot(width / 2, height / 2);
708b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setVisibility(View.VISIBLE);
709b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setAlpha(1f);
710b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setTranslationY(0);
711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(revealView, BUILD_AND_SET_LAYER);
712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
713b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Calculate the final animation values
714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToXDrift;
715b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToYDrift;
716b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
71798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
71898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            buttonView, null);
71998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToYDrift = buttonViewToPanelDelta[1];
72098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToXDrift = buttonViewToPanelDelta[0];
721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                } else {
722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift = 2 * height / 3;
723b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToXDrift = 0;
724b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
725b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
726b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // The vertical motion of the apps panel should be delayed by one frame
727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // from the conceal animation in order to give the right feel. We correspondingly
728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // shorten the duration so that the slide and conceal end at the same time.
729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                TimeInterpolator decelerateInterpolator = material ?
730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new LogDecelerateInterpolator(100, 0) :
731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new DecelerateInterpolator(1f);
7321558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY",
733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);
735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setInterpolator(decelerateInterpolator);
737006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftY);
738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
7391558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX",
740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToXDrift);
741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);
742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setInterpolator(decelerateInterpolator);
744006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftX);
745b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
746b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup animation for the reveal panel alpha
747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToAlpha = !material ? 0f :
7480ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        pCb.materialRevealViewFinalAlpha;
749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (revealViewToAlpha != 1f) {
7501558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha",
751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            1f, revealViewToAlpha);
752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setDuration(material ? revealDuration : 150);
753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setInterpolator(decelerateInterpolator);
755006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(panelAlpha);
756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
758b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup the animation for the content view
759b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(contentView, BUILD_AND_SET_LAYER);
760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Create the individual animators
7621558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
763b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
764b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setTranslationY(0);
765b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);
766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setInterpolator(decelerateInterpolator);
767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
768006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(pageDrift);
769b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setAlpha(1f);
7711558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f);
772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setDuration(100);
773b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setInterpolator(decelerateInterpolator);
774006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(itemsAlpha);
775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
7763f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                // Invalidate the scrim throughout the animation to ensure the highlight
7773f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                // cutout is correct throughout.
7783f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                ValueAnimator invalidateScrim = ValueAnimator.ofFloat(0f, 1f);
7793f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                invalidateScrim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
7803f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    @Override
7813f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    public void onAnimationUpdate(ValueAnimator animation) {
7823f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                        mLauncher.getDragLayer().invalidateScrim();
7833f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                    }
7843f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                });
7853f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham                animation.play(invalidateScrim);
7863f6c0ee7f5c75410dfe9e05f31fdb71b21ceecd3Tony Wickham
787b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
788b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Animate the all apps button
789b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    float finalRadius = pCb.getMaterialRevealViewStartFinalRadius();
790b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    AnimatorListenerAdapter listener =
79198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView);
7928f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                    Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2,
7938f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                            revealRadius, finalRadius).createRevealAnimator(revealView);
794b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
795b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setDuration(revealDuration);
796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setStartDelay(itemsAlphaStagger);
797b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (listener != null) {
798b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        reveal.addListener(listener);
799b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
800006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(reveal);
801b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
802b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
803b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
804f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
805f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
806a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham
807006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
808b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
809b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
810b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    fromView.setVisibility(View.GONE);
811b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
812b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, true);
813b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
814b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Run any queued runnables
815b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (onCompleteRunnable != null) {
816b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        onCompleteRunnable.run();
817b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
818b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
819b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
820b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
821b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
822b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
823b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
824b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
825b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
826b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Reset page transforms
827b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (contentView != null) {
828b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationX(0);
829b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationY(0);
830b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setAlpha(1);
831b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
832b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
833b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
834006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
83576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
836b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
837b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
838b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
839006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
840b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
841756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
842b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
843006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
844b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
845006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
846b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
847006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
848b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
849b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
850b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
851b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
852b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
853b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
854b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
855b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
856756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
857b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
858b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
859b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
860006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
861b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
862b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
863b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.post(startAnimRunnable);
864006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
865006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
866645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        } else if (animType == PULLUP) {
867645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            animation.addListener(new AnimatorListenerAdapter() {
868eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                boolean canceled = false;
869645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                @Override
870eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                public void onAnimationCancel(Animator animation) {
871eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                    canceled = true;
872645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
873b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
874645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                @Override
875645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                public void onAnimationEnd(Animator animation) {
876eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                    if (canceled) return;
877eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
878eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                    dispatchOnLauncherTransitionEnd(toView, animated, false);
879645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Run any queued runnables
880645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    if (onCompleteRunnable != null) {
881645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                        onCompleteRunnable.run();
882645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    }
883645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    cleanupAnimation();
884645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    pCb.onTransitionComplete();
885645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
886eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song
887645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            });
888eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song            mAllAppsController.animateToWorkspace(animation, revealDuration, false);
889eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song
890eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song            // Dispatch the prepare transition signal
8916f02f2ffb4b3cec91891bed9a0c179d2c913d27eSunny Goyal            dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
8926f02f2ffb4b3cec91891bed9a0c179d2c913d27eSunny Goyal            dispatchOnLauncherTransitionPrepare(toView, animated, multiplePagesVisible);
893645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
894645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final AnimatorSet stateAnimation = animation;
895645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            final Runnable startAnimRunnable = new Runnable() {
896645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                public void run() {
897645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Check that mCurrentAnimation hasn't changed while
898645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // we waited for a layout/draw pass
899645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    if (mCurrentAnimation != stateAnimation)
900645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                        return;
901645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(fromView, animated, false);
902645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    dispatchOnLauncherTransitionStart(toView, animated, false);
903645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song
904645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    // Focus the new view
905645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    toView.requestFocus();
906645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                    stateAnimation.start();
907645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song                }
908645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            };
909645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            fromView.post(startAnimRunnable);
910645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song            return animation;
911b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
912645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song        return null;
913b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
914b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
915006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    /**
916b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the prepare-transition event to suitable views.
917b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
918f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham    void dispatchOnLauncherTransitionPrepare(View v, boolean animated,
919f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham            boolean multiplePagesVisible) {
920b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
921b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated,
922f898b970cc9130d629d4bc969222aaa96a8a013aTony Wickham                    multiplePagesVisible);
923b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
924b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
925b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
926b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
927b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the start-transition event to suitable views.
928b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
929b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {
930b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
931b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated,
932b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
933b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
934b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
935b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
936b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 0f);
937b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
938b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
939b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
940b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the step-transition event to suitable views.
941b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
942b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStep(View v, float t) {
943b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
944b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t);
945b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
946b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
947b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
948b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
949b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the end-transition event to suitable views.
950b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
951b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {
952b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
953b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated,
954b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
955b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
956b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
957b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
958b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 1f);
959b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
960b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
961b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
962b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Cancels the current animation.
963b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
964b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void cancelAnimation() {
965006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (mCurrentAnimation != null) {
966006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.setDuration(0);
967006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.cancel();
968006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation = null;
969b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
970b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
971006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
972d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal    @Thunk void cleanupAnimation() {
973006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = null;
974006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    }
9751558893b873cd55b2df779f594f1de3c370d3328Adam Cohen}
976