LauncherStateTransitionAnimation.java revision 3f471440a8b6b71d4c15501a96befd3b715c9e8f
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;
25b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.content.res.Resources;
263f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport android.support.v7.widget.RecyclerView;
27b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.util.Log;
28b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.View;
29b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.ViewAnimationUtils;
30b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.AccelerateInterpolator;
31b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.view.animation.DecelerateInterpolator;
32b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
33091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
343f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.widget.WidgetsContainerView;
35091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen
36b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport java.util.HashMap;
37b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
38b745afbdd75157c73d581b345118cdaff99e912dWinson Chung/**
39b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * TODO: figure out what kind of tests we can write for this
40b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *
41b745afbdd75157c73d581b345118cdaff99e912dWinson Chung * Things to test when changing the following class.
42b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from workspace
43b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
44b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
45b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Home from all apps
46b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
47b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
48b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Back from all apps
49b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from center screen
50b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - from other screens
51b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from workspace and quit
52b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
53b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
54b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch app from all apps and quit
55b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
56b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
57b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Go to a screen that's not the default, then all
58b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *     apps, and launch and app, and go back
59b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
60b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          -with home
61b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, long press power and go back
62b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
63b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
64b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, long press power and go back
65b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with back
66b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - with home
67b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On workspace, power off
68b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - On all apps, power off
69b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Launch an app and turn off the screen while in that app
70b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with home key
71b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - Go back with back key  TODO: make this not go to workspace
72b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
73b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From workspace
74b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *   - Enter and exit car mode (becuase it causes an extra configuration changed)
75b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From all apps
76b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From the center workspace
77b745afbdd75157c73d581b345118cdaff99e912dWinson Chung *          - From another workspace
78b745afbdd75157c73d581b345118cdaff99e912dWinson Chung */
79b745afbdd75157c73d581b345118cdaff99e912dWinson Chungpublic class LauncherStateTransitionAnimation {
80b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
81b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
82b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Callbacks made during the state transition
83b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
84b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    interface Callbacks {
85b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        public void onStateTransitionHideSearchBar();
86b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
87b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
88b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
89b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Private callbacks made during transition setup.
90b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
91b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    static abstract class PrivateTransitionCallbacks {
92b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        void onRevealViewVisible(View revealView, View contentView, View allAppsButtonView) {}
93b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        void onAnimationComplete(View revealView, View contentView, View allAppsButtonView) {}
94b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewFinalAlpha(View revealView) {
95b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
96b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
97b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewFinalXDrift(View revealView) {
98b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
99b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
100b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewFinalYDrift(View revealView) {
101b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
102b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
103b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        float getMaterialRevealViewStartFinalRadius() {
104b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return 0;
105b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
106b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(View revealView,
107b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                View allAppsButtonView) {
108b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            return null;
109b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
110b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
111b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
112b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final String TAG = "LauncherStateTransitionAnimation";
113b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
114b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    // Flags to determine how to set the layers on views before the transition animation
115b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_LAYER = 0;
116b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int BUILD_AND_SET_LAYER = 1;
117b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public static final int SINGLE_FRAME_DELAY = 16;
118b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
119091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk Launcher mLauncher;
120091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk Callbacks mCb;
121091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk AnimatorSet mStateAnimation;
122b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
123b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public LauncherStateTransitionAnimation(Launcher l, Callbacks cb) {
124b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        mLauncher = l;
125b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        mCb = cb;
126b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
127b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
128b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
129b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the apps view.
130b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
131b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public void startAnimationToAllApps(final boolean animated) {
132b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final AppsContainerView toView = mLauncher.getAppsView();
133b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
134b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            private int[] mAllAppsToPanelDelta;
135b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
136b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
137b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public void onRevealViewVisible(View revealView, View contentView,
138b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    View allAppsButtonView) {
139b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toView.setBackground(null);
140b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Get the y delta between the center of the page and the center of the all apps
141b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // button
142b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mAllAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
143b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView, null);
144b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
145b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
146b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewFinalAlpha(View revealView) {
147b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return 1f;
148b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
149b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
150b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewFinalXDrift(View revealView) {
151b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return mAllAppsToPanelDelta[0];
152b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
153b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
154b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewFinalYDrift(View revealView) {
155b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return mAllAppsToPanelDelta[1];
156b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
157b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
158b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewStartFinalRadius() {
159b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int allAppsButtonSize = LauncherAppState.getInstance().
160b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;
161b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
162b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
163b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
164b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
165b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
166b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
167b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
168b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.INVISIBLE);
169b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
170b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
171b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
172b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
173b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
174b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
175b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
176b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        startAnimationToOverlay(Workspace.State.NORMAL_HIDDEN, toView, toView.getContentView(),
177b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toView.getRevealView(), null, animated, cb);
178b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
179b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
180b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
181b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts an animation to the widgets view.
182b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
183b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public void startAnimationToWidgets(final boolean animated) {
1843f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song        final WidgetsContainerView toView = mLauncher.getWidgetsView();
185b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
186b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
187b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public void onRevealViewVisible(View revealView, View contentView,
188b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    View allAppsButtonView) {
1893f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song                revealView.setBackground(mLauncher.getDrawable(R.drawable.quantum_panel_dark));
190b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
191b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
192b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewFinalAlpha(View revealView) {
193b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return 0.3f;
194b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
195b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
196b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewFinalYDrift(View revealView) {
197b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return revealView.getMeasuredHeight() / 2;
198b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
199b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
200b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        startAnimationToOverlay(Workspace.State.OVERVIEW_HIDDEN, toView, toView.getContentView(),
2013f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song                toView.getRevealView(), null, animated, cb);
202b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
203b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
204b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
205b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts and animation to the workspace from the current overlay view.
206b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
207b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    public void startAnimationToWorkspace(final Launcher.State fromState,
208b745afbdd75157c73d581b345118cdaff99e912dWinson Chung              final Workspace.State toWorkspaceState, final boolean animated,
209b745afbdd75157c73d581b345118cdaff99e912dWinson Chung              final Runnable onCompleteRunnable) {
210b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (toWorkspaceState != Workspace.State.NORMAL &&
211b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.SPRING_LOADED &&
212b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState != Workspace.State.OVERVIEW) {
213b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            Log.e(TAG, "Unexpected call to startAnimationToWorkspace");
214b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
215b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
216b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (fromState == Launcher.State.APPS || fromState == Launcher.State.APPS_SPRING_LOADED) {
217b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            startAnimationToWorkspaceFromAllApps(fromState, toWorkspaceState, animated,
218b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    onCompleteRunnable);
219b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
220b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            startAnimationToWorkspaceFromWidgets(fromState, toWorkspaceState, animated,
221b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    onCompleteRunnable);
222b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
223b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
224b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
225b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
226b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to a particular overlay view.
227b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
228b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void startAnimationToOverlay(final Workspace.State toWorkspaceState, final View toView,
229b745afbdd75157c73d581b345118cdaff99e912dWinson Chung             final View contentView, final View revealView, final View pageIndicatorsView,
230b745afbdd75157c73d581b345118cdaff99e912dWinson Chung             final boolean animated, final PrivateTransitionCallbacks pCb) {
231b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
232b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final boolean material = Utilities.isLmpOrAbove();
233b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);
234b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
235b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);
236b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
237b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View allAppsButtonView = mLauncher.getAllAppsButton();
238b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View fromView = mLauncher.getWorkspace();
239b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
240b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
241b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
242b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
243b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        boolean initialized = allAppsButtonView != null;
244b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
245b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
246b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
247b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
248b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Create the workspace animation.
249b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // NOTE: this call apparently also sets the state for the workspace if !animated
250b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        Animator workspaceAnim = mLauncher.getWorkspace().getChangeStateAnimation(
251b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState, animated, layerViews);
252b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
253b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (animated && initialized) {
254b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation = LauncherAnimUtils.createAnimatorSet();
255b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
256b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the reveal view animation
257b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int width = revealView.getMeasuredWidth();
258b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int height = revealView.getMeasuredHeight();
259b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);
260b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setVisibility(View.VISIBLE);
261b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setAlpha(0f);
262b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationY(0f);
263b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            revealView.setTranslationX(0f);
264b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pCb.onRevealViewVisible(revealView, contentView, allAppsButtonView);
265b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
266b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Calculate the final animation values
267b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToAlpha;
268b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToXDrift;
269b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final float revealViewToYDrift;
270b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
271b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToAlpha = pCb.getMaterialRevealViewFinalAlpha(revealView);
272b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToYDrift = pCb.getMaterialRevealViewFinalYDrift(revealView);
273b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToXDrift = pCb.getMaterialRevealViewFinalXDrift(revealView);
274b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            } else {
275b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToAlpha = 0f;
276b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToYDrift = 2 * height / 3;
277b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealViewToXDrift = 0;
278b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
279b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
280b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the animators
281b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelAlpha =
282b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    PropertyValuesHolder.ofFloat("alpha", revealViewToAlpha, 1f);
283b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftY =
284b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    PropertyValuesHolder.ofFloat("translationY", revealViewToYDrift, 0);
285b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            PropertyValuesHolder panelDriftX =
286b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    PropertyValuesHolder.ofFloat("translationX", revealViewToXDrift, 0);
287b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,
288b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha, panelDriftY, panelDriftX);
289b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setDuration(revealDuration);
290b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
291b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
292b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the animation
293b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(revealView, BUILD_AND_SET_LAYER);
294b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.play(panelAlphaAndDrift);
295b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
296b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the animation for the page indicators
297b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (pageIndicatorsView != null) {
298b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageIndicatorsView.setAlpha(0.01f);
299b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                ObjectAnimator indicatorsAlpha =
300b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        ObjectAnimator.ofFloat(pageIndicatorsView, "alpha", 1f);
301b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                indicatorsAlpha.setDuration(revealDuration);
302b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(indicatorsAlpha);
303b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
304b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
305b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Setup the animation for the content view
306b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
307b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setAlpha(0f);
308b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setTranslationY(revealViewToYDrift);
309b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            layerViews.put(contentView, BUILD_AND_SET_LAYER);
310b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
311b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Create the individual animators
312b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
313b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift, 0);
314b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setDuration(revealDuration);
315b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));
316b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            pageDrift.setStartDelay(itemsAlphaStagger);
317b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.play(pageDrift);
318b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
319b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(contentView, "alpha", 0f, 1f);
320b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setDuration(revealDuration);
321b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
322b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            itemsAlpha.setStartDelay(itemsAlphaStagger);
323b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.play(itemsAlpha);
324b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
325b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (material) {
326b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Animate the all apps button
327b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                float startRadius = pCb.getMaterialRevealViewStartFinalRadius();
328b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener(
329b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView, allAppsButtonView);
330b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,
331b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        height / 2, startRadius, revealRadius);
332b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setDuration(revealDuration);
333b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
334b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (listener != null) {
335b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.addListener(listener);
336b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
337b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(reveal);
338b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
339b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
340b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.addListener(new AnimatorListenerAdapter() {
341b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
342b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
343b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
344b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, false);
345b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
346b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Hide the reveal view
347b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealView.setVisibility(View.INVISIBLE);
348b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    pCb.onAnimationComplete(revealView, contentView, allAppsButtonView);
349b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
350b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
351b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
352b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
353b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
354b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
355b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
356b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
357b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Hide the search bar
358b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mCb.onStateTransitionHideSearchBar();
359b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
360b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
361b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mStateAnimation = null;
362b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
363b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
364b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
365b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
366b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the workspace animation
367b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (workspaceAnim != null) {
368b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(workspaceAnim);
369b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
370b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
371b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Dispatch the prepare transition signal
372b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
373b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
374b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
375b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
376b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final AnimatorSet stateAnimation = mStateAnimation;
377b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
378b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
379b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Check that mStateAnimation hasn't changed while
380b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
381b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (mStateAnimation != stateAnimation)
382b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
383b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
384b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
385b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
386b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
387b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
388b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
389b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
390b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
391b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (Utilities.isViewAttachedToWindow(v)) {
392b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
393b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
394b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
395b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
396b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Focus the new view
397b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toView.requestFocus();
398b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
399b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mStateAnimation.start();
400b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
401b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
402b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
403b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
404b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
405b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.post(startAnimRunnable);
406b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
407b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationX(0.0f);
408b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setTranslationY(0.0f);
409b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleX(1.0f);
410b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setScaleY(1.0f);
411b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.setVisibility(View.VISIBLE);
412b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            toView.bringToFront();
413b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
414b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Show the content view
415b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            contentView.setVisibility(View.VISIBLE);
416b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
417b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Hide the search bar
418b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mCb.onStateTransitionHideSearchBar();
419b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
420b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, false);
421b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, false);
422b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, false);
423b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, false);
424b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, false);
425b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, false);
426b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
427b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
428b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
429b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
430b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts and animation to the workspace from the apps view.
431b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
432b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void startAnimationToWorkspaceFromAllApps(final Launcher.State fromState,
433b745afbdd75157c73d581b345118cdaff99e912dWinson Chung              final Workspace.State toWorkspaceState, final boolean animated,
434b745afbdd75157c73d581b345118cdaff99e912dWinson Chung              final Runnable onCompleteRunnable) {
435b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        AppsContainerView appsView = mLauncher.getAppsView();
436b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
437b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            int[] mAllAppsToPanelDelta;
438b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
439b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
440b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public void onRevealViewVisible(View revealView, View contentView,
441b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                                            View allAppsButtonView) {
442b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Get the y delta between the center of the page and the center of the all apps
443b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // button
444b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mAllAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,
445b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView, null);
446b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
447b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
448b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewFinalXDrift(View revealView) {
449b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return mAllAppsToPanelDelta[0];
450b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
451b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
452b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewFinalYDrift(View revealView) {
453b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return mAllAppsToPanelDelta[1];
454b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
455b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
456b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewFinalAlpha(View revealView) {
457b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // No alpha anim from all apps
458b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return 1f;
459b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
460b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
461b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewStartFinalRadius() {
462b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int allAppsButtonSize = LauncherAppState.getInstance().
463b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;
464b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return allAppsButtonSize / 2;
465b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
466b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
467b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
468b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
469b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
470b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationStart(Animator animation) {
471b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // We set the alpha instead of visibility to ensure that the focus does not
472b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // get taken from the all apps view
473b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setVisibility(View.VISIBLE);
474b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(0f);
475b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
476b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
477b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
478b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
479b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
480b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Show the all apps button, and focus it
481b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        allAppsButtonView.setAlpha(1f);
482b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
483b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
484b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
485b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
486b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        startAnimationToWorkspaceFromOverlay(toWorkspaceState, appsView, appsView.getContentView(),
487b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                appsView.getRevealView(), null /* pageIndicatorsView */, animated,
488b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                onCompleteRunnable, cb);
489b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
490b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
491b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
492b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Starts and animation to the workspace from the widgets view.
493b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
494b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void startAnimationToWorkspaceFromWidgets(final Launcher.State fromState,
495b745afbdd75157c73d581b345118cdaff99e912dWinson Chung              final Workspace.State toWorkspaceState, final boolean animated,
496b745afbdd75157c73d581b345118cdaff99e912dWinson Chung              final Runnable onCompleteRunnable) {
4973f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song        WidgetsContainerView widgetsView = mLauncher.getWidgetsView();
498b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
499b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
500b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public float getMaterialRevealViewFinalYDrift(View revealView) {
501b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return revealView.getMeasuredHeight() / 2;
502b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
503b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
504b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            float getMaterialRevealViewFinalAlpha(View revealView) {
505b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return 0.4f;
506b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
507b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            @Override
508b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            public AnimatorListenerAdapter getMaterialRevealViewAnimatorListener(
509b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    final View revealView, final View allAppsButtonView) {
510b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                return new AnimatorListenerAdapter() {
511b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    public void onAnimationEnd(Animator animation) {
512b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        // Hide the reveal view
513b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        revealView.setVisibility(View.INVISIBLE);
514b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
515b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                };
516b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
517b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        };
518b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        startAnimationToWorkspaceFromOverlay(toWorkspaceState, widgetsView,
519b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                widgetsView.getContentView(), widgetsView.getRevealView(),
5203f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song                null, animated, onCompleteRunnable, cb);
521b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
522b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
523b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
524b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Creates and starts a new animation to the workspace.
525b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
526b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void startAnimationToWorkspaceFromOverlay(final Workspace.State toWorkspaceState,
527b745afbdd75157c73d581b345118cdaff99e912dWinson Chung              final View fromView, final View contentView, final View revealView,
528b745afbdd75157c73d581b345118cdaff99e912dWinson Chung              final View pageIndicatorsView, final boolean animated,
529b745afbdd75157c73d581b345118cdaff99e912dWinson Chung              final Runnable onCompleteRunnable, final PrivateTransitionCallbacks pCb) {
530b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final Resources res = mLauncher.getResources();
531b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final boolean material = Utilities.isLmpOrAbove();
532b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);
533b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final int itemsAlphaStagger =
534b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);
535b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
536b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View allAppsButtonView = mLauncher.getAllAppsButton();
537b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final View toView = mLauncher.getWorkspace();
538b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
539b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        final HashMap<View, Integer> layerViews = new HashMap<>();
540b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
541b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // If for some reason our views aren't initialized, don't animate
542b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        boolean initialized = allAppsButtonView != null;
543b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
544b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Cancel the current animation
545b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        cancelAnimation();
546b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
547b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Create the workspace animation.
548b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // NOTE: this call apparently also sets the state for the workspace if !animated
549b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        Animator workspaceAnim = mLauncher.getWorkspace().getChangeStateAnimation(
550b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                toWorkspaceState, animated, layerViews);
551b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
552b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (animated && initialized) {
553b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation = LauncherAnimUtils.createAnimatorSet();
554b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
555b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Play the workspace animation
556b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (workspaceAnim != null) {
557b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(workspaceAnim);
558b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
559b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
560b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // hideAppsCustomizeHelper is called in some cases when it is already hidden
561b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // don't perform all these no-op animations. In particularly, this was causing
562b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // the all-apps button to pop in and out.
563b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (fromView.getVisibility() == View.VISIBLE) {
564b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int width = revealView.getMeasuredWidth();
565b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                int height = revealView.getMeasuredHeight();
566b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);
567b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setVisibility(View.VISIBLE);
568b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setAlpha(1f);
569b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                revealView.setTranslationY(0);
570b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(revealView, BUILD_AND_SET_LAYER);
571b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pCb.onRevealViewVisible(revealView, contentView, allAppsButtonView);
572b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
573b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Calculate the final animation values
574b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToXDrift;
575b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToYDrift;
576b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
577b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift = pCb.getMaterialRevealViewFinalYDrift(revealView);
578b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToXDrift = pCb.getMaterialRevealViewFinalXDrift(revealView);
579b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                } else {
580b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToYDrift = 2 * height / 3;
581b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    revealViewToXDrift = 0;
582b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
583b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
584b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // The vertical motion of the apps panel should be delayed by one frame
585b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // from the conceal animation in order to give the right feel. We correspondingly
586b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // shorten the duration so that the slide and conceal end at the same time.
587b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                TimeInterpolator decelerateInterpolator = material ?
588b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new LogDecelerateInterpolator(100, 0) :
589b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        new DecelerateInterpolator(1f);
590b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",
591b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
592b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);
593b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
594b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftY.setInterpolator(decelerateInterpolator);
595b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(panelDriftY);
596b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
597b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",
598b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToXDrift);
599b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);
600b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
601b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                panelDriftX.setInterpolator(decelerateInterpolator);
602b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(panelDriftX);
603b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
604b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup animation for the reveal panel alpha
605b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                final float revealViewToAlpha = !material ? 0f :
606b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        pCb.getMaterialRevealViewFinalAlpha(revealView);
607b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (revealViewToAlpha != 1f) {
608b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",
609b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            1f, revealViewToAlpha);
610b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setDuration(material ? revealDuration : 150);
611b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
612b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    panelAlpha.setInterpolator(decelerateInterpolator);
613b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mStateAnimation.play(panelAlpha);
614b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
615b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
616b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup the animation for the content view
617b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                layerViews.put(contentView, BUILD_AND_SET_LAYER);
618b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
619b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Create the individual animators
620b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(contentView, "translationY",
621b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        0, revealViewToYDrift);
622b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setTranslationY(0);
623b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);
624b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setInterpolator(decelerateInterpolator);
625b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);
626b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(pageDrift);
627b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
628b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                contentView.setAlpha(1f);
629b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(contentView, "alpha", 1f, 0f);
630b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setDuration(100);
631b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                itemsAlpha.setInterpolator(decelerateInterpolator);
632b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                mStateAnimation.play(itemsAlpha);
633b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
634b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                // Setup the page indicators animation
635b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (pageIndicatorsView != null) {
636b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    pageIndicatorsView.setAlpha(1f);
637b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    ObjectAnimator indicatorsAlpha =
638b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            LauncherAnimUtils.ofFloat(pageIndicatorsView, "alpha", 0f);
639b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    indicatorsAlpha.setDuration(revealDuration);
640b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));
641b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mStateAnimation.play(indicatorsAlpha);
642b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
643b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
644b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                if (material) {
645b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Animate the all apps button
646b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    float finalRadius = pCb.getMaterialRevealViewStartFinalRadius();
647b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    AnimatorListenerAdapter listener =
648b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            pCb.getMaterialRevealViewAnimatorListener(revealView, allAppsButtonView);
649b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    Animator reveal =
650b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            LauncherAnimUtils.createCircularReveal(revealView, width / 2,
651b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                                    height / 2, revealRadius, finalRadius);
652b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
653b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setDuration(revealDuration);
654b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    reveal.setStartDelay(itemsAlphaStagger);
655b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (listener != null) {
656b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        reveal.addListener(listener);
657b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
658b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mStateAnimation.play(reveal);
659b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
660b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
661b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                dispatchOnLauncherTransitionPrepare(fromView, animated, true);
662b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                dispatchOnLauncherTransitionPrepare(toView, animated, true);
663b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
664b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
665b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.addListener(new AnimatorListenerAdapter() {
666b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                @Override
667b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void onAnimationEnd(Animator animation) {
668b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    fromView.setVisibility(View.GONE);
669b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(fromView, animated, true);
670b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionEnd(toView, animated, true);
671b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
672b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Run any queued runnables
673b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (onCompleteRunnable != null) {
674b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        onCompleteRunnable.run();
675b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
676b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
677b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Animation complete callback
678b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    pCb.onAnimationComplete(revealView, contentView, allAppsButtonView);
679b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
680b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Disable all necessary layers
681b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
682b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
683b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_NONE, null);
684b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
685b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
686b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
687b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Reset page transforms
688b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (contentView != null) {
689b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationX(0);
690b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setTranslationY(0);
691b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        contentView.setAlpha(1);
692b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
693b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
694b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // This can hold unnecessary references to views.
695b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mStateAnimation = null;
696b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
697b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            });
698b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
699b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final AnimatorSet stateAnimation = mStateAnimation;
700b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            final Runnable startAnimRunnable = new Runnable() {
701b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                public void run() {
702b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Check that mStateAnimation hasn't changed while
703b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // we waited for a layout/draw pass
704b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    if (mStateAnimation != stateAnimation)
705b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        return;
706b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(fromView, animated, false);
707b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    dispatchOnLauncherTransitionStart(toView, animated, false);
708b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
709b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    // Enable all necessary layers
710b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    for (View v : layerViews.keySet()) {
711b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
712b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
713b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
714b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        if (Utilities.isLmpOrAbove()) {
715b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                            v.buildLayer();
716b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                        }
717b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    }
718b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    mStateAnimation.start();
719b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                }
720b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            };
721b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.post(startAnimRunnable);
722b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        } else {
723b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            fromView.setVisibility(View.GONE);
724b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(fromView, animated, true);
725b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(fromView, animated, true);
726b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(fromView, animated, true);
727b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionPrepare(toView, animated, true);
728b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionStart(toView, animated, true);
729b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            dispatchOnLauncherTransitionEnd(toView, animated, true);
730b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
731b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            // Run any queued runnables
732b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            if (onCompleteRunnable != null) {
733b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                onCompleteRunnable.run();
734b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            }
735b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
736b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
737b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
738b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
739b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
740b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the prepare-transition event to suitable views.
741b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
742b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {
743b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
744b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionPrepare(mLauncher, animated,
745b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
746b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
747b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
748b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
749b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
750b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the start-transition event to suitable views.
751b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
752b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {
753b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
754b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStart(mLauncher, animated,
755b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
756b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
757b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
758b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
759b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 0f);
760b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
761b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
762b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
763b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the step-transition event to suitable views.
764b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
765b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionStep(View v, float t) {
766b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
767b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionStep(mLauncher, t);
768b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
769b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
770b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
771b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
772b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Dispatches the end-transition event to suitable views.
773b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
774b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {
775b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (v instanceof LauncherTransitionable) {
776b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            ((LauncherTransitionable) v).onLauncherTransitionEnd(mLauncher, animated,
777b745afbdd75157c73d581b345118cdaff99e912dWinson Chung                    toWorkspace);
778b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
779b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
780b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        // Update the workspace transition step as well
781b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        dispatchOnLauncherTransitionStep(v, 1f);
782b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
783b745afbdd75157c73d581b345118cdaff99e912dWinson Chung
784b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    /**
785b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     * Cancels the current animation.
786b745afbdd75157c73d581b345118cdaff99e912dWinson Chung     */
787b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    private void cancelAnimation() {
788b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        if (mStateAnimation != null) {
789b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.setDuration(0);
790b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation.cancel();
791b745afbdd75157c73d581b345118cdaff99e912dWinson Chung            mStateAnimation = null;
792b745afbdd75157c73d581b345118cdaff99e912dWinson Chung        }
793b745afbdd75157c73d581b345118cdaff99e912dWinson Chung    }
794b745afbdd75157c73d581b345118cdaff99e912dWinson Chung}