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