1 /* 2 * Copyright (C) 2022 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.statehandlers; 17 18 import android.os.SystemProperties; 19 import android.util.Log; 20 import android.view.View; 21 22 import com.android.launcher3.Launcher; 23 import com.android.launcher3.LauncherState; 24 import com.android.launcher3.statemanager.StatefulActivity; 25 import com.android.launcher3.uioverrides.QuickstepLauncher; 26 27 /** 28 * Controls the visibility of the workspace and the resumed / paused state when desktop mode 29 * is enabled. 30 */ 31 public class DesktopVisibilityController { 32 33 private static final String TAG = "DesktopVisController"; 34 private static final boolean DEBUG = false; 35 36 private final Launcher mLauncher; 37 38 private boolean mFreeformTasksVisible; 39 private boolean mInOverviewState; 40 private boolean mGestureInProgress; 41 DesktopVisibilityController(Launcher launcher)42 public DesktopVisibilityController(Launcher launcher) { 43 mLauncher = launcher; 44 } 45 46 /** 47 * Whether desktop mode is supported. 48 */ isDesktopModeSupported()49 private boolean isDesktopModeSupported() { 50 return SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false) 51 || SystemProperties.getBoolean("persist.wm.debug.desktop_mode_2", false); 52 } 53 54 /** 55 * Whether freeform windows are visible in desktop mode. 56 */ areFreeformTasksVisible()57 public boolean areFreeformTasksVisible() { 58 return mFreeformTasksVisible; 59 } 60 61 /** 62 * Sets whether freeform windows are visible and updates launcher visibility based on that. 63 */ setFreeformTasksVisible(boolean freeformTasksVisible)64 public void setFreeformTasksVisible(boolean freeformTasksVisible) { 65 if (DEBUG) { 66 Log.d(TAG, "setFreeformTasksVisible: visible=" + freeformTasksVisible); 67 } 68 if (!isDesktopModeSupported()) { 69 return; 70 } 71 if (freeformTasksVisible != mFreeformTasksVisible) { 72 mFreeformTasksVisible = freeformTasksVisible; 73 if (mFreeformTasksVisible) { 74 setLauncherViewsVisibility(View.INVISIBLE); 75 if (!mInOverviewState) { 76 // When freeform is visible & we're not in overview, we want launcher to appear 77 // paused, this ensures that taskbar displays. 78 markLauncherPaused(); 79 } 80 } else { 81 setLauncherViewsVisibility(View.VISIBLE); 82 // If freeform isn't visible ensure that launcher appears resumed to behave 83 // normally. 84 markLauncherResumed(); 85 } 86 } 87 } 88 89 /** 90 * Sets whether the overview is visible and updates launcher visibility based on that. 91 */ setOverviewStateEnabled(boolean overviewStateEnabled)92 public void setOverviewStateEnabled(boolean overviewStateEnabled) { 93 if (DEBUG) { 94 Log.d(TAG, "setOverviewStateEnabled: enabled=" + overviewStateEnabled); 95 } 96 if (!isDesktopModeSupported()) { 97 return; 98 } 99 if (overviewStateEnabled != mInOverviewState) { 100 mInOverviewState = overviewStateEnabled; 101 if (mInOverviewState) { 102 setLauncherViewsVisibility(View.VISIBLE); 103 markLauncherResumed(); 104 } else if (mFreeformTasksVisible) { 105 setLauncherViewsVisibility(View.INVISIBLE); 106 markLauncherPaused(); 107 } 108 } 109 } 110 111 /** 112 * Whether recents gesture is currently in progress. 113 */ isGestureInProgress()114 public boolean isGestureInProgress() { 115 return mGestureInProgress; 116 } 117 118 /** 119 * Sets whether recents gesture is in progress. 120 */ setGestureInProgress(boolean gestureInProgress)121 public void setGestureInProgress(boolean gestureInProgress) { 122 if (DEBUG) { 123 Log.d(TAG, "setGestureInProgress: inProgress=" + gestureInProgress); 124 } 125 if (!isDesktopModeSupported()) { 126 return; 127 } 128 if (gestureInProgress != mGestureInProgress) { 129 mGestureInProgress = gestureInProgress; 130 } 131 } 132 setLauncherViewsVisibility(int visibility)133 private void setLauncherViewsVisibility(int visibility) { 134 if (DEBUG) { 135 Log.d(TAG, "setLauncherViewsVisibility: visibility=" + visibility); 136 } 137 View workspaceView = mLauncher.getWorkspace(); 138 if (workspaceView != null) { 139 workspaceView.setVisibility(visibility); 140 } 141 View dragLayer = mLauncher.getDragLayer(); 142 if (dragLayer != null) { 143 dragLayer.setVisibility(visibility); 144 } 145 } 146 markLauncherPaused()147 private void markLauncherPaused() { 148 if (DEBUG) { 149 Log.d(TAG, "markLauncherPaused"); 150 } 151 StatefulActivity<LauncherState> activity = 152 QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity(); 153 if (activity != null) { 154 activity.setPaused(); 155 } 156 } 157 markLauncherResumed()158 private void markLauncherResumed() { 159 if (DEBUG) { 160 Log.d(TAG, "markLauncherResumed"); 161 } 162 StatefulActivity<LauncherState> activity = 163 QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity(); 164 // Check activity state before calling setResumed(). Launcher may have been actually 165 // paused (eg fullscreen task moved to front). 166 // In this case we should not mark the activity as resumed. 167 if (activity != null && activity.isResumed()) { 168 activity.setResumed(); 169 } 170 } 171 } 172