1 /* 2 * Copyright (C) 2019 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.systemui.shared.system; 18 19 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON; 20 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; 21 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; 22 23 import android.annotation.IntDef; 24 import android.content.Context; 25 import android.content.res.Resources; 26 import android.view.ViewConfiguration; 27 import android.view.WindowManagerPolicyConstants; 28 29 import com.android.internal.policy.ScreenDecorationsUtils; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 import java.util.StringJoiner; 34 35 /** 36 * Various shared constants between Launcher and SysUI as part of quickstep 37 */ 38 public class QuickStepContract { 39 // Fully qualified name of the Launcher activity. 40 public static final String LAUNCHER_ACTIVITY_CLASS_NAME = 41 "com.google.android.apps.nexuslauncher.NexusLauncherActivity"; 42 43 public static final String KEY_EXTRA_SYSUI_PROXY = "extra_sysui_proxy"; 44 public static final String KEY_EXTRA_WINDOW_CORNER_RADIUS = "extra_window_corner_radius"; 45 public static final String KEY_EXTRA_SUPPORTS_WINDOW_CORNERS = "extra_supports_window_corners"; 46 // See IPip.aidl 47 public static final String KEY_EXTRA_SHELL_PIP = "extra_shell_pip"; 48 // See ISplitScreen.aidl 49 public static final String KEY_EXTRA_SHELL_SPLIT_SCREEN = "extra_shell_split_screen"; 50 // See IOneHanded.aidl 51 public static final String KEY_EXTRA_SHELL_ONE_HANDED = "extra_shell_one_handed"; 52 // See IShellTransitions.aidl 53 public static final String KEY_EXTRA_SHELL_SHELL_TRANSITIONS = 54 "extra_shell_shell_transitions"; 55 // See IStartingWindow.aidl 56 public static final String KEY_EXTRA_SHELL_STARTING_WINDOW = 57 "extra_shell_starting_window"; 58 // See ISmartspaceTransitionController.aidl 59 public static final String KEY_EXTRA_SMARTSPACE_TRANSITION_CONTROLLER = "smartspace_transition"; 60 61 public static final String NAV_BAR_MODE_2BUTTON_OVERLAY = 62 WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY; 63 public static final String NAV_BAR_MODE_3BUTTON_OVERLAY = 64 WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY; 65 public static final String NAV_BAR_MODE_GESTURAL_OVERLAY = 66 WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY; 67 68 // Overview is disabled, either because the device is in lock task mode, or because the device 69 // policy has disabled the feature 70 public static final int SYSUI_STATE_SCREEN_PINNING = 1 << 0; 71 // The navigation bar is hidden due to immersive mode 72 public static final int SYSUI_STATE_NAV_BAR_HIDDEN = 1 << 1; 73 // The notification panel is expanded and interactive (either locked or unlocked), and the 74 // quick settings is not expanded 75 public static final int SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED = 1 << 2; 76 // The keyguard bouncer is showing 77 public static final int SYSUI_STATE_BOUNCER_SHOWING = 1 << 3; 78 // The navigation bar a11y button should be shown 79 public static final int SYSUI_STATE_A11Y_BUTTON_CLICKABLE = 1 << 4; 80 // The navigation bar a11y button shortcut is available 81 public static final int SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE = 1 << 5; 82 // The keyguard is showing and not occluded 83 public static final int SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING = 1 << 6; 84 // The recents feature is disabled (either by SUW/SysUI/device policy) 85 public static final int SYSUI_STATE_OVERVIEW_DISABLED = 1 << 7; 86 // The home feature is disabled (either by SUW/SysUI/device policy) 87 public static final int SYSUI_STATE_HOME_DISABLED = 1 << 8; 88 // The keyguard is showing, but occluded 89 public static final int SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED = 1 << 9; 90 // The search feature is disabled (either by SUW/SysUI/device policy) 91 public static final int SYSUI_STATE_SEARCH_DISABLED = 1 << 10; 92 // The notification panel is expanded and interactive (either locked or unlocked), and quick 93 // settings is expanded. 94 public static final int SYSUI_STATE_QUICK_SETTINGS_EXPANDED = 1 << 11; 95 // Winscope tracing is enabled 96 public static final int SYSUI_STATE_TRACING_ENABLED = 1 << 12; 97 // The Assistant gesture should be constrained. It is up to the launcher implementation to 98 // decide how to constrain it 99 public static final int SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED = 1 << 13; 100 // The bubble stack is expanded. This means that the home gesture should be ignored, since a 101 // swipe up is an attempt to close the bubble stack, but that the back gesture should remain 102 // enabled (since it's used to navigate back within the bubbled app, or to collapse the bubble 103 // stack. 104 public static final int SYSUI_STATE_BUBBLES_EXPANDED = 1 << 14; 105 // The global actions dialog is showing 106 public static final int SYSUI_STATE_GLOBAL_ACTIONS_SHOWING = 1 << 15; 107 // The one-handed mode is active 108 public static final int SYSUI_STATE_ONE_HANDED_ACTIVE = 1 << 16; 109 // Allow system gesture no matter the system bar(s) is visible or not 110 public static final int SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY = 1 << 17; 111 // The IME is showing 112 public static final int SYSUI_STATE_IME_SHOWING = 1 << 18; 113 // The window magnification is overlapped with system gesture insets at the bottom. 114 public static final int SYSUI_STATE_MAGNIFICATION_OVERLAP = 1 << 19; 115 116 @Retention(RetentionPolicy.SOURCE) 117 @IntDef({SYSUI_STATE_SCREEN_PINNING, 118 SYSUI_STATE_NAV_BAR_HIDDEN, 119 SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED, 120 SYSUI_STATE_QUICK_SETTINGS_EXPANDED, 121 SYSUI_STATE_BOUNCER_SHOWING, 122 SYSUI_STATE_A11Y_BUTTON_CLICKABLE, 123 SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE, 124 SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING, 125 SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED, 126 SYSUI_STATE_OVERVIEW_DISABLED, 127 SYSUI_STATE_HOME_DISABLED, 128 SYSUI_STATE_SEARCH_DISABLED, 129 SYSUI_STATE_TRACING_ENABLED, 130 SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED, 131 SYSUI_STATE_BUBBLES_EXPANDED, 132 SYSUI_STATE_GLOBAL_ACTIONS_SHOWING, 133 SYSUI_STATE_ONE_HANDED_ACTIVE, 134 SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY, 135 SYSUI_STATE_IME_SHOWING, 136 SYSUI_STATE_MAGNIFICATION_OVERLAP 137 }) 138 public @interface SystemUiStateFlags {} 139 getSystemUiStateString(int flags)140 public static String getSystemUiStateString(int flags) { 141 StringJoiner str = new StringJoiner("|"); 142 str.add((flags & SYSUI_STATE_SCREEN_PINNING) != 0 ? "screen_pinned" : ""); 143 str.add((flags & SYSUI_STATE_OVERVIEW_DISABLED) != 0 ? "overview_disabled" : ""); 144 str.add((flags & SYSUI_STATE_HOME_DISABLED) != 0 ? "home_disabled" : ""); 145 str.add((flags & SYSUI_STATE_SEARCH_DISABLED) != 0 ? "search_disabled" : ""); 146 str.add((flags & SYSUI_STATE_NAV_BAR_HIDDEN) != 0 ? "navbar_hidden" : ""); 147 str.add((flags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0 ? "notif_visible" : ""); 148 str.add((flags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) != 0 ? "qs_visible" : ""); 149 str.add((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) != 0 ? "keygrd_visible" : ""); 150 str.add((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0 151 ? "keygrd_occluded" : ""); 152 str.add((flags & SYSUI_STATE_BOUNCER_SHOWING) != 0 ? "bouncer_visible" : ""); 153 str.add((flags & SYSUI_STATE_GLOBAL_ACTIONS_SHOWING) != 0 ? "global_actions" : ""); 154 str.add((flags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0 ? "a11y_click" : ""); 155 str.add((flags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0 ? "a11y_long_click" : ""); 156 str.add((flags & SYSUI_STATE_TRACING_ENABLED) != 0 ? "tracing" : ""); 157 str.add((flags & SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED) != 0 158 ? "asst_gesture_constrain" : ""); 159 str.add((flags & SYSUI_STATE_BUBBLES_EXPANDED) != 0 ? "bubbles_expanded" : ""); 160 str.add((flags & SYSUI_STATE_ONE_HANDED_ACTIVE) != 0 ? "one_handed_active" : ""); 161 str.add((flags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0 162 ? "allow_gesture" : ""); 163 str.add((flags & SYSUI_STATE_IME_SHOWING) != 0 ? "ime_visible" : ""); 164 str.add((flags & SYSUI_STATE_MAGNIFICATION_OVERLAP) != 0 ? "magnification_overlap" : ""); 165 return str.toString(); 166 } 167 168 /** 169 * Ratio of quickstep touch slop (when system takes over the touch) to view touch slop 170 */ 171 public static final float QUICKSTEP_TOUCH_SLOP_RATIO = 3; 172 173 /** 174 * Touch slop for quickstep gesture 175 */ getQuickStepTouchSlopPx(Context context)176 public static final float getQuickStepTouchSlopPx(Context context) { 177 return QUICKSTEP_TOUCH_SLOP_RATIO * ViewConfiguration.get(context).getScaledTouchSlop(); 178 } 179 180 /** 181 * Touch slopes and thresholds for quick step operations. Drag slop is the point where the 182 * home button press/long press over are ignored and will start to drag when exceeded and the 183 * touch slop is when the respected operation will occur when exceeded. Touch slop must be 184 * larger than the drag slop. 185 */ getQuickStepDragSlopPx()186 public static int getQuickStepDragSlopPx() { 187 return convertDpToPixel(10); 188 } 189 getQuickStepTouchSlopPx()190 public static int getQuickStepTouchSlopPx() { 191 return convertDpToPixel(24); 192 } 193 getQuickScrubTouchSlopPx()194 public static int getQuickScrubTouchSlopPx() { 195 return convertDpToPixel(24); 196 } 197 convertDpToPixel(float dp)198 private static int convertDpToPixel(float dp) { 199 return (int) (dp * Resources.getSystem().getDisplayMetrics().density); 200 } 201 202 /** 203 * Returns whether the specified sysui state is such that the assistant gesture should be 204 * disabled. 205 */ isAssistantGestureDisabled(int sysuiStateFlags)206 public static boolean isAssistantGestureDisabled(int sysuiStateFlags) { 207 if ((sysuiStateFlags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0) { 208 sysuiStateFlags &= ~SYSUI_STATE_NAV_BAR_HIDDEN; 209 } 210 // Disable when in quick settings, screen pinning, immersive, the bouncer is showing, 211 // or search is disabled 212 int disableFlags = SYSUI_STATE_SCREEN_PINNING 213 | SYSUI_STATE_NAV_BAR_HIDDEN 214 | SYSUI_STATE_BOUNCER_SHOWING 215 | SYSUI_STATE_SEARCH_DISABLED 216 | SYSUI_STATE_QUICK_SETTINGS_EXPANDED; 217 if ((sysuiStateFlags & disableFlags) != 0) { 218 return true; 219 } 220 221 // Disable when notifications are showing (only if unlocked) 222 if ((sysuiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0 223 && (sysuiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) == 0) { 224 return true; 225 } 226 227 return false; 228 } 229 230 /** 231 * Returns whether the specified sysui state is such that the back gesture should be 232 * disabled. 233 */ isBackGestureDisabled(int sysuiStateFlags)234 public static boolean isBackGestureDisabled(int sysuiStateFlags) { 235 // Always allow when the bouncer/global actions is showing (even on top of the keyguard) 236 if ((sysuiStateFlags & SYSUI_STATE_BOUNCER_SHOWING) != 0 237 || (sysuiStateFlags & SYSUI_STATE_GLOBAL_ACTIONS_SHOWING) != 0) { 238 return false; 239 } 240 if ((sysuiStateFlags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0) { 241 sysuiStateFlags &= ~SYSUI_STATE_NAV_BAR_HIDDEN; 242 } 243 // Disable when in immersive, or the notifications are interactive 244 int disableFlags = SYSUI_STATE_NAV_BAR_HIDDEN 245 | SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED 246 | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING; 247 return (sysuiStateFlags & disableFlags) != 0; 248 } 249 250 /** 251 * @return whether this nav bar mode is edge to edge 252 */ isGesturalMode(int mode)253 public static boolean isGesturalMode(int mode) { 254 return mode == NAV_BAR_MODE_GESTURAL; 255 } 256 257 /** 258 * @return whether this nav bar mode is swipe up 259 */ isSwipeUpMode(int mode)260 public static boolean isSwipeUpMode(int mode) { 261 return mode == NAV_BAR_MODE_2BUTTON; 262 } 263 264 /** 265 * @return whether this nav bar mode is 3 button 266 */ isLegacyMode(int mode)267 public static boolean isLegacyMode(int mode) { 268 return mode == NAV_BAR_MODE_3BUTTON; 269 } 270 271 /** 272 * Corner radius that should be used on windows in order to cover the display. 273 * These values are expressed in pixels because they should not respect display or font 274 * scaling, this means that we don't have to reload them on config changes. 275 */ getWindowCornerRadius(Resources resources)276 public static float getWindowCornerRadius(Resources resources) { 277 return ScreenDecorationsUtils.getWindowCornerRadius(resources); 278 } 279 280 /** 281 * If live rounded corners are supported on windows. 282 */ supportsRoundedCornersOnWindows(Resources resources)283 public static boolean supportsRoundedCornersOnWindows(Resources resources) { 284 return ScreenDecorationsUtils.supportsRoundedCornersOnWindows(resources); 285 } 286 } 287