• 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.launcher3.LauncherState.QUICK_SWITCH_FROM_HOME;
20 import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT;
21 import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
22 import static com.android.launcher3.anim.Interpolators.INSTANT;
23 import static com.android.launcher3.anim.Interpolators.LINEAR;
24 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
25 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MODAL;
26 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
27 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN;
28 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE;
29 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
30 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
31 import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
32 import static com.android.quickstep.views.FloatingTaskView.PRIMARY_TRANSLATE_OFFSCREEN;
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.graphics.Rect;
40 import android.graphics.RectF;
41 import android.util.FloatProperty;
42 import android.view.animation.Interpolator;
43 
44 import androidx.annotation.NonNull;
45 
46 import com.android.launcher3.LauncherState;
47 import com.android.launcher3.Utilities;
48 import com.android.launcher3.anim.PendingAnimation;
49 import com.android.launcher3.dragndrop.DragLayer;
50 import com.android.launcher3.statemanager.StateManager.StateHandler;
51 import com.android.launcher3.states.StateAnimationConfig;
52 import com.android.quickstep.views.FloatingTaskView;
53 import com.android.quickstep.views.RecentsView;
54 
55 /**
56  * State handler for recents view. Manages UI changes and animations for recents view based off the
57  * current {@link LauncherState}.
58  *
59  * @param <T> the recents view
60  */
61 public abstract class BaseRecentsViewStateController<T extends RecentsView>
62         implements StateHandler<LauncherState> {
63     protected final T mRecentsView;
64     protected final QuickstepLauncher mLauncher;
65 
BaseRecentsViewStateController(@onNull QuickstepLauncher launcher)66     public BaseRecentsViewStateController(@NonNull QuickstepLauncher launcher) {
67         mLauncher = launcher;
68         mRecentsView = launcher.getOverviewPanel();
69     }
70 
71     @Override
setState(@onNull LauncherState state)72     public void setState(@NonNull LauncherState state) {
73         float[] scaleAndOffset = state.getOverviewScaleAndOffset(mLauncher);
74         RECENTS_SCALE_PROPERTY.set(mRecentsView, scaleAndOffset[0]);
75         ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, scaleAndOffset[1]);
76         TASK_SECONDARY_TRANSLATION.set(mRecentsView, 0f);
77 
78         getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
79         getTaskModalnessProperty().set(mRecentsView, state.getOverviewModalness());
80         RECENTS_GRID_PROGRESS.set(mRecentsView,
81                 state.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile()) ? 1f : 0f);
82         TASK_THUMBNAIL_SPLASH_ALPHA.set(mRecentsView, state.showTaskThumbnailSplash() ? 1f : 0f);
83     }
84 
85     @Override
setStateWithAnimation(LauncherState toState, StateAnimationConfig config, PendingAnimation builder)86     public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
87             PendingAnimation builder) {
88         if (config.hasAnimationFlag(SKIP_OVERVIEW)) {
89             return;
90         }
91         setStateWithAnimationInternal(toState, config, builder);
92         builder.addEndListener(success -> {
93             if (!success) {
94                 mRecentsView.reset();
95             }
96         });
97     }
98 
99     /**
100      * Core logic for animating the recents view UI.
101      *
102      * @param toState state to animate to
103      * @param config current animation config
104      * @param setter animator set builder
105      */
setStateWithAnimationInternal(@onNull final LauncherState toState, @NonNull StateAnimationConfig config, @NonNull PendingAnimation setter)106     void setStateWithAnimationInternal(@NonNull final LauncherState toState,
107             @NonNull StateAnimationConfig config, @NonNull PendingAnimation setter) {
108         float[] scaleAndOffset = toState.getOverviewScaleAndOffset(mLauncher);
109         setter.setFloat(mRecentsView, RECENTS_SCALE_PROPERTY, scaleAndOffset[0],
110                 config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR));
111         setter.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1],
112                 config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR));
113         setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f,
114                 config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
115 
116         if (mRecentsView.isSplitSelectionActive()) {
117             // TODO (b/238651489): Refactor state management to avoid need for double check
118             FloatingTaskView floatingTask = mRecentsView.getFirstFloatingTaskView();
119             if (floatingTask != null) {
120                 // We are in split selection state currently, transitioning to another state
121                 DragLayer dragLayer = mLauncher.getDragLayer();
122                 RectF onScreenRectF = new RectF();
123                 Utilities.getBoundsForViewInDragLayer(mLauncher.getDragLayer(), floatingTask,
124                         new Rect(0, 0, floatingTask.getWidth(), floatingTask.getHeight()),
125                         false, null, onScreenRectF);
126                 // Get the part of the floatingTask that intersects with the DragLayer (i.e. the
127                 // on-screen portion)
128                 onScreenRectF.intersect(
129                         dragLayer.getLeft(),
130                         dragLayer.getTop(),
131                         dragLayer.getRight(),
132                         dragLayer.getBottom()
133                 );
134 
135                 setter.setFloat(
136                         mRecentsView.getFirstFloatingTaskView(),
137                         PRIMARY_TRANSLATE_OFFSCREEN,
138                         mRecentsView.getPagedOrientationHandler()
139                                 .getFloatingTaskOffscreenTranslationTarget(
140                                         floatingTask,
141                                         onScreenRectF,
142                                         floatingTask.getStagePosition(),
143                                         mLauncher.getDeviceProfile()
144                                 ),
145                         config.getInterpolator(
146                                 ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN,
147                                 LINEAR
148                         ));
149                 setter.setViewAlpha(
150                         mRecentsView.getSplitInstructionsView(),
151                         0,
152                         config.getInterpolator(
153                                 ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE,
154                                 LINEAR
155                         )
156                 );
157             }
158         }
159 
160         setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
161                 config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
162 
163         setter.setFloat(
164                 mRecentsView, getTaskModalnessProperty(),
165                 toState.getOverviewModalness(),
166                 config.getInterpolator(ANIM_OVERVIEW_MODAL, LINEAR));
167 
168         LauncherState fromState = mLauncher.getStateManager().getState();
169         setter.setFloat(mRecentsView, TASK_THUMBNAIL_SPLASH_ALPHA,
170                 toState.showTaskThumbnailSplash() ? 1f : 0f,
171                 !toState.showTaskThumbnailSplash() && fromState == QUICK_SWITCH_FROM_HOME
172                         ? LINEAR : INSTANT);
173 
174         boolean showAsGrid = toState.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile());
175         Interpolator gridProgressInterpolator = showAsGrid
176                 ? fromState == QUICK_SWITCH_FROM_HOME ? LINEAR : INSTANT
177                 : FINAL_FRAME;
178         setter.setFloat(mRecentsView, RECENTS_GRID_PROGRESS, showAsGrid ? 1f : 0f,
179                 gridProgressInterpolator);
180     }
181 
getTaskModalnessProperty()182     abstract FloatProperty getTaskModalnessProperty();
183 
184     /**
185      * Get property for content alpha for the recents view.
186      *
187      * @return the float property for the view's content alpha
188      */
getContentAlphaProperty()189     abstract FloatProperty getContentAlphaProperty();
190 }
191