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