• 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 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