• 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 package com.android.quickstep;
17 
18 import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
19 import static com.android.quickstep.fallback.RecentsState.BACKGROUND_APP;
20 import static com.android.quickstep.fallback.RecentsState.DEFAULT;
21 import static com.android.quickstep.fallback.RecentsState.HOME;
22 
23 import android.animation.Animator;
24 import android.animation.AnimatorSet;
25 import android.content.Context;
26 import android.graphics.Rect;
27 import android.view.MotionEvent;
28 import android.view.RemoteAnimationTarget;
29 
30 import androidx.annotation.Nullable;
31 
32 import com.android.launcher3.DeviceProfile;
33 import com.android.launcher3.statemanager.StateManager;
34 import com.android.launcher3.taskbar.FallbackTaskbarUIController;
35 import com.android.launcher3.util.DisplayController;
36 import com.android.quickstep.GestureState.GestureEndTarget;
37 import com.android.quickstep.fallback.RecentsState;
38 import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
39 import com.android.quickstep.util.ActivityInitListener;
40 import com.android.quickstep.util.AnimatorControllerWithResistance;
41 import com.android.quickstep.views.RecentsView;
42 
43 import java.util.function.Consumer;
44 import java.util.function.Predicate;
45 
46 /**
47  * {@link BaseActivityInterface} for recents when the default launcher is different than the
48  * currently running one and apps should interact with the {@link RecentsActivity} as opposed
49  * to the in-launcher one.
50  */
51 public final class FallbackActivityInterface extends
52         BaseActivityInterface<RecentsState, RecentsActivity> {
53 
54     public static final FallbackActivityInterface INSTANCE = new FallbackActivityInterface();
55 
FallbackActivityInterface()56     private FallbackActivityInterface() {
57         super(false, DEFAULT, BACKGROUND_APP);
58     }
59 
60     /** 2 */
61     @Override
getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect, RecentsPagedOrientationHandler orientationHandler)62     public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect,
63             RecentsPagedOrientationHandler orientationHandler) {
64         calculateTaskSize(context, dp, outRect, orientationHandler);
65         if (dp.isVerticalBarLayout() && DisplayController.getNavigationMode(context) != NO_BUTTON) {
66             return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
67         } else {
68             return dp.heightPx - outRect.bottom;
69         }
70     }
71 
72     /** 5 */
73     @Override
onAssistantVisibilityChanged(float visibility)74     public void onAssistantVisibilityChanged(float visibility) {
75         // This class becomes active when the screen is locked.
76         // Rather than having it handle assistant visibility changes, the assistant visibility is
77         // set to zero prior to this class becoming active.
78     }
79 
80     /** 6 */
81     @Override
prepareRecentsUI(RecentsAnimationDeviceState deviceState, boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback)82     public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
83             boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback) {
84         notifyRecentsOfOrientation(deviceState.getRotationTouchHelper());
85         DefaultAnimationFactory factory = new DefaultAnimationFactory(callback);
86         factory.initBackgroundStateUI();
87         return factory;
88     }
89 
90     @Override
createActivityInitListener( Predicate<Boolean> onInitListener)91     public ActivityInitListener createActivityInitListener(
92             Predicate<Boolean> onInitListener) {
93         return new ActivityInitListener<>((activity, alreadyOnHome) ->
94                 onInitListener.test(alreadyOnHome), RecentsActivity.ACTIVITY_TRACKER);
95     }
96 
97     @Nullable
98     @Override
getCreatedContainer()99     public RecentsActivity getCreatedContainer() {
100         return RecentsActivity.ACTIVITY_TRACKER.getCreatedActivity();
101     }
102 
103     @Override
getTaskbarController()104     public FallbackTaskbarUIController getTaskbarController() {
105         RecentsActivity activity = getCreatedContainer();
106         if (activity == null) {
107             return null;
108         }
109         return activity.getTaskbarUIController();
110     }
111 
112     @Nullable
113     @Override
getVisibleRecentsView()114     public RecentsView getVisibleRecentsView() {
115         RecentsActivity activity = getCreatedContainer();
116         if (activity != null) {
117             if (activity.hasBeenResumed() || isInLiveTileMode()) {
118                 return activity.getOverviewPanel();
119             }
120         }
121         return null;
122     }
123 
124     @Override
switchToRecentsIfVisible(Animator.AnimatorListener animatorListener)125     public boolean switchToRecentsIfVisible(Animator.AnimatorListener animatorListener) {
126         return false;
127     }
128 
129     @Override
getOverviewWindowBounds(Rect homeBounds, RemoteAnimationTarget target)130     public Rect getOverviewWindowBounds(Rect homeBounds, RemoteAnimationTarget target) {
131         // TODO: Remove this once b/77875376 is fixed
132         return target.screenSpaceBounds;
133     }
134 
135     @Override
allowMinimizeSplitScreen()136     public boolean allowMinimizeSplitScreen() {
137         // TODO: Remove this once b/77875376 is fixed
138         return false;
139     }
140 
141     @Override
allowAllAppsFromOverview()142     public boolean allowAllAppsFromOverview() {
143         return false;
144     }
145 
146     @Override
deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev)147     public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
148         // In non-gesture mode, user might be clicking on the home button which would directly
149         // start the home activity instead of going through recents. In that case, defer starting
150         // recents until we are sure it is a gesture.
151         return !deviceState.isFullyGesturalNavMode()
152                 || super.deferStartingActivity(deviceState, ev);
153     }
154 
155     @Override
onExitOverview(RotationTouchHelper deviceState, Runnable exitRunnable)156     public void onExitOverview(RotationTouchHelper deviceState, Runnable exitRunnable) {
157         final StateManager<RecentsState, RecentsActivity> stateManager =
158                 getCreatedContainer().getStateManager();
159         if (stateManager.getState() == HOME) {
160             exitRunnable.run();
161             notifyRecentsOfOrientation(deviceState);
162             return;
163         }
164 
165         stateManager.addStateListener(
166                 new StateManager.StateListener<RecentsState>() {
167                     @Override
168                     public void onStateTransitionComplete(RecentsState toState) {
169                         // Are we going from Recents to Workspace?
170                         if (toState == HOME) {
171                             exitRunnable.run();
172                             notifyRecentsOfOrientation(deviceState);
173                             stateManager.removeStateListener(this);
174                         }
175                     }
176                 });
177     }
178 
179     @Override
isInLiveTileMode()180     public boolean isInLiveTileMode() {
181         RecentsActivity activity = getCreatedContainer();
182         return activity != null && activity.getStateManager().getState() == DEFAULT &&
183                 activity.isStarted();
184     }
185 
186     @Override
onLaunchTaskFailed()187     public void onLaunchTaskFailed() {
188         // TODO: probably go back to overview instead.
189         RecentsActivity activity = getCreatedContainer();
190         if (activity == null) {
191             return;
192         }
193         activity.<RecentsView>getOverviewPanel().startHome();
194     }
195 
196     @Override
stateFromGestureEndTarget(GestureEndTarget endTarget)197     public RecentsState stateFromGestureEndTarget(GestureEndTarget endTarget) {
198         switch (endTarget) {
199             case RECENTS:
200                 return DEFAULT;
201             case NEW_TASK:
202             case LAST_TASK:
203                 return BACKGROUND_APP;
204             case HOME:
205             case ALL_APPS:
206             default:
207                 return HOME;
208         }
209     }
210 
notifyRecentsOfOrientation(RotationTouchHelper rotationTouchHelper)211     private void notifyRecentsOfOrientation(RotationTouchHelper rotationTouchHelper) {
212         // reset layout on swipe to home
213         RecentsView recentsView = getCreatedContainer().getOverviewPanel();
214         recentsView.setLayoutRotation(rotationTouchHelper.getCurrentActiveRotation(),
215                 rotationTouchHelper.getDisplayRotation());
216     }
217 
218     @Override
getParallelAnimationToLauncher(GestureEndTarget endTarget, long duration, RecentsAnimationCallbacks callbacks)219     public @Nullable Animator getParallelAnimationToLauncher(GestureEndTarget endTarget,
220             long duration, RecentsAnimationCallbacks callbacks) {
221         FallbackTaskbarUIController uiController = getTaskbarController();
222         Animator superAnimator = super.getParallelAnimationToLauncher(
223                 endTarget, duration, callbacks);
224         if (uiController == null) {
225             return superAnimator;
226         }
227         RecentsState toState = stateFromGestureEndTarget(endTarget);
228         Animator taskbarAnimator = uiController.createAnimToRecentsState(toState, duration);
229         if (taskbarAnimator == null) {
230             return superAnimator;
231         }
232         if (superAnimator == null) {
233             return taskbarAnimator;
234         }
235         AnimatorSet animatorSet = new AnimatorSet();
236         animatorSet.playTogether(superAnimator, taskbarAnimator);
237         return animatorSet;
238     }
239 
240     @Override
getOverviewScrimColorForState(RecentsActivity activity, RecentsState state)241     protected int getOverviewScrimColorForState(RecentsActivity activity, RecentsState state) {
242         return state.getScrimColor(activity);
243     }
244 }
245