Fix invoking transient taskbar in desktop windowing prototypes

When transient taskbar is invoked, it starts the recents animation.
Recents animation triggers the launch of launcher activity. We need to
ensure that after recents animation is cancelled (since the gesture was
only for taskbar), we bring the desktop tasks back to front.

When the transient taskbar gesture finishes, we need to ensure that
launcher state is restored to normal. With fullscreen tasks, launcher
activity in stopped after gesture finishes as a fullscreen task is on
top. This stop triggers the launcher state to return to normal.
When freeform tasks are visible on top of launcher, launcher activity is
not stopped. This means we have to manually move launcher to normal
state after transient taskbar gesture finishes.

Bug: 267364407
Test: enable proto 1, switch to desktop mode and open some tasks, swipe
  up for transient taskbar, swipe up to recents view
Test: enable proto 2, move a task to desktop, swipe up for transient
  taskbar, swipe up to recents view
Change-Id: I712bc5086407c26779638d824f34674f7db1ff51
This commit is contained in:
Ats Jenk
2023-02-08 15:16:43 -08:00
parent f4fa65db39
commit d9f6d4e31c
6 changed files with 72 additions and 3 deletions
@@ -16,6 +16,7 @@
package com.android.launcher3.statehandlers;
import android.os.SystemProperties;
import android.util.Log;
import android.view.View;
import com.android.launcher3.Launcher;
@@ -29,6 +30,9 @@ import com.android.launcher3.uioverrides.QuickstepLauncher;
*/
public class DesktopVisibilityController {
private static final String TAG = "DesktopVisController";
private static final boolean DEBUG = false;
private final Launcher mLauncher;
private boolean mFreeformTasksVisible;
@@ -58,6 +62,9 @@ public class DesktopVisibilityController {
* Sets whether freeform windows are visible and updates launcher visibility based on that.
*/
public void setFreeformTasksVisible(boolean freeformTasksVisible) {
if (DEBUG) {
Log.d(TAG, "setFreeformTasksVisible: visible=" + freeformTasksVisible);
}
if (!isDesktopModeSupported()) {
return;
}
@@ -83,6 +90,9 @@ public class DesktopVisibilityController {
* Sets whether the overview is visible and updates launcher visibility based on that.
*/
public void setOverviewStateEnabled(boolean overviewStateEnabled) {
if (DEBUG) {
Log.d(TAG, "setOverviewStateEnabled: enabled=" + overviewStateEnabled);
}
if (!isDesktopModeSupported()) {
return;
}
@@ -109,6 +119,9 @@ public class DesktopVisibilityController {
* Sets whether recents gesture is in progress.
*/
public void setGestureInProgress(boolean gestureInProgress) {
if (DEBUG) {
Log.d(TAG, "setGestureInProgress: inProgress=" + gestureInProgress);
}
if (!isDesktopModeSupported()) {
return;
}
@@ -118,6 +131,9 @@ public class DesktopVisibilityController {
}
private void setLauncherViewsVisibility(int visibility) {
if (DEBUG) {
Log.d(TAG, "setLauncherViewsVisibility: visibility=" + visibility);
}
View workspaceView = mLauncher.getWorkspace();
if (workspaceView != null) {
workspaceView.setVisibility(visibility);
@@ -129,6 +145,9 @@ public class DesktopVisibilityController {
}
private void markLauncherPaused() {
if (DEBUG) {
Log.d(TAG, "markLauncherPaused");
}
StatefulActivity<LauncherState> activity =
QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity();
if (activity != null) {
@@ -137,6 +156,9 @@ public class DesktopVisibilityController {
}
private void markLauncherResumed() {
if (DEBUG) {
Log.d(TAG, "markLauncherResumed");
}
StatefulActivity<LauncherState> activity =
QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity();
// Check activity state before calling setResumed(). Launcher may have been actually
@@ -800,7 +800,7 @@ public class QuickstepLauncher extends Launcher {
@Override
public void setResumed() {
if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED) {
if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
DesktopVisibilityController controller = mDesktopVisibilityController;
if (controller != null && controller.areFreeformTasksVisible()
&& !controller.isGestureInProgress()) {
@@ -20,6 +20,7 @@ import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.quickstep.AbsSwipeUpHandler.RECENTS_ATTACH_DURATION;
import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM;
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_X_ANIM;
@@ -62,6 +63,7 @@ import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.views.ScrimView;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -107,6 +109,20 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
if (endTarget != null) {
// We were on our way to this state when we got canceled, end there instead.
startState = stateFromGestureEndTarget(endTarget);
if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
DesktopVisibilityController controller = getDesktopVisibilityController();
if (controller != null && controller.areFreeformTasksVisible()
&& endTarget == LAST_TASK) {
// When we are cancelling the transition and going back to last task, move to
// rest state instead when desktop tasks are visible.
// If a fullscreen task is visible, launcher goes to normal state when the
// activity is stopped. This does not happen when freeform tasks are visible
// on top of launcher. Force the launcher state to rest state here.
startState = activity.getStateManager().getRestState();
// Do not animate the transition
activityVisible = false;
}
}
}
activity.getStateManager().goToState(startState, activityVisible);
}
@@ -40,6 +40,7 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -238,6 +239,12 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
// to let the transition controller collect Home activity.
CachedTaskInfo cti = gestureState.getRunningTask();
boolean homeIsOnTop = cti != null && cti.isHomeTask();
if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
if (cti != null && cti.isFreeformTask()) {
// No transient launch when desktop task is on top
homeIsOnTop = true;
}
}
if (!homeIsOnTop) {
options.setTransientLaunch();
}
@@ -18,6 +18,7 @@ package com.android.quickstep;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.content.Intent.ACTION_CHOOSER;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -254,6 +255,15 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta
.getActivityType() == ACTIVITY_TYPE_HOME;
}
/**
* Returns {@code true} if this task windowing mode is set to {@link
* android.app.WindowConfiguration#WINDOWING_MODE_FREEFORM}
*/
public boolean isFreeformTask() {
return mTopTask != null && mTopTask.configuration.windowConfiguration.getWindowingMode()
== WINDOWING_MODE_FREEFORM;
}
/**
* Returns {@link Task} array which can be used as a placeholder until the true object
* is loaded by the model
@@ -41,8 +41,10 @@ import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.PendingSplitSelectInfo;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
import com.android.quickstep.GestureState;
import com.android.quickstep.LauncherActivityInterface;
import com.android.quickstep.RotationTouchHelper;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.SplitSelectStateController;
import com.android.systemui.shared.recents.model.Task;
@@ -222,11 +224,23 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
@Override
public void onGestureAnimationEnd() {
DesktopVisibilityController desktopVisibilityController = null;
boolean showDesktopApps = false;
if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
desktopVisibilityController = mActivity.getDesktopVisibilityController();
if (mCurrentGestureEndTarget == GestureState.GestureEndTarget.LAST_TASK
&& desktopVisibilityController.areFreeformTasksVisible()) {
// Recents gesture was cancelled and we are returning to the previous task.
// After super class has handled clean up, show desktop apps on top again
showDesktopApps = true;
}
}
super.onGestureAnimationEnd();
DesktopVisibilityController desktopVisibilityController =
mActivity.getDesktopVisibilityController();
if (desktopVisibilityController != null) {
desktopVisibilityController.setGestureInProgress(false);
}
if (showDesktopApps) {
SystemUiProxy.INSTANCE.get(mActivity).showDesktopApps();
}
}
}