diff --git a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java new file mode 100644 index 0000000000..0c8952d705 --- /dev/null +++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.statehandlers; + +import android.os.SystemProperties; +import android.view.View; + +import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherState; +import com.android.launcher3.statemanager.StatefulActivity; +import com.android.launcher3.uioverrides.QuickstepLauncher; + +/** + * Controls the visibility of the workspace and the resumed / paused state when desktop mode + * is enabled. + */ +public class DesktopVisibilityController { + + private final Launcher mLauncher; + + private boolean mFreeformTasksVisible; + private boolean mInOverviewState; + + public DesktopVisibilityController(Launcher launcher) { + mLauncher = launcher; + } + + /** + * Whether desktop mode is supported. + */ + private boolean isDesktopModeSupported() { + return SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false); + } + + /** + * Whether freeform windows are visible in desktop mode. + */ + public boolean areFreeformTasksVisible() { + return mFreeformTasksVisible; + } + + /** + * Sets whether freeform windows are visible and updates launcher visibility based on that. + */ + public void setFreeformTasksVisible(boolean freeformTasksVisible) { + if (freeformTasksVisible != mFreeformTasksVisible) { + mFreeformTasksVisible = freeformTasksVisible; + updateLauncherVisibility(); + } + } + + /** + * Sets whether the overview is visible and updates launcher visibility based on that. + */ + public void setOverviewStateEnabled(boolean overviewStateEnabled) { + if (overviewStateEnabled != mInOverviewState) { + mInOverviewState = overviewStateEnabled; + updateLauncherVisibility(); + } + } + + /** + * Updates launcher visibility and state to look like it is paused or resumed depending on + * whether freeform windows are showing in desktop mode. + */ + private void updateLauncherVisibility() { + StatefulActivity activity = + QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity(); + View workspaceView = mLauncher.getWorkspace(); + if (activity == null || workspaceView == null || !isDesktopModeSupported()) return; + + if (mFreeformTasksVisible) { + workspaceView.setVisibility(View.INVISIBLE); + if (!mInOverviewState) { + // When freeform is visible & we're not in overview, we want launcher to appear + // paused, this ensures that taskbar displays. + activity.setPaused(); + } + } else { + workspaceView.setVisibility(View.VISIBLE); + // If freeform isn't visible ensure that launcher appears resumed to behave normally. + activity.setResumed(); + } + } +} diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 3203f44ce2..4d96bf73a0 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -96,6 +96,7 @@ import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.proxy.ProxyActivityStarter; import com.android.launcher3.proxy.StartActivityParams; import com.android.launcher3.statehandlers.DepthController; +import com.android.launcher3.statehandlers.DesktopVisibilityController; import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.taskbar.LauncherTaskbarUIController; @@ -167,6 +168,7 @@ public class QuickstepLauncher extends Launcher { private FixedContainerItems mAllAppsPredictions; private HotseatPredictionController mHotseatPredictionController; private DepthController mDepthController; + private DesktopVisibilityController mDesktopVisibilityController; private QuickstepTransitionManager mAppTransitionManager; private OverviewActionsView mActionsView; private TISBindHelper mTISBindHelper; @@ -207,6 +209,7 @@ public class QuickstepLauncher extends Launcher { mTISBindHelper = new TISBindHelper(this, this::onTISConnected); mDepthController = new DepthController(this); + mDesktopVisibilityController = new DesktopVisibilityController(this); mHotseatPredictionController = new HotseatPredictionController(this); mEnableWidgetDepth = ENABLE_WIDGET_PICKER_DEPTH.get() @@ -732,6 +735,10 @@ public class QuickstepLauncher extends Launcher { return mDepthController; } + public DesktopVisibilityController getDesktopVisibilityController() { + return mDesktopVisibilityController; + } + @Nullable public UnfoldTransitionProgressProvider getUnfoldTransitionProgressProvider() { return mUnfoldTransitionProgressProvider; diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 07ddcc8b31..59e786c5ec 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -1882,10 +1882,16 @@ public abstract class AbsSwipeUpHandler, } private void finishCurrentTransitionToRecents() { - // TODO(b/245569277#comment2): enable once isFreeformActive is implemented - mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED); - if (mRecentsAnimationController != null) { - mRecentsAnimationController.detachNavigationBarFromApp(true); + if (mRecentsAnimationController != null + && mActivityInterface.getDesktopVisibilityController() != null + && mActivityInterface.getDesktopVisibilityController().areFreeformTasksVisible()) { + mRecentsAnimationController.finish(true /* toRecents */, + () -> mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED)); + } else { + mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED); + if (mRecentsAnimationController != null) { + mRecentsAnimationController.detachNavigationBarFromApp(true); + } } ActiveGestureLog.INSTANCE.addLog( /* event= */ "finishRecentsAnimation", diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index d4320043b0..294fa90ae4 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -50,6 +50,7 @@ import com.android.launcher3.R; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.statehandlers.DepthController; +import com.android.launcher3.statehandlers.DesktopVisibilityController; import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.taskbar.TaskbarUIController; @@ -141,6 +142,11 @@ public abstract class BaseActivityInterface