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