• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 package com.android.quickstep.fallback;
17 
18 import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
19 import static com.android.launcher3.anim.Interpolators.INSTANT;
20 import static com.android.launcher3.anim.Interpolators.LINEAR;
21 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MODAL;
22 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
23 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
24 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
25 import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
26 import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
27 import static com.android.quickstep.fallback.RecentsState.OVERVIEW_SPLIT_SELECT;
28 import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
29 import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
30 import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
31 import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
32 import static com.android.quickstep.views.RecentsView.TASK_MODALNESS;
33 import static com.android.quickstep.views.RecentsView.TASK_PRIMARY_SPLIT_TRANSLATION;
34 import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_SPLIT_TRANSLATION;
35 import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
36 import static com.android.quickstep.views.RecentsView.TASK_THUMBNAIL_SPLASH_ALPHA;
37 import static com.android.quickstep.views.TaskView.FLAG_UPDATE_ALL;
38 
39 import android.util.FloatProperty;
40 import android.util.Pair;
41 
42 import androidx.annotation.NonNull;
43 
44 import com.android.launcher3.anim.PendingAnimation;
45 import com.android.launcher3.anim.PropertySetter;
46 import com.android.launcher3.statemanager.StateManager.StateHandler;
47 import com.android.launcher3.states.StateAnimationConfig;
48 import com.android.launcher3.util.MultiPropertyFactory;
49 import com.android.quickstep.RecentsActivity;
50 import com.android.quickstep.views.ClearAllButton;
51 
52 /**
53  * State controller for fallback recents activity
54  */
55 public class FallbackRecentsStateController implements StateHandler<RecentsState> {
56 
57     private final StateAnimationConfig mNoConfig = new StateAnimationConfig();
58     private final RecentsActivity mActivity;
59     private final FallbackRecentsView mRecentsView;
60 
FallbackRecentsStateController(RecentsActivity activity)61     public FallbackRecentsStateController(RecentsActivity activity) {
62         mActivity = activity;
63         mRecentsView = activity.getOverviewPanel();
64     }
65 
66     @Override
setState(RecentsState state)67     public void setState(RecentsState state) {
68         mRecentsView.updateEmptyMessage();
69         mRecentsView.resetTaskVisuals();
70         setProperties(state, mNoConfig, PropertySetter.NO_ANIM_PROPERTY_SETTER);
71     }
72 
73     @Override
setStateWithAnimation(RecentsState toState, StateAnimationConfig config, PendingAnimation setter)74     public void setStateWithAnimation(RecentsState toState, StateAnimationConfig config,
75             PendingAnimation setter) {
76         if (config.hasAnimationFlag(SKIP_OVERVIEW)) {
77             return;
78         }
79         // While animating into recents, update the visible task data as needed
80         setter.addOnFrameCallback(() -> mRecentsView.loadVisibleTaskData(FLAG_UPDATE_ALL));
81         setter.addEndListener(success -> {
82             if (!success) {
83                 mRecentsView.reset();
84             }
85         });
86         mRecentsView.updateEmptyMessage();
87 
88         setProperties(toState, config, setter);
89     }
90 
setProperties(RecentsState state, StateAnimationConfig config, PropertySetter setter)91     private void setProperties(RecentsState state, StateAnimationConfig config,
92             PropertySetter setter) {
93         float clearAllButtonAlpha = state.hasClearAllButton() ? 1 : 0;
94         setter.setFloat(mRecentsView.getClearAllButton(), ClearAllButton.VISIBILITY_ALPHA,
95                 clearAllButtonAlpha, LINEAR);
96         float overviewButtonAlpha = state.hasOverviewActions() ? 1 : 0;
97         setter.setFloat(mActivity.getActionsView().getVisibilityAlpha(),
98                 MultiPropertyFactory.MULTI_PROPERTY_VALUE, overviewButtonAlpha, LINEAR);
99 
100         float[] scaleAndOffset = state.getOverviewScaleAndOffset(mActivity);
101         setter.setFloat(mRecentsView, RECENTS_SCALE_PROPERTY, scaleAndOffset[0],
102                 config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR));
103         setter.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1],
104                 config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR));
105         setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f,
106                 config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
107 
108         setter.setFloat(mRecentsView, TASK_MODALNESS, state.getOverviewModalness(),
109                 config.getInterpolator(ANIM_OVERVIEW_MODAL, LINEAR));
110         setter.setFloat(mRecentsView, FULLSCREEN_PROGRESS, state.isFullScreen() ? 1 : 0, LINEAR);
111         boolean showAsGrid = state.displayOverviewTasksAsGrid(mActivity.getDeviceProfile());
112         setter.setFloat(mRecentsView, RECENTS_GRID_PROGRESS, showAsGrid ? 1f : 0f,
113                 showAsGrid ? INSTANT : FINAL_FRAME);
114         setter.setFloat(mRecentsView, TASK_THUMBNAIL_SPLASH_ALPHA,
115                 state.showTaskThumbnailSplash() ? 1f : 0f, INSTANT);
116 
117         setter.setViewBackgroundColor(mActivity.getScrimView(), state.getScrimColor(mActivity),
118                 config.getInterpolator(ANIM_SCRIM_FADE, LINEAR));
119 
120         RecentsState currentState = mActivity.getStateManager().getState();
121         if (isSplitSelectionState(state) && !isSplitSelectionState(currentState)) {
122             int duration = state.getTransitionDuration(mActivity, true /* isToState */);
123             // TODO (b/246851887): Pass in setter as a NO_ANIM PendingAnimation instead
124             PendingAnimation pa = new PendingAnimation(duration);
125             mRecentsView.createSplitSelectInitAnimation(pa, duration);
126             setter.add(pa.buildAnim());
127         }
128 
129         Pair<FloatProperty, FloatProperty> taskViewsFloat =
130                 mRecentsView.getPagedOrientationHandler().getSplitSelectTaskOffset(
131                         TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
132                         mActivity.getDeviceProfile());
133         setter.setFloat(mRecentsView, taskViewsFloat.first, isSplitSelectionState(state)
134                 ? mRecentsView.getSplitSelectTranslation() : 0, LINEAR);
135         setter.setFloat(mRecentsView, taskViewsFloat.second, 0, LINEAR);
136     }
137 
138     /**
139      * @return true if {@param toState} is {@link RecentsState#OVERVIEW_SPLIT_SELECT}
140      */
isSplitSelectionState(@onNull RecentsState toState)141     private boolean isSplitSelectionState(@NonNull RecentsState toState) {
142         return toState == OVERVIEW_SPLIT_SELECT;
143     }
144 }
145