LauncherStateTransitionAnimation.java revision 7c50b31f57e3e3ec1f433d243afe05554dcaf977
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;
36091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
375d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyalimport com.android.launcher3.util.UiThreadCircularReveal;
383f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.widget.WidgetsContainerView;
391558893b873cd55b2df779f594f1de3c370d3328Adam Cohen
40b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport java.util.HashMap;
41b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
42b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/**
43b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * TODO: figure out what kind of tests we can write for this
44b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
45b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Things to test when changing the following class.
46b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from workspace
47b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
48b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
49b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from all apps
50b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
51b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
52b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Back from all apps
53b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
54b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
55b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from workspace and quit
56b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
57b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
58b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from all apps and quit
59b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
60b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
61b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Go to a screen that's not the default, then all
62b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *     apps, and launch and app, and go back
63b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
64b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          -with home
65b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, long press power and go back
66b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
67b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
68b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, long press power and go back
69b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
70b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
71b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, power off
72b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, power off
73b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch an app and turn off the screen while in that app
74b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with home key
75b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with back key  TODO: make this not go to workspace
76b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
77b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From workspace
78b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Enter and exit car mode (becuase it causes an extra configuration changed)
79b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
80b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From the center workspace
81b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From another workspace
82b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */
83b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpublic class LauncherStateTransitionAnimation {
84b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
850ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private static final float FINAL_REVEAL_ALPHA_FOR_WIDGETS = 0.3f;
860ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
87b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
88b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Private callbacks made during transition setup.
89b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
900ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private static class PrivateTransitionCallbacks {
910ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        private final float materialRevealViewFinalAlpha;
920ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
930ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks(float revealAlpha) {
940ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            materialRevealViewFinalAlpha = revealAlpha;
95b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
960ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
97b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewStartFinalRadius() {
98b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
99b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
100b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView,
10198ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                View buttonView) {
102b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return null;
103b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
10476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung        void onTransitionComplete() {}
105b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
106b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
1070ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    public static final String TAG = "LSTAnimation";
108b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
109b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    // Flags to determine how to set the layers on views before the transition animation
110b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_LAYER = 0;
111b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_AND_SET_LAYER = 1;
112b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int SINGLE_FRAME_DELAY = 16;
113b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
114091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk Launcher mLauncher;
115006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    @Thunk AnimatorSet mCurrentAnimation;
116b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
117006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public LauncherStateTransitionAnimation(Launcher l) {
118b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        mLauncher = l;
119b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
120b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
121b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
122b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the apps view.
12376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *
12476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     * @param startSearchAfterTransition Immediately starts app search after the transition to
12576648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung     *                                   All Apps is completed.
126b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
127006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public void startAnimationToAllApps(final Workspace.State fromWorkspaceState,
128006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final boolean startSearchAfterTransition) {
1295f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final AllAppsContainerView toView = mLauncher.getAppsView();
13098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getAllAppsButton();
1310ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) {
132b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
133b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewStartFinalRadius() {
1342e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
135b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
136b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
137b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
138b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
139b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
140b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
141b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
142b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.INVISIBLE);
143b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
144b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
145b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
146b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
147b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
148b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
14976648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            @Override
15076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            void onTransitionComplete() {
15176648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                if (startSearchAfterTransition) {
15276648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    toView.startAppsSearch();
15376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                }
15476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            }
155b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
156ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating from spring loaded mode back to all apps
157006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState,
1580ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                Workspace.State.NORMAL_HIDDEN, buttonView, toView, animated, cb);
159b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
160b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
161b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
162b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the widgets view.
163b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
164006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    public void startAnimationToWidgets(final Workspace.State fromWorkspaceState,
165006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated) {
1663f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song        final WidgetsContainerView toView = mLauncher.getWidgetsView();
16798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        final View buttonView = mLauncher.getWidgetsButton();
168006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState,
1690ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, animated,
1700ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS));
171b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
172b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
173b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
1746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the current overlay view.
175b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
176b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public void startAnimationToWorkspace(final Launcher.State fromState,
177006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
1782a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final boolean animated, final Runnable onCompleteRunnable) {
179b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (toWorkspaceState != Workspace.State.NORMAL &&
180b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.SPRING_LOADED &&
181b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.OVERVIEW) {
182b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            Log.e(TAG, "Unexpected call to startAnimationToWorkspace");
183b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
184b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
185b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) {
1862a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            startAnimationToWorkspaceFromAllApps(fromWorkspaceState, toWorkspaceState,
187dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
1886d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else if (fromState == Launcher.State.WIDGETS ||
1896d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                fromState == Launcher.State.WIDGETS_SPRING_LOADED) {
1902a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            startAnimationToWorkspaceFromWidgets(fromWorkspaceState, toWorkspaceState,
191dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    animated, onCompleteRunnable);
1926d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else {
1936d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            startAnimationToNewWorkspaceState(fromWorkspaceState, toWorkspaceState,
1946d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    animated, onCompleteRunnable);
195b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
196b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
197b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
198b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
199b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to a particular overlay view.
200b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
2017066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal    @SuppressLint("NewApi")
2020ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private AnimatorSet startAnimationToOverlay(
2030ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
2040ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View buttonView, final BaseContainerView toView,
205006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final boolean animated, final PrivateTransitionCallbacks pCb) {
206006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
207b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
2089fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
2095f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
2100ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        final int itemsAlphaStagger = res.getInteger(R.integer.config_overlayItemsAlphaStagger);
211b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
212b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View fromView = mLauncher.getWorkspace();
213b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
214b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
215b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
216b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
21798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
218b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
219b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
220b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
221b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
2227c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        playCommonTransitionAnimations(toWorkspaceState, fromView, toView,
2237c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                animated, initialized, animation, revealDuration, layerViews);
2240bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
2250ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        final View contentView = toView.getContentView();
2260bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
227006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (animated && initialized) {
228b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the reveal view animation
2290ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View revealView = toView.getRevealView();
2300ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal
231b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int width = revealView.getMeasuredWidth();
232b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int height = revealView.getMeasuredHeight();
233f7a29e83f06909b378dba39c83a522375682710aSunny Goyal            float revealRadius = (float) Math.hypot(width / 2, height / 2);
234b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setVisibility(View.VISIBLE);
235b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setAlpha(0f);
236b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationY(0f);
237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationX(0f);
238b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
239b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Calculate the final animation values
240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToAlpha;
241b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToXDrift;
242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToYDrift;
243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
2440ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(
2450ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        revealView, buttonView, null);
2460ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                revealViewToAlpha = pCb.materialRevealViewFinalAlpha;
24798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToYDrift = buttonViewToPanelDelta[1];
24898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                revealViewToXDrift = buttonViewToPanelDelta[0];
249b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            } else {
250b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToAlpha = 0f;
251b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToYDrift = 2 * height / 3;
252b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToXDrift = 0;
253b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
254b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
255b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the animators
256b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelAlpha =
2575d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.ALPHA, revealViewToAlpha, 1f);
258b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftY =
2595d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, revealViewToYDrift, 0);
260b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftX =
2615d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                    PropertyValuesHolder.ofFloat(View.TRANSLATION_X, revealViewToXDrift, 0);
262b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,
263b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha, panelDriftY, panelDriftX);
264b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setDuration(revealDuration);
265b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
266b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
267b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the animation
268b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(revealView, BUILD_AND_SET_LAYER);
269006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(panelAlphaAndDrift);
270b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
271b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the animation for the content view
272b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
273b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setAlpha(0f);
274b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setTranslationY(revealViewToYDrift);
275b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(contentView, BUILD_AND_SET_LAYER);
276b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
277b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the individual animators
278b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
279b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift, 0);
280b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setDuration(revealDuration);
281b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
282b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setStartDelay(itemsAlphaStagger);
283006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(pageDrift);
284b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
285b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f);
286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setDuration(revealDuration);
287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setStartDelay(itemsAlphaStagger);
289006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.play(itemsAlpha);
290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                float startRadius = pCb.getMaterialRevealViewStartFinalRadius();
293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener(
29498ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                        revealView, buttonView);
2951558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        height / 2, startRadius, revealRadius);
297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setDuration(revealDuration);
298b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
299b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (listener != null) {
300b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.addListener(listener);
301b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
302006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(reveal);
303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
305006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, false);
310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
311b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Hide the reveal view
312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealView.setVisibility(View.INVISIBLE);
313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
322006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
32376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Dispatch the prepare transition signal
329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
332006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
335006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
337006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
347756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
349b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Focus the new view
353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toView.requestFocus();
354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
355006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.post(startAnimRunnable);
361006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
362006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationX(0.0f);
365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationY(0.0f);
366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleX(1.0f);
367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleY(1.0f);
368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Show the content view
372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, false);
376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, false);
377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, false);
379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, false);
38076648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            pCb.onTransitionComplete();
381006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
382006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return null;
383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
387685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham     * Plays animations used by various transitions.
388685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham     */
3897c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal    private void playCommonTransitionAnimations(
3907c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal            Workspace.State toWorkspaceState, View fromView, View toView,
391685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            boolean animated, boolean initialized, AnimatorSet animation, int revealDuration,
392685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            HashMap<View, Integer> layerViews) {
393685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // Create the workspace animation.
394685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // NOTE: this call apparently also sets the state for the workspace if !animated
395685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
396685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham                animated, layerViews);
397685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
398685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        // Animate the search bar
3997c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        final SearchDropTargetBar.State toSearchBarState =
4007c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                toWorkspaceState.getSearchDropTargetBarState();
4017c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        mLauncher.getSearchDropTargetBar().animateToState(toSearchBarState,
4027c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                animated ? revealDuration : 0, animation);
403685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
404685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        if (animated && initialized) {
405685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            // Play the workspace animation
406685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            if (workspaceAnim != null) {
407685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham                animation.play(workspaceAnim);
408685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            }
409685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            // Dispatch onLauncherTransitionStep() as the animation interpolates.
410685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham            animation.play(dispatchOnLauncherTransitionStepAnim(fromView, toView));
411685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham        }
412685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham    }
413685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham
414685726b504d8bff913d0a51860bbda9142f7aeb5Tony Wickham    /**
4150bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * Returns an Animator that calls {@link #dispatchOnLauncherTransitionStep(View, float)} on
4160bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * {@param fromView} and {@param toView} as the animation interpolates.
4170bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     *
4180bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     * This is a bit hacky: we create a dummy ValueAnimator just for the AnimatorUpdateListener.
4190bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham     */
4200bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    private Animator dispatchOnLauncherTransitionStepAnim(final View fromView, final View toView) {
4210bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        ValueAnimator updateAnimator = ValueAnimator.ofFloat(0, 1);
4220bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        updateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
4230bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            @Override
4240bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            public void onAnimationUpdate(ValueAnimator animation) {
4250bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(fromView, animation.getAnimatedFraction());
4260bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham                dispatchOnLauncherTransitionStep(toView, animation.getAnimatedFraction());
4270bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham            }
4280bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        });
4290bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham        return updateAnimator;
4300bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    }
4310bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
4320bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham    /**
4336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the apps view.
434b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
435006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromAllApps(final Workspace.State fromWorkspaceState,
4362a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Workspace.State toWorkspaceState, final boolean animated,
4372a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
4385f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        AllAppsContainerView appsView = mLauncher.getAppsView();
4390ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        // No alpha anim from all apps
4400ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks(1f) {
441b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
442b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewStartFinalRadius() {
4432e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen                int allAppsButtonSize = mLauncher.getDeviceProfile().allAppsButtonVisualSize;
444b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
445b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
446b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
447b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
448b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
449b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
450b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
451b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // We set the alpha instead of visibility to ensure that the focus does not
452b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // get taken from the all apps view
453b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
454b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(0f);
455b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
456b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
457b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
458b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
459b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
460b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Show the all apps button, and focus it
461b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(1f);
462b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
463b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
464b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
465b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
466ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        // Only animate the search bar if animating to spring loaded mode from all apps
467006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState,
4687c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                mLauncher.getAllAppsButton(), appsView,
4690ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                animated, onCompleteRunnable, cb);
470b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
471b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
472b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
4736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from the widgets view.
474b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
475006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    private void startAnimationToWorkspaceFromWidgets(final Workspace.State fromWorkspaceState,
4766d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
4772a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson            final Runnable onCompleteRunnable) {
4784cea4c830283e017fc36197cfe9d7ce713aec49dHyunyoung Song        final WidgetsContainerView widgetsView = mLauncher.getWidgetsView();
4790ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        PrivateTransitionCallbacks cb =
4800ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS) {
481b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
482b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
48398ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    final View revealView, final View widgetsButtonView) {
484b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
485b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
486b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
487b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
488b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
489b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
490b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
491b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
4920ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal        mCurrentAnimation = startAnimationToWorkspaceFromOverlay(
4930ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                fromWorkspaceState, toWorkspaceState,
4947c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                mLauncher.getWidgetsButton(), widgetsView,
4950ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                animated, onCompleteRunnable, cb);
496b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
497b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
498b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
4996d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     * Starts an animation to the workspace from another workspace state, e.g. normal to overview.
5006d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham     */
5016d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    private void startAnimationToNewWorkspaceState(final Workspace.State fromWorkspaceState,
5026d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Workspace.State toWorkspaceState, final boolean animated,
5036d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable onCompleteRunnable) {
5046d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final View fromWorkspace = mLauncher.getWorkspace();
5056d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final HashMap<View, Integer> layerViews = new HashMap<>();
5066d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
5076d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        final int revealDuration = mLauncher.getResources()
5086d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                .getInteger(R.integer.config_overlayRevealTime);
5096d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5106d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        // Cancel the current animation
5116d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        cancelAnimation();
5126d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5137c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null,
5147c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                animated, animated, animation, revealDuration, layerViews);
5156d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5166d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        if (animated) {
5176d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, true);
5186d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5196d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final AnimatorSet stateAnimation = animation;
5206d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            final Runnable startAnimRunnable = new Runnable() {
5216d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
5226d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void run() {
5236d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Check that mCurrentAnimation hasn't changed while
5246d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // we waited for a layout/draw pass
5256d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (mCurrentAnimation != stateAnimation)
5266d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        return;
5276d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5286d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
5296d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5306d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Enable all necessary layers
5316d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
5326d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
5336d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
5346d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
5356d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
5366d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.buildLayer();
5376d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
5386d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
5396d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    stateAnimation.start();
5406d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
5416d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            };
5426d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            animation.addListener(new AnimatorListenerAdapter() {
5436d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                @Override
5446d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                public void onAnimationEnd(Animator animation) {
5456d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
5466d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5476d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Run any queued runnables
5486d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    if (onCompleteRunnable != null) {
5496d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        onCompleteRunnable.run();
5506d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
5516d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5526d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // Disable all necessary layers
5536d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    for (View v : layerViews.keySet()) {
5546d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
5556d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                            v.setLayerType(View.LAYER_TYPE_NONE, null);
5566d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                        }
5576d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    }
5586d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5596d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    // This can hold unnecessary references to views.
5606d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                    cleanupAnimation();
5616d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                }
5626d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            });
5636d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            fromWorkspace.post(startAnimRunnable);
5646d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = animation;
5656d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else /* if (!animated) */ {
5666d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, true);
5676d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);
5686d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            dispatchOnLauncherTransitionEnd(fromWorkspace, animated, true);
5696d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5706d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            // Run any queued runnables
5716d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            if (onCompleteRunnable != null) {
5726d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham                onCompleteRunnable.run();
5736d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            }
5746d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5756d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham            mCurrentAnimation = null;
5766d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        }
5776d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    }
5786d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham
5796d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham    /**
580b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to the workspace.
581b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
5820ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal    private AnimatorSet startAnimationToWorkspaceFromOverlay(
5830ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState,
5840ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View buttonView, final BaseContainerView fromView,
5850ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final boolean animated, final Runnable onCompleteRunnable,
586006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final PrivateTransitionCallbacks pCb) {
587006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
588b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
5899fc953b94dbc6b99e6de08c9dcc80a0cb8e3e319Sunny Goyal        final boolean material = Utilities.ATLEAST_LOLLIPOP;
5905f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        final int revealDuration = res.getInteger(R.integer.config_overlayRevealTime);
591b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
5925f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung                res.getInteger(R.integer.config_overlayItemsAlphaStagger);
593b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
594b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View toView = mLauncher.getWorkspace();
595b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
596b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
597b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
598b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
59998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song        boolean initialized = buttonView != null;
600b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
601b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
602b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
603b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
6047c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal        playCommonTransitionAnimations(toWorkspaceState, fromView, toView,
6057c50b31f57e3e3ec1f433d243afe05554dcaf977Sunny Goyal                animated, initialized, animation, revealDuration, layerViews);
6060bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
607006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (animated && initialized) {
6080ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View revealView = fromView.getRevealView();
6090ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal            final View contentView = fromView.getContentView();
6100bb211a9d5cd4eabcbf46385bbfb9895e5cd7325Tony Wickham
611b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // hideAppsCustomizeHelper is called in some cases when it is already hidden
612b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // don't perform all these no-op animations. In particularly, this was causing
613b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // the all-apps button to pop in and out.
614b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (fromView.getVisibility() == View.VISIBLE) {
615b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int width = revealView.getMeasuredWidth();
616b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int height = revealView.getMeasuredHeight();
617f7a29e83f06909b378dba39c83a522375682710aSunny Goyal                float revealRadius = (float) Math.hypot(width / 2, height / 2);
618b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setVisibility(View.VISIBLE);
619b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setAlpha(1f);
620b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setTranslationY(0);
621b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(revealView, BUILD_AND_SET_LAYER);
622b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
623b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Calculate the final animation values
624b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToXDrift;
625b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToYDrift;
626b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
62798ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    int[] buttonViewToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
62898ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            buttonView, null);
62998ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToYDrift = buttonViewToPanelDelta[1];
63098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                    revealViewToXDrift = buttonViewToPanelDelta[0];
631b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                } else {
632b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift = 2 * height / 3;
633b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToXDrift = 0;
634b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
635b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
636b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // The vertical motion of the apps panel should be delayed by one frame
637b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // from the conceal animation in order to give the right feel. We correspondingly
638b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // shorten the duration so that the slide and conceal end at the same time.
639b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                TimeInterpolator decelerateInterpolator = material ?
640b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new LogDecelerateInterpolator(100, 0) :
641b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new DecelerateInterpolator(1f);
6421558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftY = ObjectAnimator.ofFloat(revealView, "translationY",
643b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
644b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);
645b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
646b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setInterpolator(decelerateInterpolator);
647006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftY);
648b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
6491558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator panelDriftX = ObjectAnimator.ofFloat(revealView, "translationX",
650b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToXDrift);
651b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);
652b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
653b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setInterpolator(decelerateInterpolator);
654006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(panelDriftX);
655b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
656b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup animation for the reveal panel alpha
657b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToAlpha = !material ? 0f :
6580ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal                        pCb.materialRevealViewFinalAlpha;
659b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (revealViewToAlpha != 1f) {
6601558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    ObjectAnimator panelAlpha = ObjectAnimator.ofFloat(revealView, "alpha",
661b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            1f, revealViewToAlpha);
662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setDuration(material ? revealDuration : 150);
663b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setInterpolator(decelerateInterpolator);
665006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(panelAlpha);
666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
668b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup the animation for the content view
669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(contentView, BUILD_AND_SET_LAYER);
670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Create the individual animators
6721558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
673b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
674b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setTranslationY(0);
675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);
676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setInterpolator(decelerateInterpolator);
677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
678006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(pageDrift);
679b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
680b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setAlpha(1f);
6811558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 1f, 0f);
682b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setDuration(100);
683b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setInterpolator(decelerateInterpolator);
684006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                animation.play(itemsAlpha);
685b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
686b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
687b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Animate the all apps button
688b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    float finalRadius = pCb.getMaterialRevealViewStartFinalRadius();
689b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    AnimatorListenerAdapter listener =
69098ff38aa48b4c9d3e33c128fae2d5c851e49a3ebHyunyoung Song                            pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView);
6911558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                    Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2,
6921558893b873cd55b2df779f594f1de3c370d3328Adam Cohen                            height / 2, revealRadius, finalRadius);
693b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
694b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setDuration(revealDuration);
695b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setStartDelay(itemsAlphaStagger);
696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (listener != null) {
697b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        reveal.addListener(listener);
698b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
699006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    animation.play(reveal);
700b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
702b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
703a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham            dispatchOnLauncherTransitionPrepare(fromView, animated, true);
704a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham            dispatchOnLauncherTransitionPrepare(toView, animated, true);
705a5209e33fcce5cd429086971ef1b57bcfc106c23Tony Wickham
706006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            animation.addListener(new AnimatorListenerAdapter() {
707b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
708b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
709b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    fromView.setVisibility(View.GONE);
710b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, true);
712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
713b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Run any queued runnables
714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (onCompleteRunnable != null) {
715b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        onCompleteRunnable.run();
716b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
717b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
718b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
719b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
720b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
723b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
724b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
725b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Reset page transforms
726b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (contentView != null) {
727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationX(0);
728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationY(0);
729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setAlpha(1);
730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
733006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    cleanupAnimation();
73476648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung                    pCb.onTransitionComplete();
735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
738006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            final AnimatorSet stateAnimation = animation;
739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
740756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
742006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    // Check that mCurrentAnimation hasn't changed while
743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
744006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    if (mCurrentAnimation != stateAnimation)
745b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
746006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
755756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
758b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
759006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung                    stateAnimation.start();
760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.post(startAnimRunnable);
763006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
764006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return animation;
7656d1bbe350f0e37e99ec31b4ab480cc83f0b0c5dcTony Wickham        } else /* if (!(animated && initialized)) */ {
766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.setVisibility(View.GONE);
767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, true);
768b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, true);
769b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, true);
770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, true);
771b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, true);
772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, true);
77376648c58d5fe8e5c0695f865243d3f421c53a84dWinson Chung            pCb.onTransitionComplete();
774b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Run any queued runnables
776b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (onCompleteRunnable != null) {
777b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                onCompleteRunnable.run();
778b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
779006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
780006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            return null;
781b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
782b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
783b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
784006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    /**
785b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the prepare-transition event to suitable views.
786b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
787b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {
788b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
789b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated,
790b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
791b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
792b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
793b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
794b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
795b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the start-transition event to suitable views.
796b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
797b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {
798b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
799b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated,
800b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
801b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
802b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
803b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
804b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 0f);
805b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
806b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
807b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
808b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the step-transition event to suitable views.
809b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
810b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStep(View v, float t) {
811b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
812b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t);
813b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
814b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
815b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
816b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
817b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the end-transition event to suitable views.
818b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
819b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {
820b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
821b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated,
822b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
823b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
824b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
825b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
826b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 1f);
827b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
828b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
829b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
830b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Cancels the current animation.
831b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
832b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void cancelAnimation() {
833006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        if (mCurrentAnimation != null) {
834006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.setDuration(0);
835006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation.cancel();
836006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung            mCurrentAnimation = null;
837b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
838b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
839006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung
840d1ea63f24a751521e6c35cc06be0e548e0b04f23Sunny Goyal    @Thunk void cleanupAnimation() {
841006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        mCurrentAnimation = null;
842006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung    }
8431558893b873cd55b2df779f594f1de3c370d3328Adam Cohen}
844