1 /* 2 * Copyright (C) 2021 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.launcher3.taskbar; 17 18 import static com.android.launcher3.Utilities.isRunningInTestHarness; 19 import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP; 20 import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_STASHED_LAUNCHER_STATE; 21 22 import android.animation.Animator; 23 24 import androidx.annotation.Nullable; 25 26 import com.android.launcher3.popup.SystemShortcut; 27 import com.android.launcher3.statemanager.StateManager; 28 import com.android.quickstep.RecentsActivity; 29 import com.android.quickstep.TopTaskTracker; 30 import com.android.quickstep.fallback.RecentsState; 31 import com.android.quickstep.util.TISBindHelper; 32 import com.android.quickstep.views.RecentsView; 33 34 import java.util.stream.Stream; 35 36 /** 37 * A data source which integrates with the fallback RecentsActivity instance (for 3P launchers). 38 */ 39 public class FallbackTaskbarUIController extends TaskbarUIController { 40 41 private final RecentsActivity mRecentsActivity; 42 43 private final StateManager.StateListener<RecentsState> mStateListener = 44 new StateManager.StateListener<RecentsState>() { 45 @Override 46 public void onStateTransitionStart(RecentsState toState) { 47 animateToRecentsState(toState); 48 49 // Handle tapping on live tile. 50 getRecentsView().setTaskLaunchListener(toState == RecentsState.DEFAULT 51 ? (() -> animateToRecentsState(RecentsState.BACKGROUND_APP)) : null); 52 } 53 54 @Override 55 public void onStateTransitionComplete(RecentsState finalState) { 56 boolean finalStateDefault = finalState == RecentsState.DEFAULT; 57 // TODO(b/268120202) Taskbar shows up on 3P home, currently we don't go to 58 // overview from 3P home. Either implement that or it'll change w/ contextual? 59 boolean disallowLongClick = finalState == RecentsState.OVERVIEW_SPLIT_SELECT; 60 Utilities.setOverviewDragState(mControllers, 61 finalStateDefault /*disallowGlobalDrag*/, disallowLongClick, 62 finalStateDefault /*allowInitialSplitSelection*/); 63 } 64 }; 65 FallbackTaskbarUIController(RecentsActivity recentsActivity)66 public FallbackTaskbarUIController(RecentsActivity recentsActivity) { 67 mRecentsActivity = recentsActivity; 68 } 69 70 @Override init(TaskbarControllers taskbarControllers)71 protected void init(TaskbarControllers taskbarControllers) { 72 super.init(taskbarControllers); 73 74 mRecentsActivity.setTaskbarUIController(this); 75 mRecentsActivity.getStateManager().addStateListener(mStateListener); 76 } 77 78 @Override onDestroy()79 protected void onDestroy() { 80 super.onDestroy(); 81 mRecentsActivity.setTaskbarUIController(null); 82 mRecentsActivity.getStateManager().removeStateListener(mStateListener); 83 } 84 85 /** 86 * Creates an animation to animate the taskbar for the given state (but does not start it). 87 * Currently this animation just force stashes the taskbar in Overview. 88 */ createAnimToRecentsState(RecentsState toState, long duration)89 public Animator createAnimToRecentsState(RecentsState toState, long duration) { 90 // Force stash taskbar (disallow unstashing) when: 91 // - in a 3P launcher or overview task. 92 // - not running in a test harness (unstash is needed for tests) 93 boolean forceStash = isIn3pHomeOrRecents() && !isRunningInTestHarness(); 94 TaskbarStashController stashController = mControllers.taskbarStashController; 95 // Set both FLAG_IN_STASHED_LAUNCHER_STATE and FLAG_IN_APP to ensure the state is respected. 96 // For all other states, just use the current stashed-in-app setting (e.g. if long clicked). 97 stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, forceStash); 98 stashController.updateStateForFlag(FLAG_IN_APP, !forceStash); 99 return stashController.createApplyStateAnimator(duration); 100 } 101 animateToRecentsState(RecentsState toState)102 private void animateToRecentsState(RecentsState toState) { 103 Animator anim = createAnimToRecentsState(toState, 104 mControllers.taskbarStashController.getStashDuration()); 105 if (anim != null) { 106 anim.start(); 107 } 108 } 109 110 @Override getRecentsView()111 public RecentsView getRecentsView() { 112 return mRecentsActivity.getOverviewPanel(); 113 } 114 115 @Override getSplitMenuOptions()116 Stream<SystemShortcut.Factory<BaseTaskbarContext>> getSplitMenuOptions() { 117 if (isIn3pHomeOrRecents()) { 118 // Split from Taskbar is not supported in fallback launcher, so return empty stream 119 return Stream.empty(); 120 } else { 121 return super.getSplitMenuOptions(); 122 } 123 } 124 isIn3pHomeOrRecents()125 private boolean isIn3pHomeOrRecents() { 126 TopTaskTracker.CachedTaskInfo topTask = TopTaskTracker.INSTANCE 127 .get(mControllers.taskbarActivityContext).getCachedTopTask(true); 128 return topTask.isHomeTask() || topTask.isRecentsTask(); 129 } 130 131 @Nullable 132 @Override getTISBindHelper()133 protected TISBindHelper getTISBindHelper() { 134 return mRecentsActivity.getTISBindHelper(); 135 } 136 137 @Override getTaskbarUIControllerName()138 protected String getTaskbarUIControllerName() { 139 return "FallbackTaskbarUIController"; 140 } 141 } 142