• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static com.android.systemui.shared.Flags.shadeAllowBackGesture;
24 
25 import android.annotation.LongDef;
26 import android.content.Context;
27 import android.content.res.Resources;
28 import android.view.ViewConfiguration;
29 import android.view.WindowManagerPolicyConstants;
30 
31 import com.android.internal.policy.ScreenDecorationsUtils;
32 
33 import java.lang.annotation.Retention;
34 import java.lang.annotation.RetentionPolicy;
35 import java.util.StringJoiner;
36 
37 /**
38  * Various shared constants between Launcher and SysUI as part of quickstep
39  */
40 public class QuickStepContract {
41 
42     public static final String KEY_EXTRA_SYSUI_PROXY = "extra_sysui_proxy";
43     public static final String KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER = "extra_unfold_animation";
44     // See ISysuiUnlockAnimationController.aidl
45     public static final String KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER = "unlock_animation";
46 
47     public static final String NAV_BAR_MODE_3BUTTON_OVERLAY =
48             WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
49     public static final String NAV_BAR_MODE_GESTURAL_OVERLAY =
50             WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
51 
52     // Overview is disabled, either because the device is in lock task mode, or because the device
53     // policy has disabled the feature
54     public static final long SYSUI_STATE_SCREEN_PINNING = 1L << 0;
55     // The navigation bar is hidden due to immersive mode
56     public static final long SYSUI_STATE_NAV_BAR_HIDDEN = 1L << 1;
57     // The notification panel is expanded and interactive (either locked or unlocked), and the
58     // quick settings is not expanded
59     public static final long SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED = 1L << 2;
60     // The keyguard bouncer is showing
61     public static final long SYSUI_STATE_BOUNCER_SHOWING = 1L << 3;
62     // The navigation bar a11y button should be shown
63     public static final long SYSUI_STATE_A11Y_BUTTON_CLICKABLE = 1L << 4;
64     // The navigation bar a11y button shortcut is available
65     public static final long SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE = 1L << 5;
66     // The keyguard is showing and not occluded
67     public static final long SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING = 1L << 6;
68     // The recents feature is disabled (either by SUW/SysUI/device policy)
69     public static final long SYSUI_STATE_OVERVIEW_DISABLED = 1L << 7;
70     // The home feature is disabled (either by SUW/SysUI/device policy)
71     public static final long SYSUI_STATE_HOME_DISABLED = 1L << 8;
72     // The keyguard is showing, but occluded
73     public static final long SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED = 1L << 9;
74     // The search feature is disabled (either by SUW/SysUI/device policy)
75     public static final long SYSUI_STATE_SEARCH_DISABLED = 1L << 10;
76     // The notification panel is expanded and interactive (either locked or unlocked), and quick
77     // settings is expanded.
78     public static final long SYSUI_STATE_QUICK_SETTINGS_EXPANDED = 1L << 11;
79     // Winscope tracing is enabled
80     public static final long SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION = 1L << 12;
81     // The Assistant gesture should be constrained. It is up to the launcher implementation to
82     // decide how to constrain it
83     public static final long SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED = 1L << 13;
84     // The bubble stack is expanded. This means that the home gesture should be ignored, since a
85     // swipe up is an attempt to close the bubble stack, but that the back gesture should remain
86     // enabled (since it's used to navigate back within the bubbled app, or to collapse the bubble
87     // stack.
88     public static final long SYSUI_STATE_BUBBLES_EXPANDED = 1L << 14;
89     // A SysUI dialog is showing.
90     public static final long SYSUI_STATE_DIALOG_SHOWING = 1L << 15;
91     // The one-handed mode is active
92     public static final long SYSUI_STATE_ONE_HANDED_ACTIVE = 1L << 16;
93     // Allow system gesture no matter the system bar(s) is visible or not
94     public static final long SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY = 1L << 17;
95     // The IME is showing
96     public static final long SYSUI_STATE_IME_SHOWING = 1L << 18;
97     // The window magnification is overlapped with system gesture insets at the bottom.
98     public static final long SYSUI_STATE_MAGNIFICATION_OVERLAP = 1L << 19;
99     // ImeSwitcher is showing
100     public static final long SYSUI_STATE_IME_SWITCHER_SHOWING = 1L << 20;
101     // Device dozing/AOD state
102     public static final long SYSUI_STATE_DEVICE_DOZING = 1L << 21;
103     // The home feature is disabled (either by SUW/SysUI/device policy)
104     public static final long SYSUI_STATE_BACK_DISABLED = 1L << 22;
105     // The bubble stack is expanded AND the mange menu for bubbles is expanded on top of it.
106     public static final long SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED = 1L << 23;
107     // The voice interaction session window is showing
108     public static final long SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING = 1L << 25;
109     // Freeform windows are showing in desktop mode
110     public static final long SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE = 1L << 26;
111     // Device dreaming state
112     public static final long SYSUI_STATE_DEVICE_DREAMING = 1L << 27;
113     // Whether the device is currently awake (as opposed to asleep, see WakefulnessLifecycle).
114     // Note that the device is awake on while waking up on, but not while going to sleep.
115     public static final long SYSUI_STATE_AWAKE = 1L << 28;
116     // Whether the device is currently transitioning between awake/asleep indicated by
117     // SYSUI_STATE_AWAKE.
118     public static final long SYSUI_STATE_WAKEFULNESS_TRANSITION = 1L << 29;
119     // The notification panel expansion fraction is > 0
120     public static final long SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE = 1L << 30;
121     // When keyguard will be dismissed but didn't start animation yet
122     public static final long SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY = 1L << 31;
123     // Physical keyboard shortcuts helper is showing
124     public static final long SYSUI_STATE_SHORTCUT_HELPER_SHOWING = 1L << 32;
125     // Touchpad gestures are disabled
126     public static final long SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED = 1L << 33;
127 
128     // Mask for SystemUiStateFlags to isolate SYSUI_STATE_AWAKE and
129     // SYSUI_STATE_WAKEFULNESS_TRANSITION, to match WAKEFULNESS_* constants
130     public static final long SYSUI_STATE_WAKEFULNESS_MASK =
131             SYSUI_STATE_AWAKE | SYSUI_STATE_WAKEFULNESS_TRANSITION;
132     // Mirroring the WakefulnessLifecycle#Wakefulness states
133     public static final long WAKEFULNESS_ASLEEP = 0;
134     public static final long WAKEFULNESS_AWAKE = SYSUI_STATE_AWAKE;
135     public static final long WAKEFULNESS_GOING_TO_SLEEP = SYSUI_STATE_WAKEFULNESS_TRANSITION;
136     public static final long 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 = shadeAllowBackGesture();
141 
142     @Retention(RetentionPolicy.SOURCE)
143     @LongDef({SYSUI_STATE_SCREEN_PINNING,
144             SYSUI_STATE_NAV_BAR_HIDDEN,
145             SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED,
146             SYSUI_STATE_QUICK_SETTINGS_EXPANDED,
147             SYSUI_STATE_BOUNCER_SHOWING,
148             SYSUI_STATE_A11Y_BUTTON_CLICKABLE,
149             SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE,
150             SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
151             SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
152             SYSUI_STATE_OVERVIEW_DISABLED,
153             SYSUI_STATE_HOME_DISABLED,
154             SYSUI_STATE_SEARCH_DISABLED,
155             SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION,
156             SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED,
157             SYSUI_STATE_BUBBLES_EXPANDED,
158             SYSUI_STATE_DIALOG_SHOWING,
159             SYSUI_STATE_ONE_HANDED_ACTIVE,
160             SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY,
161             SYSUI_STATE_IME_SHOWING,
162             SYSUI_STATE_MAGNIFICATION_OVERLAP,
163             SYSUI_STATE_IME_SWITCHER_SHOWING,
164             SYSUI_STATE_DEVICE_DOZING,
165             SYSUI_STATE_BACK_DISABLED,
166             SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED,
167             SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING,
168             SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE,
169             SYSUI_STATE_DEVICE_DREAMING,
170             SYSUI_STATE_AWAKE,
171             SYSUI_STATE_WAKEFULNESS_TRANSITION,
172             SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE,
173             SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY,
174             SYSUI_STATE_SHORTCUT_HELPER_SHOWING,
175             SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED,
176     })
177     public @interface SystemUiStateFlags {}
178 
getSystemUiStateString(long flags)179     public static String getSystemUiStateString(long 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_DISABLE_GESTURE_SPLIT_INVOCATION) != 0) {
221             str.add("disable_gesture_split_invocation");
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_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         if ((flags & SYSUI_STATE_SHORTCUT_HELPER_SHOWING) != 0) {
275             str.add("shortcut_helper_showing");
276         }
277         if ((flags & SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED) != 0) {
278             str.add("touchpad_gestures_disabled");
279         }
280 
281         return str.toString();
282     }
283 
284     /**
285      * Ratio of quickstep touch slop (when system takes over the touch) to view touch slop
286      */
287     public static final float QUICKSTEP_TOUCH_SLOP_RATIO = 3;
288 
289     /**
290      * Touch slop for quickstep gesture
291      */
getQuickStepTouchSlopPx(Context context)292     public static final float getQuickStepTouchSlopPx(Context context) {
293         return QUICKSTEP_TOUCH_SLOP_RATIO * ViewConfiguration.get(context).getScaledTouchSlop();
294     }
295 
296     /**
297      * Returns whether the specified sysui state is such that the assistant gesture should be
298      * disabled.
299      */
isAssistantGestureDisabled(long sysuiStateFlags)300     public static boolean isAssistantGestureDisabled(long sysuiStateFlags) {
301         if ((sysuiStateFlags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0) {
302             sysuiStateFlags &= ~SYSUI_STATE_NAV_BAR_HIDDEN;
303         }
304         // Disable when in quick settings, screen pinning, immersive, the bouncer is showing,
305         // or search is disabled
306         long disableFlags = SYSUI_STATE_SCREEN_PINNING
307                 | SYSUI_STATE_NAV_BAR_HIDDEN
308                 | SYSUI_STATE_BOUNCER_SHOWING
309                 | SYSUI_STATE_SEARCH_DISABLED
310                 | SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
311         if ((sysuiStateFlags & disableFlags) != 0) {
312             return true;
313         }
314 
315         // Disable when notifications are showing (only if unlocked)
316         if ((sysuiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0
317                 && (sysuiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) == 0) {
318             return true;
319         }
320 
321         return false;
322     }
323 
324     /**
325      * Returns whether the specified sysui state is such that the back gesture should be
326      * disabled.
327      */
isBackGestureDisabled(long sysuiStateFlags, boolean forTrackpad)328     public static boolean isBackGestureDisabled(long sysuiStateFlags, boolean forTrackpad) {
329         // Always allow when the bouncer/global actions/voice session is showing (even on top of
330         // the keyguard)
331         if ((sysuiStateFlags & SYSUI_STATE_BOUNCER_SHOWING) != 0
332                 || (sysuiStateFlags & SYSUI_STATE_DIALOG_SHOWING) != 0
333                 || (sysuiStateFlags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0) {
334             return false;
335         }
336         if ((sysuiStateFlags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0) {
337             sysuiStateFlags &= ~SYSUI_STATE_NAV_BAR_HIDDEN;
338         }
339 
340         return (sysuiStateFlags & getBackGestureDisabledMask(forTrackpad)) != 0;
341     }
342 
getBackGestureDisabledMask(boolean forTrackpad)343     private static long getBackGestureDisabledMask(boolean forTrackpad) {
344         // Disable when in immersive, or the notifications are interactive
345         long disableFlags = SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
346         if (!forTrackpad) {
347             disableFlags |= SYSUI_STATE_NAV_BAR_HIDDEN;
348         }
349 
350         // EdgeBackGestureHandler ignores Back gesture when SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED.
351         // To allow Shade to respond to Back, we're bypassing this check (behind a flag).
352         if (!ALLOW_BACK_GESTURE_IN_SHADE) {
353             disableFlags |= SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
354         }
355         return disableFlags;
356     }
357 
358     /**
359      * @return whether this nav bar mode is edge to edge
360      */
isGesturalMode(int mode)361     public static boolean isGesturalMode(int mode) {
362         return mode == NAV_BAR_MODE_GESTURAL;
363     }
364 
365     /**
366      * @return whether this nav bar mode is swipe up
367      */
isSwipeUpMode(int mode)368     public static boolean isSwipeUpMode(int mode) {
369         return mode == NAV_BAR_MODE_2BUTTON;
370     }
371 
372     /**
373      * @return whether this nav bar mode is 3 button
374      */
isLegacyMode(int mode)375     public static boolean isLegacyMode(int mode) {
376         return mode == NAV_BAR_MODE_3BUTTON;
377     }
378 
379     /**
380      * Corner radius that should be used on windows in order to cover the display.
381      * These values are expressed in pixels because they should not respect display or font
382      * scaling. The corner radius may change when folding/unfolding the device.
383      */
getWindowCornerRadius(Context context)384     public static float getWindowCornerRadius(Context context) {
385         return ScreenDecorationsUtils.getWindowCornerRadius(context);
386     }
387 
388     /**
389      * If live rounded corners are supported on windows.
390      */
supportsRoundedCornersOnWindows(Resources resources)391     public static boolean supportsRoundedCornersOnWindows(Resources resources) {
392         return ScreenDecorationsUtils.supportsRoundedCornersOnWindows(resources);
393     }
394 }
395