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.INVALID_DISPLAY;
24 
25 import android.annotation.Nullable;
26 import android.app.ITransientNotificationCallback;
27 import android.app.StatusBarManager;
28 import android.app.StatusBarManager.Disable2Flags;
29 import android.app.StatusBarManager.DisableFlags;
30 import android.app.StatusBarManager.WindowType;
31 import android.app.StatusBarManager.WindowVisibleState;
32 import android.content.ComponentName;
33 import android.content.Context;
34 import android.graphics.drawable.Icon;
35 import android.hardware.biometrics.BiometricAuthenticator.Modality;
36 import android.hardware.biometrics.IBiometricContextListener;
37 import android.hardware.biometrics.IBiometricSysuiReceiver;
38 import android.hardware.biometrics.PromptInfo;
39 import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback;
40 import android.inputmethodservice.InputMethodService.BackDispositionMode;
41 import android.media.INearbyMediaDevicesProvider;
42 import android.media.MediaRoute2Info;
43 import android.os.Binder;
44 import android.os.Bundle;
45 import android.os.Handler;
46 import android.os.HandlerExecutor;
47 import android.os.IBinder;
48 import android.os.Looper;
49 import android.os.Message;
50 import android.os.ParcelFileDescriptor;
51 import android.os.Process;
52 import android.os.RemoteException;
53 import android.util.Pair;
54 import android.util.SparseArray;
55 import android.view.KeyEvent;
56 import android.view.WindowInsets.Type.InsetsType;
57 import android.view.WindowInsetsController.Appearance;
58 import android.view.WindowInsetsController.Behavior;
59 
60 import androidx.annotation.NonNull;
61 import androidx.annotation.VisibleForTesting;
62 
63 import com.android.internal.os.SomeArgs;
64 import com.android.internal.statusbar.IAddTileResultCallback;
65 import com.android.internal.statusbar.IStatusBar;
66 import com.android.internal.statusbar.IUndoMediaTransferCallback;
67 import com.android.internal.statusbar.LetterboxDetails;
68 import com.android.internal.statusbar.StatusBarIcon;
69 import com.android.internal.util.GcUtils;
70 import com.android.internal.view.AppearanceRegion;
71 import com.android.systemui.dump.DumpHandler;
72 import com.android.systemui.settings.DisplayTracker;
73 import com.android.systemui.statusbar.CommandQueue.Callbacks;
74 import com.android.systemui.statusbar.commandline.CommandRegistry;
75 import com.android.systemui.statusbar.policy.CallbackController;
76 
77 import java.io.FileDescriptor;
78 import java.io.FileOutputStream;
79 import java.io.OutputStream;
80 import java.io.PrintWriter;
81 import java.util.ArrayList;
82 
83 /**
84  * This class takes the functions from IStatusBar that come in on
85  * binder pool threads and posts messages to get them onto the main
86  * thread, and calls onto Callbacks.  It also takes care of
87  * coalescing these calls so they don't stack up.  For the calls
88  * are coalesced, note that they are all idempotent.
89  */
90 public class CommandQueue extends IStatusBar.Stub implements
91         CallbackController<Callbacks> {
92     private static final String TAG = CommandQueue.class.getSimpleName();
93 
94     private static final int INDEX_MASK = 0xffff;
95     private static final int MSG_SHIFT  = 16;
96     private static final int MSG_MASK   = 0xffff << MSG_SHIFT;
97 
98     private static final int OP_SET_ICON    = 1;
99     private static final int OP_REMOVE_ICON = 2;
100 
101     private static final int MSG_ICON                              = 1 << MSG_SHIFT;
102     private static final int MSG_DISABLE                           = 2 << MSG_SHIFT;
103     private static final int MSG_EXPAND_NOTIFICATIONS              = 3 << MSG_SHIFT;
104     private static final int MSG_COLLAPSE_PANELS                   = 4 << MSG_SHIFT;
105     private static final int MSG_EXPAND_SETTINGS                   = 5 << MSG_SHIFT;
106     private static final int MSG_SYSTEM_BAR_CHANGED                = 6 << MSG_SHIFT;
107     private static final int MSG_DISPLAY_READY                     = 7 << MSG_SHIFT;
108     private static final int MSG_SHOW_IME_BUTTON                   = 8 << MSG_SHIFT;
109     private static final int MSG_TOGGLE_RECENT_APPS                = 9 << MSG_SHIFT;
110     private static final int MSG_PRELOAD_RECENT_APPS               = 10 << MSG_SHIFT;
111     private static final int MSG_CANCEL_PRELOAD_RECENT_APPS        = 11 << MSG_SHIFT;
112     private static final int MSG_SET_WINDOW_STATE                  = 12 << MSG_SHIFT;
113     private static final int MSG_SHOW_RECENT_APPS                  = 13 << MSG_SHIFT;
114     private static final int MSG_HIDE_RECENT_APPS                  = 14 << MSG_SHIFT;
115     private static final int MSG_SHOW_SCREEN_PIN_REQUEST           = 18 << MSG_SHIFT;
116     private static final int MSG_APP_TRANSITION_PENDING            = 19 << MSG_SHIFT;
117     private static final int MSG_APP_TRANSITION_CANCELLED          = 20 << MSG_SHIFT;
118     private static final int MSG_APP_TRANSITION_STARTING           = 21 << MSG_SHIFT;
119     private static final int MSG_ASSIST_DISCLOSURE                 = 22 << MSG_SHIFT;
120     private static final int MSG_START_ASSIST                      = 23 << MSG_SHIFT;
121     private static final int MSG_CAMERA_LAUNCH_GESTURE             = 24 << MSG_SHIFT;
122     private static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS         = 25 << MSG_SHIFT;
123     private static final int MSG_SHOW_PICTURE_IN_PICTURE_MENU      = 26 << MSG_SHIFT;
124     private static final int MSG_ADD_QS_TILE                       = 27 << MSG_SHIFT;
125     private static final int MSG_REMOVE_QS_TILE                    = 28 << MSG_SHIFT;
126     private static final int MSG_CLICK_QS_TILE                     = 29 << MSG_SHIFT;
127     private static final int MSG_TOGGLE_APP_SPLIT_SCREEN           = 30 << MSG_SHIFT;
128     private static final int MSG_APP_TRANSITION_FINISHED           = 31 << MSG_SHIFT;
129     private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS        = 32 << MSG_SHIFT;
130     private static final int MSG_HANDLE_SYSTEM_KEY                 = 33 << MSG_SHIFT;
131     private static final int MSG_SHOW_GLOBAL_ACTIONS               = 34 << MSG_SHIFT;
132     private static final int MSG_TOGGLE_PANEL                      = 35 << MSG_SHIFT;
133     private static final int MSG_SHOW_SHUTDOWN_UI                  = 36 << MSG_SHIFT;
134     private static final int MSG_SET_TOP_APP_HIDES_STATUS_BAR      = 37 << MSG_SHIFT;
135     private static final int MSG_ROTATION_PROPOSAL                 = 38 << MSG_SHIFT;
136     private static final int MSG_BIOMETRIC_SHOW                    = 39 << MSG_SHIFT;
137     private static final int MSG_BIOMETRIC_AUTHENTICATED           = 40 << MSG_SHIFT;
138     private static final int MSG_BIOMETRIC_HELP                    = 41 << MSG_SHIFT;
139     private static final int MSG_BIOMETRIC_ERROR                   = 42 << MSG_SHIFT;
140     private static final int MSG_BIOMETRIC_HIDE                    = 43 << MSG_SHIFT;
141     private static final int MSG_SHOW_CHARGING_ANIMATION           = 44 << MSG_SHIFT;
142     private static final int MSG_SHOW_PINNING_TOAST_ENTER_EXIT     = 45 << MSG_SHIFT;
143     private static final int MSG_SHOW_PINNING_TOAST_ESCAPE         = 46 << MSG_SHIFT;
144     private static final int MSG_RECENTS_ANIMATION_STATE_CHANGED   = 47 << MSG_SHIFT;
145     private static final int MSG_SHOW_TRANSIENT                    = 48 << MSG_SHIFT;
146     private static final int MSG_ABORT_TRANSIENT                   = 49 << MSG_SHIFT;
147     private static final int MSG_SHOW_INATTENTIVE_SLEEP_WARNING    = 50 << MSG_SHIFT;
148     private static final int MSG_DISMISS_INATTENTIVE_SLEEP_WARNING = 51 << MSG_SHIFT;
149     private static final int MSG_SHOW_TOAST                        = 52 << MSG_SHIFT;
150     private static final int MSG_HIDE_TOAST                        = 53 << MSG_SHIFT;
151     private static final int MSG_TRACING_STATE_CHANGED             = 54 << MSG_SHIFT;
152     private static final int MSG_SUPPRESS_AMBIENT_DISPLAY          = 55 << MSG_SHIFT;
153     private static final int MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION = 56 << MSG_SHIFT;
154     //TODO(b/169175022) Update name and when feature name is locked.
155     private static final int MSG_EMERGENCY_ACTION_LAUNCH_GESTURE      = 58 << MSG_SHIFT;
156     private static final int MSG_SET_NAVIGATION_BAR_LUMA_SAMPLING_ENABLED = 59 << MSG_SHIFT;
157     private static final int MSG_SET_UDFPS_REFRESH_RATE_CALLBACK = 60 << MSG_SHIFT;
158     private static final int MSG_TILE_SERVICE_REQUEST_ADD = 61 << MSG_SHIFT;
159     private static final int MSG_TILE_SERVICE_REQUEST_CANCEL = 62 << MSG_SHIFT;
160     private static final int MSG_SET_BIOMETRICS_LISTENER = 63 << MSG_SHIFT;
161     private static final int MSG_MEDIA_TRANSFER_SENDER_STATE = 64 << MSG_SHIFT;
162     private static final int MSG_MEDIA_TRANSFER_RECEIVER_STATE = 65 << MSG_SHIFT;
163     private static final int MSG_REGISTER_NEARBY_MEDIA_DEVICE_PROVIDER = 66 << MSG_SHIFT;
164     private static final int MSG_UNREGISTER_NEARBY_MEDIA_DEVICE_PROVIDER = 67 << MSG_SHIFT;
165     private static final int MSG_TILE_SERVICE_REQUEST_LISTENING_STATE = 68 << MSG_SHIFT;
166     private static final int MSG_SHOW_REAR_DISPLAY_DIALOG = 69 << MSG_SHIFT;
167     private static final int MSG_GO_TO_FULLSCREEN_FROM_SPLIT = 70 << MSG_SHIFT;
168     private static final int MSG_ENTER_STAGE_SPLIT_FROM_RUNNING_APP = 71 << MSG_SHIFT;
169     private static final int MSG_SHOW_MEDIA_OUTPUT_SWITCHER = 72 << MSG_SHIFT;
170     private static final int MSG_TOGGLE_TASKBAR = 73 << MSG_SHIFT;
171     private static final int MSG_SETTING_CHANGED = 74 << MSG_SHIFT;
172     private static final int MSG_LOCK_TASK_MODE_CHANGED = 75 << MSG_SHIFT;
173     private static final int MSG_CONFIRM_IMMERSIVE_PROMPT = 77 << MSG_SHIFT;
174     private static final int MSG_IMMERSIVE_CHANGED = 78 << MSG_SHIFT;
175     public static final int FLAG_EXCLUDE_NONE = 0;
176     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
177     public static final int FLAG_EXCLUDE_RECENTS_PANEL = 1 << 1;
178     public static final int FLAG_EXCLUDE_NOTIFICATION_PANEL = 1 << 2;
179     public static final int FLAG_EXCLUDE_INPUT_METHODS_PANEL = 1 << 3;
180     public static final int FLAG_EXCLUDE_COMPAT_MODE_PANEL = 1 << 4;
181 
182     private static final String SHOW_IME_SWITCHER_KEY = "showImeSwitcherKey";
183 
184     private final Object mLock = new Object();
185     private ArrayList<Callbacks> mCallbacks = new ArrayList<>();
186     private Handler mHandler = new H(Looper.getMainLooper());
187     /** A map of display id - disable flag pair */
188     private SparseArray<Pair<Integer, Integer>> mDisplayDisabled = new SparseArray<>();
189     /**
190      * The last ID of the display where IME window for which we received setImeWindowStatus
191      * event.
192      */
193     private int mLastUpdatedImeDisplayId = INVALID_DISPLAY;
194     private final DisplayTracker mDisplayTracker;
195     private final @Nullable CommandRegistry mRegistry;
196     private final @Nullable DumpHandler mDumpHandler;
197 
198     /**
199      * These methods are called back on the main thread.
200      */
201     public interface Callbacks {
setIcon(String slot, StatusBarIcon icon)202         default void setIcon(String slot, StatusBarIcon icon) { }
removeIcon(String slot)203         default void removeIcon(String slot) { }
204 
205         /**
206          * Called to notify that disable flags are updated.
207          * @see IStatusBar#disable(int, int, int).
208          *
209          * @param displayId The id of the display to notify.
210          * @param state1 The combination of following DISABLE_* flags:
211          * @param state2 The combination of following DISABLE2_* flags:
212          * @param animate {@code true} to show animations.
213          */
disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, boolean animate)214         default void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2,
215                 boolean animate) { }
animateExpandNotificationsPanel()216         default void animateExpandNotificationsPanel() { }
animateCollapsePanels(int flags, boolean force)217         default void animateCollapsePanels(int flags, boolean force) { }
togglePanel()218         default void togglePanel() { }
animateExpandSettingsPanel(String obj)219         default void animateExpandSettingsPanel(String obj) { }
220 
221         /**
222          * Called to notify IME window status changes.
223          *
224          * @param displayId The id of the display to notify.
225          * @param token IME token.
226          * @param vis IME visibility.
227          * @param backDisposition Disposition mode of back button. It should be one of below flags:
228          * @param showImeSwitcher {@code true} to show IME switch button.
229          */
setImeWindowStatus(int displayId, IBinder token, int vis, @BackDispositionMode int backDisposition, boolean showImeSwitcher)230         default void setImeWindowStatus(int displayId, IBinder token,  int vis,
231                 @BackDispositionMode int backDisposition, boolean showImeSwitcher) { }
showRecentApps(boolean triggeredFromAltTab)232         default void showRecentApps(boolean triggeredFromAltTab) { }
hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)233         default void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { }
toggleTaskbar()234         default void toggleTaskbar() { }
toggleRecentApps()235         default void toggleRecentApps() { }
toggleSplitScreen()236         default void toggleSplitScreen() { }
preloadRecentApps()237         default void preloadRecentApps() { }
dismissKeyboardShortcutsMenu()238         default void dismissKeyboardShortcutsMenu() { }
toggleKeyboardShortcutsMenu(int deviceId)239         default void toggleKeyboardShortcutsMenu(int deviceId) { }
cancelPreloadRecentApps()240         default void cancelPreloadRecentApps() { }
241 
242         /**
243          * Called to notify window state changes.
244          * @see IStatusBar#setWindowState(int, int, int)
245          *
246          * @param displayId The id of the display to notify.
247          * @param window Window type. It should be one of {@link StatusBarManager#WINDOW_STATUS_BAR}
248          *               or {@link StatusBarManager#WINDOW_NAVIGATION_BAR}
249          * @param state Window visible state.
250          */
setWindowState(int displayId, @WindowType int window, @WindowVisibleState int state)251         default void setWindowState(int displayId, @WindowType int window,
252                 @WindowVisibleState int state) { }
showScreenPinningRequest(int taskId)253         default void showScreenPinningRequest(int taskId) { }
254 
255         /**
256          * Called to notify System UI that an application transition is pending.
257          * @see IStatusBar#appTransitionPending(int).
258          *
259          * @param displayId The id of the display to notify.
260          * @param forced {@code true} to force transition pending.
261          */
appTransitionPending(int displayId, boolean forced)262         default void appTransitionPending(int displayId, boolean forced) { }
263 
264         /**
265          * Called to notify System UI that an application transition is canceled.
266          * @see IStatusBar#appTransitionCancelled(int).
267          *
268          * @param displayId The id of the display to notify.
269          */
appTransitionCancelled(int displayId)270         default void appTransitionCancelled(int displayId) { }
271 
272         /**
273          * Called to notify System UI that an application transition is starting.
274          * @see IStatusBar#appTransitionStarting(int, long, long).
275          *
276          * @param displayId The id of the display to notify.
277          * @param startTime Transition start time.
278          * @param duration Transition duration.
279          * @param forced {@code true} to force transition pending.
280          */
appTransitionStarting( int displayId, long startTime, long duration, boolean forced)281         default void appTransitionStarting(
282                 int displayId, long startTime, long duration, boolean forced) { }
283 
284         /**
285          * Called to notify System UI that an application transition is finished.
286          * @see IStatusBar#appTransitionFinished(int)
287          *
288          * @param displayId The id of the display to notify.
289          */
appTransitionFinished(int displayId)290         default void appTransitionFinished(int displayId) { }
showAssistDisclosure()291         default void showAssistDisclosure() { }
startAssist(Bundle args)292         default void startAssist(Bundle args) { }
onCameraLaunchGestureDetected(int source)293         default void onCameraLaunchGestureDetected(int source) { }
294 
295         /**
296          * Notifies SysUI that the emergency action gesture was detected.
297          */
onEmergencyActionLaunchGestureDetected()298         default void onEmergencyActionLaunchGestureDetected() { }
showPictureInPictureMenu()299         default void showPictureInPictureMenu() { }
setTopAppHidesStatusBar(boolean topAppHidesStatusBar)300         default void setTopAppHidesStatusBar(boolean topAppHidesStatusBar) { }
301 
addQsTile(ComponentName tile)302         default void addQsTile(ComponentName tile) { }
remQsTile(ComponentName tile)303         default void remQsTile(ComponentName tile) { }
clickTile(ComponentName tile)304         default void clickTile(ComponentName tile) { }
305 
handleSystemKey(KeyEvent arg1)306         default void handleSystemKey(KeyEvent arg1) { }
showPinningEnterExitToast(boolean entering)307         default void showPinningEnterExitToast(boolean entering) { }
showPinningEscapeToast()308         default void showPinningEscapeToast() { }
handleShowGlobalActionsMenu()309         default void handleShowGlobalActionsMenu() { }
handleShowShutdownUi(boolean isReboot, String reason)310         default void handleShowShutdownUi(boolean isReboot, String reason) { }
311 
showWirelessChargingAnimation(int batteryLevel)312         default void showWirelessChargingAnimation(int batteryLevel) {  }
313 
onRotationProposal(int rotation, boolean isValid)314         default void onRotationProposal(int rotation, boolean isValid) { }
315 
showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver, int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId, long operationId, String opPackageName, long requestId)316         default void showAuthenticationDialog(PromptInfo promptInfo,
317                 IBiometricSysuiReceiver receiver,
318                 int[] sensorIds, boolean credentialAllowed,
319                 boolean requireConfirmation, int userId, long operationId, String opPackageName,
320                 long requestId) {
321         }
322 
323         /** @see IStatusBar#onBiometricAuthenticated(int) */
onBiometricAuthenticated(@odality int modality)324         default void onBiometricAuthenticated(@Modality int modality) {
325         }
326 
327         /** @see IStatusBar#onBiometricHelp(int, String) */
onBiometricHelp(@odality int modality, String message)328         default void onBiometricHelp(@Modality int modality, String message) {
329         }
330 
331         /** @see IStatusBar#onBiometricError(int, int, int) */
onBiometricError(@odality int modality, int error, int vendorCode)332         default void onBiometricError(@Modality int modality, int error, int vendorCode) {
333         }
334 
hideAuthenticationDialog(long requestId)335         default void hideAuthenticationDialog(long requestId) {
336         }
337 
338         /**
339          * @see IStatusBar#setBiometicContextListener(IBiometricContextListener)
340          */
setBiometricContextListener(IBiometricContextListener listener)341         default void setBiometricContextListener(IBiometricContextListener listener) {
342         }
343 
344         /**
345          * @see IStatusBar#setUdfpsRefreshRateCallback(IUdfpsRefreshRateRequestCallback)
346          */
setUdfpsRefreshRateCallback(IUdfpsRefreshRateRequestCallback callback)347         default void setUdfpsRefreshRateCallback(IUdfpsRefreshRateRequestCallback callback) {
348         }
349 
350         /**
351          * @see IStatusBar#onDisplayReady(int)
352          */
onDisplayReady(int displayId)353         default void onDisplayReady(int displayId) {
354         }
355 
356         /**
357          * @see DisplayTracker.Callback#onDisplayRemoved(int)
358          */
onDisplayRemoved(int displayId)359         default void onDisplayRemoved(int displayId) {
360         }
361 
362         /**
363          * @see IStatusBar#onRecentsAnimationStateChanged(boolean)
364          */
onRecentsAnimationStateChanged(boolean running)365         default void onRecentsAnimationStateChanged(boolean running) { }
366 
367         /**
368          * @see IStatusBar#onSystemBarAttributesChanged
369          */
onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, @InsetsType int requestedVisibleTypes, String packageName, LetterboxDetails[] letterboxDetails)370         default void onSystemBarAttributesChanged(int displayId, @Appearance int appearance,
371                 AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme,
372                 @Behavior int behavior, @InsetsType int requestedVisibleTypes,
373                 String packageName, LetterboxDetails[] letterboxDetails) { }
374 
375         /**
376          * @see IStatusBar#showTransient(int, int, boolean).
377          */
showTransient(int displayId, @InsetsType int types)378         default void showTransient(int displayId, @InsetsType int types) { }
379 
380         /**
381          * @see IStatusBar#showTransient(int, int, boolean).
382          */
showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar)383         default void showTransient(int displayId, @InsetsType int types,
384                 boolean isGestureOnSystemBar) {
385             showTransient(displayId, types);
386         }
387 
388         /**
389          * @see IStatusBar#abortTransient(int, int).
390          */
abortTransient(int displayId, @InsetsType int types)391         default void abortTransient(int displayId, @InsetsType int types) { }
392 
393         /**
394          * Called to notify System UI that a warning about the device going to sleep
395          * due to prolonged user inactivity should be shown.
396          */
showInattentiveSleepWarning()397         default void showInattentiveSleepWarning() { }
398 
399         /**
400          * Called to notify System UI that the warning about the device going to sleep
401          * due to prolonged user inactivity should be dismissed.
402          */
dismissInattentiveSleepWarning(boolean animated)403         default void dismissInattentiveSleepWarning(boolean animated) { }
404 
405         /** Called to suppress ambient display. */
suppressAmbientDisplay(boolean suppress)406         default void suppressAmbientDisplay(boolean suppress) { }
407 
408         /**
409          * @see IStatusBar#showToast(int, String, IBinder, CharSequence, IBinder, int,
410          * ITransientNotificationCallback, int)
411          */
showToast(int uid, String packageName, IBinder token, CharSequence text, IBinder windowToken, int duration, @Nullable ITransientNotificationCallback callback, int displayId)412         default void showToast(int uid, String packageName, IBinder token, CharSequence text,
413                 IBinder windowToken, int duration,
414                 @Nullable ITransientNotificationCallback callback, int displayId) { }
415 
416         /**
417          * @see IStatusBar#hideToast(String, IBinder) (String, IBinder)
418          */
hideToast(String packageName, IBinder token)419         default void hideToast(String packageName, IBinder token) { }
420 
421         /**
422          * @param enabled
423          */
onTracingStateChanged(boolean enabled)424         default void onTracingStateChanged(boolean enabled) { }
425 
426         /**
427          * Requests {@link com.android.systemui.accessibility.WindowMagnification} to invoke
428          * {@code android.view.accessibility.AccessibilityManager#
429          * setWindowMagnificationConnection(IWindowMagnificationConnection)}
430          *
431          * @param connect {@code true} if needs connection, otherwise set the connection to null.
432          */
requestWindowMagnificationConnection(boolean connect)433         default void requestWindowMagnificationConnection(boolean connect) { }
434 
435         /**
436          * @see IStatusBar#setNavigationBarLumaSamplingEnabled(int, boolean)
437          */
setNavigationBarLumaSamplingEnabled(int displayId, boolean enable)438         default void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {}
439 
440         /**
441          * @see IStatusBar#requestTileServiceListeningState
442          */
requestTileServiceListeningState(@onNull ComponentName componentName)443         default void requestTileServiceListeningState(@NonNull ComponentName componentName) {}
444 
445         /**
446          * @see IStatusBar#requestAddTile
447          */
requestAddTile( @onNull ComponentName componentName, @NonNull CharSequence appName, @NonNull CharSequence label, @NonNull Icon icon, @NonNull IAddTileResultCallback callback)448         default void requestAddTile(
449                 @NonNull ComponentName componentName,
450                 @NonNull CharSequence appName,
451                 @NonNull CharSequence label,
452                 @NonNull Icon icon,
453                 @NonNull IAddTileResultCallback callback) {}
454 
455         /**
456          * @see IStatusBar#cancelRequestAddTile
457          */
cancelRequestAddTile(@onNull String packageName)458         default void cancelRequestAddTile(@NonNull String packageName) {}
459 
460         /** @see IStatusBar#updateMediaTapToTransferSenderDisplay */
updateMediaTapToTransferSenderDisplay( @tatusBarManager.MediaTransferSenderState int displayState, @NonNull MediaRoute2Info routeInfo, @Nullable IUndoMediaTransferCallback undoCallback)461         default void updateMediaTapToTransferSenderDisplay(
462                 @StatusBarManager.MediaTransferSenderState int displayState,
463                 @NonNull MediaRoute2Info routeInfo,
464                 @Nullable IUndoMediaTransferCallback undoCallback) {}
465 
466         /** @see IStatusBar#updateMediaTapToTransferReceiverDisplay */
updateMediaTapToTransferReceiverDisplay( @tatusBarManager.MediaTransferReceiverState int displayState, @NonNull MediaRoute2Info routeInfo, @Nullable Icon appIcon, @Nullable CharSequence appName)467         default void updateMediaTapToTransferReceiverDisplay(
468                 @StatusBarManager.MediaTransferReceiverState int displayState,
469                 @NonNull MediaRoute2Info routeInfo,
470                 @Nullable Icon appIcon,
471                 @Nullable CharSequence appName) {}
472 
473         /**
474          * @see IStatusBar#registerNearbyMediaDevicesProvider
475          */
registerNearbyMediaDevicesProvider( @onNull INearbyMediaDevicesProvider provider)476         default void registerNearbyMediaDevicesProvider(
477                 @NonNull INearbyMediaDevicesProvider provider) {}
478 
479         /**
480          * @see IStatusBar#unregisterNearbyMediaDevicesProvider
481          */
unregisterNearbyMediaDevicesProvider( @onNull INearbyMediaDevicesProvider provider)482         default void unregisterNearbyMediaDevicesProvider(
483                 @NonNull INearbyMediaDevicesProvider provider) {}
484 
485         /**
486          * @see IStatusBar#showRearDisplayDialog
487          */
showRearDisplayDialog(int currentBaseState)488         default void showRearDisplayDialog(int currentBaseState) {}
489 
490         /**
491          * @see IStatusBar#goToFullscreenFromSplit
492          */
goToFullscreenFromSplit()493         default void goToFullscreenFromSplit() {}
494 
495         /**
496          * @see IStatusBar#enterStageSplitFromRunningApp
497          */
enterStageSplitFromRunningApp(boolean leftOrTop)498         default void enterStageSplitFromRunningApp(boolean leftOrTop) {}
499 
500         /**
501          * @see IStatusBar#showMediaOutputSwitcher
502          */
showMediaOutputSwitcher(String packageName)503         default void showMediaOutputSwitcher(String packageName) {}
504 
505         /**
506          * @see IStatusBar#confirmImmersivePrompt
507          */
confirmImmersivePrompt()508         default void confirmImmersivePrompt() {}
509 
510         /**
511          * @see IStatusBar#immersiveModeChanged
512          */
immersiveModeChanged(int rootDisplayAreaId, boolean isImmersiveMode)513         default void immersiveModeChanged(int rootDisplayAreaId, boolean isImmersiveMode) {}
514     }
515 
516     @VisibleForTesting
CommandQueue(Context context, DisplayTracker displayTracker)517     public CommandQueue(Context context, DisplayTracker displayTracker) {
518         this(context, displayTracker, null, null);
519     }
520 
CommandQueue( Context context, DisplayTracker displayTracker, CommandRegistry registry, DumpHandler dumpHandler )521     public CommandQueue(
522             Context context,
523             DisplayTracker displayTracker,
524             CommandRegistry registry,
525             DumpHandler dumpHandler
526     ) {
527         mDisplayTracker = displayTracker;
528         mRegistry = registry;
529         mDumpHandler = dumpHandler;
530         mDisplayTracker.addDisplayChangeCallback(new DisplayTracker.Callback() {
531             @Override
532             public void onDisplayRemoved(int displayId) {
533                 synchronized (mLock) {
534                     mDisplayDisabled.remove(displayId);
535                 }
536                 // This callback is registered with {@link #mHandler} that already posts to run on
537                 // main thread, so it is safe to dispatch directly.
538                 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
539                     mCallbacks.get(i).onDisplayRemoved(displayId);
540                 }
541             }
542         }, new HandlerExecutor(mHandler));
543         // We always have default display.
544         setDisabled(mDisplayTracker.getDefaultDisplayId(), DISABLE_NONE, DISABLE2_NONE);
545     }
546 
547     // TODO(b/118592525): add multi-display support if needed.
panelsEnabled()548     public boolean panelsEnabled() {
549         final int disabled1 = getDisabled1(mDisplayTracker.getDefaultDisplayId());
550         final int disabled2 = getDisabled2(mDisplayTracker.getDefaultDisplayId());
551         return (disabled1 & StatusBarManager.DISABLE_EXPAND) == 0
552                 && (disabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0;
553     }
554 
555     @Override
addCallback(@onNull Callbacks callbacks)556     public void addCallback(@NonNull Callbacks callbacks) {
557         mCallbacks.add(callbacks);
558         // TODO(b/117478341): find a better way to pass disable flags by display.
559         for (int i = 0; i < mDisplayDisabled.size(); i++) {
560             int displayId = mDisplayDisabled.keyAt(i);
561             int disabled1 = getDisabled1(displayId);
562             int disabled2 = getDisabled2(displayId);
563             callbacks.disable(displayId, disabled1, disabled2, false /* animate */);
564         }
565     }
566 
567     @Override
removeCallback(@onNull Callbacks callbacks)568     public void removeCallback(@NonNull Callbacks callbacks) {
569         mCallbacks.remove(callbacks);
570     }
571 
setIcon(String slot, StatusBarIcon icon)572     public void setIcon(String slot, StatusBarIcon icon) {
573         synchronized (mLock) {
574             // don't coalesce these
575             mHandler.obtainMessage(MSG_ICON, OP_SET_ICON, 0,
576                     new Pair<String, StatusBarIcon>(slot, icon)).sendToTarget();
577         }
578     }
579 
removeIcon(String slot)580     public void removeIcon(String slot) {
581         synchronized (mLock) {
582             // don't coalesce these
583             mHandler.obtainMessage(MSG_ICON, OP_REMOVE_ICON, 0, slot).sendToTarget();
584         }
585     }
586 
587     /**
588      * Called to notify that disable flags are updated.
589      * @see Callbacks#disable(int, int, int, boolean).
590      */
disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, boolean animate)591     public void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2,
592             boolean animate) {
593         synchronized (mLock) {
594             setDisabled(displayId, state1, state2);
595             mHandler.removeMessages(MSG_DISABLE);
596             final SomeArgs args = SomeArgs.obtain();
597             args.argi1 = displayId;
598             args.argi2 = state1;
599             args.argi3 = state2;
600             args.argi4 = animate ? 1 : 0;
601             Message msg = mHandler.obtainMessage(MSG_DISABLE, args);
602             if (Looper.myLooper() == mHandler.getLooper()) {
603                 // If its the right looper execute immediately so hides can be handled quickly.
604                 mHandler.handleMessage(msg);
605                 msg.recycle();
606             } else {
607                 msg.sendToTarget();
608             }
609         }
610     }
611 
612     @Override
disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2)613     public void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2) {
614         disable(displayId, state1, state2, true);
615     }
616 
617     /**
618      * Apply current disable flags by {@link CommandQueue#disable(int, int, int, boolean)}.
619      *
620      * @param displayId The id of the display to notify.
621      * @param animate {@code true} to show animations.
622      */
recomputeDisableFlags(int displayId, boolean animate)623     public void recomputeDisableFlags(int displayId, boolean animate) {
624         // This must update holding the lock otherwise it can clobber the disabled flags set on the
625         // binder thread from the disable() call
626         synchronized (mLock) {
627             int disabled1 = getDisabled1(displayId);
628             int disabled2 = getDisabled2(displayId);
629             disable(displayId, disabled1, disabled2, animate);
630         }
631     }
632 
setDisabled(int displayId, int disabled1, int disabled2)633     private void setDisabled(int displayId, int disabled1, int disabled2) {
634         mDisplayDisabled.put(displayId, new Pair<>(disabled1, disabled2));
635     }
636 
getDisabled1(int displayId)637     private int getDisabled1(int displayId) {
638         return getDisabled(displayId).first;
639     }
640 
getDisabled2(int displayId)641     private int getDisabled2(int displayId) {
642         return getDisabled(displayId).second;
643     }
644 
getDisabled(int displayId)645     private Pair<Integer, Integer> getDisabled(int displayId) {
646         Pair<Integer, Integer> disablePair = mDisplayDisabled.get(displayId);
647         if (disablePair == null) {
648             disablePair = new Pair<>(DISABLE_NONE, DISABLE2_NONE);
649             mDisplayDisabled.put(displayId, disablePair);
650         }
651         return disablePair;
652     }
653 
animateExpandNotificationsPanel()654     public void animateExpandNotificationsPanel() {
655         synchronized (mLock) {
656             mHandler.removeMessages(MSG_EXPAND_NOTIFICATIONS);
657             mHandler.sendEmptyMessage(MSG_EXPAND_NOTIFICATIONS);
658         }
659     }
660 
animateCollapsePanels()661     public void animateCollapsePanels() {
662         synchronized (mLock) {
663             mHandler.removeMessages(MSG_COLLAPSE_PANELS);
664             mHandler.obtainMessage(MSG_COLLAPSE_PANELS, 0, 0).sendToTarget();
665         }
666     }
667 
animateCollapsePanels(int flags, boolean force)668     public void animateCollapsePanels(int flags, boolean force) {
669         synchronized (mLock) {
670             mHandler.removeMessages(MSG_COLLAPSE_PANELS);
671             mHandler.obtainMessage(MSG_COLLAPSE_PANELS, flags, force ? 1 : 0).sendToTarget();
672         }
673     }
674 
togglePanel()675     public void togglePanel() {
676         synchronized (mLock) {
677             mHandler.removeMessages(MSG_TOGGLE_PANEL);
678             mHandler.obtainMessage(MSG_TOGGLE_PANEL, 0, 0).sendToTarget();
679         }
680     }
681 
animateExpandSettingsPanel(String subPanel)682     public void animateExpandSettingsPanel(String subPanel) {
683         synchronized (mLock) {
684             mHandler.removeMessages(MSG_EXPAND_SETTINGS);
685             mHandler.obtainMessage(MSG_EXPAND_SETTINGS, subPanel).sendToTarget();
686         }
687     }
688 
689     @Override
setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher)690     public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
691             boolean showImeSwitcher) {
692         synchronized (mLock) {
693             mHandler.removeMessages(MSG_SHOW_IME_BUTTON);
694             SomeArgs args = SomeArgs.obtain();
695             args.argi1 = displayId;
696             args.argi2 = vis;
697             args.argi3 = backDisposition;
698             args.argi4 = showImeSwitcher ? 1 : 0;
699             args.arg1 = token;
700             Message m = mHandler.obtainMessage(MSG_SHOW_IME_BUTTON, args);
701             m.sendToTarget();
702         }
703     }
704 
showRecentApps(boolean triggeredFromAltTab)705     public void showRecentApps(boolean triggeredFromAltTab) {
706         synchronized (mLock) {
707             mHandler.removeMessages(MSG_SHOW_RECENT_APPS);
708             mHandler.obtainMessage(MSG_SHOW_RECENT_APPS, triggeredFromAltTab ? 1 : 0, 0,
709                     null).sendToTarget();
710         }
711     }
712 
hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)713     public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
714         synchronized (mLock) {
715             mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
716             mHandler.obtainMessage(MSG_HIDE_RECENT_APPS,
717                     triggeredFromAltTab ? 1 : 0, triggeredFromHomeKey ? 1 : 0,
718                     null).sendToTarget();
719         }
720     }
721 
toggleSplitScreen()722     public void toggleSplitScreen() {
723         synchronized (mLock) {
724             mHandler.removeMessages(MSG_TOGGLE_APP_SPLIT_SCREEN);
725             mHandler.obtainMessage(MSG_TOGGLE_APP_SPLIT_SCREEN, 0, 0, null).sendToTarget();
726         }
727     }
728 
toggleTaskbar()729     public void toggleTaskbar() {
730         synchronized (mLock) {
731             mHandler.removeMessages(MSG_TOGGLE_TASKBAR);
732             mHandler.obtainMessage(MSG_TOGGLE_TASKBAR, 0, 0, null).sendToTarget();
733         }
734     }
735 
toggleRecentApps()736     public void toggleRecentApps() {
737         synchronized (mLock) {
738             mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS);
739             Message msg = mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null);
740             msg.setAsynchronous(true);
741             msg.sendToTarget();
742         }
743     }
744 
preloadRecentApps()745     public void preloadRecentApps() {
746         synchronized (mLock) {
747             mHandler.removeMessages(MSG_PRELOAD_RECENT_APPS);
748             mHandler.obtainMessage(MSG_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget();
749         }
750     }
751 
cancelPreloadRecentApps()752     public void cancelPreloadRecentApps() {
753         synchronized (mLock) {
754             mHandler.removeMessages(MSG_CANCEL_PRELOAD_RECENT_APPS);
755             mHandler.obtainMessage(MSG_CANCEL_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget();
756         }
757     }
758 
759     @Override
dismissKeyboardShortcutsMenu()760     public void dismissKeyboardShortcutsMenu() {
761         synchronized (mLock) {
762             mHandler.removeMessages(MSG_DISMISS_KEYBOARD_SHORTCUTS);
763             mHandler.obtainMessage(MSG_DISMISS_KEYBOARD_SHORTCUTS).sendToTarget();
764         }
765     }
766 
767     @Override
toggleKeyboardShortcutsMenu(int deviceId)768     public void toggleKeyboardShortcutsMenu(int deviceId) {
769         synchronized (mLock) {
770             mHandler.removeMessages(MSG_TOGGLE_KEYBOARD_SHORTCUTS);
771             mHandler.obtainMessage(MSG_TOGGLE_KEYBOARD_SHORTCUTS, deviceId, 0).sendToTarget();
772         }
773     }
774 
775     @Override
showPictureInPictureMenu()776     public void showPictureInPictureMenu() {
777         synchronized (mLock) {
778             mHandler.removeMessages(MSG_SHOW_PICTURE_IN_PICTURE_MENU);
779             mHandler.obtainMessage(MSG_SHOW_PICTURE_IN_PICTURE_MENU).sendToTarget();
780         }
781     }
782 
783     @Override
setWindowState(int displayId, int window, int state)784     public void setWindowState(int displayId, int window, int state) {
785         synchronized (mLock) {
786             // don't coalesce these
787             mHandler.obtainMessage(MSG_SET_WINDOW_STATE, displayId, window, state).sendToTarget();
788         }
789     }
790 
showScreenPinningRequest(int taskId)791     public void showScreenPinningRequest(int taskId) {
792         synchronized (mLock) {
793             mHandler.obtainMessage(MSG_SHOW_SCREEN_PIN_REQUEST, taskId, 0, null)
794                     .sendToTarget();
795         }
796     }
797 
798     @Override
confirmImmersivePrompt()799     public void confirmImmersivePrompt() {
800         synchronized (mLock) {
801             mHandler.obtainMessage(MSG_CONFIRM_IMMERSIVE_PROMPT).sendToTarget();
802         }
803     }
804 
805     @Override
immersiveModeChanged(int rootDisplayAreaId, boolean isImmersiveMode)806     public void immersiveModeChanged(int rootDisplayAreaId, boolean isImmersiveMode) {
807         synchronized (mLock) {
808             final SomeArgs args = SomeArgs.obtain();
809             args.argi1 = rootDisplayAreaId;
810             args.argi2 = isImmersiveMode ? 1 : 0;
811             mHandler.obtainMessage(MSG_IMMERSIVE_CHANGED, args).sendToTarget();
812         }
813     }
814 
815     @Override
appTransitionPending(int displayId)816     public void appTransitionPending(int displayId) {
817         appTransitionPending(displayId, false /* forced */);
818     }
819 
820     /**
821      * Called to notify System UI that an application transition is pending.
822      * @see Callbacks#appTransitionPending(int, boolean)
823      */
appTransitionPending(int displayId, boolean forced)824     public void appTransitionPending(int displayId, boolean forced) {
825         synchronized (mLock) {
826             mHandler.obtainMessage(MSG_APP_TRANSITION_PENDING, displayId, forced ? 1 : 0)
827                     .sendToTarget();
828         }
829     }
830 
831     @Override
appTransitionCancelled(int displayId)832     public void appTransitionCancelled(int displayId) {
833         synchronized (mLock) {
834             mHandler.obtainMessage(MSG_APP_TRANSITION_CANCELLED, displayId, 0 /* unused */)
835                     .sendToTarget();
836         }
837     }
838 
839     @Override
appTransitionStarting(int displayId, long startTime, long duration)840     public void appTransitionStarting(int displayId, long startTime, long duration) {
841         appTransitionStarting(displayId, startTime, duration, false /* forced */);
842     }
843 
844     /**
845      * Called to notify System UI that an application transition is starting.
846      * @see Callbacks#appTransitionStarting(int, long, long, boolean).
847      */
appTransitionStarting(int displayId, long startTime, long duration, boolean forced)848     public void appTransitionStarting(int displayId, long startTime, long duration,
849             boolean forced) {
850         synchronized (mLock) {
851             final SomeArgs args = SomeArgs.obtain();
852             args.argi1 = displayId;
853             args.argi2 = forced ? 1 : 0;
854             args.arg1 = startTime;
855             args.arg2 = duration;
856             mHandler.obtainMessage(MSG_APP_TRANSITION_STARTING, args).sendToTarget();
857         }
858     }
859 
860     @Override
appTransitionFinished(int displayId)861     public void appTransitionFinished(int displayId) {
862         synchronized (mLock) {
863             mHandler.obtainMessage(MSG_APP_TRANSITION_FINISHED, displayId, 0 /* unused */)
864                     .sendToTarget();
865         }
866     }
867 
showAssistDisclosure()868     public void showAssistDisclosure() {
869         synchronized (mLock) {
870             mHandler.removeMessages(MSG_ASSIST_DISCLOSURE);
871             mHandler.obtainMessage(MSG_ASSIST_DISCLOSURE).sendToTarget();
872         }
873     }
874 
startAssist(Bundle args)875     public void startAssist(Bundle args) {
876         synchronized (mLock) {
877             mHandler.removeMessages(MSG_START_ASSIST);
878             mHandler.obtainMessage(MSG_START_ASSIST, args).sendToTarget();
879         }
880     }
881 
882     @Override
onCameraLaunchGestureDetected(int source)883     public void onCameraLaunchGestureDetected(int source) {
884         synchronized (mLock) {
885             mHandler.removeMessages(MSG_CAMERA_LAUNCH_GESTURE);
886             mHandler.obtainMessage(MSG_CAMERA_LAUNCH_GESTURE, source, 0).sendToTarget();
887         }
888     }
889 
890     @Override
onEmergencyActionLaunchGestureDetected()891     public void onEmergencyActionLaunchGestureDetected() {
892         synchronized (mLock) {
893             mHandler.removeMessages(MSG_EMERGENCY_ACTION_LAUNCH_GESTURE);
894             mHandler.obtainMessage(MSG_EMERGENCY_ACTION_LAUNCH_GESTURE).sendToTarget();
895         }
896     }
897 
898     @Override
addQsTile(ComponentName tile)899     public void addQsTile(ComponentName tile) {
900         synchronized (mLock) {
901             mHandler.obtainMessage(MSG_ADD_QS_TILE, tile).sendToTarget();
902         }
903     }
904 
905     @Override
remQsTile(ComponentName tile)906     public void remQsTile(ComponentName tile) {
907         synchronized (mLock) {
908             mHandler.obtainMessage(MSG_REMOVE_QS_TILE, tile).sendToTarget();
909         }
910     }
911 
912     @Override
clickQsTile(ComponentName tile)913     public void clickQsTile(ComponentName tile) {
914         synchronized (mLock) {
915             mHandler.obtainMessage(MSG_CLICK_QS_TILE, tile).sendToTarget();
916         }
917     }
918 
919     @Override
handleSystemKey(KeyEvent key)920     public void handleSystemKey(KeyEvent key) {
921         synchronized (mLock) {
922             mHandler.obtainMessage(MSG_HANDLE_SYSTEM_KEY, key).sendToTarget();
923         }
924     }
925 
926     @Override
showPinningEnterExitToast(boolean entering)927     public void showPinningEnterExitToast(boolean entering) {
928         synchronized (mLock) {
929             mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ENTER_EXIT, entering).sendToTarget();
930         }
931     }
932 
933     @Override
showPinningEscapeToast()934     public void showPinningEscapeToast() {
935         synchronized (mLock) {
936             mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ESCAPE).sendToTarget();
937         }
938     }
939 
940 
941     @Override
showGlobalActionsMenu()942     public void showGlobalActionsMenu() {
943         synchronized (mLock) {
944             mHandler.removeMessages(MSG_SHOW_GLOBAL_ACTIONS);
945             mHandler.obtainMessage(MSG_SHOW_GLOBAL_ACTIONS).sendToTarget();
946         }
947     }
948 
949     @Override
setTopAppHidesStatusBar(boolean hidesStatusBar)950     public void setTopAppHidesStatusBar(boolean hidesStatusBar) {
951         mHandler.removeMessages(MSG_SET_TOP_APP_HIDES_STATUS_BAR);
952         mHandler.obtainMessage(MSG_SET_TOP_APP_HIDES_STATUS_BAR, hidesStatusBar ? 1 : 0, 0)
953                 .sendToTarget();
954     }
955 
956     @Override
showShutdownUi(boolean isReboot, String reason)957     public void showShutdownUi(boolean isReboot, String reason) {
958         synchronized (mLock) {
959             mHandler.removeMessages(MSG_SHOW_SHUTDOWN_UI);
960             mHandler.obtainMessage(MSG_SHOW_SHUTDOWN_UI, isReboot ? 1 : 0, 0, reason)
961                     .sendToTarget();
962         }
963     }
964 
965     @Override
showWirelessChargingAnimation(int batteryLevel)966     public void showWirelessChargingAnimation(int batteryLevel) {
967         mHandler.removeMessages(MSG_SHOW_CHARGING_ANIMATION);
968         mHandler.obtainMessage(MSG_SHOW_CHARGING_ANIMATION, batteryLevel, 0)
969                 .sendToTarget();
970     }
971 
972     @Override
onProposedRotationChanged(int rotation, boolean isValid)973     public void onProposedRotationChanged(int rotation, boolean isValid) {
974         synchronized (mLock) {
975             mHandler.removeMessages(MSG_ROTATION_PROPOSAL);
976             mHandler.obtainMessage(MSG_ROTATION_PROPOSAL, rotation, isValid ? 1 : 0,
977                     null).sendToTarget();
978         }
979     }
980 
981     @Override
showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver, int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId, long operationId, String opPackageName, long requestId)982     public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver,
983             int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
984             int userId, long operationId, String opPackageName, long requestId) {
985         synchronized (mLock) {
986             SomeArgs args = SomeArgs.obtain();
987             args.arg1 = promptInfo;
988             args.arg2 = receiver;
989             args.arg3 = sensorIds;
990             args.arg4 = credentialAllowed;
991             args.arg5 = requireConfirmation;
992             args.argi1 = userId;
993             args.arg6 = opPackageName;
994             args.argl1 = operationId;
995             args.argl2 = requestId;
996             mHandler.obtainMessage(MSG_BIOMETRIC_SHOW, args)
997                     .sendToTarget();
998         }
999     }
1000 
1001     @Override
showToast(int uid, String packageName, IBinder token, CharSequence text, IBinder windowToken, int duration, @Nullable ITransientNotificationCallback callback, int displayId)1002     public void showToast(int uid, String packageName, IBinder token, CharSequence text,
1003             IBinder windowToken, int duration, @Nullable ITransientNotificationCallback callback,
1004             int displayId) {
1005         synchronized (mLock) {
1006             SomeArgs args = SomeArgs.obtain();
1007             args.arg1 = packageName;
1008             args.arg2 = token;
1009             args.arg3 = text;
1010             args.arg4 = windowToken;
1011             args.arg5 = callback;
1012             args.argi1 = uid;
1013             args.argi2 = duration;
1014             args.argi3 = displayId;
1015             mHandler.obtainMessage(MSG_SHOW_TOAST, args).sendToTarget();
1016         }
1017     }
1018 
1019     @Override
hideToast(String packageName, IBinder token)1020     public void hideToast(String packageName, IBinder token) {
1021         synchronized (mLock) {
1022             SomeArgs args = SomeArgs.obtain();
1023             args.arg1 = packageName;
1024             args.arg2 = token;
1025             mHandler.obtainMessage(MSG_HIDE_TOAST, args).sendToTarget();
1026         }
1027     }
1028 
1029     @Override
onBiometricAuthenticated(@odality int modality)1030     public void onBiometricAuthenticated(@Modality int modality) {
1031         synchronized (mLock) {
1032             SomeArgs args = SomeArgs.obtain();
1033             args.argi1 = modality;
1034             mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATED, args).sendToTarget();
1035         }
1036     }
1037 
1038     @Override
onBiometricHelp(@odality int modality, String message)1039     public void onBiometricHelp(@Modality int modality, String message) {
1040         synchronized (mLock) {
1041             SomeArgs args = SomeArgs.obtain();
1042             args.argi1 = modality;
1043             args.arg1 = message;
1044             mHandler.obtainMessage(MSG_BIOMETRIC_HELP, args).sendToTarget();
1045         }
1046     }
1047 
1048     @Override
onBiometricError(int modality, int error, int vendorCode)1049     public void onBiometricError(int modality, int error, int vendorCode) {
1050         synchronized (mLock) {
1051             SomeArgs args = SomeArgs.obtain();
1052             args.argi1 = modality;
1053             args.argi2 = error;
1054             args.argi3 = vendorCode;
1055             mHandler.obtainMessage(MSG_BIOMETRIC_ERROR, args).sendToTarget();
1056         }
1057     }
1058 
1059     @Override
hideAuthenticationDialog(long requestId)1060     public void hideAuthenticationDialog(long requestId) {
1061         synchronized (mLock) {
1062             final SomeArgs args = SomeArgs.obtain();
1063             args.argl1 = requestId;
1064             mHandler.obtainMessage(MSG_BIOMETRIC_HIDE, args).sendToTarget();
1065         }
1066     }
1067 
1068     @Override
setBiometicContextListener(IBiometricContextListener listener)1069     public void setBiometicContextListener(IBiometricContextListener listener) {
1070         synchronized (mLock) {
1071             mHandler.obtainMessage(MSG_SET_BIOMETRICS_LISTENER, listener).sendToTarget();
1072         }
1073     }
1074 
1075     @Override
setUdfpsRefreshRateCallback(IUdfpsRefreshRateRequestCallback callback)1076     public void setUdfpsRefreshRateCallback(IUdfpsRefreshRateRequestCallback callback) {
1077         synchronized (mLock) {
1078             mHandler.obtainMessage(MSG_SET_UDFPS_REFRESH_RATE_CALLBACK, callback).sendToTarget();
1079         }
1080     }
1081 
1082     @Override
onDisplayReady(int displayId)1083     public void onDisplayReady(int displayId) {
1084         synchronized (mLock) {
1085             mHandler.obtainMessage(MSG_DISPLAY_READY, displayId, 0).sendToTarget();
1086         }
1087     }
1088 
1089     @Override
onRecentsAnimationStateChanged(boolean running)1090     public void onRecentsAnimationStateChanged(boolean running) {
1091         synchronized (mLock) {
1092             mHandler.obtainMessage(MSG_RECENTS_ANIMATION_STATE_CHANGED, running ? 1 : 0, 0)
1093                     .sendToTarget();
1094         }
1095     }
1096 
1097     @Override
showInattentiveSleepWarning()1098     public void showInattentiveSleepWarning() {
1099         synchronized (mLock) {
1100             mHandler.obtainMessage(MSG_SHOW_INATTENTIVE_SLEEP_WARNING)
1101                     .sendToTarget();
1102         }
1103     }
1104 
1105     @Override
dismissInattentiveSleepWarning(boolean animated)1106     public void dismissInattentiveSleepWarning(boolean animated) {
1107         synchronized (mLock) {
1108             mHandler.obtainMessage(MSG_DISMISS_INATTENTIVE_SLEEP_WARNING, animated)
1109                     .sendToTarget();
1110         }
1111     }
1112 
1113     @Override
requestWindowMagnificationConnection(boolean connect)1114     public void requestWindowMagnificationConnection(boolean connect) {
1115         synchronized (mLock) {
1116             mHandler.obtainMessage(MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION, connect)
1117                     .sendToTarget();
1118         }
1119     }
1120 
handleShowImeButton(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher)1121     private void handleShowImeButton(int displayId, IBinder token, int vis, int backDisposition,
1122             boolean showImeSwitcher) {
1123         if (displayId == INVALID_DISPLAY) return;
1124 
1125         if (mLastUpdatedImeDisplayId != displayId
1126                 && mLastUpdatedImeDisplayId != INVALID_DISPLAY) {
1127             // Set previous NavBar's IME window status as invisible when IME
1128             // window switched to another display for single-session IME case.
1129             sendImeInvisibleStatusForPrevNavBar();
1130         }
1131         for (int i = 0; i < mCallbacks.size(); i++) {
1132             mCallbacks.get(i).setImeWindowStatus(displayId, token, vis, backDisposition,
1133                     showImeSwitcher);
1134         }
1135         mLastUpdatedImeDisplayId = displayId;
1136     }
1137 
sendImeInvisibleStatusForPrevNavBar()1138     private void sendImeInvisibleStatusForPrevNavBar() {
1139         for (int i = 0; i < mCallbacks.size(); i++) {
1140             mCallbacks.get(i).setImeWindowStatus(mLastUpdatedImeDisplayId,
1141                     null /* token */, IME_INVISIBLE, BACK_DISPOSITION_DEFAULT,
1142                     false /* showImeSwitcher */);
1143         }
1144     }
1145 
1146     @Override
onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, @InsetsType int requestedVisibleTypes, String packageName, LetterboxDetails[] letterboxDetails)1147     public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance,
1148             AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme,
1149             @Behavior int behavior, @InsetsType int requestedVisibleTypes, String packageName,
1150             LetterboxDetails[] letterboxDetails) {
1151         synchronized (mLock) {
1152             SomeArgs args = SomeArgs.obtain();
1153             args.argi1 = displayId;
1154             args.argi2 = appearance;
1155             args.argi3 = navbarColorManagedByIme ? 1 : 0;
1156             args.arg1 = appearanceRegions;
1157             args.argi4 = behavior;
1158             args.argi5 = requestedVisibleTypes;
1159             args.arg3 = packageName;
1160             args.arg4 = letterboxDetails;
1161             mHandler.obtainMessage(MSG_SYSTEM_BAR_CHANGED, args).sendToTarget();
1162         }
1163     }
1164 
1165     @Override
showTransient(int displayId, int types, boolean isGestureOnSystemBar)1166     public void showTransient(int displayId, int types, boolean isGestureOnSystemBar) {
1167         synchronized (mLock) {
1168             SomeArgs args = SomeArgs.obtain();
1169             args.argi1 = displayId;
1170             args.argi2 = types;
1171             args.argi3 = isGestureOnSystemBar ? 1 : 0;
1172             mHandler.obtainMessage(MSG_SHOW_TRANSIENT, args).sendToTarget();
1173         }
1174     }
1175 
1176     @Override
abortTransient(int displayId, int types)1177     public void abortTransient(int displayId, int types) {
1178         synchronized (mLock) {
1179             SomeArgs args = SomeArgs.obtain();
1180             args.argi1 = displayId;
1181             args.argi2 = types;
1182             mHandler.obtainMessage(MSG_ABORT_TRANSIENT, args).sendToTarget();
1183         }
1184     }
1185 
1186     @Override
startTracing()1187     public void startTracing() {
1188         synchronized (mLock) {
1189             mHandler.obtainMessage(MSG_TRACING_STATE_CHANGED, true).sendToTarget();
1190         }
1191     }
1192 
1193     @Override
stopTracing()1194     public void stopTracing() {
1195         synchronized (mLock) {
1196             mHandler.obtainMessage(MSG_TRACING_STATE_CHANGED, false).sendToTarget();
1197         }
1198     }
1199 
1200     @Override
suppressAmbientDisplay(boolean suppress)1201     public void suppressAmbientDisplay(boolean suppress) {
1202         synchronized (mLock) {
1203             mHandler.obtainMessage(MSG_SUPPRESS_AMBIENT_DISPLAY, suppress).sendToTarget();
1204         }
1205     }
1206 
1207     @Override
setNavigationBarLumaSamplingEnabled(int displayId, boolean enable)1208     public void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {
1209         synchronized (mLock) {
1210             mHandler.obtainMessage(MSG_SET_NAVIGATION_BAR_LUMA_SAMPLING_ENABLED, displayId,
1211                     enable ? 1 : 0).sendToTarget();
1212         }
1213     }
1214 
1215     @Override
passThroughShellCommand(String[] args, ParcelFileDescriptor pfd)1216     public void passThroughShellCommand(String[] args, ParcelFileDescriptor pfd) {
1217         final FileOutputStream fos = new FileOutputStream(pfd.getFileDescriptor());
1218         final PrintWriter pw = new PrintWriter(fos);
1219         // This is mimicking Binder#dumpAsync, but on this side of the binder. Might be possible
1220         // to just throw this work onto the handler just like the other messages
1221         Thread thr = new Thread("Sysui.passThroughShellCommand") {
1222             public void run() {
1223                 try {
1224                     if (mRegistry == null) {
1225                         return;
1226                     }
1227 
1228                     // Registry blocks this thread until finished
1229                     mRegistry.onShellCommand(pw, args);
1230                 } finally {
1231                     pw.flush();
1232                     try {
1233                         // Close the file descriptor so the TransferPipe finishes its thread
1234                         pfd.close();
1235                     } catch (Exception e) {
1236                     }
1237                 }
1238             }
1239         };
1240         thr.start();
1241     }
1242 
1243     @Override
dumpProto(String[] args, ParcelFileDescriptor pfd)1244     public void dumpProto(String[] args, ParcelFileDescriptor pfd) {
1245         final FileDescriptor fd = pfd.getFileDescriptor();
1246         // This is mimicking Binder#dumpAsync, but on this side of the binder. Might be possible
1247         // to just throw this work onto the handler just like the other messages
1248         Thread thr = new Thread("Sysui.dumpProto") {
1249             public void run() {
1250                 try {
1251                     if (mDumpHandler == null) {
1252                         return;
1253                     }
1254                     // We won't be using the PrintWriter.
1255                     OutputStream o = new OutputStream() {
1256                         @Override
1257                         public void write(int b) {}
1258                     };
1259                     mDumpHandler.dump(fd, new PrintWriter(o), args);
1260                 } finally {
1261                     try {
1262                         // Close the file descriptor so the TransferPipe finishes its thread
1263                         pfd.close();
1264                     } catch (Exception e) {
1265                     }
1266                 }
1267             }
1268         };
1269         thr.start();
1270     }
1271 
1272     @Override
runGcForTest()1273     public void runGcForTest() {
1274         // Gc sysui
1275         GcUtils.runGcAndFinalizersSync();
1276     }
1277 
1278     @Override
requestTileServiceListeningState(@onNull ComponentName componentName)1279     public void requestTileServiceListeningState(@NonNull ComponentName componentName) {
1280         mHandler.obtainMessage(MSG_TILE_SERVICE_REQUEST_LISTENING_STATE, componentName)
1281                 .sendToTarget();
1282     }
1283 
1284     @Override
showRearDisplayDialog(int currentBaseState)1285     public void showRearDisplayDialog(int currentBaseState) {
1286         synchronized (mLock) {
1287             mHandler.obtainMessage(MSG_SHOW_REAR_DISPLAY_DIALOG, currentBaseState).sendToTarget();
1288         }
1289     }
1290 
1291     @Override
enterStageSplitFromRunningApp(boolean leftOrTop)1292     public void enterStageSplitFromRunningApp(boolean leftOrTop) {
1293         synchronized (mLock) {
1294             mHandler.obtainMessage(MSG_ENTER_STAGE_SPLIT_FROM_RUNNING_APP,
1295                     leftOrTop).sendToTarget();
1296         }
1297     }
1298 
1299     @Override
showMediaOutputSwitcher(String packageName)1300     public void showMediaOutputSwitcher(String packageName) {
1301         int callingUid = Binder.getCallingUid();
1302         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
1303             throw new SecurityException("Call only allowed from system server.");
1304         }
1305         synchronized (mLock) {
1306             SomeArgs args = SomeArgs.obtain();
1307             args.arg1 = packageName;
1308             mHandler.obtainMessage(MSG_SHOW_MEDIA_OUTPUT_SWITCHER, args).sendToTarget();
1309         }
1310     }
1311 
1312     @Override
requestAddTile( @onNull ComponentName componentName, @NonNull CharSequence appName, @NonNull CharSequence label, @NonNull Icon icon, @NonNull IAddTileResultCallback callback )1313     public void requestAddTile(
1314             @NonNull ComponentName componentName,
1315             @NonNull CharSequence appName,
1316             @NonNull CharSequence label,
1317             @NonNull Icon icon,
1318             @NonNull IAddTileResultCallback callback
1319     ) {
1320         SomeArgs args = SomeArgs.obtain();
1321         args.arg1 = componentName;
1322         args.arg2 = appName;
1323         args.arg3 = label;
1324         args.arg4 = icon;
1325         args.arg5 = callback;
1326         mHandler.obtainMessage(MSG_TILE_SERVICE_REQUEST_ADD, args).sendToTarget();
1327     }
1328 
1329     @Override
cancelRequestAddTile(@onNull String s)1330     public void cancelRequestAddTile(@NonNull String s) throws RemoteException {
1331         mHandler.obtainMessage(MSG_TILE_SERVICE_REQUEST_CANCEL, s).sendToTarget();
1332     }
1333 
1334     @Override
updateMediaTapToTransferSenderDisplay( @tatusBarManager.MediaTransferSenderState int displayState, MediaRoute2Info routeInfo, IUndoMediaTransferCallback undoCallback )1335     public void updateMediaTapToTransferSenderDisplay(
1336             @StatusBarManager.MediaTransferSenderState int displayState,
1337             MediaRoute2Info routeInfo,
1338             IUndoMediaTransferCallback undoCallback
1339     ) throws RemoteException {
1340         SomeArgs args = SomeArgs.obtain();
1341         args.arg1 = displayState;
1342         args.arg2 = routeInfo;
1343         args.arg3 = undoCallback;
1344         mHandler.obtainMessage(MSG_MEDIA_TRANSFER_SENDER_STATE, args).sendToTarget();
1345     }
1346 
1347     @Override
updateMediaTapToTransferReceiverDisplay( int displayState, @NonNull MediaRoute2Info routeInfo, @Nullable Icon appIcon, @Nullable CharSequence appName)1348     public void updateMediaTapToTransferReceiverDisplay(
1349             int displayState,
1350             @NonNull MediaRoute2Info routeInfo,
1351             @Nullable Icon appIcon,
1352             @Nullable CharSequence appName) {
1353         SomeArgs args = SomeArgs.obtain();
1354         args.arg1 = displayState;
1355         args.arg2 = routeInfo;
1356         args.arg3 = appIcon;
1357         args.arg4 = appName;
1358         mHandler.obtainMessage(MSG_MEDIA_TRANSFER_RECEIVER_STATE, args).sendToTarget();
1359     }
1360 
1361     @Override
registerNearbyMediaDevicesProvider(@onNull INearbyMediaDevicesProvider provider)1362     public void registerNearbyMediaDevicesProvider(@NonNull INearbyMediaDevicesProvider provider) {
1363         mHandler.obtainMessage(MSG_REGISTER_NEARBY_MEDIA_DEVICE_PROVIDER, provider).sendToTarget();
1364     }
1365 
1366     @Override
unregisterNearbyMediaDevicesProvider( @onNull INearbyMediaDevicesProvider provider)1367     public void unregisterNearbyMediaDevicesProvider(
1368             @NonNull INearbyMediaDevicesProvider provider) {
1369         mHandler.obtainMessage(MSG_UNREGISTER_NEARBY_MEDIA_DEVICE_PROVIDER, provider)
1370                 .sendToTarget();
1371     }
1372 
1373     @Override
goToFullscreenFromSplit()1374     public void goToFullscreenFromSplit() {
1375         mHandler.obtainMessage(MSG_GO_TO_FULLSCREEN_FROM_SPLIT).sendToTarget();
1376     }
1377 
1378     private final class H extends Handler {
H(Looper l)1379         private H(Looper l) {
1380             super(l);
1381         }
1382 
handleMessage(Message msg)1383         public void handleMessage(Message msg) {
1384             final int what = msg.what & MSG_MASK;
1385             switch (what) {
1386                 case MSG_ICON: {
1387                     switch (msg.arg1) {
1388                         case OP_SET_ICON: {
1389                             Pair<String, StatusBarIcon> p = (Pair<String, StatusBarIcon>) msg.obj;
1390                             for (int i = 0; i < mCallbacks.size(); i++) {
1391                                 mCallbacks.get(i).setIcon(p.first, p.second);
1392                             }
1393                             break;
1394                         }
1395                         case OP_REMOVE_ICON:
1396                             for (int i = 0; i < mCallbacks.size(); i++) {
1397                                 mCallbacks.get(i).removeIcon((String) msg.obj);
1398                             }
1399                             break;
1400                     }
1401                     break;
1402                 }
1403                 case MSG_DISABLE:
1404                     SomeArgs args = (SomeArgs) msg.obj;
1405                     for (int i = 0; i < mCallbacks.size(); i++) {
1406                         mCallbacks.get(i).disable(args.argi1, args.argi2, args.argi3,
1407                                 args.argi4 != 0 /* animate */);
1408                     }
1409                     break;
1410                 case MSG_EXPAND_NOTIFICATIONS:
1411                     for (int i = 0; i < mCallbacks.size(); i++) {
1412                         mCallbacks.get(i).animateExpandNotificationsPanel();
1413                     }
1414                     break;
1415                 case MSG_COLLAPSE_PANELS:
1416                     for (int i = 0; i < mCallbacks.size(); i++) {
1417                         mCallbacks.get(i).animateCollapsePanels(msg.arg1, msg.arg2 != 0);
1418                     }
1419                     break;
1420                 case MSG_TOGGLE_PANEL:
1421                     for (int i = 0; i < mCallbacks.size(); i++) {
1422                         mCallbacks.get(i).togglePanel();
1423                     }
1424                     break;
1425                 case MSG_EXPAND_SETTINGS:
1426                     for (int i = 0; i < mCallbacks.size(); i++) {
1427                         mCallbacks.get(i).animateExpandSettingsPanel((String) msg.obj);
1428                     }
1429                     break;
1430                 case MSG_SHOW_IME_BUTTON:
1431                     args = (SomeArgs) msg.obj;
1432                     handleShowImeButton(args.argi1 /* displayId */, (IBinder) args.arg1 /* token */,
1433                             args.argi2 /* vis */, args.argi3 /* backDisposition */,
1434                             args.argi4 != 0 /* showImeSwitcher */);
1435                     break;
1436                 case MSG_SHOW_RECENT_APPS:
1437                     for (int i = 0; i < mCallbacks.size(); i++) {
1438                         mCallbacks.get(i).showRecentApps(msg.arg1 != 0);
1439                     }
1440                     break;
1441                 case MSG_HIDE_RECENT_APPS:
1442                     for (int i = 0; i < mCallbacks.size(); i++) {
1443                         mCallbacks.get(i).hideRecentApps(msg.arg1 != 0, msg.arg2 != 0);
1444                     }
1445                     break;
1446                 case MSG_TOGGLE_TASKBAR:
1447                     for (int i = 0; i < mCallbacks.size(); i++) {
1448                         mCallbacks.get(i).toggleTaskbar();
1449                     }
1450                     break;
1451                 case MSG_TOGGLE_RECENT_APPS:
1452                     for (int i = 0; i < mCallbacks.size(); i++) {
1453                         mCallbacks.get(i).toggleRecentApps();
1454                     }
1455                     break;
1456                 case MSG_PRELOAD_RECENT_APPS:
1457                     for (int i = 0; i < mCallbacks.size(); i++) {
1458                         mCallbacks.get(i).preloadRecentApps();
1459                     }
1460                     break;
1461                 case MSG_CANCEL_PRELOAD_RECENT_APPS:
1462                     for (int i = 0; i < mCallbacks.size(); i++) {
1463                         mCallbacks.get(i).cancelPreloadRecentApps();
1464                     }
1465                     break;
1466                 case MSG_DISMISS_KEYBOARD_SHORTCUTS:
1467                     for (int i = 0; i < mCallbacks.size(); i++) {
1468                         mCallbacks.get(i).dismissKeyboardShortcutsMenu();
1469                     }
1470                     break;
1471                 case MSG_TOGGLE_KEYBOARD_SHORTCUTS:
1472                     for (int i = 0; i < mCallbacks.size(); i++) {
1473                         mCallbacks.get(i).toggleKeyboardShortcutsMenu(msg.arg1);
1474                     }
1475                     break;
1476                 case MSG_SET_WINDOW_STATE:
1477                     for (int i = 0; i < mCallbacks.size(); i++) {
1478                         mCallbacks.get(i).setWindowState(msg.arg1, msg.arg2, (int) msg.obj);
1479                     }
1480                     break;
1481                 case MSG_SHOW_SCREEN_PIN_REQUEST:
1482                     for (int i = 0; i < mCallbacks.size(); i++) {
1483                         mCallbacks.get(i).showScreenPinningRequest(msg.arg1);
1484                     }
1485                     break;
1486                 case MSG_APP_TRANSITION_PENDING:
1487                     for (int i = 0; i < mCallbacks.size(); i++) {
1488                         mCallbacks.get(i).appTransitionPending(msg.arg1, msg.arg2 != 0);
1489                     }
1490                     break;
1491                 case MSG_APP_TRANSITION_CANCELLED:
1492                     for (int i = 0; i < mCallbacks.size(); i++) {
1493                         mCallbacks.get(i).appTransitionCancelled(msg.arg1);
1494                     }
1495                     break;
1496                 case MSG_APP_TRANSITION_STARTING:
1497                     args = (SomeArgs) msg.obj;
1498                     for (int i = 0; i < mCallbacks.size(); i++) {
1499                         mCallbacks.get(i).appTransitionStarting(args.argi1, (long) args.arg1,
1500                                 (long) args.arg2, args.argi2 != 0 /* forced */);
1501                     }
1502                     break;
1503                 case MSG_APP_TRANSITION_FINISHED:
1504                     for (int i = 0; i < mCallbacks.size(); i++) {
1505                         mCallbacks.get(i).appTransitionFinished(msg.arg1);
1506                     }
1507                     break;
1508                 case MSG_ASSIST_DISCLOSURE:
1509                     for (int i = 0; i < mCallbacks.size(); i++) {
1510                         mCallbacks.get(i).showAssistDisclosure();
1511                     }
1512                     break;
1513                 case MSG_START_ASSIST:
1514                     for (int i = 0; i < mCallbacks.size(); i++) {
1515                         mCallbacks.get(i).startAssist((Bundle) msg.obj);
1516                     }
1517                     break;
1518                 case MSG_CAMERA_LAUNCH_GESTURE:
1519                     for (int i = 0; i < mCallbacks.size(); i++) {
1520                         mCallbacks.get(i).onCameraLaunchGestureDetected(msg.arg1);
1521                     }
1522                     break;
1523                 case MSG_EMERGENCY_ACTION_LAUNCH_GESTURE:
1524                     for (int i = 0; i < mCallbacks.size(); i++) {
1525                         mCallbacks.get(i).onEmergencyActionLaunchGestureDetected();
1526                     }
1527                     break;
1528                 case MSG_SHOW_PICTURE_IN_PICTURE_MENU:
1529                     for (int i = 0; i < mCallbacks.size(); i++) {
1530                         mCallbacks.get(i).showPictureInPictureMenu();
1531                     }
1532                     break;
1533                 case MSG_ADD_QS_TILE:
1534                     for (int i = 0; i < mCallbacks.size(); i++) {
1535                         mCallbacks.get(i).addQsTile((ComponentName) msg.obj);
1536                     }
1537                     break;
1538                 case MSG_REMOVE_QS_TILE:
1539                     for (int i = 0; i < mCallbacks.size(); i++) {
1540                         mCallbacks.get(i).remQsTile((ComponentName) msg.obj);
1541                     }
1542                     break;
1543                 case MSG_CLICK_QS_TILE:
1544                     for (int i = 0; i < mCallbacks.size(); i++) {
1545                         mCallbacks.get(i).clickTile((ComponentName) msg.obj);
1546                     }
1547                     break;
1548                 case MSG_TOGGLE_APP_SPLIT_SCREEN:
1549                     for (int i = 0; i < mCallbacks.size(); i++) {
1550                         mCallbacks.get(i).toggleSplitScreen();
1551                     }
1552                     break;
1553                 case MSG_HANDLE_SYSTEM_KEY:
1554                     for (int i = 0; i < mCallbacks.size(); i++) {
1555                         mCallbacks.get(i).handleSystemKey((KeyEvent) msg.obj);
1556                     }
1557                     break;
1558                 case MSG_SHOW_GLOBAL_ACTIONS:
1559                     for (int i = 0; i < mCallbacks.size(); i++) {
1560                         mCallbacks.get(i).handleShowGlobalActionsMenu();
1561                     }
1562                     break;
1563                 case MSG_SHOW_SHUTDOWN_UI:
1564                     for (int i = 0; i < mCallbacks.size(); i++) {
1565                         mCallbacks.get(i).handleShowShutdownUi(msg.arg1 != 0, (String) msg.obj);
1566                     }
1567                     break;
1568                 case MSG_SET_TOP_APP_HIDES_STATUS_BAR:
1569                     for (int i = 0; i < mCallbacks.size(); i++) {
1570                         mCallbacks.get(i).setTopAppHidesStatusBar(msg.arg1 != 0);
1571                     }
1572                     break;
1573                 case MSG_ROTATION_PROPOSAL:
1574                     for (int i = 0; i < mCallbacks.size(); i++) {
1575                         mCallbacks.get(i).onRotationProposal(msg.arg1, msg.arg2 != 0);
1576                     }
1577                     break;
1578                 case MSG_BIOMETRIC_SHOW: {
1579                     mHandler.removeMessages(MSG_BIOMETRIC_ERROR);
1580                     mHandler.removeMessages(MSG_BIOMETRIC_HELP);
1581                     mHandler.removeMessages(MSG_BIOMETRIC_AUTHENTICATED);
1582                     SomeArgs someArgs = (SomeArgs) msg.obj;
1583                     for (int i = 0; i < mCallbacks.size(); i++) {
1584                         mCallbacks.get(i).showAuthenticationDialog(
1585                                 (PromptInfo) someArgs.arg1,
1586                                 (IBiometricSysuiReceiver) someArgs.arg2,
1587                                 (int[]) someArgs.arg3 /* sensorIds */,
1588                                 (boolean) someArgs.arg4 /* credentialAllowed */,
1589                                 (boolean) someArgs.arg5 /* requireConfirmation */,
1590                                 someArgs.argi1 /* userId */,
1591                                 someArgs.argl1 /* operationId */,
1592                                 (String) someArgs.arg6 /* opPackageName */,
1593                                 someArgs.argl2 /* requestId */);
1594                     }
1595                     someArgs.recycle();
1596                     break;
1597                 }
1598                 case MSG_BIOMETRIC_AUTHENTICATED: {
1599                     SomeArgs someArgs = (SomeArgs) msg.obj;
1600                     for (int i = 0; i < mCallbacks.size(); i++) {
1601                         mCallbacks.get(i).onBiometricAuthenticated(someArgs.argi1 /* modality */);
1602                     }
1603                     someArgs.recycle();
1604                     break;
1605                 }
1606                 case MSG_BIOMETRIC_HELP: {
1607                     SomeArgs someArgs = (SomeArgs) msg.obj;
1608                     for (int i = 0; i < mCallbacks.size(); i++) {
1609                         mCallbacks.get(i).onBiometricHelp(
1610                                 someArgs.argi1 /* modality */,
1611                                 (String) someArgs.arg1 /* message */);
1612                     }
1613                     someArgs.recycle();
1614                     break;
1615                 }
1616                 case MSG_BIOMETRIC_ERROR: {
1617                     SomeArgs someArgs = (SomeArgs) msg.obj;
1618                     for (int i = 0; i < mCallbacks.size(); i++) {
1619                         mCallbacks.get(i).onBiometricError(
1620                                 someArgs.argi1 /* modality */,
1621                                 someArgs.argi2 /* error */,
1622                                 someArgs.argi3 /* vendorCode */
1623                         );
1624                     }
1625                     someArgs.recycle();
1626                     break;
1627                 }
1628                 case MSG_BIOMETRIC_HIDE: {
1629                     final SomeArgs someArgs = (SomeArgs) msg.obj;
1630                     for (int i = 0; i < mCallbacks.size(); i++) {
1631                         mCallbacks.get(i).hideAuthenticationDialog(someArgs.argl1 /* requestId */);
1632                     }
1633                     someArgs.recycle();
1634                     break;
1635                 }
1636                 case MSG_SET_BIOMETRICS_LISTENER:
1637                     for (int i = 0; i < mCallbacks.size(); i++) {
1638                         mCallbacks.get(i).setBiometricContextListener(
1639                                 (IBiometricContextListener) msg.obj);
1640                     }
1641                     break;
1642                 case MSG_SET_UDFPS_REFRESH_RATE_CALLBACK:
1643                     for (int i = 0; i < mCallbacks.size(); i++) {
1644                         mCallbacks.get(i).setUdfpsRefreshRateCallback(
1645                                 (IUdfpsRefreshRateRequestCallback) msg.obj);
1646                     }
1647                     break;
1648                 case MSG_SHOW_CHARGING_ANIMATION:
1649                     for (int i = 0; i < mCallbacks.size(); i++) {
1650                         mCallbacks.get(i).showWirelessChargingAnimation(msg.arg1);
1651                     }
1652                     break;
1653                 case MSG_SHOW_PINNING_TOAST_ENTER_EXIT:
1654                     for (int i = 0; i < mCallbacks.size(); i++) {
1655                         mCallbacks.get(i).showPinningEnterExitToast((Boolean) msg.obj);
1656                     }
1657                     break;
1658                 case MSG_SHOW_PINNING_TOAST_ESCAPE:
1659                     for (int i = 0; i < mCallbacks.size(); i++) {
1660                         mCallbacks.get(i).showPinningEscapeToast();
1661                     }
1662                     break;
1663                 case MSG_DISPLAY_READY:
1664                     for (int i = 0; i < mCallbacks.size(); i++) {
1665                         mCallbacks.get(i).onDisplayReady(msg.arg1);
1666                     }
1667                     break;
1668                 case MSG_RECENTS_ANIMATION_STATE_CHANGED:
1669                     for (int i = 0; i < mCallbacks.size(); i++) {
1670                         mCallbacks.get(i).onRecentsAnimationStateChanged(msg.arg1 > 0);
1671                     }
1672                     break;
1673                 case MSG_SYSTEM_BAR_CHANGED:
1674                     args = (SomeArgs) msg.obj;
1675                     for (int i = 0; i < mCallbacks.size(); i++) {
1676                         mCallbacks.get(i).onSystemBarAttributesChanged(args.argi1, args.argi2,
1677                                 (AppearanceRegion[]) args.arg1, args.argi3 == 1, args.argi4,
1678                                 args.argi5, (String) args.arg3, (LetterboxDetails[]) args.arg4);
1679                     }
1680                     args.recycle();
1681                     break;
1682                 case MSG_SHOW_TRANSIENT: {
1683                     args = (SomeArgs) msg.obj;
1684                     final int displayId = args.argi1;
1685                     final int types = args.argi2;
1686                     final boolean isGestureOnSystemBar = args.argi3 != 0;
1687                     args.recycle();
1688                     for (int i = 0; i < mCallbacks.size(); i++) {
1689                         mCallbacks.get(i).showTransient(displayId, types, isGestureOnSystemBar);
1690                     }
1691                     break;
1692                 }
1693                 case MSG_ABORT_TRANSIENT: {
1694                     args = (SomeArgs) msg.obj;
1695                     final int displayId = args.argi1;
1696                     final int types = args.argi2;
1697                     args.recycle();
1698                     for (int i = 0; i < mCallbacks.size(); i++) {
1699                         mCallbacks.get(i).abortTransient(displayId, types);
1700                     }
1701                     break;
1702                 }
1703                 case MSG_SHOW_INATTENTIVE_SLEEP_WARNING:
1704                     for (int i = 0; i < mCallbacks.size(); i++) {
1705                         mCallbacks.get(i).showInattentiveSleepWarning();
1706                     }
1707                     break;
1708                 case MSG_DISMISS_INATTENTIVE_SLEEP_WARNING:
1709                     for (int i = 0; i < mCallbacks.size(); i++) {
1710                         mCallbacks.get(i).dismissInattentiveSleepWarning((Boolean) msg.obj);
1711                     }
1712                     break;
1713                 case MSG_SHOW_TOAST: {
1714                     args = (SomeArgs) msg.obj;
1715                     String packageName = (String) args.arg1;
1716                     IBinder token = (IBinder) args.arg2;
1717                     CharSequence text = (CharSequence) args.arg3;
1718                     IBinder windowToken = (IBinder) args.arg4;
1719                     ITransientNotificationCallback callback =
1720                             (ITransientNotificationCallback) args.arg5;
1721                     int uid = args.argi1;
1722                     int duration = args.argi2;
1723                     int displayId = args.argi3;
1724                     for (Callbacks callbacks : mCallbacks) {
1725                         callbacks.showToast(uid, packageName, token, text, windowToken, duration,
1726                                 callback, displayId);
1727                     }
1728                     break;
1729                 }
1730                 case MSG_HIDE_TOAST: {
1731                     args = (SomeArgs) msg.obj;
1732                     String packageName = (String) args.arg1;
1733                     IBinder token = (IBinder) args.arg2;
1734                     for (Callbacks callbacks : mCallbacks) {
1735                         callbacks.hideToast(packageName, token);
1736                     }
1737                     break;
1738                 }
1739                 case MSG_TRACING_STATE_CHANGED:
1740                     for (int i = 0; i < mCallbacks.size(); i++) {
1741                         mCallbacks.get(i).onTracingStateChanged((Boolean) msg.obj);
1742                     }
1743                     break;
1744                 case MSG_SUPPRESS_AMBIENT_DISPLAY:
1745                     for (Callbacks callbacks: mCallbacks) {
1746                         callbacks.suppressAmbientDisplay((boolean) msg.obj);
1747                     }
1748                     break;
1749                 case MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION:
1750                     for (int i = 0; i < mCallbacks.size(); i++) {
1751                         mCallbacks.get(i).requestWindowMagnificationConnection((Boolean) msg.obj);
1752                     }
1753                     break;
1754                 case MSG_SET_NAVIGATION_BAR_LUMA_SAMPLING_ENABLED:
1755                     for (int i = 0; i < mCallbacks.size(); i++) {
1756                         mCallbacks.get(i).setNavigationBarLumaSamplingEnabled(msg.arg1,
1757                                 msg.arg2 != 0);
1758                     }
1759                     break;
1760                 case MSG_TILE_SERVICE_REQUEST_ADD:
1761                     args = (SomeArgs) msg.obj;
1762                     ComponentName componentName = (ComponentName) args.arg1;
1763                     CharSequence appName = (CharSequence) args.arg2;
1764                     CharSequence label = (CharSequence) args.arg3;
1765                     Icon icon = (Icon) args.arg4;
1766                     IAddTileResultCallback callback = (IAddTileResultCallback) args.arg5;
1767                     for (int i = 0; i < mCallbacks.size(); i++) {
1768                         mCallbacks.get(i).requestAddTile(
1769                                 componentName, appName, label, icon, callback);
1770                     }
1771                     args.recycle();
1772                     break;
1773                 case MSG_TILE_SERVICE_REQUEST_CANCEL:
1774                     String packageName = (String) msg.obj;
1775                     for (int i = 0; i < mCallbacks.size(); i++) {
1776                         mCallbacks.get(i).cancelRequestAddTile(packageName);
1777                     }
1778                     break;
1779                 case MSG_MEDIA_TRANSFER_SENDER_STATE:
1780                     args = (SomeArgs) msg.obj;
1781                     int displayState = (int) args.arg1;
1782                     MediaRoute2Info routeInfo = (MediaRoute2Info) args.arg2;
1783                     IUndoMediaTransferCallback undoCallback =
1784                             (IUndoMediaTransferCallback) args.arg3;
1785                     for (int i = 0; i < mCallbacks.size(); i++) {
1786                         mCallbacks.get(i).updateMediaTapToTransferSenderDisplay(
1787                                 displayState, routeInfo, undoCallback);
1788                     }
1789                     args.recycle();
1790                     break;
1791                 case MSG_MEDIA_TRANSFER_RECEIVER_STATE:
1792                     args = (SomeArgs) msg.obj;
1793                     int receiverDisplayState = (int) args.arg1;
1794                     MediaRoute2Info receiverRouteInfo = (MediaRoute2Info) args.arg2;
1795                     Icon appIcon = (Icon) args.arg3;
1796                     appName = (CharSequence) args.arg4;
1797                     for (int i = 0; i < mCallbacks.size(); i++) {
1798                         mCallbacks.get(i).updateMediaTapToTransferReceiverDisplay(
1799                                 receiverDisplayState, receiverRouteInfo, appIcon, appName);
1800                     }
1801                     args.recycle();
1802                     break;
1803                 case MSG_REGISTER_NEARBY_MEDIA_DEVICE_PROVIDER:
1804                     INearbyMediaDevicesProvider provider = (INearbyMediaDevicesProvider) msg.obj;
1805                     for (int i = 0; i < mCallbacks.size(); i++) {
1806                         mCallbacks.get(i).registerNearbyMediaDevicesProvider(provider);
1807                     }
1808                     break;
1809                 case MSG_UNREGISTER_NEARBY_MEDIA_DEVICE_PROVIDER:
1810                     provider = (INearbyMediaDevicesProvider) msg.obj;
1811                     for (int i = 0; i < mCallbacks.size(); i++) {
1812                         mCallbacks.get(i).unregisterNearbyMediaDevicesProvider(provider);
1813                     }
1814                     break;
1815                 case MSG_TILE_SERVICE_REQUEST_LISTENING_STATE:
1816                     ComponentName component = (ComponentName) msg.obj;
1817                     for (int i = 0; i < mCallbacks.size(); i++) {
1818                         mCallbacks.get(i).requestTileServiceListeningState(component);
1819                     }
1820                     break;
1821                 case MSG_SHOW_REAR_DISPLAY_DIALOG:
1822                     for (int i = 0; i < mCallbacks.size(); i++) {
1823                         mCallbacks.get(i).showRearDisplayDialog((Integer) msg.obj);
1824                     }
1825                     break;
1826                 case MSG_GO_TO_FULLSCREEN_FROM_SPLIT:
1827                     for (int i = 0; i < mCallbacks.size(); i++) {
1828                         mCallbacks.get(i).goToFullscreenFromSplit();
1829                     }
1830                     break;
1831                 case MSG_ENTER_STAGE_SPLIT_FROM_RUNNING_APP:
1832                     for (int i = 0; i < mCallbacks.size(); i++) {
1833                         mCallbacks.get(i).enterStageSplitFromRunningApp((Boolean) msg.obj);
1834                     }
1835                     break;
1836                 case MSG_SHOW_MEDIA_OUTPUT_SWITCHER:
1837                     args = (SomeArgs) msg.obj;
1838                     String clientPackageName = (String) args.arg1;
1839                     for (int i = 0; i < mCallbacks.size(); i++) {
1840                         mCallbacks.get(i).showMediaOutputSwitcher(clientPackageName);
1841                     }
1842                     break;
1843                 case MSG_CONFIRM_IMMERSIVE_PROMPT:
1844                     for (int i = 0; i < mCallbacks.size(); i++) {
1845                         mCallbacks.get(i).confirmImmersivePrompt();
1846                     }
1847                     break;
1848                 case MSG_IMMERSIVE_CHANGED:
1849                     args = (SomeArgs) msg.obj;
1850                     int rootDisplayAreaId = args.argi1;
1851                     boolean isImmersiveMode = args.argi2 != 0;
1852                     for (int i = 0; i < mCallbacks.size(); i++) {
1853                         mCallbacks.get(i).immersiveModeChanged(rootDisplayAreaId, isImmersiveMode);
1854                     }
1855                     break;
1856             }
1857         }
1858     }
1859 }
1860