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