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