1dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung/*
2dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * Copyright (C) 2015 The Android Open Source Project
3dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung *
4dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * Licensed under the Apache License, Version 2.0 (the "License");
5dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * you may not use this file except in compliance with the License.
6dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * You may obtain a copy of the License at
7dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung *
8dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung *      http://www.apache.org/licenses/LICENSE-2.0
9dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung *
10dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * Unless required by applicable law or agreed to in writing, software
11dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * distributed under the License is distributed on an "AS IS" BASIS,
12dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * See the License for the specific language governing permissions and
14dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * limitations under the License.
15dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung */
16dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
17dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungpackage com.android.launcher3;
18dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
19dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungimport android.animation.Animator;
20dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungimport android.animation.AnimatorListenerAdapter;
21dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungimport android.animation.AnimatorSet;
224f3e9383eb422c87e2689548653b89f34f5516a5Sunny Goyalimport android.animation.ObjectAnimator;
23dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungimport android.animation.TimeInterpolator;
24dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungimport android.animation.ValueAnimator;
25dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungimport android.content.Context;
26dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungimport android.content.res.Resources;
27dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungimport android.view.View;
281d08f70441999c66b76c97e48b4149e1433be3c3Sunny Goyalimport android.view.ViewGroup;
29dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungimport android.view.accessibility.AccessibilityManager;
301d08f70441999c66b76c97e48b4149e1433be3c3Sunny Goyalimport android.view.accessibility.AccessibilityNodeInfo;
31dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungimport android.view.animation.DecelerateInterpolator;
321d08f70441999c66b76c97e48b4149e1433be3c3Sunny Goyal
33b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyalimport com.android.launcher3.anim.AnimationLayerSet;
349e76f682f3e52afa1f11172564b883c7dfda5063Sunny Goyalimport com.android.launcher3.anim.PropertyListBuilder;
35eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Songimport com.android.launcher3.config.FeatureFlags;
36fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.dragndrop.DragLayer;
37dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungimport com.android.launcher3.util.Thunk;
38dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
39dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung/**
40dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * A convenience class to update a view's visibility state after an alpha animation.
41dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung */
42dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungclass AlphaUpdateListener extends AnimatorListenerAdapter implements ValueAnimator.AnimatorUpdateListener {
43dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    private static final float ALPHA_CUTOFF_THRESHOLD = 0.01f;
44dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
45dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    private View mView;
46dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    private boolean mAccessibilityEnabled;
47eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song    private boolean mCanceled = false;
48dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
49dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public AlphaUpdateListener(View v, boolean accessibilityEnabled) {
50dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        mView = v;
51dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        mAccessibilityEnabled = accessibilityEnabled;
52dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
53dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
54dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Override
55dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public void onAnimationUpdate(ValueAnimator arg0) {
56dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        updateVisibility(mView, mAccessibilityEnabled);
57dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
58dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
59dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public static void updateVisibility(View view, boolean accessibilityEnabled) {
60dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        // We want to avoid the extra layout pass by setting the views to GONE unless
61dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        // accessibility is on, in which case not setting them to GONE causes a glitch.
62dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        int invisibleState = accessibilityEnabled ? View.GONE : View.INVISIBLE;
63dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        if (view.getAlpha() < ALPHA_CUTOFF_THRESHOLD && view.getVisibility() != invisibleState) {
64dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            view.setVisibility(invisibleState);
65dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        } else if (view.getAlpha() > ALPHA_CUTOFF_THRESHOLD
66dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                && view.getVisibility() != View.VISIBLE) {
67dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            view.setVisibility(View.VISIBLE);
68dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        }
69dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
70dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
71dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Override
72eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song    public void onAnimationCancel(Animator animation) {
73eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song        mCanceled = true;
74eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song    }
75eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song
76eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song    @Override
77dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public void onAnimationEnd(Animator arg0) {
78eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song        if (mCanceled) return;
79dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        updateVisibility(mView, mAccessibilityEnabled);
80dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
81dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
82dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Override
83dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public void onAnimationStart(Animator arg0) {
84dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        // We want the views to be visible for animation, so fade-in/out is visible
85dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        mView.setVisibility(View.VISIBLE);
86dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
87dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung}
88dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
89dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung/**
90dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * This interpolator emulates the rate at which the perceived scale of an object changes
91dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * as its distance from a camera increases. When this interpolator is applied to a scale
92dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * animation on a view, it evokes the sense that the object is shrinking due to moving away
93dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * from the camera.
94dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung */
95dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungclass ZInterpolator implements TimeInterpolator {
96dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    private float focalLength;
97dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
98dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public ZInterpolator(float foc) {
99dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        focalLength = foc;
100dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
101dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
102dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public float getInterpolation(float input) {
103dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        return (1.0f - focalLength / (focalLength + input)) /
104dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                (1.0f - focalLength / (focalLength + 1.0f));
105dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
106dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung}
107dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
108dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung/**
109dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * The exact reverse of ZInterpolator.
110dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung */
111dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungclass InverseZInterpolator implements TimeInterpolator {
112dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    private ZInterpolator zInterpolator;
113dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public InverseZInterpolator(float foc) {
114dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        zInterpolator = new ZInterpolator(foc);
115dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
116dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public float getInterpolation(float input) {
117dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        return 1 - zInterpolator.getInterpolation(1 - input);
118dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
119dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung}
120dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
121dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung/**
122dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * InverseZInterpolator compounded with an ease-out.
123dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung */
124dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungclass ZoomInInterpolator implements TimeInterpolator {
125dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    private final InverseZInterpolator inverseZInterpolator = new InverseZInterpolator(0.35f);
126dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    private final DecelerateInterpolator decelerate = new DecelerateInterpolator(3.0f);
127dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
128dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public float getInterpolation(float input) {
129dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        return decelerate.getInterpolation(inverseZInterpolator.getInterpolation(input));
130dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
131dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung}
132dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
133dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung/**
134ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung * Stores the transition states for convenience.
135ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung */
136ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chungclass TransitionStates {
137ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung
138ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    // Raw states
139ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean oldStateIsNormal;
140ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean oldStateIsSpringLoaded;
141ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean oldStateIsNormalHidden;
142ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean oldStateIsOverviewHidden;
143ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean oldStateIsOverview;
144ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung
145ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean stateIsNormal;
146ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean stateIsSpringLoaded;
147ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean stateIsNormalHidden;
148ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean stateIsOverviewHidden;
149ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean stateIsOverview;
150ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung
151ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    // Convenience members
152ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean workspaceToAllApps;
153ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean overviewToAllApps;
154ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean allAppsToWorkspace;
155ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean workspaceToOverview;
156ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    final boolean overviewToWorkspace;
157ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung
158ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    public TransitionStates(final Workspace.State fromState, final Workspace.State toState) {
159ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        oldStateIsNormal = (fromState == Workspace.State.NORMAL);
160ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        oldStateIsSpringLoaded = (fromState == Workspace.State.SPRING_LOADED);
161ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        oldStateIsNormalHidden = (fromState == Workspace.State.NORMAL_HIDDEN);
162ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        oldStateIsOverviewHidden = (fromState == Workspace.State.OVERVIEW_HIDDEN);
163ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        oldStateIsOverview = (fromState == Workspace.State.OVERVIEW);
164ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung
165ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        stateIsNormal = (toState == Workspace.State.NORMAL);
166ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        stateIsSpringLoaded = (toState == Workspace.State.SPRING_LOADED);
167ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        stateIsNormalHidden = (toState == Workspace.State.NORMAL_HIDDEN);
168ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        stateIsOverviewHidden = (toState == Workspace.State.OVERVIEW_HIDDEN);
169ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        stateIsOverview = (toState == Workspace.State.OVERVIEW);
170ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung
171ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        workspaceToOverview = (oldStateIsNormal && stateIsOverview);
172ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        workspaceToAllApps = (oldStateIsNormal && stateIsNormalHidden);
173ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        overviewToWorkspace = (oldStateIsOverview && stateIsNormal);
174ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        overviewToAllApps = (oldStateIsOverview && stateIsOverviewHidden);
17597d89e924926cacad053e182def107e3eaa578dcHyunyoung Song        allAppsToWorkspace = (oldStateIsNormalHidden && stateIsNormal);
176ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    }
177ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung}
178ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung
179ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung/**
180dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung * Manages the animations between each of the workspace states.
181dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung */
182dc61c4d41468a8beced2863de1b863b340cf49baWinson Chungpublic class WorkspaceStateTransitionAnimation {
183dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
184dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public static final String TAG = "WorkspaceStateTransitionAnimation";
185dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
186dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Thunk static final int BACKGROUND_FADE_OUT_DURATION = 350;
187dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
188dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    final @Thunk Launcher mLauncher;
189dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    final @Thunk Workspace mWorkspace;
190dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
191dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Thunk AnimatorSet mStateAnimator;
192dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
193dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Thunk float mCurrentScale;
194dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Thunk float mNewScale;
195dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
196dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Thunk final ZoomInInterpolator mZoomInInterpolator = new ZoomInInterpolator();
197dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
198dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Thunk float mSpringLoadedShrinkFactor;
199dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Thunk float mOverviewModeShrinkFactor;
200dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Thunk float mWorkspaceScrimAlpha;
201dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Thunk int mAllAppsTransitionTime;
202dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Thunk int mOverviewTransitionTime;
203dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Thunk int mOverlayTransitionTime;
204e0c332365604976d999eb25d4bdcc49ec75b7a1cTony Wickham    @Thunk int mSpringLoadedTransitionTime;
205dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    @Thunk boolean mWorkspaceFadeInAdjacentScreens;
206dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
207dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public WorkspaceStateTransitionAnimation(Launcher launcher, Workspace workspace) {
208dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        mLauncher = launcher;
209dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        mWorkspace = workspace;
210dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
2112e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen        DeviceProfile grid = mLauncher.getDeviceProfile();
212dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        Resources res = launcher.getResources();
2135f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        mAllAppsTransitionTime = res.getInteger(R.integer.config_allAppsTransitionTime);
214dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        mOverviewTransitionTime = res.getInteger(R.integer.config_overviewTransitionTime);
2155f4e0fdd2e4edeb9211e2dcd1c99497f175731f8Winson Chung        mOverlayTransitionTime = res.getInteger(R.integer.config_overlayTransitionTime);
216e0c332365604976d999eb25d4bdcc49ec75b7a1cTony Wickham        mSpringLoadedTransitionTime = mOverlayTransitionTime / 2;
21747328fd53f43fd0c2ed14ad925dd04483f9229a0Sunny Goyal        mSpringLoadedShrinkFactor = mLauncher.getDeviceProfile().workspaceSpringLoadShrinkFactor;
2184f7eb4077e901a28b2b698060079292b56e991bdWinson Chung        mOverviewModeShrinkFactor =
2194f7eb4077e901a28b2b698060079292b56e991bdWinson Chung                res.getInteger(R.integer.config_workspaceOverviewShrinkPercentage) / 100f;
220dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        mWorkspaceScrimAlpha = res.getInteger(R.integer.config_workspaceScrimAlpha) / 100f;
221dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        mWorkspaceFadeInAdjacentScreens = grid.shouldFadeAdjacentWorkspaceScreens();
222dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
223dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
224ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal    public void snapToPageFromOverView(int whichPage) {
225ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal        mWorkspace.snapToPage(whichPage, mOverviewTransitionTime, mZoomInInterpolator);
226ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal    }
227ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal
228dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public AnimatorSet getAnimationToState(Workspace.State fromState, Workspace.State toState,
229b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal            boolean animated, AnimationLayerSet layerViews) {
230ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        AccessibilityManager am = (AccessibilityManager)
231ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                mLauncher.getSystemService(Context.ACCESSIBILITY_SERVICE);
232ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        final boolean accessibilityEnabled = am.isEnabled();
233ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        TransitionStates states = new TransitionStates(fromState, toState);
234006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung        int workspaceDuration = getAnimationDuration(states);
2352a87fe8c41338e746c6959d992edfeb9cb00bcc1Winson        animateWorkspace(states, animated, workspaceDuration, layerViews,
236ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                accessibilityEnabled);
2375796b03f6d526ee775fa48f175ceee0e92200b45Hyunyoung Song        animateBackgroundGradient(states, animated, BACKGROUND_FADE_OUT_DURATION);
238dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        return mStateAnimator;
239dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
240dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
241dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    public float getFinalScale() {
242dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        return mNewScale;
243dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
244dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
245dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    /**
246ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung     * Returns the proper animation duration for a transition.
247ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung     */
248ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    private int getAnimationDuration(TransitionStates states) {
249ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        if (states.workspaceToAllApps || states.overviewToAllApps) {
250ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            return mAllAppsTransitionTime;
251ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        } else if (states.workspaceToOverview || states.overviewToWorkspace) {
252ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            return mOverviewTransitionTime;
253e0c332365604976d999eb25d4bdcc49ec75b7a1cTony Wickham        } else if (mLauncher.mState == Launcher.State.WORKSPACE_SPRING_LOADED
254e0c332365604976d999eb25d4bdcc49ec75b7a1cTony Wickham                || states.oldStateIsNormal && states.stateIsSpringLoaded) {
255e0c332365604976d999eb25d4bdcc49ec75b7a1cTony Wickham            return mSpringLoadedTransitionTime;
256ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        } else {
257ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            return mOverlayTransitionTime;
258ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        }
259ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    }
260ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung
261ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung    /**
262ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung     * Starts a transition animation for the workspace.
263ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung     */
264ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal    private void animateWorkspace(final TransitionStates states, final boolean animated,
265b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal            final int duration, AnimationLayerSet layerViews, final boolean accessibilityEnabled) {
266dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        // Cancel existing workspace animations and create a new animator set if requested
267dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        cancelAnimation();
268dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        if (animated) {
269dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            mStateAnimator = LauncherAnimUtils.createAnimatorSet();
270dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        }
271dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
272dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        // Update the workspace state
273ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        float finalBackgroundAlpha = (states.stateIsSpringLoaded || states.stateIsOverview) ?
274ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                1.0f : 0f;
275a97c64bf9f57827eea8f680fff834b1140571a54Hyunyoung Song        float finalHotseatAlpha = (states.stateIsNormal || states.stateIsSpringLoaded ||
276d725f644b70239332a4440173e6411e9ffb169a0Hyunyoung Song                states.stateIsNormalHidden) ? 1f : 0f;
277d725f644b70239332a4440173e6411e9ffb169a0Hyunyoung Song        float finalQsbAlpha = (states.stateIsNormal || states.stateIsNormalHidden) ? 1f : 0f;
27834d2c915c4762a073b60bb676a9e905392e9679cTony Wickham
27934d2c915c4762a073b60bb676a9e905392e9679cTony Wickham        float finalWorkspaceTranslationY = 0;
28034d2c915c4762a073b60bb676a9e905392e9679cTony Wickham        if (states.stateIsOverview || states.stateIsOverviewHidden) {
28134d2c915c4762a073b60bb676a9e905392e9679cTony Wickham            finalWorkspaceTranslationY = mWorkspace.getOverviewModeTranslationY();
28234d2c915c4762a073b60bb676a9e905392e9679cTony Wickham        } else if (states.stateIsSpringLoaded) {
28334d2c915c4762a073b60bb676a9e905392e9679cTony Wickham            finalWorkspaceTranslationY = mWorkspace.getSpringLoadedTranslationY();
28434d2c915c4762a073b60bb676a9e905392e9679cTony Wickham        }
285dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
286dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        final int childCount = mWorkspace.getChildCount();
287dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        final int customPageCount = mWorkspace.numCustomPages();
288dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
289dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        mNewScale = 1.0f;
290dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
291ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        if (states.oldStateIsOverview) {
292dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            mWorkspace.disableFreeScroll();
293ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        } else if (states.stateIsOverview) {
294dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            mWorkspace.enableFreeScroll();
295dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        }
296dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
297ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung        if (!states.stateIsNormal) {
298ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            if (states.stateIsSpringLoaded) {
299dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                mNewScale = mSpringLoadedShrinkFactor;
300ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            } else if (states.stateIsOverview || states.stateIsOverviewHidden) {
301dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                mNewScale = mOverviewModeShrinkFactor;
302dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            }
303dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        }
304dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
305ce5a7e5ee4c880081faef3a508f68725d0317ee9Sunny Goyal        int toPage = mWorkspace.getPageNearestToCenterOfScreen();
3066d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal        // TODO: Animate the celllayout alpha instead of the pages.
307dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        for (int i = 0; i < childCount; i++) {
308dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            final CellLayout cl = (CellLayout) mWorkspace.getChildAt(i);
309dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            float initialAlpha = cl.getShortcutsAndWidgets().getAlpha();
310dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            float finalAlpha;
311eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song            if (states.stateIsOverviewHidden) {
312dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                finalAlpha = 0f;
313eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song            } else if(states.stateIsNormalHidden) {
314d725f644b70239332a4440173e6411e9ffb169a0Hyunyoung Song                finalAlpha = (i == mWorkspace.getNextPage()) ? 1 : 0;
315ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            } else if (states.stateIsNormal && mWorkspaceFadeInAdjacentScreens) {
316dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                finalAlpha = (i == toPage || i < customPageCount) ? 1f : 0f;
317dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            } else {
318dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                finalAlpha = 1f;
319dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            }
320dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
321dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            // If we are animating to/from the small state, then hide the side pages and fade the
322dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            // current page in
323d725f644b70239332a4440173e6411e9ffb169a0Hyunyoung Song            if (!FeatureFlags.NO_ALL_APPS_ICON && !mWorkspace.isSwitchingState()) {
324ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                if (states.workspaceToAllApps || states.allAppsToWorkspace) {
3256d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal                    boolean isCurrentPage = (i == toPage);
326ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung                    if (states.allAppsToWorkspace && isCurrentPage) {
327dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                        initialAlpha = 0f;
328dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    } else if (!isCurrentPage) {
329dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                        initialAlpha = finalAlpha = 0f;
330dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    }
331dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    cl.setShortcutAndWidgetAlpha(initialAlpha);
332dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                }
333dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            }
334dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
335dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            if (animated) {
3366d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal                float oldBackgroundAlpha = cl.getBackgroundAlpha();
3376d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal                if (initialAlpha != finalAlpha) {
3389e76f682f3e52afa1f11172564b883c7dfda5063Sunny Goyal                    Animator alphaAnim = ObjectAnimator.ofFloat(
3399e76f682f3e52afa1f11172564b883c7dfda5063Sunny Goyal                            cl.getShortcutsAndWidgets(), View.ALPHA, finalAlpha);
3409e76f682f3e52afa1f11172564b883c7dfda5063Sunny Goyal                    alphaAnim.setDuration(duration)
3416d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal                            .setInterpolator(mZoomInInterpolator);
3426d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal                    mStateAnimator.play(alphaAnim);
3436d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal                }
3446d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal                if (oldBackgroundAlpha != 0 || finalBackgroundAlpha != 0) {
3456d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal                    ValueAnimator bgAnim = ObjectAnimator.ofFloat(cl, "backgroundAlpha",
3466d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal                            oldBackgroundAlpha, finalBackgroundAlpha);
3476d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal                    bgAnim.setInterpolator(mZoomInInterpolator);
3486d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal                    bgAnim.setDuration(duration);
3496d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal                    mStateAnimator.play(bgAnim);
3506d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal                }
351dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            } else {
352dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                cl.setBackgroundAlpha(finalBackgroundAlpha);
353dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                cl.setShortcutAndWidgetAlpha(finalAlpha);
354dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            }
355dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        }
356dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
3571d08f70441999c66b76c97e48b4149e1433be3c3Sunny Goyal        final ViewGroup overviewPanel = mLauncher.getOverviewPanel();
3586178f13e2d1f0c1a89cea74538b51993ef3439e3Sunny Goyal
3597f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda        float finalOverviewPanelAlpha = states.stateIsOverview ? 1f : 0f;
360dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        if (animated) {
3617f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda            // This is true when transitioning between:
3627f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda            // - Overview <-> Workspace
3637f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda            // - Overview <-> Widget Tray
3647f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda            if (finalOverviewPanelAlpha != overviewPanel.getAlpha()) {
3657f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda                Animator overviewPanelAlpha = ObjectAnimator.ofFloat(
3667f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda                        overviewPanel, View.ALPHA, finalOverviewPanelAlpha);
3677f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda                overviewPanelAlpha.addListener(new AlphaUpdateListener(overviewPanel,
3687f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda                        accessibilityEnabled));
3697f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda                layerViews.addView(overviewPanel);
3707f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda
3717f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda                if (states.overviewToWorkspace) {
3727f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda                    overviewPanelAlpha.setInterpolator(new DecelerateInterpolator(2));
3737f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda                } else if (states.workspaceToOverview) {
3747f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda                    overviewPanelAlpha.setInterpolator(null);
3757f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda                }
3767f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda
3777f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda                overviewPanelAlpha.setDuration(duration);
3787f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda                mStateAnimator.play(overviewPanelAlpha);
3797f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda            }
3807f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda
3819e76f682f3e52afa1f11172564b883c7dfda5063Sunny Goyal            Animator scale = LauncherAnimUtils.ofPropertyValuesHolder(mWorkspace,
3829e76f682f3e52afa1f11172564b883c7dfda5063Sunny Goyal                    new PropertyListBuilder().scale(mNewScale)
3839e76f682f3e52afa1f11172564b883c7dfda5063Sunny Goyal                            .translationY(finalWorkspaceTranslationY).build())
3849e76f682f3e52afa1f11172564b883c7dfda5063Sunny Goyal                    .setDuration(duration);
3859e76f682f3e52afa1f11172564b883c7dfda5063Sunny Goyal            scale.setInterpolator(mZoomInInterpolator);
386dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            mStateAnimator.play(scale);
387dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
38861d9e78f23efcf43be1945d4233780ac89db99d9Winson            // For animation optimization, we may need to provide the Launcher transition
38961d9e78f23efcf43be1945d4233780ac89db99d9Winson            // with a set of views on which to force build and manage layers in certain scenarios.
390b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal            layerViews.addView(mLauncher.getHotseat());
391b5e65c8bd3785409d4aeda21f2c88e75c9e22c9fSunny Goyal            layerViews.addView(mWorkspace.getPageIndicator());
392dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
3937f522a25c39ceb35aa009f029abe74497f03c403Jon Miranda            Animator hotseatAlpha = mWorkspace.createHotseatAlphaAnimator(finalHotseatAlpha);
394ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            if (states.workspaceToOverview) {
395dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                hotseatAlpha.setInterpolator(new DecelerateInterpolator(2));
396ef7f874a889b609bd34e692b9c9a1f8cefd1ea95Winson Chung            } else if (states.overviewToWorkspace) {
397dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                hotseatAlpha.setInterpolator(null);
398dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            }
399dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            hotseatAlpha.setDuration(duration);
400dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            mStateAnimator.play(hotseatAlpha);
401dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            mStateAnimator.addListener(new AnimatorListenerAdapter() {
402eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                boolean canceled = false;
403eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                @Override
404eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                public void onAnimationCancel(Animator animation) {
405eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                    canceled = true;
406eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                }
407eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song
408dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                @Override
409db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal                public void onAnimationStart(Animator animation) {
410db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal                    mWorkspace.getPageIndicator().setShouldAutoHide(!states.stateIsSpringLoaded);
411db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal                }
412db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal
413db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal                @Override
414dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                public void onAnimationEnd(Animator animation) {
415dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    mStateAnimator = null;
416eac1dac23944ea5127dc12a161f016f18a5599cbHyunyoung Song                    if (canceled) return;
4171d08f70441999c66b76c97e48b4149e1433be3c3Sunny Goyal                    if (accessibilityEnabled && overviewPanel.getVisibility() == View.VISIBLE) {
4181d08f70441999c66b76c97e48b4149e1433be3c3Sunny Goyal                        overviewPanel.getChildAt(0).performAccessibilityAction(
4191d08f70441999c66b76c97e48b4149e1433be3c3Sunny Goyal                                AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
4201d08f70441999c66b76c97e48b4149e1433be3c3Sunny Goyal                    }
421dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                }
422dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            });
423dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        } else {
424dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            overviewPanel.setAlpha(finalOverviewPanelAlpha);
425dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            AlphaUpdateListener.updateVisibility(overviewPanel, accessibilityEnabled);
426db364379312e56a3a3905a54d0de783062a92a73Sunny Goyal            mWorkspace.getPageIndicator().setShouldAutoHide(!states.stateIsSpringLoaded);
4276178f13e2d1f0c1a89cea74538b51993ef3439e3Sunny Goyal
4286d64d88b0f222c951f406a7e2195f8f3c0be208fSunny Goyal            mWorkspace.createHotseatAlphaAnimator(finalHotseatAlpha).end();
429dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            mWorkspace.updateCustomContentVisibility();
430dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            mWorkspace.setScaleX(mNewScale);
431dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            mWorkspace.setScaleY(mNewScale);
432dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            mWorkspace.setTranslationY(finalWorkspaceTranslationY);
4331d08f70441999c66b76c97e48b4149e1433be3c3Sunny Goyal
4341d08f70441999c66b76c97e48b4149e1433be3c3Sunny Goyal            if (accessibilityEnabled && overviewPanel.getVisibility() == View.VISIBLE) {
4351d08f70441999c66b76c97e48b4149e1433be3c3Sunny Goyal                overviewPanel.getChildAt(0).performAccessibilityAction(
4361d08f70441999c66b76c97e48b4149e1433be3c3Sunny Goyal                        AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
4371d08f70441999c66b76c97e48b4149e1433be3c3Sunny Goyal            }
438dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        }
439dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
440dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
441dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    /**
4425796b03f6d526ee775fa48f175ceee0e92200b45Hyunyoung Song     * Animates the background scrim. Add to the state animator to prevent jankiness.
443dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung     *
444006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung     * @param states the current and final workspace states
445dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung     * @param animated whether or not to set the background alpha immediately
4465796b03f6d526ee775fa48f175ceee0e92200b45Hyunyoung Song     * @duration duration of the animation
447dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung     */
4487eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song    private void animateBackgroundGradient(TransitionStates states,
4497eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song            boolean animated, int duration) {
4507eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song
451dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        final DragLayer dragLayer = mLauncher.getDragLayer();
452dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        final float startAlpha = dragLayer.getBackgroundAlpha();
453a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song        float finalAlpha = states.stateIsNormal || states.stateIsNormalHidden ?
454a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song                0 : mWorkspaceScrimAlpha;
4555796b03f6d526ee775fa48f175ceee0e92200b45Hyunyoung Song
456dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        if (finalAlpha != startAlpha) {
457dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            if (animated) {
4587eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song                // These properties refer to the background protection gradient used for AllApps
4597eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song                // and Widget tray.
4605d2fc32e6da66f877dfba4fe513fbabdcdae5f99Sunny Goyal                ValueAnimator bgFadeOutAnimation = ValueAnimator.ofFloat(startAlpha, finalAlpha);
4617eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song                bgFadeOutAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
4627eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song                    @Override
463dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    public void onAnimationUpdate(ValueAnimator animation) {
464dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                        dragLayer.setBackgroundAlpha(
465dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                                ((Float)animation.getAnimatedValue()).floatValue());
466dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                    }
467dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                });
4687eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song                bgFadeOutAnimation.setInterpolator(new DecelerateInterpolator(1.5f));
4697eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song                bgFadeOutAnimation.setDuration(duration);
4707eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song                mStateAnimator.play(bgFadeOutAnimation);
471dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            } else {
472dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung                dragLayer.setBackgroundAlpha(finalAlpha);
473dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung            }
474dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        }
475dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
476dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung
477dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    /**
478dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung     * Cancels the current animation.
479dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung     */
480dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    private void cancelAnimation() {
4817eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song        if (mStateAnimator != null) {
4827eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song            mStateAnimator.setDuration(0);
4837eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song            mStateAnimator.cancel();
484dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung        }
4857eea78a1ed8a1e9ea7fabb5b203556bfa94a25feHyunyoung Song        mStateAnimator = null;
486dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung    }
487dc61c4d41468a8beced2863de1b863b340cf49baWinson Chung}