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.os.SystemProperties; 27 import android.view.ViewConfiguration; 28 import android.view.WindowManagerPolicyConstants; 29 30 import com.android.internal.policy.ScreenDecorationsUtils; 31 32 import java.lang.annotation.Retention; 33 import java.lang.annotation.RetentionPolicy; 34 import java.util.StringJoiner; 35 36 /** 37 * Various shared constants between Launcher and SysUI as part of quickstep 38 */ 39 public class QuickStepContract { 40 // Fully qualified name of the Launcher activity. 41 public static final String LAUNCHER_ACTIVITY_CLASS_NAME = 42 "com.google.android.apps.nexuslauncher.NexusLauncherActivity"; 43 44 public static final String KEY_EXTRA_SYSUI_PROXY = "extra_sysui_proxy"; 45 public static final String KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER = "extra_unfold_animation"; 46 // See ISysuiUnlockAnimationController.aidl 47 public static final String KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER = "unlock_animation"; 48 49 public static final String NAV_BAR_MODE_3BUTTON_OVERLAY = 50 WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY; 51 public static final String NAV_BAR_MODE_GESTURAL_OVERLAY = 52 WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY; 53 54 // Overview is disabled, either because the device is in lock task mode, or because the device 55 // policy has disabled the feature 56 public static final int SYSUI_STATE_SCREEN_PINNING = 1 << 0; 57 // The navigation bar is hidden due to immersive mode 58 public static final int SYSUI_STATE_NAV_BAR_HIDDEN = 1 << 1; 59 // The notification panel is expanded and interactive (either locked or unlocked), and the 60 // quick settings is not expanded 61 public static final int SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED = 1 << 2; 62 // The keyguard bouncer is showing 63 public static final int SYSUI_STATE_BOUNCER_SHOWING = 1 << 3; 64 // The navigation bar a11y button should be shown 65 public static final int SYSUI_STATE_A11Y_BUTTON_CLICKABLE = 1 << 4; 66 // The navigation bar a11y button shortcut is available 67 public static final int SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE = 1 << 5; 68 // The keyguard is showing and not occluded 69 public static final int SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING = 1 << 6; 70 // The recents feature is disabled (either by SUW/SysUI/device policy) 71 public static final int SYSUI_STATE_OVERVIEW_DISABLED = 1 << 7; 72 // The home feature is disabled (either by SUW/SysUI/device policy) 73 public static final int SYSUI_STATE_HOME_DISABLED = 1 << 8; 74 // The keyguard is showing, but occluded 75 public static final int SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED = 1 << 9; 76 // The search feature is disabled (either by SUW/SysUI/device policy) 77 public static final int SYSUI_STATE_SEARCH_DISABLED = 1 << 10; 78 // The notification panel is expanded and interactive (either locked or unlocked), and quick 79 // settings is expanded. 80 public static final int SYSUI_STATE_QUICK_SETTINGS_EXPANDED = 1 << 11; 81 // Winscope tracing is enabled 82 public static final int SYSUI_STATE_TRACING_ENABLED = 1 << 12; 83 // The Assistant gesture should be constrained. It is up to the launcher implementation to 84 // decide how to constrain it 85 public static final int SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED = 1 << 13; 86 // The bubble stack is expanded. This means that the home gesture should be ignored, since a 87 // swipe up is an attempt to close the bubble stack, but that the back gesture should remain 88 // enabled (since it's used to navigate back within the bubbled app, or to collapse the bubble 89 // stack. 90 public static final int SYSUI_STATE_BUBBLES_EXPANDED = 1 << 14; 91 // A SysUI dialog is showing. 92 public static final int SYSUI_STATE_DIALOG_SHOWING = 1 << 15; 93 // The one-handed mode is active 94 public static final int SYSUI_STATE_ONE_HANDED_ACTIVE = 1 << 16; 95 // Allow system gesture no matter the system bar(s) is visible or not 96 public static final int SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY = 1 << 17; 97 // The IME is showing 98 public static final int SYSUI_STATE_IME_SHOWING = 1 << 18; 99 // The window magnification is overlapped with system gesture insets at the bottom. 100 public static final int SYSUI_STATE_MAGNIFICATION_OVERLAP = 1 << 19; 101 // ImeSwitcher is showing 102 public static final int SYSUI_STATE_IME_SWITCHER_SHOWING = 1 << 20; 103 // Device dozing/AOD state 104 public static final int SYSUI_STATE_DEVICE_DOZING = 1 << 21; 105 // The home feature is disabled (either by SUW/SysUI/device policy) 106 public static final int SYSUI_STATE_BACK_DISABLED = 1 << 22; 107 // The bubble stack is expanded AND the mange menu for bubbles is expanded on top of it. 108 public static final int SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED = 1 << 23; 109 // The current app is in immersive mode 110 public static final int SYSUI_STATE_IMMERSIVE_MODE = 1 << 24; 111 // The voice interaction session window is showing 112 public static final int SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING = 1 << 25; 113 // Freeform windows are showing in desktop mode 114 public static final int SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE = 1 << 26; 115 // Device dreaming state 116 public static final int SYSUI_STATE_DEVICE_DREAMING = 1 << 27; 117 // Whether the device is currently awake (as opposed to asleep, see WakefulnessLifecycle). 118 // Note that the device is awake on while waking up on, but not while going to sleep. 119 public static final int SYSUI_STATE_AWAKE = 1 << 28; 120 // Whether the device is currently transitioning between awake/asleep indicated by 121 // SYSUI_STATE_AWAKE. 122 public static final int SYSUI_STATE_WAKEFULNESS_TRANSITION = 1 << 29; 123 // The notification panel expansion fraction is > 0 124 public static final int SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE = 1 << 30; 125 // When keyguard will be dismissed but didn't start animation yet 126 public static final int SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY = 1 << 31; 127 128 // Mask for SystemUiStateFlags to isolate SYSUI_STATE_AWAKE and 129 // SYSUI_STATE_WAKEFULNESS_TRANSITION, to match WAKEFULNESS_* constants 130 public static final int SYSUI_STATE_WAKEFULNESS_MASK = 131 SYSUI_STATE_AWAKE | SYSUI_STATE_WAKEFULNESS_TRANSITION; 132 // Mirroring the WakefulnessLifecycle#Wakefulness states 133 public static final int WAKEFULNESS_ASLEEP = 0; 134 public static final int WAKEFULNESS_AWAKE = SYSUI_STATE_AWAKE; 135 public static final int WAKEFULNESS_GOING_TO_SLEEP = SYSUI_STATE_WAKEFULNESS_TRANSITION; 136 public static final int WAKEFULNESS_WAKING = 137 SYSUI_STATE_WAKEFULNESS_TRANSITION | SYSUI_STATE_AWAKE; 138 139 // Whether the back gesture is allowed (or ignored) by the Shade 140 public static final boolean ALLOW_BACK_GESTURE_IN_SHADE = SystemProperties.getBoolean( 141 "persist.wm.debug.shade_allow_back_gesture", false); 142 143 @Retention(RetentionPolicy.SOURCE) 144 @IntDef({SYSUI_STATE_SCREEN_PINNING, 145 SYSUI_STATE_NAV_BAR_HIDDEN, 146 SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED, 147 SYSUI_STATE_QUICK_SETTINGS_EXPANDED, 148 SYSUI_STATE_BOUNCER_SHOWING, 149 SYSUI_STATE_A11Y_BUTTON_CLICKABLE, 150 SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE, 151 SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING, 152 SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED, 153 SYSUI_STATE_OVERVIEW_DISABLED, 154 SYSUI_STATE_HOME_DISABLED, 155 SYSUI_STATE_SEARCH_DISABLED, 156 SYSUI_STATE_TRACING_ENABLED, 157 SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED, 158 SYSUI_STATE_BUBBLES_EXPANDED, 159 SYSUI_STATE_DIALOG_SHOWING, 160 SYSUI_STATE_ONE_HANDED_ACTIVE, 161 SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY, 162 SYSUI_STATE_IME_SHOWING, 163 SYSUI_STATE_MAGNIFICATION_OVERLAP, 164 SYSUI_STATE_IME_SWITCHER_SHOWING, 165 SYSUI_STATE_DEVICE_DOZING, 166 SYSUI_STATE_BACK_DISABLED, 167 SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED, 168 SYSUI_STATE_IMMERSIVE_MODE, 169 SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING, 170 SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE, 171 SYSUI_STATE_DEVICE_DREAMING, 172 SYSUI_STATE_AWAKE, 173 SYSUI_STATE_WAKEFULNESS_TRANSITION, 174 SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE, 175 SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY, 176 }) 177 public @interface SystemUiStateFlags {} 178 getSystemUiStateString(int flags)179 public static String getSystemUiStateString(int flags) { 180 StringJoiner str = new StringJoiner("|"); 181 if ((flags & SYSUI_STATE_SCREEN_PINNING) != 0) { 182 str.add("screen_pinned"); 183 } 184 if ((flags & SYSUI_STATE_OVERVIEW_DISABLED) != 0) { 185 str.add("overview_disabled"); 186 } 187 if ((flags & SYSUI_STATE_HOME_DISABLED) != 0) { 188 str.add("home_disabled"); 189 } 190 if ((flags & SYSUI_STATE_SEARCH_DISABLED) != 0) { 191 str.add("search_disabled"); 192 } 193 if ((flags & SYSUI_STATE_NAV_BAR_HIDDEN) != 0) { 194 str.add("navbar_hidden"); 195 } 196 if ((flags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0) { 197 str.add("notif_expanded"); 198 } 199 if ((flags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) != 0) { 200 str.add("qs_visible"); 201 } 202 if ((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) != 0) { 203 str.add("keygrd_visible"); 204 } 205 if ((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0) { 206 str.add("keygrd_occluded"); 207 } 208 if ((flags & SYSUI_STATE_BOUNCER_SHOWING) != 0) { 209 str.add("bouncer_visible"); 210 } 211 if ((flags & SYSUI_STATE_DIALOG_SHOWING) != 0) { 212 str.add("dialog_showing"); 213 } 214 if ((flags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0) { 215 str.add("a11y_click"); 216 } 217 if ((flags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0) { 218 str.add("a11y_long_click"); 219 } 220 if ((flags & SYSUI_STATE_TRACING_ENABLED) != 0) { 221 str.add("tracing"); 222 } 223 if ((flags & SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED) != 0) { 224 str.add("asst_gesture_constrain"); 225 } 226 if ((flags & SYSUI_STATE_BUBBLES_EXPANDED) != 0) { 227 str.add("bubbles_expanded"); 228 } 229 if ((flags & SYSUI_STATE_ONE_HANDED_ACTIVE) != 0) { 230 str.add("one_handed_active"); 231 } 232 if ((flags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0) { 233 str.add("allow_gesture"); 234 } 235 if ((flags & SYSUI_STATE_IME_SHOWING) != 0) { 236 str.add("ime_visible"); 237 } 238 if ((flags & SYSUI_STATE_MAGNIFICATION_OVERLAP) != 0) { 239 str.add("magnification_overlap"); 240 } 241 if ((flags & SYSUI_STATE_IME_SWITCHER_SHOWING) != 0) { 242 str.add("ime_switcher_showing"); 243 } 244 if ((flags & SYSUI_STATE_DEVICE_DOZING) != 0) { 245 str.add("device_dozing"); 246 } 247 if ((flags & SYSUI_STATE_BACK_DISABLED) != 0) { 248 str.add("back_disabled"); 249 } 250 if ((flags & SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED) != 0) { 251 str.add("bubbles_mange_menu_expanded"); 252 } 253 if ((flags & SYSUI_STATE_IMMERSIVE_MODE) != 0) { 254 str.add("immersive_mode"); 255 } 256 if ((flags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0) { 257 str.add("vis_win_showing"); 258 } 259 if ((flags & SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE) != 0) { 260 str.add("freeform_active_in_desktop_mode"); 261 } 262 if ((flags & SYSUI_STATE_DEVICE_DREAMING) != 0) { 263 str.add("device_dreaming"); 264 } 265 if ((flags & SYSUI_STATE_WAKEFULNESS_TRANSITION) != 0) { 266 str.add("wakefulness_transition"); 267 } 268 if ((flags & SYSUI_STATE_AWAKE) != 0) { 269 str.add("awake"); 270 } 271 if ((flags & SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE) != 0) { 272 str.add("notif_visible"); 273 } 274 if ((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY) != 0) { 275 str.add("keygrd_going_away"); 276 } 277 278 return str.toString(); 279 } 280 281 /** 282 * Ratio of quickstep touch slop (when system takes over the touch) to view touch slop 283 */ 284 public static final float QUICKSTEP_TOUCH_SLOP_RATIO = 3; 285 286 /** 287 * Touch slop for quickstep gesture 288 */ getQuickStepTouchSlopPx(Context context)289 public static final float getQuickStepTouchSlopPx(Context context) { 290 return QUICKSTEP_TOUCH_SLOP_RATIO * ViewConfiguration.get(context).getScaledTouchSlop(); 291 } 292 293 /** 294 * Returns whether the specified sysui state is such that the assistant gesture should be 295 * disabled. 296 */ isAssistantGestureDisabled(int sysuiStateFlags)297 public static boolean isAssistantGestureDisabled(int sysuiStateFlags) { 298 if ((sysuiStateFlags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0) { 299 sysuiStateFlags &= ~SYSUI_STATE_NAV_BAR_HIDDEN; 300 } 301 // Disable when in quick settings, screen pinning, immersive, the bouncer is showing, 302 // or search is disabled 303 int disableFlags = SYSUI_STATE_SCREEN_PINNING 304 | SYSUI_STATE_NAV_BAR_HIDDEN 305 | SYSUI_STATE_BOUNCER_SHOWING 306 | SYSUI_STATE_SEARCH_DISABLED 307 | SYSUI_STATE_QUICK_SETTINGS_EXPANDED; 308 if ((sysuiStateFlags & disableFlags) != 0) { 309 return true; 310 } 311 312 // Disable when notifications are showing (only if unlocked) 313 if ((sysuiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0 314 && (sysuiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) == 0) { 315 return true; 316 } 317 318 return false; 319 } 320 321 /** 322 * Returns whether the specified sysui state is such that the back gesture should be 323 * disabled. 324 */ isBackGestureDisabled(int sysuiStateFlags, boolean forTrackpad)325 public static boolean isBackGestureDisabled(int sysuiStateFlags, boolean forTrackpad) { 326 // Always allow when the bouncer/global actions/voice session is showing (even on top of 327 // the keyguard) 328 if ((sysuiStateFlags & SYSUI_STATE_BOUNCER_SHOWING) != 0 329 || (sysuiStateFlags & SYSUI_STATE_DIALOG_SHOWING) != 0 330 || (sysuiStateFlags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0) { 331 return false; 332 } 333 if ((sysuiStateFlags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0) { 334 sysuiStateFlags &= ~SYSUI_STATE_NAV_BAR_HIDDEN; 335 } 336 337 return (sysuiStateFlags & getBackGestureDisabledMask(forTrackpad)) != 0; 338 } 339 getBackGestureDisabledMask(boolean forTrackpad)340 private static int getBackGestureDisabledMask(boolean forTrackpad) { 341 // Disable when in immersive, or the notifications are interactive 342 int disableFlags = SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING; 343 if (!forTrackpad) { 344 disableFlags |= SYSUI_STATE_NAV_BAR_HIDDEN; 345 } 346 347 // EdgeBackGestureHandler ignores Back gesture when SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED. 348 // To allow Shade to respond to Back, we're bypassing this check (behind a flag). 349 if (!ALLOW_BACK_GESTURE_IN_SHADE) { 350 disableFlags |= SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED; 351 } 352 return disableFlags; 353 } 354 355 /** 356 * @return whether this nav bar mode is edge to edge 357 */ isGesturalMode(int mode)358 public static boolean isGesturalMode(int mode) { 359 return mode == NAV_BAR_MODE_GESTURAL; 360 } 361 362 /** 363 * @return whether this nav bar mode is swipe up 364 */ isSwipeUpMode(int mode)365 public static boolean isSwipeUpMode(int mode) { 366 return mode == NAV_BAR_MODE_2BUTTON; 367 } 368 369 /** 370 * @return whether this nav bar mode is 3 button 371 */ isLegacyMode(int mode)372 public static boolean isLegacyMode(int mode) { 373 return mode == NAV_BAR_MODE_3BUTTON; 374 } 375 376 /** 377 * Corner radius that should be used on windows in order to cover the display. 378 * These values are expressed in pixels because they should not respect display or font 379 * scaling, this means that we don't have to reload them on config changes. 380 */ getWindowCornerRadius(Context context)381 public static float getWindowCornerRadius(Context context) { 382 return ScreenDecorationsUtils.getWindowCornerRadius(context); 383 } 384 385 /** 386 * If live rounded corners are supported on windows. 387 */ supportsRoundedCornersOnWindows(Resources resources)388 public static boolean supportsRoundedCornersOnWindows(Resources resources) { 389 return ScreenDecorationsUtils.supportsRoundedCornersOnWindows(resources); 390 } 391 } 392