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 17 package com.android.wm.shell.shared; 18 19 import android.annotation.NonNull; 20 import android.content.Context; 21 import android.os.SystemProperties; 22 23 import com.android.internal.R; 24 import com.android.internal.annotations.VisibleForTesting; 25 import com.android.window.flags.Flags; 26 27 /** 28 * Constants for desktop mode feature 29 */ 30 public class DesktopModeStatus { 31 32 /** 33 * Flag to indicate whether task resizing is veiled. 34 */ 35 private static final boolean IS_VEILED_RESIZE_ENABLED = SystemProperties.getBoolean( 36 "persist.wm.debug.desktop_veiled_resizing", true); 37 38 /** 39 * Flag to indicate is moving task to another display is enabled. 40 */ 41 public static final boolean IS_DISPLAY_CHANGE_ENABLED = SystemProperties.getBoolean( 42 "persist.wm.debug.desktop_change_display", false); 43 44 /** 45 * Flag to indicate whether to apply shadows to windows in desktop mode. 46 */ 47 private static final boolean USE_WINDOW_SHADOWS = SystemProperties.getBoolean( 48 "persist.wm.debug.desktop_use_window_shadows", true); 49 50 /** 51 * Flag to indicate whether to apply shadows to the focused window in desktop mode. 52 * 53 * Note: this flag is only relevant if USE_WINDOW_SHADOWS is false. 54 */ 55 private static final boolean USE_WINDOW_SHADOWS_FOCUSED_WINDOW = SystemProperties.getBoolean( 56 "persist.wm.debug.desktop_use_window_shadows_focused_window", false); 57 58 /** 59 * Flag to indicate whether to use rounded corners for windows in desktop mode. 60 */ 61 private static final boolean USE_ROUNDED_CORNERS = SystemProperties.getBoolean( 62 "persist.wm.debug.desktop_use_rounded_corners", true); 63 64 /** 65 * Flag to indicate whether to restrict desktop mode to supported devices. 66 */ 67 private static final boolean ENFORCE_DEVICE_RESTRICTIONS = SystemProperties.getBoolean( 68 "persist.wm.debug.desktop_mode_enforce_device_restrictions", true); 69 70 /** Whether the desktop density override is enabled. */ 71 public static final boolean DESKTOP_DENSITY_OVERRIDE_ENABLED = 72 SystemProperties.getBoolean("persist.wm.debug.desktop_mode_density_enabled", false); 73 74 /** Override density for tasks when they're inside the desktop. */ 75 public static final int DESKTOP_DENSITY_OVERRIDE = 76 SystemProperties.getInt("persist.wm.debug.desktop_mode_density", 284); 77 78 /** The minimum override density allowed for tasks inside the desktop. */ 79 private static final int DESKTOP_DENSITY_MIN = 100; 80 81 /** The maximum override density allowed for tasks inside the desktop. */ 82 private static final int DESKTOP_DENSITY_MAX = 1000; 83 84 /** 85 * Default value for {@code MAX_TASK_LIMIT}. 86 */ 87 @VisibleForTesting 88 public static final int DEFAULT_MAX_TASK_LIMIT = 4; 89 90 // TODO(b/335131008): add a config-overlay field for the max number of tasks in Desktop Mode 91 /** 92 * Flag declaring the maximum number of Tasks to show in Desktop Mode at any one time. 93 * 94 * <p> The limit does NOT affect Picture-in-Picture, Bubbles, or System Modals (like a screen 95 * recording window, or Bluetooth pairing window). 96 */ 97 private static final int MAX_TASK_LIMIT = SystemProperties.getInt( 98 "persist.wm.debug.desktop_max_task_limit", DEFAULT_MAX_TASK_LIMIT); 99 100 /** 101 * Return {@code true} if desktop windowing is enabled. Only to be used for testing. Callers 102 * should use {@link #canEnterDesktopMode(Context)} to query the state of desktop windowing. 103 */ 104 @VisibleForTesting isEnabled()105 public static boolean isEnabled() { 106 return Flags.enableDesktopWindowingMode(); 107 } 108 109 /** 110 * Return {@code true} if veiled resizing is active. If false, fluid resizing is used. 111 */ isVeiledResizeEnabled()112 public static boolean isVeiledResizeEnabled() { 113 return IS_VEILED_RESIZE_ENABLED; 114 } 115 116 /** 117 * Return whether to use window shadows. 118 * 119 * @param isFocusedWindow whether the window to apply shadows to is focused 120 */ useWindowShadow(boolean isFocusedWindow)121 public static boolean useWindowShadow(boolean isFocusedWindow) { 122 return USE_WINDOW_SHADOWS 123 || (USE_WINDOW_SHADOWS_FOCUSED_WINDOW && isFocusedWindow); 124 } 125 126 /** 127 * Return whether to use rounded corners for windows. 128 */ useRoundedCorners()129 public static boolean useRoundedCorners() { 130 return USE_ROUNDED_CORNERS; 131 } 132 133 /** 134 * Return {@code true} if desktop mode should be restricted to supported devices. 135 */ 136 @VisibleForTesting enforceDeviceRestrictions()137 public static boolean enforceDeviceRestrictions() { 138 return ENFORCE_DEVICE_RESTRICTIONS; 139 } 140 141 /** 142 * Return the maximum limit on the number of Tasks to show in Desktop Mode at any one time. 143 */ getMaxTaskLimit()144 public static int getMaxTaskLimit() { 145 return MAX_TASK_LIMIT; 146 } 147 148 /** 149 * Return {@code true} if the current device supports desktop mode. 150 */ 151 @VisibleForTesting isDesktopModeSupported(@onNull Context context)152 public static boolean isDesktopModeSupported(@NonNull Context context) { 153 return context.getResources().getBoolean(R.bool.config_isDesktopModeSupported); 154 } 155 156 /** 157 * Return {@code true} if desktop mode is enabled and can be entered on the current device. 158 */ canEnterDesktopMode(@onNull Context context)159 public static boolean canEnterDesktopMode(@NonNull Context context) { 160 return (!enforceDeviceRestrictions() || isDesktopModeSupported(context)) && isEnabled(); 161 } 162 163 /** 164 * Return {@code true} if the override desktop density is enabled and valid. 165 */ useDesktopOverrideDensity()166 public static boolean useDesktopOverrideDensity() { 167 return isDesktopDensityOverrideEnabled() && isValidDesktopDensityOverrideSet(); 168 } 169 170 /** 171 * Return {@code true} if the override desktop density is enabled. 172 */ isDesktopDensityOverrideEnabled()173 private static boolean isDesktopDensityOverrideEnabled() { 174 return DESKTOP_DENSITY_OVERRIDE_ENABLED; 175 } 176 177 /** 178 * Return {@code true} if the override desktop density is set and within a valid range. 179 */ isValidDesktopDensityOverrideSet()180 private static boolean isValidDesktopDensityOverrideSet() { 181 return DESKTOP_DENSITY_OVERRIDE >= DESKTOP_DENSITY_MIN 182 && DESKTOP_DENSITY_OVERRIDE <= DESKTOP_DENSITY_MAX; 183 } 184 } 185