• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.launcher3.uioverrides;
18 
19 import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE;
20 import static com.android.app.animation.Interpolators.AGGRESSIVE_EASE_IN_OUT;
21 import static com.android.app.animation.Interpolators.FINAL_FRAME;
22 import static com.android.app.animation.Interpolators.INSTANT;
23 import static com.android.app.animation.Interpolators.LINEAR;
24 import static com.android.launcher3.LauncherState.QUICK_SWITCH_FROM_HOME;
25 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SPLIT_SELECTION_EXIT_HOME;
26 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
27 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MODAL;
28 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
29 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE;
30 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
31 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
32 import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
33 import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
34 import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
35 import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
36 import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
37 import static com.android.quickstep.views.RecentsView.TASK_THUMBNAIL_SPLASH_ALPHA;
38 
39 import android.util.FloatProperty;
40 import android.view.animation.Interpolator;
41 
42 import androidx.annotation.NonNull;
43 
44 import com.android.launcher3.LauncherState;
45 import com.android.launcher3.anim.PendingAnimation;
46 import com.android.launcher3.config.FeatureFlags;
47 import com.android.launcher3.statemanager.StateManager.StateHandler;
48 import com.android.launcher3.states.StateAnimationConfig;
49 import com.android.quickstep.views.RecentsView;
50 
51 /**
52  * State handler for recents view. Manages UI changes and animations for recents view based off the
53  * current {@link LauncherState}.
54  *
55  * @param <T> the recents view
56  */
57 public abstract class BaseRecentsViewStateController<T extends RecentsView>
58         implements StateHandler<LauncherState> {
59     protected final T mRecentsView;
60     protected final QuickstepLauncher mLauncher;
61 
BaseRecentsViewStateController(@onNull QuickstepLauncher launcher)62     public BaseRecentsViewStateController(@NonNull QuickstepLauncher launcher) {
63         mLauncher = launcher;
64         mRecentsView = launcher.getOverviewPanel();
65     }
66 
67     @Override
setState(@onNull LauncherState state)68     public void setState(@NonNull LauncherState state) {
69         float[] scaleAndOffset = state.getOverviewScaleAndOffset(mLauncher);
70         RECENTS_SCALE_PROPERTY.set(mRecentsView, scaleAndOffset[0]);
71         ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, scaleAndOffset[1]);
72         TASK_SECONDARY_TRANSLATION.set(mRecentsView, 0f);
73 
74         getContentAlphaProperty().set(mRecentsView, state.isRecentsViewVisible ? 1f : 0);
75         getTaskModalnessProperty().set(mRecentsView, state.getOverviewModalness());
76         RECENTS_GRID_PROGRESS.set(mRecentsView,
77                 state.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile()) ? 1f : 0f);
78         TASK_THUMBNAIL_SPLASH_ALPHA.set(mRecentsView, state.showTaskThumbnailSplash() ? 1f : 0f);
79     }
80 
81     @Override
setStateWithAnimation(LauncherState toState, StateAnimationConfig config, PendingAnimation builder)82     public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
83             PendingAnimation builder) {
84         if (config.hasAnimationFlag(SKIP_OVERVIEW)) {
85             return;
86         }
87         setStateWithAnimationInternal(toState, config, builder);
88         builder.addEndListener(success -> {
89             if (!success) {
90                 mRecentsView.reset();
91             }
92         });
93     }
94 
95     /**
96      * Core logic for animating the recents view UI.
97      *
98      * @param toState state to animate to
99      * @param config current animation config
100      * @param setter animator set builder
101      */
setStateWithAnimationInternal(@onNull final LauncherState toState, @NonNull StateAnimationConfig config, @NonNull PendingAnimation setter)102     void setStateWithAnimationInternal(@NonNull final LauncherState toState,
103             @NonNull StateAnimationConfig config, @NonNull PendingAnimation setter) {
104         float[] scaleAndOffset = toState.getOverviewScaleAndOffset(mLauncher);
105         setter.setFloat(mRecentsView, RECENTS_SCALE_PROPERTY, scaleAndOffset[0],
106                 config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR));
107         setter.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1],
108                 config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR));
109         setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f,
110                 config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
111 
112         boolean exitingOverview =
113                 !FeatureFlags.enableSplitContextually() && !toState.isRecentsViewVisible;
114         if (mRecentsView.isSplitSelectionActive() && exitingOverview) {
115             setter.add(mRecentsView.getSplitSelectController().getSplitAnimationController()
116                     .createPlaceholderDismissAnim(mLauncher, LAUNCHER_SPLIT_SELECTION_EXIT_HOME,
117                             setter.getDuration()));
118             setter.setViewAlpha(
119                     mRecentsView.getSplitInstructionsView(),
120                     0,
121                     config.getInterpolator(
122                             ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE,
123                             LINEAR
124                     )
125             );
126         }
127 
128         setter.setFloat(mRecentsView, getContentAlphaProperty(),
129                 toState.isRecentsViewVisible ? 1 : 0,
130                 config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
131 
132         setter.setFloat(
133                 mRecentsView, getTaskModalnessProperty(),
134                 toState.getOverviewModalness(),
135                 config.getInterpolator(ANIM_OVERVIEW_MODAL, LINEAR));
136 
137         LauncherState fromState = mLauncher.getStateManager().getState();
138         setter.setFloat(mRecentsView, TASK_THUMBNAIL_SPLASH_ALPHA,
139                 toState.showTaskThumbnailSplash() ? 1f : 0f,
140                 getOverviewInterpolator(fromState, toState));
141 
142         setter.setFloat(mRecentsView, RECENTS_GRID_PROGRESS,
143                 toState.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile()) ? 1f : 0f,
144                 getOverviewInterpolator(fromState, toState));
145     }
146 
getOverviewInterpolator(LauncherState fromState, LauncherState toState)147     private Interpolator getOverviewInterpolator(LauncherState fromState, LauncherState toState) {
148         return fromState == QUICK_SWITCH_FROM_HOME
149                 ? ACCELERATE_DECELERATE
150                 : toState.isRecentsViewVisible ? INSTANT : FINAL_FRAME;
151     }
152 
getTaskModalnessProperty()153     abstract FloatProperty getTaskModalnessProperty();
154 
155     /**
156      * Get property for content alpha for the recents view.
157      *
158      * @return the float property for the view's content alpha
159      */
getContentAlphaProperty()160     abstract FloatProperty getContentAlphaProperty();
161 }
162