• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.statusbar;
18 
19 import static android.app.StatusBarManager.DISABLE2_NONE;
20 import static android.app.StatusBarManager.DISABLE_NONE;
21 import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT;
22 import static android.inputmethodservice.InputMethodService.IME_INVISIBLE;
23 import static android.view.Display.DEFAULT_DISPLAY;
24 import static android.view.Display.INVALID_DISPLAY;
25 
26 import static com.android.systemui.statusbar.phone.StatusBar.ONLY_CORE_APPS;
27 
28 import android.annotation.Nullable;
29 import android.app.ITransientNotificationCallback;
30 import android.app.StatusBarManager;
31 import android.app.StatusBarManager.Disable2Flags;
32 import android.app.StatusBarManager.DisableFlags;
33 import android.app.StatusBarManager.WindowType;
34 import android.app.StatusBarManager.WindowVisibleState;
35 import android.content.ComponentName;
36 import android.content.Context;
37 import android.hardware.biometrics.BiometricAuthenticator.Modality;
38 import android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode;
39 import android.hardware.biometrics.IBiometricSysuiReceiver;
40 import android.hardware.biometrics.PromptInfo;
41 import android.hardware.display.DisplayManager;
42 import android.hardware.fingerprint.IUdfpsHbmListener;
43 import android.inputmethodservice.InputMethodService.BackDispositionMode;
44 import android.os.Bundle;
45 import android.os.Handler;
46 import android.os.IBinder;
47 import android.os.Looper;
48 import android.os.Message;
49 import android.os.ParcelFileDescriptor;
50 import android.util.Log;
51 import android.util.Pair;
52 import android.util.SparseArray;
53 import android.view.InsetsState.InternalInsetsType;
54 import android.view.WindowInsetsController.Appearance;
55 import android.view.WindowInsetsController.Behavior;
56 
57 import androidx.annotation.NonNull;
58 
59 import com.android.internal.os.SomeArgs;
60 import com.android.internal.statusbar.IStatusBar;
61 import com.android.internal.statusbar.StatusBarIcon;
62 import com.android.internal.util.GcUtils;
63 import com.android.internal.view.AppearanceRegion;
64 import com.android.systemui.statusbar.CommandQueue.Callbacks;
65 import com.android.systemui.statusbar.commandline.CommandRegistry;
66 import com.android.systemui.statusbar.policy.CallbackController;
67 import com.android.systemui.tracing.ProtoTracer;
68 
69 import java.io.FileOutputStream;
70 import java.io.IOException;
71 import java.io.PrintWriter;
72 import java.util.ArrayList;
73 
74 /**
75  * This class takes the functions from IStatusBar that come in on
76  * binder pool threads and posts messages to get them onto the main
77  * thread, and calls onto Callbacks.  It also takes care of
78  * coalescing these calls so they don't stack up.  For the calls
79  * are coalesced, note that they are all idempotent.
80  */
81 public class CommandQueue extends IStatusBar.Stub implements CallbackController<Callbacks>,
82         DisplayManager.DisplayListener {
83     private static final String TAG = CommandQueue.class.getSimpleName();
84 
85     private static final int INDEX_MASK = 0xffff;
86     private static final int MSG_SHIFT  = 16;
87     private static final int MSG_MASK   = 0xffff << MSG_SHIFT;
88 
89     private static final int OP_SET_ICON    = 1;
90     private static final int OP_REMOVE_ICON = 2;
91 
92     private static final int MSG_ICON                              = 1 << MSG_SHIFT;
93     private static final int MSG_DISABLE                           = 2 << MSG_SHIFT;
94     private static final int MSG_EXPAND_NOTIFICATIONS              = 3 << MSG_SHIFT;
95     private static final int MSG_COLLAPSE_PANELS                   = 4 << MSG_SHIFT;
96     private static final int MSG_EXPAND_SETTINGS                   = 5 << MSG_SHIFT;
97     private static final int MSG_SYSTEM_BAR_CHANGED                = 6 << MSG_SHIFT;
98     private static final int MSG_DISPLAY_READY                     = 7 << MSG_SHIFT;
99     private static final int MSG_SHOW_IME_BUTTON                   = 8 << MSG_SHIFT;
100     private static final int MSG_TOGGLE_RECENT_APPS                = 9 << MSG_SHIFT;
101     private static final int MSG_PRELOAD_RECENT_APPS               = 10 << MSG_SHIFT;
102     private static final int MSG_CANCEL_PRELOAD_RECENT_APPS        = 11 << MSG_SHIFT;
103     private static final int MSG_SET_WINDOW_STATE                  = 12 << MSG_SHIFT;
104     private static final int MSG_SHOW_RECENT_APPS                  = 13 << MSG_SHIFT;
105     private static final int MSG_HIDE_RECENT_APPS                  = 14 << MSG_SHIFT;
106     private static final int MSG_SHOW_SCREEN_PIN_REQUEST           = 18 << MSG_SHIFT;
107     private static final int MSG_APP_TRANSITION_PENDING            = 19 << MSG_SHIFT;
108     private static final int MSG_APP_TRANSITION_CANCELLED          = 20 << MSG_SHIFT;
109     private static final int MSG_APP_TRANSITION_STARTING           = 21 << MSG_SHIFT;
110     private static final int MSG_ASSIST_DISCLOSURE                 = 22 << MSG_SHIFT;
111     private static final int MSG_START_ASSIST                      = 23 << MSG_SHIFT;
112     private static final int MSG_CAMERA_LAUNCH_GESTURE             = 24 << MSG_SHIFT;
113     private static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS         = 25 << MSG_SHIFT;
114     private static final int MSG_SHOW_PICTURE_IN_PICTURE_MENU      = 26 << MSG_SHIFT;
115     private static final int MSG_ADD_QS_TILE                       = 27 << MSG_SHIFT;
116     private static final int MSG_REMOVE_QS_TILE                    = 28 << MSG_SHIFT;
117     private static final int MSG_CLICK_QS_TILE                     = 29 << MSG_SHIFT;
118     private static final int MSG_TOGGLE_APP_SPLIT_SCREEN           = 30 << MSG_SHIFT;
119     private static final int MSG_APP_TRANSITION_FINISHED           = 31 << MSG_SHIFT;
120     private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS        = 32 << MSG_SHIFT;
121     private static final int MSG_HANDLE_SYSTEM_KEY                 = 33 << MSG_SHIFT;
122     private static final int MSG_SHOW_GLOBAL_ACTIONS               = 34 << MSG_SHIFT;
123     private static final int MSG_TOGGLE_PANEL                      = 35 << MSG_SHIFT;
124     private static final int MSG_SHOW_SHUTDOWN_UI                  = 36 << MSG_SHIFT;
125     private static final int MSG_SET_TOP_APP_HIDES_STATUS_BAR      = 37 << MSG_SHIFT;
126     private static final int MSG_ROTATION_PROPOSAL                 = 38 << MSG_SHIFT;
127     private static final int MSG_BIOMETRIC_SHOW                    = 39 << MSG_SHIFT;
128     private static final int MSG_BIOMETRIC_AUTHENTICATED           = 40 << MSG_SHIFT;
129     private static final int MSG_BIOMETRIC_HELP                    = 41 << MSG_SHIFT;
130     private static final int MSG_BIOMETRIC_ERROR                   = 42 << MSG_SHIFT;
131     private static final int MSG_BIOMETRIC_HIDE                    = 43 << MSG_SHIFT;
132     private static final int MSG_SHOW_CHARGING_ANIMATION           = 44 << MSG_SHIFT;
133     private static final int MSG_SHOW_PINNING_TOAST_ENTER_EXIT     = 45 << MSG_SHIFT;
134     private static final int MSG_SHOW_PINNING_TOAST_ESCAPE         = 46 << MSG_SHIFT;
135     private static final int MSG_RECENTS_ANIMATION_STATE_CHANGED   = 47 << MSG_SHIFT;
136     private static final int MSG_SHOW_TRANSIENT                    = 48 << MSG_SHIFT;
137     private static final int MSG_ABORT_TRANSIENT                   = 49 << MSG_SHIFT;
138     private static final int MSG_SHOW_INATTENTIVE_SLEEP_WARNING    = 50 << MSG_SHIFT;
139     private static final int MSG_DISMISS_INATTENTIVE_SLEEP_WARNING = 51 << MSG_SHIFT;
140     private static final int MSG_SHOW_TOAST                        = 52 << MSG_SHIFT;
141     private static final int MSG_HIDE_TOAST                        = 53 << MSG_SHIFT;
142     private static final int MSG_TRACING_STATE_CHANGED             = 54 << MSG_SHIFT;
143     private static final int MSG_SUPPRESS_AMBIENT_DISPLAY          = 55 << MSG_SHIFT;
144     private static final int MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION = 56 << MSG_SHIFT;
145     private static final int MSG_HANDLE_WINDOW_MANAGER_LOGGING_COMMAND = 57 << MSG_SHIFT;
146     //TODO(b/169175022) Update name and when feature name is locked.
147     private static final int MSG_EMERGENCY_ACTION_LAUNCH_GESTURE      = 58 << MSG_SHIFT;
148     private static final int MSG_SET_NAVIGATION_BAR_LUMA_SAMPLING_ENABLED = 59 << MSG_SHIFT;
149     private static final int MSG_SET_UDFPS_HBM_LISTENER = 60 << MSG_SHIFT;
150 
151     public static final int FLAG_EXCLUDE_NONE = 0;
152     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
153     public static final int FLAG_EXCLUDE_RECENTS_PANEL = 1 << 1;
154     public static final int FLAG_EXCLUDE_NOTIFICATION_PANEL = 1 << 2;
155     public static final int FLAG_EXCLUDE_INPUT_METHODS_PANEL = 1 << 3;
156     public static final int FLAG_EXCLUDE_COMPAT_MODE_PANEL = 1 << 4;
157 
158     private static final String SHOW_IME_SWITCHER_KEY = "showImeSwitcherKey";
159 
160     private final Object mLock = new Object();
161     private ArrayList<Callbacks> mCallbacks = new ArrayList<>();
162     private Handler mHandler = new H(Looper.getMainLooper());
163     /** A map of display id - disable flag pair */
164     private SparseArray<Pair<Integer, Integer>> mDisplayDisabled = new SparseArray<>();
165     /**
166      * The last ID of the display where IME window for which we received setImeWindowStatus
167      * event.
168      */
169     private int mLastUpdatedImeDisplayId = INVALID_DISPLAY;
170     private ProtoTracer mProtoTracer;
171     private final @Nullable CommandRegistry mRegistry;
172 
173     /**
174      * These methods are called back on the main thread.
175      */
176     public interface Callbacks {
setIcon(String slot, StatusBarIcon icon)177         default void setIcon(String slot, StatusBarIcon icon) { }
removeIcon(String slot)178         default void removeIcon(String slot) { }
179 
180         /**
181          * Called to notify that disable flags are updated.
182          * @see IStatusBar#disable(int, int, int).
183          *
184          * @param displayId The id of the display to notify.
185          * @param state1 The combination of following DISABLE_* flags:
186          * @param state2 The combination of following DISABLE2_* flags:
187          * @param animate {@code true} to show animations.
188          */
disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, boolean animate)189         default void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2,
190                 boolean animate) { }
animateExpandNotificationsPanel()191         default void animateExpandNotificationsPanel() { }
animateCollapsePanels(int flags, boolean force)192         default void animateCollapsePanels(int flags, boolean force) { }
togglePanel()193         default void togglePanel() { }
animateExpandSettingsPanel(String obj)194         default void animateExpandSettingsPanel(String obj) { }
195 
196         /**
197          * Called to notify IME window status changes.
198          *
199          * @param displayId The id of the display to notify.
200          * @param token IME token.
201          * @param vis IME visibility.
202          * @param backDisposition Disposition mode of back button. It should be one of below flags:
203          * @param showImeSwitcher {@code true} to show IME switch button.
204          */
setImeWindowStatus(int displayId, IBinder token, int vis, @BackDispositionMode int backDisposition, boolean showImeSwitcher)205         default void setImeWindowStatus(int displayId, IBinder token,  int vis,
206                 @BackDispositionMode int backDisposition, boolean showImeSwitcher) { }
showRecentApps(boolean triggeredFromAltTab)207         default void showRecentApps(boolean triggeredFromAltTab) { }
hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)208         default void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { }
toggleRecentApps()209         default void toggleRecentApps() { }
toggleSplitScreen()210         default void toggleSplitScreen() { }
preloadRecentApps()211         default void preloadRecentApps() { }
dismissKeyboardShortcutsMenu()212         default void dismissKeyboardShortcutsMenu() { }
toggleKeyboardShortcutsMenu(int deviceId)213         default void toggleKeyboardShortcutsMenu(int deviceId) { }
cancelPreloadRecentApps()214         default void cancelPreloadRecentApps() { }
215 
216         /**
217          * Called to notify window state changes.
218          * @see IStatusBar#setWindowState(int, int, int)
219          *
220          * @param displayId The id of the display to notify.
221          * @param window Window type. It should be one of {@link StatusBarManager#WINDOW_STATUS_BAR}
222          *               or {@link StatusBarManager#WINDOW_NAVIGATION_BAR}
223          * @param state Window visible state.
224          */
setWindowState(int displayId, @WindowType int window, @WindowVisibleState int state)225         default void setWindowState(int displayId, @WindowType int window,
226                 @WindowVisibleState int state) { }
showScreenPinningRequest(int taskId)227         default void showScreenPinningRequest(int taskId) { }
228 
229         /**
230          * Called to notify System UI that an application transition is pending.
231          * @see IStatusBar#appTransitionPending(int).
232          *
233          * @param displayId The id of the display to notify.
234          * @param forced {@code true} to force transition pending.
235          */
appTransitionPending(int displayId, boolean forced)236         default void appTransitionPending(int displayId, boolean forced) { }
237 
238         /**
239          * Called to notify System UI that an application transition is canceled.
240          * @see IStatusBar#appTransitionCancelled(int).
241          *
242          * @param displayId The id of the display to notify.
243          */
appTransitionCancelled(int displayId)244         default void appTransitionCancelled(int displayId) { }
245 
246         /**
247          * Called to notify System UI that an application transition is starting.
248          * @see IStatusBar#appTransitionStarting(int, long, long).
249          *
250          * @param displayId The id of the display to notify.
251          * @param startTime Transition start time.
252          * @param duration Transition duration.
253          * @param forced {@code true} to force transition pending.
254          */
appTransitionStarting( int displayId, long startTime, long duration, boolean forced)255         default void appTransitionStarting(
256                 int displayId, long startTime, long duration, boolean forced) { }
257 
258         /**
259          * Called to notify System UI that an application transition is finished.
260          * @see IStatusBar#appTransitionFinished(int)
261          *
262          * @param displayId The id of the display to notify.
263          */
appTransitionFinished(int displayId)264         default void appTransitionFinished(int displayId) { }
showAssistDisclosure()265         default void showAssistDisclosure() { }
startAssist(Bundle args)266         default void startAssist(Bundle args) { }
onCameraLaunchGestureDetected(int source)267         default void onCameraLaunchGestureDetected(int source) { }
268 
269         /**
270          * Notifies SysUI that the emergency action gesture was detected.
271          */
onEmergencyActionLaunchGestureDetected()272         default void onEmergencyActionLaunchGestureDetected() { }
showPictureInPictureMenu()273         default void showPictureInPictureMenu() { }
setTopAppHidesStatusBar(boolean topAppHidesStatusBar)274         default void setTopAppHidesStatusBar(boolean topAppHidesStatusBar) { }
275 
addQsTile(ComponentName tile)276         default void addQsTile(ComponentName tile) { }
remQsTile(ComponentName tile)277         default void remQsTile(ComponentName tile) { }
clickTile(ComponentName tile)278         default void clickTile(ComponentName tile) { }
279 
handleSystemKey(int arg1)280         default void handleSystemKey(int arg1) { }
showPinningEnterExitToast(boolean entering)281         default void showPinningEnterExitToast(boolean entering) { }
showPinningEscapeToast()282         default void showPinningEscapeToast() { }
handleShowGlobalActionsMenu()283         default void handleShowGlobalActionsMenu() { }
handleShowShutdownUi(boolean isReboot, String reason)284         default void handleShowShutdownUi(boolean isReboot, String reason) { }
285 
showWirelessChargingAnimation(int batteryLevel)286         default void showWirelessChargingAnimation(int batteryLevel) {  }
287 
onRotationProposal(int rotation, boolean isValid)288         default void onRotationProposal(int rotation, boolean isValid) { }
289 
showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver, int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId, String opPackageName, long operationId, @BiometricMultiSensorMode int multiSensorConfig)290         default void showAuthenticationDialog(PromptInfo promptInfo,
291                 IBiometricSysuiReceiver receiver,
292                 int[] sensorIds, boolean credentialAllowed,
293                 boolean requireConfirmation, int userId, String opPackageName,
294                 long operationId, @BiometricMultiSensorMode int multiSensorConfig) {
295         }
296 
297         /** @see IStatusBar#onBiometricAuthenticated() */
onBiometricAuthenticated()298         default void onBiometricAuthenticated() {
299         }
300 
301         /** @see IStatusBar#onBiometricHelp(String) */
onBiometricHelp(@odality int modality, String message)302         default void onBiometricHelp(@Modality int modality, String message) {
303         }
304 
305         /** @see IStatusBar#onBiometricError(int, int, int) */
onBiometricError(@odality int modality, int error, int vendorCode)306         default void onBiometricError(@Modality int modality, int error, int vendorCode) {
307         }
308 
hideAuthenticationDialog()309         default void hideAuthenticationDialog() {
310         }
311 
312         /**
313          * @see IStatusBar#setUdfpsHbmListener(IUdfpsHbmListener)
314          */
setUdfpsHbmListener(IUdfpsHbmListener listener)315         default void setUdfpsHbmListener(IUdfpsHbmListener listener) {
316         }
317 
318         /**
319          * @see IStatusBar#onDisplayReady(int)
320          */
onDisplayReady(int displayId)321         default void onDisplayReady(int displayId) {
322         }
323 
324         /**
325          * @see DisplayManager.DisplayListener#onDisplayRemoved(int)
326          */
onDisplayRemoved(int displayId)327         default void onDisplayRemoved(int displayId) {
328         }
329 
330         /**
331          * @see IStatusBar#onRecentsAnimationStateChanged(boolean)
332          */
onRecentsAnimationStateChanged(boolean running)333         default void onRecentsAnimationStateChanged(boolean running) { }
334 
335         /**
336          * @see IStatusBar#onSystemBarAttributesChanged.
337          */
onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, boolean isFullscreen)338         default void onSystemBarAttributesChanged(int displayId, @Appearance int appearance,
339                 AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme,
340                 @Behavior int behavior, boolean isFullscreen) { }
341 
342         /**
343          * @see IStatusBar#showTransient(int, int[]).
344          */
showTransient(int displayId, @InternalInsetsType int[] types)345         default void showTransient(int displayId, @InternalInsetsType int[] types) { }
346 
347         /**
348          * @see IStatusBar#abortTransient(int, int[]).
349          */
abortTransient(int displayId, @InternalInsetsType int[] types)350         default void abortTransient(int displayId, @InternalInsetsType int[] types) { }
351 
352         /**
353          * Called to notify System UI that a warning about the device going to sleep
354          * due to prolonged user inactivity should be shown.
355          */
showInattentiveSleepWarning()356         default void showInattentiveSleepWarning() { }
357 
358         /**
359          * Called to notify System UI that the warning about the device going to sleep
360          * due to prolonged user inactivity should be dismissed.
361          */
dismissInattentiveSleepWarning(boolean animated)362         default void dismissInattentiveSleepWarning(boolean animated) { }
363 
364         /** Called to suppress ambient display. */
suppressAmbientDisplay(boolean suppress)365         default void suppressAmbientDisplay(boolean suppress) { }
366 
367         /**
368          * @see IStatusBar#showToast(int, String, IBinder, CharSequence, IBinder, int,
369          * ITransientNotificationCallback)
370          */
showToast(int uid, String packageName, IBinder token, CharSequence text, IBinder windowToken, int duration, @Nullable ITransientNotificationCallback callback)371         default void showToast(int uid, String packageName, IBinder token, CharSequence text,
372                 IBinder windowToken, int duration,
373                 @Nullable ITransientNotificationCallback callback) { }
374 
375         /**
376          * @see IStatusBar#hideToast(String, IBinder) (String, IBinder)
377          */
hideToast(String packageName, IBinder token)378         default void hideToast(String packageName, IBinder token) { }
379 
380         /**
381          * @param enabled
382          */
onTracingStateChanged(boolean enabled)383         default void onTracingStateChanged(boolean enabled) { }
384 
385         /**
386          * Requests {@link com.android.systemui.accessibility.WindowMagnification} to invoke
387          * {@code android.view.accessibility.AccessibilityManager#
388          * setWindowMagnificationConnection(IWindowMagnificationConnection)}
389          *
390          * @param connect {@code true} if needs connection, otherwise set the connection to null.
391          */
requestWindowMagnificationConnection(boolean connect)392         default void requestWindowMagnificationConnection(boolean connect) { }
393 
394         /**
395          * Handles a window manager shell logging command.
396          */
handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd)397         default void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd) {}
398 
399         /**
400          * @see IStatusBar#setNavigationBarLumaSamplingEnabled(int, boolean)
401          */
setNavigationBarLumaSamplingEnabled(int displayId, boolean enable)402         default void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {}
403     }
404 
CommandQueue(Context context)405     public CommandQueue(Context context) {
406         this(context, null, null);
407     }
408 
CommandQueue(Context context, ProtoTracer protoTracer, CommandRegistry registry)409     public CommandQueue(Context context, ProtoTracer protoTracer, CommandRegistry registry) {
410         mProtoTracer = protoTracer;
411         mRegistry = registry;
412         context.getSystemService(DisplayManager.class).registerDisplayListener(this, mHandler);
413         // We always have default display.
414         setDisabled(DEFAULT_DISPLAY, DISABLE_NONE, DISABLE2_NONE);
415     }
416 
417     @Override
onDisplayAdded(int displayId)418     public void onDisplayAdded(int displayId) { }
419 
420     @Override
onDisplayRemoved(int displayId)421     public void onDisplayRemoved(int displayId) {
422         synchronized (mLock) {
423             mDisplayDisabled.remove(displayId);
424         }
425         // This callback is registered with {@link #mHandler} that already posts to run on main
426         // thread, so it is safe to dispatch directly.
427         for (int i = mCallbacks.size() - 1; i >= 0; i--) {
428             mCallbacks.get(i).onDisplayRemoved(displayId);
429         }
430     }
431 
432     @Override
onDisplayChanged(int displayId)433     public void onDisplayChanged(int displayId) { }
434 
435     // TODO(b/118592525): add multi-display support if needed.
panelsEnabled()436     public boolean panelsEnabled() {
437         final int disabled1 = getDisabled1(DEFAULT_DISPLAY);
438         final int disabled2 = getDisabled2(DEFAULT_DISPLAY);
439         return (disabled1 & StatusBarManager.DISABLE_EXPAND) == 0
440                 && (disabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0
441                 && !ONLY_CORE_APPS;
442     }
443 
444     @Override
addCallback(@onNull Callbacks callbacks)445     public void addCallback(@NonNull Callbacks callbacks) {
446         mCallbacks.add(callbacks);
447         // TODO(b/117478341): find a better way to pass disable flags by display.
448         for (int i = 0; i < mDisplayDisabled.size(); i++) {
449             int displayId = mDisplayDisabled.keyAt(i);
450             int disabled1 = getDisabled1(displayId);
451             int disabled2 = getDisabled2(displayId);
452             callbacks.disable(displayId, disabled1, disabled2, false /* animate */);
453         }
454     }
455 
456     @Override
removeCallback(@onNull Callbacks callbacks)457     public void removeCallback(@NonNull Callbacks callbacks) {
458         mCallbacks.remove(callbacks);
459     }
460 
setIcon(String slot, StatusBarIcon icon)461     public void setIcon(String slot, StatusBarIcon icon) {
462         synchronized (mLock) {
463             // don't coalesce these
464             mHandler.obtainMessage(MSG_ICON, OP_SET_ICON, 0,
465                     new Pair<String, StatusBarIcon>(slot, icon)).sendToTarget();
466         }
467     }
468 
removeIcon(String slot)469     public void removeIcon(String slot) {
470         synchronized (mLock) {
471             // don't coalesce these
472             mHandler.obtainMessage(MSG_ICON, OP_REMOVE_ICON, 0, slot).sendToTarget();
473         }
474     }
475 
476     /**
477      * Called to notify that disable flags are updated.
478      * @see Callbacks#disable(int, int, int, boolean).
479      */
disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, boolean animate)480     public void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2,
481             boolean animate) {
482         synchronized (mLock) {
483             setDisabled(displayId, state1, state2);
484             mHandler.removeMessages(MSG_DISABLE);
485             final SomeArgs args = SomeArgs.obtain();
486             args.argi1 = displayId;
487             args.argi2 = state1;
488             args.argi3 = state2;
489             args.argi4 = animate ? 1 : 0;
490             Message msg = mHandler.obtainMessage(MSG_DISABLE, args);
491             if (Looper.myLooper() == mHandler.getLooper()) {
492                 // If its the right looper execute immediately so hides can be handled quickly.
493                 mHandler.handleMessage(msg);
494                 msg.recycle();
495             } else {
496                 msg.sendToTarget();
497             }
498         }
499     }
500 
501     @Override
disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2)502     public void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2) {
503         disable(displayId, state1, state2, true);
504     }
505 
506     /**
507      * Apply current disable flags by {@link CommandQueue#disable(int, int, int, boolean)}.
508      *
509      * @param displayId The id of the display to notify.
510      * @param animate {@code true} to show animations.
511      */
recomputeDisableFlags(int displayId, boolean animate)512     public void recomputeDisableFlags(int displayId, boolean animate) {
513         int disabled1 = getDisabled1(displayId);
514         int disabled2 = getDisabled2(displayId);
515         disable(displayId, disabled1, disabled2, animate);
516     }
517 
setDisabled(int displayId, int disabled1, int disabled2)518     private void setDisabled(int displayId, int disabled1, int disabled2) {
519         mDisplayDisabled.put(displayId, new Pair<>(disabled1, disabled2));
520     }
521 
getDisabled1(int displayId)522     private int getDisabled1(int displayId) {
523         return getDisabled(displayId).first;
524     }
525 
getDisabled2(int displayId)526     private int getDisabled2(int displayId) {
527         return getDisabled(displayId).second;
528     }
529 
getDisabled(int displayId)530     private Pair<Integer, Integer> getDisabled(int displayId) {
531         Pair<Integer, Integer> disablePair = mDisplayDisabled.get(displayId);
532         if (disablePair == null) {
533             disablePair = new Pair<>(DISABLE_NONE, DISABLE2_NONE);
534             mDisplayDisabled.put(displayId, disablePair);
535         }
536         return disablePair;
537     }
538 
animateExpandNotificationsPanel()539     public void animateExpandNotificationsPanel() {
540         synchronized (mLock) {
541             mHandler.removeMessages(MSG_EXPAND_NOTIFICATIONS);
542             mHandler.sendEmptyMessage(MSG_EXPAND_NOTIFICATIONS);
543         }
544     }
545 
animateCollapsePanels()546     public void animateCollapsePanels() {
547         synchronized (mLock) {
548             mHandler.removeMessages(MSG_COLLAPSE_PANELS);
549             mHandler.obtainMessage(MSG_COLLAPSE_PANELS, 0, 0).sendToTarget();
550         }
551     }
552 
animateCollapsePanels(int flags, boolean force)553     public void animateCollapsePanels(int flags, boolean force) {
554         synchronized (mLock) {
555             mHandler.removeMessages(MSG_COLLAPSE_PANELS);
556             mHandler.obtainMessage(MSG_COLLAPSE_PANELS, flags, force ? 1 : 0).sendToTarget();
557         }
558     }
559 
togglePanel()560     public void togglePanel() {
561         synchronized (mLock) {
562             mHandler.removeMessages(MSG_TOGGLE_PANEL);
563             mHandler.obtainMessage(MSG_TOGGLE_PANEL, 0, 0).sendToTarget();
564         }
565     }
566 
animateExpandSettingsPanel(String subPanel)567     public void animateExpandSettingsPanel(String subPanel) {
568         synchronized (mLock) {
569             mHandler.removeMessages(MSG_EXPAND_SETTINGS);
570             mHandler.obtainMessage(MSG_EXPAND_SETTINGS, subPanel).sendToTarget();
571         }
572     }
573 
574     @Override
setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher, boolean isMultiClientImeEnabled)575     public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
576             boolean showImeSwitcher, boolean isMultiClientImeEnabled) {
577         synchronized (mLock) {
578             mHandler.removeMessages(MSG_SHOW_IME_BUTTON);
579             SomeArgs args = SomeArgs.obtain();
580             args.argi1 = displayId;
581             args.argi2 = vis;
582             args.argi3 = backDisposition;
583             args.argi4 = showImeSwitcher ? 1 : 0;
584             args.argi5 = isMultiClientImeEnabled ? 1 : 0;
585             args.arg1 = token;
586             Message m = mHandler.obtainMessage(MSG_SHOW_IME_BUTTON, args);
587             m.sendToTarget();
588         }
589     }
590 
showRecentApps(boolean triggeredFromAltTab)591     public void showRecentApps(boolean triggeredFromAltTab) {
592         synchronized (mLock) {
593             mHandler.removeMessages(MSG_SHOW_RECENT_APPS);
594             mHandler.obtainMessage(MSG_SHOW_RECENT_APPS, triggeredFromAltTab ? 1 : 0, 0,
595                     null).sendToTarget();
596         }
597     }
598 
hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)599     public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
600         synchronized (mLock) {
601             mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
602             mHandler.obtainMessage(MSG_HIDE_RECENT_APPS,
603                     triggeredFromAltTab ? 1 : 0, triggeredFromHomeKey ? 1 : 0,
604                     null).sendToTarget();
605         }
606     }
607 
toggleSplitScreen()608     public void toggleSplitScreen() {
609         synchronized (mLock) {
610             mHandler.removeMessages(MSG_TOGGLE_APP_SPLIT_SCREEN);
611             mHandler.obtainMessage(MSG_TOGGLE_APP_SPLIT_SCREEN, 0, 0, null).sendToTarget();
612         }
613     }
614 
toggleRecentApps()615     public void toggleRecentApps() {
616         synchronized (mLock) {
617             mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS);
618             Message msg = mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null);
619             msg.setAsynchronous(true);
620             msg.sendToTarget();
621         }
622     }
623 
preloadRecentApps()624     public void preloadRecentApps() {
625         synchronized (mLock) {
626             mHandler.removeMessages(MSG_PRELOAD_RECENT_APPS);
627             mHandler.obtainMessage(MSG_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget();
628         }
629     }
630 
cancelPreloadRecentApps()631     public void cancelPreloadRecentApps() {
632         synchronized (mLock) {
633             mHandler.removeMessages(MSG_CANCEL_PRELOAD_RECENT_APPS);
634             mHandler.obtainMessage(MSG_CANCEL_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget();
635         }
636     }
637 
638     @Override
dismissKeyboardShortcutsMenu()639     public void dismissKeyboardShortcutsMenu() {
640         synchronized (mLock) {
641             mHandler.removeMessages(MSG_DISMISS_KEYBOARD_SHORTCUTS);
642             mHandler.obtainMessage(MSG_DISMISS_KEYBOARD_SHORTCUTS).sendToTarget();
643         }
644     }
645 
646     @Override
toggleKeyboardShortcutsMenu(int deviceId)647     public void toggleKeyboardShortcutsMenu(int deviceId) {
648         synchronized (mLock) {
649             mHandler.removeMessages(MSG_TOGGLE_KEYBOARD_SHORTCUTS);
650             mHandler.obtainMessage(MSG_TOGGLE_KEYBOARD_SHORTCUTS, deviceId, 0).sendToTarget();
651         }
652     }
653 
654     @Override
showPictureInPictureMenu()655     public void showPictureInPictureMenu() {
656         synchronized (mLock) {
657             mHandler.removeMessages(MSG_SHOW_PICTURE_IN_PICTURE_MENU);
658             mHandler.obtainMessage(MSG_SHOW_PICTURE_IN_PICTURE_MENU).sendToTarget();
659         }
660     }
661 
662     @Override
setWindowState(int displayId, int window, int state)663     public void setWindowState(int displayId, int window, int state) {
664         synchronized (mLock) {
665             // don't coalesce these
666             mHandler.obtainMessage(MSG_SET_WINDOW_STATE, displayId, window, state).sendToTarget();
667         }
668     }
669 
showScreenPinningRequest(int taskId)670     public void showScreenPinningRequest(int taskId) {
671         synchronized (mLock) {
672             mHandler.obtainMessage(MSG_SHOW_SCREEN_PIN_REQUEST, taskId, 0, null)
673                     .sendToTarget();
674         }
675     }
676 
677     @Override
appTransitionPending(int displayId)678     public void appTransitionPending(int displayId) {
679         appTransitionPending(displayId, false /* forced */);
680     }
681 
682     /**
683      * Called to notify System UI that an application transition is pending.
684      * @see Callbacks#appTransitionPending(int, boolean)
685      */
appTransitionPending(int displayId, boolean forced)686     public void appTransitionPending(int displayId, boolean forced) {
687         synchronized (mLock) {
688             mHandler.obtainMessage(MSG_APP_TRANSITION_PENDING, displayId, forced ? 1 : 0)
689                     .sendToTarget();
690         }
691     }
692 
693     @Override
appTransitionCancelled(int displayId)694     public void appTransitionCancelled(int displayId) {
695         synchronized (mLock) {
696             mHandler.obtainMessage(MSG_APP_TRANSITION_CANCELLED, displayId, 0 /* unused */)
697                     .sendToTarget();
698         }
699     }
700 
701     @Override
appTransitionStarting(int displayId, long startTime, long duration)702     public void appTransitionStarting(int displayId, long startTime, long duration) {
703         appTransitionStarting(displayId, startTime, duration, false /* forced */);
704     }
705 
706     /**
707      * Called to notify System UI that an application transition is starting.
708      * @see Callbacks#appTransitionStarting(int, long, long, boolean).
709      */
appTransitionStarting(int displayId, long startTime, long duration, boolean forced)710     public void appTransitionStarting(int displayId, long startTime, long duration,
711             boolean forced) {
712         synchronized (mLock) {
713             final SomeArgs args = SomeArgs.obtain();
714             args.argi1 = displayId;
715             args.argi2 = forced ? 1 : 0;
716             args.arg1 = startTime;
717             args.arg2 = duration;
718             mHandler.obtainMessage(MSG_APP_TRANSITION_STARTING, args).sendToTarget();
719         }
720     }
721 
722     @Override
appTransitionFinished(int displayId)723     public void appTransitionFinished(int displayId) {
724         synchronized (mLock) {
725             mHandler.obtainMessage(MSG_APP_TRANSITION_FINISHED, displayId, 0 /* unused */)
726                     .sendToTarget();
727         }
728     }
729 
showAssistDisclosure()730     public void showAssistDisclosure() {
731         synchronized (mLock) {
732             mHandler.removeMessages(MSG_ASSIST_DISCLOSURE);
733             mHandler.obtainMessage(MSG_ASSIST_DISCLOSURE).sendToTarget();
734         }
735     }
736 
startAssist(Bundle args)737     public void startAssist(Bundle args) {
738         synchronized (mLock) {
739             mHandler.removeMessages(MSG_START_ASSIST);
740             mHandler.obtainMessage(MSG_START_ASSIST, args).sendToTarget();
741         }
742     }
743 
744     @Override
onCameraLaunchGestureDetected(int source)745     public void onCameraLaunchGestureDetected(int source) {
746         synchronized (mLock) {
747             mHandler.removeMessages(MSG_CAMERA_LAUNCH_GESTURE);
748             mHandler.obtainMessage(MSG_CAMERA_LAUNCH_GESTURE, source, 0).sendToTarget();
749         }
750     }
751 
752     @Override
onEmergencyActionLaunchGestureDetected()753     public void onEmergencyActionLaunchGestureDetected() {
754         synchronized (mLock) {
755             mHandler.removeMessages(MSG_EMERGENCY_ACTION_LAUNCH_GESTURE);
756             mHandler.obtainMessage(MSG_EMERGENCY_ACTION_LAUNCH_GESTURE).sendToTarget();
757         }
758     }
759 
760     @Override
addQsTile(ComponentName tile)761     public void addQsTile(ComponentName tile) {
762         synchronized (mLock) {
763             mHandler.obtainMessage(MSG_ADD_QS_TILE, tile).sendToTarget();
764         }
765     }
766 
767     @Override
remQsTile(ComponentName tile)768     public void remQsTile(ComponentName tile) {
769         synchronized (mLock) {
770             mHandler.obtainMessage(MSG_REMOVE_QS_TILE, tile).sendToTarget();
771         }
772     }
773 
774     @Override
clickQsTile(ComponentName tile)775     public void clickQsTile(ComponentName tile) {
776         synchronized (mLock) {
777             mHandler.obtainMessage(MSG_CLICK_QS_TILE, tile).sendToTarget();
778         }
779     }
780 
781     @Override
handleSystemKey(int key)782     public void handleSystemKey(int key) {
783         synchronized (mLock) {
784             mHandler.obtainMessage(MSG_HANDLE_SYSTEM_KEY, key, 0).sendToTarget();
785         }
786     }
787 
788     @Override
showPinningEnterExitToast(boolean entering)789     public void showPinningEnterExitToast(boolean entering) {
790         synchronized (mLock) {
791             mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ENTER_EXIT, entering).sendToTarget();
792         }
793     }
794 
795     @Override
showPinningEscapeToast()796     public void showPinningEscapeToast() {
797         synchronized (mLock) {
798             mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ESCAPE).sendToTarget();
799         }
800     }
801 
802 
803     @Override
showGlobalActionsMenu()804     public void showGlobalActionsMenu() {
805         synchronized (mLock) {
806             mHandler.removeMessages(MSG_SHOW_GLOBAL_ACTIONS);
807             mHandler.obtainMessage(MSG_SHOW_GLOBAL_ACTIONS).sendToTarget();
808         }
809     }
810 
811     @Override
setTopAppHidesStatusBar(boolean hidesStatusBar)812     public void setTopAppHidesStatusBar(boolean hidesStatusBar) {
813         mHandler.removeMessages(MSG_SET_TOP_APP_HIDES_STATUS_BAR);
814         mHandler.obtainMessage(MSG_SET_TOP_APP_HIDES_STATUS_BAR, hidesStatusBar ? 1 : 0, 0)
815                 .sendToTarget();
816     }
817 
818     @Override
showShutdownUi(boolean isReboot, String reason)819     public void showShutdownUi(boolean isReboot, String reason) {
820         synchronized (mLock) {
821             mHandler.removeMessages(MSG_SHOW_SHUTDOWN_UI);
822             mHandler.obtainMessage(MSG_SHOW_SHUTDOWN_UI, isReboot ? 1 : 0, 0, reason)
823                     .sendToTarget();
824         }
825     }
826 
827     @Override
showWirelessChargingAnimation(int batteryLevel)828     public void showWirelessChargingAnimation(int batteryLevel) {
829         mHandler.removeMessages(MSG_SHOW_CHARGING_ANIMATION);
830         mHandler.obtainMessage(MSG_SHOW_CHARGING_ANIMATION, batteryLevel, 0)
831                 .sendToTarget();
832     }
833 
834     @Override
onProposedRotationChanged(int rotation, boolean isValid)835     public void onProposedRotationChanged(int rotation, boolean isValid) {
836         synchronized (mLock) {
837             mHandler.removeMessages(MSG_ROTATION_PROPOSAL);
838             mHandler.obtainMessage(MSG_ROTATION_PROPOSAL, rotation, isValid ? 1 : 0,
839                     null).sendToTarget();
840         }
841     }
842 
843     @Override
showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver, int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId, String opPackageName, long operationId, @BiometricMultiSensorMode int multiSensorConfig)844     public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver,
845             int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
846             int userId, String opPackageName, long operationId,
847             @BiometricMultiSensorMode int multiSensorConfig) {
848         synchronized (mLock) {
849             SomeArgs args = SomeArgs.obtain();
850             args.arg1 = promptInfo;
851             args.arg2 = receiver;
852             args.arg3 = sensorIds;
853             args.arg4 = credentialAllowed;
854             args.arg5 = requireConfirmation;
855             args.argi1 = userId;
856             args.arg6 = opPackageName;
857             args.arg7 = operationId;
858             args.argi2 = multiSensorConfig;
859             mHandler.obtainMessage(MSG_BIOMETRIC_SHOW, args)
860                     .sendToTarget();
861         }
862     }
863 
864     @Override
showToast(int uid, String packageName, IBinder token, CharSequence text, IBinder windowToken, int duration, @Nullable ITransientNotificationCallback callback)865     public void showToast(int uid, String packageName, IBinder token, CharSequence text,
866             IBinder windowToken, int duration, @Nullable ITransientNotificationCallback callback) {
867         synchronized (mLock) {
868             SomeArgs args = SomeArgs.obtain();
869             args.arg1 = packageName;
870             args.arg2 = token;
871             args.arg3 = text;
872             args.arg4 = windowToken;
873             args.arg5 = callback;
874             args.argi1 = uid;
875             args.argi2 = duration;
876             mHandler.obtainMessage(MSG_SHOW_TOAST, args).sendToTarget();
877         }
878     }
879 
880     @Override
hideToast(String packageName, IBinder token)881     public void hideToast(String packageName, IBinder token) {
882         synchronized (mLock) {
883             SomeArgs args = SomeArgs.obtain();
884             args.arg1 = packageName;
885             args.arg2 = token;
886             mHandler.obtainMessage(MSG_HIDE_TOAST, args).sendToTarget();
887         }
888     }
889 
890     @Override
onBiometricAuthenticated()891     public void onBiometricAuthenticated() {
892         synchronized (mLock) {
893             mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATED).sendToTarget();
894         }
895     }
896 
897     @Override
onBiometricHelp(@odality int modality, String message)898     public void onBiometricHelp(@Modality int modality, String message) {
899         synchronized (mLock) {
900             SomeArgs args = SomeArgs.obtain();
901             args.argi1 = modality;
902             args.arg1 = message;
903             mHandler.obtainMessage(MSG_BIOMETRIC_HELP, args).sendToTarget();
904         }
905     }
906 
907     @Override
onBiometricError(int modality, int error, int vendorCode)908     public void onBiometricError(int modality, int error, int vendorCode) {
909         synchronized (mLock) {
910             SomeArgs args = SomeArgs.obtain();
911             args.argi1 = modality;
912             args.argi2 = error;
913             args.argi3 = vendorCode;
914             mHandler.obtainMessage(MSG_BIOMETRIC_ERROR, args).sendToTarget();
915         }
916     }
917 
918     @Override
hideAuthenticationDialog()919     public void hideAuthenticationDialog() {
920         synchronized (mLock) {
921             mHandler.obtainMessage(MSG_BIOMETRIC_HIDE).sendToTarget();
922         }
923     }
924 
925     @Override
setUdfpsHbmListener(IUdfpsHbmListener listener)926     public void setUdfpsHbmListener(IUdfpsHbmListener listener) {
927         synchronized (mLock) {
928             mHandler.obtainMessage(MSG_SET_UDFPS_HBM_LISTENER, listener).sendToTarget();
929         }
930     }
931 
932     @Override
onDisplayReady(int displayId)933     public void onDisplayReady(int displayId) {
934         synchronized (mLock) {
935             mHandler.obtainMessage(MSG_DISPLAY_READY, displayId, 0).sendToTarget();
936         }
937     }
938 
939     @Override
onRecentsAnimationStateChanged(boolean running)940     public void onRecentsAnimationStateChanged(boolean running) {
941         synchronized (mLock) {
942             mHandler.obtainMessage(MSG_RECENTS_ANIMATION_STATE_CHANGED, running ? 1 : 0, 0)
943                     .sendToTarget();
944         }
945     }
946 
947     @Override
showInattentiveSleepWarning()948     public void showInattentiveSleepWarning() {
949         synchronized (mLock) {
950             mHandler.obtainMessage(MSG_SHOW_INATTENTIVE_SLEEP_WARNING)
951                     .sendToTarget();
952         }
953     }
954 
955     @Override
dismissInattentiveSleepWarning(boolean animated)956     public void dismissInattentiveSleepWarning(boolean animated) {
957         synchronized (mLock) {
958             mHandler.obtainMessage(MSG_DISMISS_INATTENTIVE_SLEEP_WARNING, animated)
959                     .sendToTarget();
960         }
961     }
962 
963     @Override
requestWindowMagnificationConnection(boolean connect)964     public void requestWindowMagnificationConnection(boolean connect) {
965         synchronized (mLock) {
966             mHandler.obtainMessage(MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION, connect)
967                     .sendToTarget();
968         }
969     }
970 
handleShowImeButton(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher, boolean isMultiClientImeEnabled)971     private void handleShowImeButton(int displayId, IBinder token, int vis, int backDisposition,
972             boolean showImeSwitcher, boolean isMultiClientImeEnabled) {
973         if (displayId == INVALID_DISPLAY) return;
974 
975         if (!isMultiClientImeEnabled && mLastUpdatedImeDisplayId != displayId
976                 && mLastUpdatedImeDisplayId != INVALID_DISPLAY) {
977             // Set previous NavBar's IME window status as invisible when IME
978             // window switched to another display for single-session IME case.
979             sendImeInvisibleStatusForPrevNavBar();
980         }
981         for (int i = 0; i < mCallbacks.size(); i++) {
982             mCallbacks.get(i).setImeWindowStatus(displayId, token, vis, backDisposition,
983                     showImeSwitcher);
984         }
985         mLastUpdatedImeDisplayId = displayId;
986     }
987 
sendImeInvisibleStatusForPrevNavBar()988     private void sendImeInvisibleStatusForPrevNavBar() {
989         for (int i = 0; i < mCallbacks.size(); i++) {
990             mCallbacks.get(i).setImeWindowStatus(mLastUpdatedImeDisplayId,
991                     null /* token */, IME_INVISIBLE, BACK_DISPOSITION_DEFAULT,
992                     false /* showImeSwitcher */);
993         }
994     }
995 
996     @Override
onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, boolean isFullscreen)997     public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance,
998             AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme,
999             @Behavior int behavior, boolean isFullscreen) {
1000         synchronized (mLock) {
1001             SomeArgs args = SomeArgs.obtain();
1002             args.argi1 = displayId;
1003             args.argi2 = appearance;
1004             args.argi3 = navbarColorManagedByIme ? 1 : 0;
1005             args.arg1 = appearanceRegions;
1006             args.argi4 = behavior;
1007             args.argi5 = isFullscreen ? 1 : 0;
1008             mHandler.obtainMessage(MSG_SYSTEM_BAR_CHANGED, args).sendToTarget();
1009         }
1010     }
1011 
1012     @Override
showTransient(int displayId, int[] types)1013     public void showTransient(int displayId, int[] types) {
1014         synchronized (mLock) {
1015             mHandler.obtainMessage(MSG_SHOW_TRANSIENT, displayId, 0, types).sendToTarget();
1016         }
1017     }
1018 
1019     @Override
abortTransient(int displayId, int[] types)1020     public void abortTransient(int displayId, int[] types) {
1021         synchronized (mLock) {
1022             mHandler.obtainMessage(MSG_ABORT_TRANSIENT, displayId, 0, types).sendToTarget();
1023         }
1024     }
1025 
1026     @Override
startTracing()1027     public void startTracing() {
1028         synchronized (mLock) {
1029             if (mProtoTracer != null) {
1030                 mProtoTracer.start();
1031             }
1032             mHandler.obtainMessage(MSG_TRACING_STATE_CHANGED, true).sendToTarget();
1033         }
1034     }
1035 
1036     @Override
stopTracing()1037     public void stopTracing() {
1038         synchronized (mLock) {
1039             if (mProtoTracer != null) {
1040                 mProtoTracer.stop();
1041             }
1042             mHandler.obtainMessage(MSG_TRACING_STATE_CHANGED, false).sendToTarget();
1043         }
1044     }
1045 
1046     @Override
handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd)1047     public void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd) {
1048         synchronized (mLock) {
1049             SomeArgs internalArgs = SomeArgs.obtain();
1050             internalArgs.arg1 = args;
1051             internalArgs.arg2 = outFd;
1052             mHandler.obtainMessage(MSG_HANDLE_WINDOW_MANAGER_LOGGING_COMMAND, internalArgs)
1053                     .sendToTarget();
1054         }
1055     }
1056 
1057     @Override
suppressAmbientDisplay(boolean suppress)1058     public void suppressAmbientDisplay(boolean suppress) {
1059         synchronized (mLock) {
1060             mHandler.obtainMessage(MSG_SUPPRESS_AMBIENT_DISPLAY, suppress).sendToTarget();
1061         }
1062     }
1063 
1064     @Override
setNavigationBarLumaSamplingEnabled(int displayId, boolean enable)1065     public void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {
1066         synchronized (mLock) {
1067             mHandler.obtainMessage(MSG_SET_NAVIGATION_BAR_LUMA_SAMPLING_ENABLED, displayId,
1068                     enable ? 1 : 0).sendToTarget();
1069         }
1070     }
1071 
1072     @Override
passThroughShellCommand(String[] args, ParcelFileDescriptor pfd)1073     public void passThroughShellCommand(String[] args, ParcelFileDescriptor pfd) {
1074         final FileOutputStream fos = new FileOutputStream(pfd.getFileDescriptor());
1075         final PrintWriter pw = new PrintWriter(fos);
1076         // This is mimicking Binder#dumpAsync, but on this side of the binder. Might be possible
1077         // to just throw this work onto the handler just like the other messages
1078         Thread thr = new Thread("Sysui.passThroughShellCommand") {
1079             public void run() {
1080                 try {
1081                     if (mRegistry == null) {
1082                         return;
1083                     }
1084 
1085                     // Registry blocks this thread until finished
1086                     mRegistry.onShellCommand(pw, args);
1087                 } finally {
1088                     pw.flush();
1089                     try {
1090                         // Close the file descriptor so the TransferPipe finishes its thread
1091                         pfd.close();
1092                     } catch (Exception e) {
1093                     }
1094                 }
1095             }
1096         };
1097         thr.start();
1098     }
1099 
1100     @Override
runGcForTest()1101     public void runGcForTest() {
1102         // Gc sysui
1103         GcUtils.runGcAndFinalizersSync();
1104     }
1105 
1106     private final class H extends Handler {
H(Looper l)1107         private H(Looper l) {
1108             super(l);
1109         }
1110 
handleMessage(Message msg)1111         public void handleMessage(Message msg) {
1112             final int what = msg.what & MSG_MASK;
1113             switch (what) {
1114                 case MSG_ICON: {
1115                     switch (msg.arg1) {
1116                         case OP_SET_ICON: {
1117                             Pair<String, StatusBarIcon> p = (Pair<String, StatusBarIcon>) msg.obj;
1118                             for (int i = 0; i < mCallbacks.size(); i++) {
1119                                 mCallbacks.get(i).setIcon(p.first, p.second);
1120                             }
1121                             break;
1122                         }
1123                         case OP_REMOVE_ICON:
1124                             for (int i = 0; i < mCallbacks.size(); i++) {
1125                                 mCallbacks.get(i).removeIcon((String) msg.obj);
1126                             }
1127                             break;
1128                     }
1129                     break;
1130                 }
1131                 case MSG_DISABLE:
1132                     SomeArgs args = (SomeArgs) msg.obj;
1133                     for (int i = 0; i < mCallbacks.size(); i++) {
1134                         mCallbacks.get(i).disable(args.argi1, args.argi2, args.argi3,
1135                                 args.argi4 != 0 /* animate */);
1136                     }
1137                     break;
1138                 case MSG_EXPAND_NOTIFICATIONS:
1139                     for (int i = 0; i < mCallbacks.size(); i++) {
1140                         mCallbacks.get(i).animateExpandNotificationsPanel();
1141                     }
1142                     break;
1143                 case MSG_COLLAPSE_PANELS:
1144                     for (int i = 0; i < mCallbacks.size(); i++) {
1145                         mCallbacks.get(i).animateCollapsePanels(msg.arg1, msg.arg2 != 0);
1146                     }
1147                     break;
1148                 case MSG_TOGGLE_PANEL:
1149                     for (int i = 0; i < mCallbacks.size(); i++) {
1150                         mCallbacks.get(i).togglePanel();
1151                     }
1152                     break;
1153                 case MSG_EXPAND_SETTINGS:
1154                     for (int i = 0; i < mCallbacks.size(); i++) {
1155                         mCallbacks.get(i).animateExpandSettingsPanel((String) msg.obj);
1156                     }
1157                     break;
1158                 case MSG_SHOW_IME_BUTTON:
1159                     args = (SomeArgs) msg.obj;
1160                     handleShowImeButton(args.argi1 /* displayId */, (IBinder) args.arg1 /* token */,
1161                             args.argi2 /* vis */, args.argi3 /* backDisposition */,
1162                             args.argi4 != 0 /* showImeSwitcher */,
1163                             args.argi5 != 0 /* isMultiClientImeEnabled */);
1164                     break;
1165                 case MSG_SHOW_RECENT_APPS:
1166                     for (int i = 0; i < mCallbacks.size(); i++) {
1167                         mCallbacks.get(i).showRecentApps(msg.arg1 != 0);
1168                     }
1169                     break;
1170                 case MSG_HIDE_RECENT_APPS:
1171                     for (int i = 0; i < mCallbacks.size(); i++) {
1172                         mCallbacks.get(i).hideRecentApps(msg.arg1 != 0, msg.arg2 != 0);
1173                     }
1174                     break;
1175                 case MSG_TOGGLE_RECENT_APPS:
1176                     for (int i = 0; i < mCallbacks.size(); i++) {
1177                         mCallbacks.get(i).toggleRecentApps();
1178                     }
1179                     break;
1180                 case MSG_PRELOAD_RECENT_APPS:
1181                     for (int i = 0; i < mCallbacks.size(); i++) {
1182                         mCallbacks.get(i).preloadRecentApps();
1183                     }
1184                     break;
1185                 case MSG_CANCEL_PRELOAD_RECENT_APPS:
1186                     for (int i = 0; i < mCallbacks.size(); i++) {
1187                         mCallbacks.get(i).cancelPreloadRecentApps();
1188                     }
1189                     break;
1190                 case MSG_DISMISS_KEYBOARD_SHORTCUTS:
1191                     for (int i = 0; i < mCallbacks.size(); i++) {
1192                         mCallbacks.get(i).dismissKeyboardShortcutsMenu();
1193                     }
1194                     break;
1195                 case MSG_TOGGLE_KEYBOARD_SHORTCUTS:
1196                     for (int i = 0; i < mCallbacks.size(); i++) {
1197                         mCallbacks.get(i).toggleKeyboardShortcutsMenu(msg.arg1);
1198                     }
1199                     break;
1200                 case MSG_SET_WINDOW_STATE:
1201                     for (int i = 0; i < mCallbacks.size(); i++) {
1202                         mCallbacks.get(i).setWindowState(msg.arg1, msg.arg2, (int) msg.obj);
1203                     }
1204                     break;
1205                 case MSG_SHOW_SCREEN_PIN_REQUEST:
1206                     for (int i = 0; i < mCallbacks.size(); i++) {
1207                         mCallbacks.get(i).showScreenPinningRequest(msg.arg1);
1208                     }
1209                     break;
1210                 case MSG_APP_TRANSITION_PENDING:
1211                     for (int i = 0; i < mCallbacks.size(); i++) {
1212                         mCallbacks.get(i).appTransitionPending(msg.arg1, msg.arg2 != 0);
1213                     }
1214                     break;
1215                 case MSG_APP_TRANSITION_CANCELLED:
1216                     for (int i = 0; i < mCallbacks.size(); i++) {
1217                         mCallbacks.get(i).appTransitionCancelled(msg.arg1);
1218                     }
1219                     break;
1220                 case MSG_APP_TRANSITION_STARTING:
1221                     args = (SomeArgs) msg.obj;
1222                     for (int i = 0; i < mCallbacks.size(); i++) {
1223                         mCallbacks.get(i).appTransitionStarting(args.argi1, (long) args.arg1,
1224                                 (long) args.arg2, args.argi2 != 0 /* forced */);
1225                     }
1226                     break;
1227                 case MSG_APP_TRANSITION_FINISHED:
1228                     for (int i = 0; i < mCallbacks.size(); i++) {
1229                         mCallbacks.get(i).appTransitionFinished(msg.arg1);
1230                     }
1231                     break;
1232                 case MSG_ASSIST_DISCLOSURE:
1233                     for (int i = 0; i < mCallbacks.size(); i++) {
1234                         mCallbacks.get(i).showAssistDisclosure();
1235                     }
1236                     break;
1237                 case MSG_START_ASSIST:
1238                     for (int i = 0; i < mCallbacks.size(); i++) {
1239                         mCallbacks.get(i).startAssist((Bundle) msg.obj);
1240                     }
1241                     break;
1242                 case MSG_CAMERA_LAUNCH_GESTURE:
1243                     for (int i = 0; i < mCallbacks.size(); i++) {
1244                         mCallbacks.get(i).onCameraLaunchGestureDetected(msg.arg1);
1245                     }
1246                     break;
1247                 case MSG_EMERGENCY_ACTION_LAUNCH_GESTURE:
1248                     for (int i = 0; i < mCallbacks.size(); i++) {
1249                         mCallbacks.get(i).onEmergencyActionLaunchGestureDetected();
1250                     }
1251                     break;
1252                 case MSG_SHOW_PICTURE_IN_PICTURE_MENU:
1253                     for (int i = 0; i < mCallbacks.size(); i++) {
1254                         mCallbacks.get(i).showPictureInPictureMenu();
1255                     }
1256                     break;
1257                 case MSG_ADD_QS_TILE:
1258                     for (int i = 0; i < mCallbacks.size(); i++) {
1259                         mCallbacks.get(i).addQsTile((ComponentName) msg.obj);
1260                     }
1261                     break;
1262                 case MSG_REMOVE_QS_TILE:
1263                     for (int i = 0; i < mCallbacks.size(); i++) {
1264                         mCallbacks.get(i).remQsTile((ComponentName) msg.obj);
1265                     }
1266                     break;
1267                 case MSG_CLICK_QS_TILE:
1268                     for (int i = 0; i < mCallbacks.size(); i++) {
1269                         mCallbacks.get(i).clickTile((ComponentName) msg.obj);
1270                     }
1271                     break;
1272                 case MSG_TOGGLE_APP_SPLIT_SCREEN:
1273                     for (int i = 0; i < mCallbacks.size(); i++) {
1274                         mCallbacks.get(i).toggleSplitScreen();
1275                     }
1276                     break;
1277                 case MSG_HANDLE_SYSTEM_KEY:
1278                     for (int i = 0; i < mCallbacks.size(); i++) {
1279                         mCallbacks.get(i).handleSystemKey(msg.arg1);
1280                     }
1281                     break;
1282                 case MSG_SHOW_GLOBAL_ACTIONS:
1283                     for (int i = 0; i < mCallbacks.size(); i++) {
1284                         mCallbacks.get(i).handleShowGlobalActionsMenu();
1285                     }
1286                     break;
1287                 case MSG_SHOW_SHUTDOWN_UI:
1288                     for (int i = 0; i < mCallbacks.size(); i++) {
1289                         mCallbacks.get(i).handleShowShutdownUi(msg.arg1 != 0, (String) msg.obj);
1290                     }
1291                     break;
1292                 case MSG_SET_TOP_APP_HIDES_STATUS_BAR:
1293                     for (int i = 0; i < mCallbacks.size(); i++) {
1294                         mCallbacks.get(i).setTopAppHidesStatusBar(msg.arg1 != 0);
1295                     }
1296                     break;
1297                 case MSG_ROTATION_PROPOSAL:
1298                     for (int i = 0; i < mCallbacks.size(); i++) {
1299                         mCallbacks.get(i).onRotationProposal(msg.arg1, msg.arg2 != 0);
1300                     }
1301                     break;
1302                 case MSG_BIOMETRIC_SHOW: {
1303                     mHandler.removeMessages(MSG_BIOMETRIC_ERROR);
1304                     mHandler.removeMessages(MSG_BIOMETRIC_HELP);
1305                     mHandler.removeMessages(MSG_BIOMETRIC_AUTHENTICATED);
1306                     SomeArgs someArgs = (SomeArgs) msg.obj;
1307                     for (int i = 0; i < mCallbacks.size(); i++) {
1308                         mCallbacks.get(i).showAuthenticationDialog(
1309                                 (PromptInfo) someArgs.arg1,
1310                                 (IBiometricSysuiReceiver) someArgs.arg2,
1311                                 (int[]) someArgs.arg3 /* sensorIds */,
1312                                 (boolean) someArgs.arg4 /* credentialAllowed */,
1313                                 (boolean) someArgs.arg5 /* requireConfirmation */,
1314                                 someArgs.argi1 /* userId */,
1315                                 (String) someArgs.arg6 /* opPackageName */,
1316                                 (long) someArgs.arg7 /* operationId */,
1317                                 someArgs.argi2 /* multiSensorConfig */);
1318                     }
1319                     someArgs.recycle();
1320                     break;
1321                 }
1322                 case MSG_BIOMETRIC_AUTHENTICATED: {
1323                     for (int i = 0; i < mCallbacks.size(); i++) {
1324                         mCallbacks.get(i).onBiometricAuthenticated();
1325                     }
1326                     break;
1327                 }
1328                 case MSG_BIOMETRIC_HELP: {
1329                     SomeArgs someArgs = (SomeArgs) msg.obj;
1330                     for (int i = 0; i < mCallbacks.size(); i++) {
1331                         mCallbacks.get(i).onBiometricHelp(
1332                                 someArgs.argi1 /* modality */,
1333                                 (String) someArgs.arg1 /* message */);
1334                     }
1335                     someArgs.recycle();
1336                     break;
1337                 }
1338                 case MSG_BIOMETRIC_ERROR: {
1339                     SomeArgs someArgs = (SomeArgs) msg.obj;
1340                     for (int i = 0; i < mCallbacks.size(); i++) {
1341                         mCallbacks.get(i).onBiometricError(
1342                                 someArgs.argi1 /* modality */,
1343                                 someArgs.argi2 /* error */,
1344                                 someArgs.argi3 /* vendorCode */
1345                         );
1346                     }
1347                     someArgs.recycle();
1348                     break;
1349                 }
1350                 case MSG_BIOMETRIC_HIDE:
1351                     for (int i = 0; i < mCallbacks.size(); i++) {
1352                         mCallbacks.get(i).hideAuthenticationDialog();
1353                     }
1354                     break;
1355                 case MSG_SET_UDFPS_HBM_LISTENER:
1356                     for (int i = 0; i < mCallbacks.size(); i++) {
1357                         mCallbacks.get(i).setUdfpsHbmListener((IUdfpsHbmListener) msg.obj);
1358                     }
1359                     break;
1360                 case MSG_SHOW_CHARGING_ANIMATION:
1361                     for (int i = 0; i < mCallbacks.size(); i++) {
1362                         mCallbacks.get(i).showWirelessChargingAnimation(msg.arg1);
1363                     }
1364                     break;
1365                 case MSG_SHOW_PINNING_TOAST_ENTER_EXIT:
1366                     for (int i = 0; i < mCallbacks.size(); i++) {
1367                         mCallbacks.get(i).showPinningEnterExitToast((Boolean) msg.obj);
1368                     }
1369                     break;
1370                 case MSG_SHOW_PINNING_TOAST_ESCAPE:
1371                     for (int i = 0; i < mCallbacks.size(); i++) {
1372                         mCallbacks.get(i).showPinningEscapeToast();
1373                     }
1374                     break;
1375                 case MSG_DISPLAY_READY:
1376                     for (int i = 0; i < mCallbacks.size(); i++) {
1377                         mCallbacks.get(i).onDisplayReady(msg.arg1);
1378                     }
1379                     break;
1380                 case MSG_RECENTS_ANIMATION_STATE_CHANGED:
1381                     for (int i = 0; i < mCallbacks.size(); i++) {
1382                         mCallbacks.get(i).onRecentsAnimationStateChanged(msg.arg1 > 0);
1383                     }
1384                     break;
1385                 case MSG_SYSTEM_BAR_CHANGED:
1386                     args = (SomeArgs) msg.obj;
1387                     for (int i = 0; i < mCallbacks.size(); i++) {
1388                         mCallbacks.get(i).onSystemBarAttributesChanged(args.argi1, args.argi2,
1389                                 (AppearanceRegion[]) args.arg1, args.argi3 == 1, args.argi4,
1390                                 args.argi5 == 1);
1391                     }
1392                     args.recycle();
1393                     break;
1394                 case MSG_SHOW_TRANSIENT: {
1395                     final int displayId = msg.arg1;
1396                     final int[] types = (int[]) msg.obj;
1397                     for (int i = 0; i < mCallbacks.size(); i++) {
1398                         mCallbacks.get(i).showTransient(displayId, types);
1399                     }
1400                     break;
1401                 }
1402                 case MSG_ABORT_TRANSIENT: {
1403                     final int displayId = msg.arg1;
1404                     final int[] types = (int[]) msg.obj;
1405                     for (int i = 0; i < mCallbacks.size(); i++) {
1406                         mCallbacks.get(i).abortTransient(displayId, types);
1407                     }
1408                     break;
1409                 }
1410                 case MSG_SHOW_INATTENTIVE_SLEEP_WARNING:
1411                     for (int i = 0; i < mCallbacks.size(); i++) {
1412                         mCallbacks.get(i).showInattentiveSleepWarning();
1413                     }
1414                     break;
1415                 case MSG_DISMISS_INATTENTIVE_SLEEP_WARNING:
1416                     for (int i = 0; i < mCallbacks.size(); i++) {
1417                         mCallbacks.get(i).dismissInattentiveSleepWarning((Boolean) msg.obj);
1418                     }
1419                     break;
1420                 case MSG_SHOW_TOAST: {
1421                     args = (SomeArgs) msg.obj;
1422                     String packageName = (String) args.arg1;
1423                     IBinder token = (IBinder) args.arg2;
1424                     CharSequence text = (CharSequence) args.arg3;
1425                     IBinder windowToken = (IBinder) args.arg4;
1426                     ITransientNotificationCallback callback =
1427                             (ITransientNotificationCallback) args.arg5;
1428                     int uid = args.argi1;
1429                     int duration = args.argi2;
1430                     for (Callbacks callbacks : mCallbacks) {
1431                         callbacks.showToast(uid, packageName, token, text, windowToken, duration,
1432                                 callback);
1433                     }
1434                     break;
1435                 }
1436                 case MSG_HIDE_TOAST: {
1437                     args = (SomeArgs) msg.obj;
1438                     String packageName = (String) args.arg1;
1439                     IBinder token = (IBinder) args.arg2;
1440                     for (Callbacks callbacks : mCallbacks) {
1441                         callbacks.hideToast(packageName, token);
1442                     }
1443                     break;
1444                 }
1445                 case MSG_TRACING_STATE_CHANGED:
1446                     for (int i = 0; i < mCallbacks.size(); i++) {
1447                         mCallbacks.get(i).onTracingStateChanged((Boolean) msg.obj);
1448                     }
1449                     break;
1450                 case MSG_SUPPRESS_AMBIENT_DISPLAY:
1451                     for (Callbacks callbacks: mCallbacks) {
1452                         callbacks.suppressAmbientDisplay((boolean) msg.obj);
1453                     }
1454                     break;
1455                 case MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION:
1456                     for (int i = 0; i < mCallbacks.size(); i++) {
1457                         mCallbacks.get(i).requestWindowMagnificationConnection((Boolean) msg.obj);
1458                     }
1459                     break;
1460                 case MSG_HANDLE_WINDOW_MANAGER_LOGGING_COMMAND:
1461                     args = (SomeArgs) msg.obj;
1462                     try (ParcelFileDescriptor pfd = (ParcelFileDescriptor) args.arg2) {
1463                         for (int i = 0; i < mCallbacks.size(); i++) {
1464                             mCallbacks.get(i).handleWindowManagerLoggingCommand(
1465                                     (String[]) args.arg1, pfd);
1466                         }
1467                     } catch (IOException e) {
1468                         Log.e(TAG, "Failed to handle logging command", e);
1469                     }
1470                     args.recycle();
1471                     break;
1472                 case MSG_SET_NAVIGATION_BAR_LUMA_SAMPLING_ENABLED:
1473                     for (int i = 0; i < mCallbacks.size(); i++) {
1474                         mCallbacks.get(i).setNavigationBarLumaSamplingEnabled(msg.arg1,
1475                                 msg.arg2 != 0);
1476                     }
1477                     break;
1478             }
1479         }
1480     }
1481 }
1482