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.app.StatusBarManager; 29 import android.app.StatusBarManager.Disable2Flags; 30 import android.app.StatusBarManager.DisableFlags; 31 import android.app.StatusBarManager.WindowType; 32 import android.app.StatusBarManager.WindowVisibleState; 33 import android.content.ComponentName; 34 import android.content.Context; 35 import android.graphics.Rect; 36 import android.hardware.biometrics.IBiometricServiceReceiverInternal; 37 import android.hardware.display.DisplayManager; 38 import android.inputmethodservice.InputMethodService.BackDispositionMode; 39 import android.os.Bundle; 40 import android.os.Handler; 41 import android.os.IBinder; 42 import android.os.Looper; 43 import android.os.Message; 44 import android.util.Pair; 45 import android.util.SparseArray; 46 import android.view.inputmethod.InputMethodSystemProperty; 47 48 import androidx.annotation.VisibleForTesting; 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.systemui.SystemUI; 54 import com.android.systemui.statusbar.CommandQueue.Callbacks; 55 import com.android.systemui.statusbar.policy.CallbackController; 56 57 import java.util.ArrayList; 58 59 /** 60 * This class takes the functions from IStatusBar that come in on 61 * binder pool threads and posts messages to get them onto the main 62 * thread, and calls onto Callbacks. It also takes care of 63 * coalescing these calls so they don't stack up. For the calls 64 * are coalesced, note that they are all idempotent. 65 */ 66 public class CommandQueue extends IStatusBar.Stub implements CallbackController<Callbacks>, 67 DisplayManager.DisplayListener { 68 private static final int INDEX_MASK = 0xffff; 69 private static final int MSG_SHIFT = 16; 70 private static final int MSG_MASK = 0xffff << MSG_SHIFT; 71 72 private static final int OP_SET_ICON = 1; 73 private static final int OP_REMOVE_ICON = 2; 74 75 private static final int MSG_ICON = 1 << MSG_SHIFT; 76 private static final int MSG_DISABLE = 2 << MSG_SHIFT; 77 private static final int MSG_EXPAND_NOTIFICATIONS = 3 << MSG_SHIFT; 78 private static final int MSG_COLLAPSE_PANELS = 4 << MSG_SHIFT; 79 private static final int MSG_EXPAND_SETTINGS = 5 << MSG_SHIFT; 80 private static final int MSG_SET_SYSTEMUI_VISIBILITY = 6 << MSG_SHIFT; 81 private static final int MSG_DISPLAY_READY = 7 << MSG_SHIFT; 82 private static final int MSG_SHOW_IME_BUTTON = 8 << MSG_SHIFT; 83 private static final int MSG_TOGGLE_RECENT_APPS = 9 << MSG_SHIFT; 84 private static final int MSG_PRELOAD_RECENT_APPS = 10 << MSG_SHIFT; 85 private static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 11 << MSG_SHIFT; 86 private static final int MSG_SET_WINDOW_STATE = 12 << MSG_SHIFT; 87 private static final int MSG_SHOW_RECENT_APPS = 13 << MSG_SHIFT; 88 private static final int MSG_HIDE_RECENT_APPS = 14 << MSG_SHIFT; 89 private static final int MSG_SHOW_SCREEN_PIN_REQUEST = 18 << MSG_SHIFT; 90 private static final int MSG_APP_TRANSITION_PENDING = 19 << MSG_SHIFT; 91 private static final int MSG_APP_TRANSITION_CANCELLED = 20 << MSG_SHIFT; 92 private static final int MSG_APP_TRANSITION_STARTING = 21 << MSG_SHIFT; 93 private static final int MSG_ASSIST_DISCLOSURE = 22 << MSG_SHIFT; 94 private static final int MSG_START_ASSIST = 23 << MSG_SHIFT; 95 private static final int MSG_CAMERA_LAUNCH_GESTURE = 24 << MSG_SHIFT; 96 private static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS = 25 << MSG_SHIFT; 97 private static final int MSG_SHOW_PICTURE_IN_PICTURE_MENU = 26 << MSG_SHIFT; 98 private static final int MSG_ADD_QS_TILE = 27 << MSG_SHIFT; 99 private static final int MSG_REMOVE_QS_TILE = 28 << MSG_SHIFT; 100 private static final int MSG_CLICK_QS_TILE = 29 << MSG_SHIFT; 101 private static final int MSG_TOGGLE_APP_SPLIT_SCREEN = 30 << MSG_SHIFT; 102 private static final int MSG_APP_TRANSITION_FINISHED = 31 << MSG_SHIFT; 103 private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS = 32 << MSG_SHIFT; 104 private static final int MSG_HANDLE_SYSTEM_KEY = 33 << MSG_SHIFT; 105 private static final int MSG_SHOW_GLOBAL_ACTIONS = 34 << MSG_SHIFT; 106 private static final int MSG_TOGGLE_PANEL = 35 << MSG_SHIFT; 107 private static final int MSG_SHOW_SHUTDOWN_UI = 36 << MSG_SHIFT; 108 private static final int MSG_SET_TOP_APP_HIDES_STATUS_BAR = 37 << MSG_SHIFT; 109 private static final int MSG_ROTATION_PROPOSAL = 38 << MSG_SHIFT; 110 private static final int MSG_BIOMETRIC_SHOW = 39 << MSG_SHIFT; 111 private static final int MSG_BIOMETRIC_AUTHENTICATED = 40 << MSG_SHIFT; 112 private static final int MSG_BIOMETRIC_HELP = 41 << MSG_SHIFT; 113 private static final int MSG_BIOMETRIC_ERROR = 42 << MSG_SHIFT; 114 private static final int MSG_BIOMETRIC_HIDE = 43 << MSG_SHIFT; 115 private static final int MSG_SHOW_CHARGING_ANIMATION = 44 << MSG_SHIFT; 116 private static final int MSG_SHOW_PINNING_TOAST_ENTER_EXIT = 45 << MSG_SHIFT; 117 private static final int MSG_SHOW_PINNING_TOAST_ESCAPE = 46 << MSG_SHIFT; 118 private static final int MSG_RECENTS_ANIMATION_STATE_CHANGED = 47 << MSG_SHIFT; 119 120 public static final int FLAG_EXCLUDE_NONE = 0; 121 public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0; 122 public static final int FLAG_EXCLUDE_RECENTS_PANEL = 1 << 1; 123 public static final int FLAG_EXCLUDE_NOTIFICATION_PANEL = 1 << 2; 124 public static final int FLAG_EXCLUDE_INPUT_METHODS_PANEL = 1 << 3; 125 public static final int FLAG_EXCLUDE_COMPAT_MODE_PANEL = 1 << 4; 126 127 private static final String SHOW_IME_SWITCHER_KEY = "showImeSwitcherKey"; 128 129 private final Object mLock = new Object(); 130 private ArrayList<Callbacks> mCallbacks = new ArrayList<>(); 131 private Handler mHandler = new H(Looper.getMainLooper()); 132 /** A map of display id - disable flag pair */ 133 private SparseArray<Pair<Integer, Integer>> mDisplayDisabled = new SparseArray<>(); 134 /** 135 * The last ID of the display where IME window for which we received setImeWindowStatus 136 * event. 137 */ 138 private int mLastUpdatedImeDisplayId = INVALID_DISPLAY; 139 140 /** 141 * These methods are called back on the main thread. 142 */ 143 public interface Callbacks { setIcon(String slot, StatusBarIcon icon)144 default void setIcon(String slot, StatusBarIcon icon) { } removeIcon(String slot)145 default void removeIcon(String slot) { } 146 147 /** 148 * Called to notify that disable flags are updated. 149 * @see IStatusBar#disable(int, int, int). 150 * 151 * @param displayId The id of the display to notify. 152 * @param state1 The combination of following DISABLE_* flags: 153 * @param state2 The combination of following DISABLE2_* flags: 154 * @param animate {@code true} to show animations. 155 */ disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, boolean animate)156 default void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, 157 boolean animate) { } animateExpandNotificationsPanel()158 default void animateExpandNotificationsPanel() { } animateCollapsePanels(int flags, boolean force)159 default void animateCollapsePanels(int flags, boolean force) { } togglePanel()160 default void togglePanel() { } animateExpandSettingsPanel(String obj)161 default void animateExpandSettingsPanel(String obj) { } 162 163 /** 164 * Called to notify visibility flag changes. 165 * @see IStatusBar#setSystemUiVisibility(int, int, int, int, int, Rect, Rect). 166 * 167 * @param displayId The id of the display to notify. 168 * @param vis The visibility flags except SYSTEM_UI_FLAG_LIGHT_STATUS_BAR which will 169 * be reported separately in fullscreenStackVis and dockedStackVis. 170 * @param fullscreenStackVis The flags which only apply in the region of the fullscreen 171 * stack, which is currently only SYSTEM_UI_FLAG_LIGHT_STATUS_BAR. 172 * @param dockedStackVis The flags that only apply in the region of the docked stack, which 173 * is currently only SYSTEM_UI_FLAG_LIGHT_STATUS_BAR. 174 * @param mask Which flags to change. 175 * @param fullscreenStackBounds The current bounds of the fullscreen stack, in screen 176 * coordinates. 177 * @param dockedStackBounds The current bounds of the docked stack, in screen coordinates. 178 * @param navbarColorManagedByIme {@code true} if navigation bar color is managed by IME. 179 */ setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis, int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds, boolean navbarColorManagedByIme)180 default void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis, 181 int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds, 182 boolean navbarColorManagedByIme) { 183 } 184 185 /** 186 * Called to notify IME window status changes. 187 * 188 * @param displayId The id of the display to notify. 189 * @param token IME token. 190 * @param vis IME visibility. 191 * @param backDisposition Disposition mode of back button. It should be one of below flags: 192 * @param showImeSwitcher {@code true} to show IME switch button. 193 */ setImeWindowStatus(int displayId, IBinder token, int vis, @BackDispositionMode int backDisposition, boolean showImeSwitcher)194 default void setImeWindowStatus(int displayId, IBinder token, int vis, 195 @BackDispositionMode int backDisposition, boolean showImeSwitcher) { } showRecentApps(boolean triggeredFromAltTab)196 default void showRecentApps(boolean triggeredFromAltTab) { } hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)197 default void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { } toggleRecentApps()198 default void toggleRecentApps() { } toggleSplitScreen()199 default void toggleSplitScreen() { } preloadRecentApps()200 default void preloadRecentApps() { } dismissKeyboardShortcutsMenu()201 default void dismissKeyboardShortcutsMenu() { } toggleKeyboardShortcutsMenu(int deviceId)202 default void toggleKeyboardShortcutsMenu(int deviceId) { } cancelPreloadRecentApps()203 default void cancelPreloadRecentApps() { } 204 205 /** 206 * Called to notify window state changes. 207 * @see IStatusBar#setWindowState(int, int, int) 208 * 209 * @param displayId The id of the display to notify. 210 * @param window Window type. It should be one of {@link StatusBarManager#WINDOW_STATUS_BAR} 211 * or {@link StatusBarManager#WINDOW_NAVIGATION_BAR} 212 * @param state Window visible state. 213 */ setWindowState(int displayId, @WindowType int window, @WindowVisibleState int state)214 default void setWindowState(int displayId, @WindowType int window, 215 @WindowVisibleState int state) { } showScreenPinningRequest(int taskId)216 default void showScreenPinningRequest(int taskId) { } 217 218 /** 219 * Called to notify System UI that an application transition is pending. 220 * @see IStatusBar#appTransitionPending(int). 221 * 222 * @param displayId The id of the display to notify. 223 * @param forced {@code true} to force transition pending. 224 */ appTransitionPending(int displayId, boolean forced)225 default void appTransitionPending(int displayId, boolean forced) { } 226 227 /** 228 * Called to notify System UI that an application transition is canceled. 229 * @see IStatusBar#appTransitionCancelled(int). 230 * 231 * @param displayId The id of the display to notify. 232 */ appTransitionCancelled(int displayId)233 default void appTransitionCancelled(int displayId) { } 234 235 /** 236 * Called to notify System UI that an application transition is starting. 237 * @see IStatusBar#appTransitionStarting(int, long, long). 238 * 239 * @param displayId The id of the display to notify. 240 * @param startTime Transition start time. 241 * @param duration Transition duration. 242 * @param forced {@code true} to force transition pending. 243 */ appTransitionStarting( int displayId, long startTime, long duration, boolean forced)244 default void appTransitionStarting( 245 int displayId, long startTime, long duration, boolean forced) { } 246 247 /** 248 * Called to notify System UI that an application transition is finished. 249 * @see IStatusBar#appTransitionFinished(int) 250 * 251 * @param displayId The id of the display to notify. 252 */ appTransitionFinished(int displayId)253 default void appTransitionFinished(int displayId) { } showAssistDisclosure()254 default void showAssistDisclosure() { } startAssist(Bundle args)255 default void startAssist(Bundle args) { } onCameraLaunchGestureDetected(int source)256 default void onCameraLaunchGestureDetected(int source) { } showPictureInPictureMenu()257 default void showPictureInPictureMenu() { } setTopAppHidesStatusBar(boolean topAppHidesStatusBar)258 default void setTopAppHidesStatusBar(boolean topAppHidesStatusBar) { } 259 addQsTile(ComponentName tile)260 default void addQsTile(ComponentName tile) { } remQsTile(ComponentName tile)261 default void remQsTile(ComponentName tile) { } clickTile(ComponentName tile)262 default void clickTile(ComponentName tile) { } 263 handleSystemKey(int arg1)264 default void handleSystemKey(int arg1) { } showPinningEnterExitToast(boolean entering)265 default void showPinningEnterExitToast(boolean entering) { } showPinningEscapeToast()266 default void showPinningEscapeToast() { } handleShowGlobalActionsMenu()267 default void handleShowGlobalActionsMenu() { } handleShowShutdownUi(boolean isReboot, String reason)268 default void handleShowShutdownUi(boolean isReboot, String reason) { } 269 showWirelessChargingAnimation(int batteryLevel)270 default void showWirelessChargingAnimation(int batteryLevel) { } 271 onRotationProposal(int rotation, boolean isValid)272 default void onRotationProposal(int rotation, boolean isValid) { } 273 showBiometricDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver, int type, boolean requireConfirmation, int userId)274 default void showBiometricDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver, 275 int type, boolean requireConfirmation, int userId) { } onBiometricAuthenticated(boolean authenticated, String failureReason)276 default void onBiometricAuthenticated(boolean authenticated, String failureReason) { } onBiometricHelp(String message)277 default void onBiometricHelp(String message) { } onBiometricError(String error)278 default void onBiometricError(String error) { } hideBiometricDialog()279 default void hideBiometricDialog() { } 280 281 /** 282 * @see IStatusBar#onDisplayReady(int) 283 */ onDisplayReady(int displayId)284 default void onDisplayReady(int displayId) { } 285 286 /** 287 * @see DisplayManager.DisplayListener#onDisplayRemoved(int) 288 */ onDisplayRemoved(int displayId)289 default void onDisplayRemoved(int displayId) { } 290 291 /** 292 * @see IStatusBar#onRecentsAnimationStateChanged(boolean) 293 */ onRecentsAnimationStateChanged(boolean running)294 default void onRecentsAnimationStateChanged(boolean running) { } 295 } 296 297 @VisibleForTesting CommandQueue(Context context)298 public CommandQueue(Context context) { 299 context.getSystemService(DisplayManager.class).registerDisplayListener(this, mHandler); 300 // We always have default display. 301 setDisabled(DEFAULT_DISPLAY, DISABLE_NONE, DISABLE2_NONE); 302 } 303 304 @Override onDisplayAdded(int displayId)305 public void onDisplayAdded(int displayId) { } 306 307 @Override onDisplayRemoved(int displayId)308 public void onDisplayRemoved(int displayId) { 309 synchronized (mLock) { 310 mDisplayDisabled.remove(displayId); 311 } 312 // This callback is registered with {@link #mHandler} that already posts to run on main 313 // thread, so it is safe to dispatch directly. 314 for (int i = mCallbacks.size() - 1; i >= 0; i--) { 315 mCallbacks.get(i).onDisplayRemoved(displayId); 316 } 317 } 318 319 @Override onDisplayChanged(int displayId)320 public void onDisplayChanged(int displayId) { } 321 322 // TODO(b/118592525): add multi-display support if needed. panelsEnabled()323 public boolean panelsEnabled() { 324 final int disabled1 = getDisabled1(DEFAULT_DISPLAY); 325 final int disabled2 = getDisabled2(DEFAULT_DISPLAY); 326 return (disabled1 & StatusBarManager.DISABLE_EXPAND) == 0 327 && (disabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0 328 && !ONLY_CORE_APPS; 329 } 330 addCallback(Callbacks callbacks)331 public void addCallback(Callbacks callbacks) { 332 mCallbacks.add(callbacks); 333 // TODO(b/117478341): find a better way to pass disable flags by display. 334 for (int i = 0; i < mDisplayDisabled.size(); i++) { 335 int displayId = mDisplayDisabled.keyAt(i); 336 int disabled1 = getDisabled1(displayId); 337 int disabled2 = getDisabled2(displayId); 338 callbacks.disable(displayId, disabled1, disabled2, false /* animate */); 339 } 340 } 341 removeCallback(Callbacks callbacks)342 public void removeCallback(Callbacks callbacks) { 343 mCallbacks.remove(callbacks); 344 } 345 setIcon(String slot, StatusBarIcon icon)346 public void setIcon(String slot, StatusBarIcon icon) { 347 synchronized (mLock) { 348 // don't coalesce these 349 mHandler.obtainMessage(MSG_ICON, OP_SET_ICON, 0, 350 new Pair<String, StatusBarIcon>(slot, icon)).sendToTarget(); 351 } 352 } 353 removeIcon(String slot)354 public void removeIcon(String slot) { 355 synchronized (mLock) { 356 // don't coalesce these 357 mHandler.obtainMessage(MSG_ICON, OP_REMOVE_ICON, 0, slot).sendToTarget(); 358 } 359 } 360 361 /** 362 * Called to notify that disable flags are updated. 363 * @see Callbacks#disable(int, int, int, boolean). 364 */ disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, boolean animate)365 public void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, 366 boolean animate) { 367 synchronized (mLock) { 368 setDisabled(displayId, state1, state2); 369 mHandler.removeMessages(MSG_DISABLE); 370 final SomeArgs args = SomeArgs.obtain(); 371 args.argi1 = displayId; 372 args.argi2 = state1; 373 args.argi3 = state2; 374 args.argi4 = animate ? 1 : 0; 375 Message msg = mHandler.obtainMessage(MSG_DISABLE, args); 376 if (Looper.myLooper() == mHandler.getLooper()) { 377 // If its the right looper execute immediately so hides can be handled quickly. 378 mHandler.handleMessage(msg); 379 msg.recycle(); 380 } else { 381 msg.sendToTarget(); 382 } 383 } 384 } 385 386 @Override disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2)387 public void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2) { 388 disable(displayId, state1, state2, true); 389 } 390 391 /** 392 * Apply current disable flags by {@link CommandQueue#disable(int, int, int, boolean)}. 393 * 394 * @param displayId The id of the display to notify. 395 * @param animate {@code true} to show animations. 396 */ recomputeDisableFlags(int displayId, boolean animate)397 public void recomputeDisableFlags(int displayId, boolean animate) { 398 int disabled1 = getDisabled1(displayId); 399 int disabled2 = getDisabled2(displayId); 400 disable(displayId, disabled1, disabled2, animate); 401 } 402 setDisabled(int displayId, int disabled1, int disabled2)403 private void setDisabled(int displayId, int disabled1, int disabled2) { 404 mDisplayDisabled.put(displayId, new Pair<>(disabled1, disabled2)); 405 } 406 getDisabled1(int displayId)407 private int getDisabled1(int displayId) { 408 return getDisabled(displayId).first; 409 } 410 getDisabled2(int displayId)411 private int getDisabled2(int displayId) { 412 return getDisabled(displayId).second; 413 } 414 getDisabled(int displayId)415 private Pair<Integer, Integer> getDisabled(int displayId) { 416 Pair<Integer, Integer> disablePair = mDisplayDisabled.get(displayId); 417 if (disablePair == null) { 418 disablePair = new Pair<>(DISABLE_NONE, DISABLE2_NONE); 419 mDisplayDisabled.put(displayId, disablePair); 420 } 421 return disablePair; 422 } 423 animateExpandNotificationsPanel()424 public void animateExpandNotificationsPanel() { 425 synchronized (mLock) { 426 mHandler.removeMessages(MSG_EXPAND_NOTIFICATIONS); 427 mHandler.sendEmptyMessage(MSG_EXPAND_NOTIFICATIONS); 428 } 429 } 430 animateCollapsePanels()431 public void animateCollapsePanels() { 432 synchronized (mLock) { 433 mHandler.removeMessages(MSG_COLLAPSE_PANELS); 434 mHandler.obtainMessage(MSG_COLLAPSE_PANELS, 0, 0).sendToTarget(); 435 } 436 } 437 animateCollapsePanels(int flags, boolean force)438 public void animateCollapsePanels(int flags, boolean force) { 439 synchronized (mLock) { 440 mHandler.removeMessages(MSG_COLLAPSE_PANELS); 441 mHandler.obtainMessage(MSG_COLLAPSE_PANELS, flags, force ? 1 : 0).sendToTarget(); 442 } 443 } 444 togglePanel()445 public void togglePanel() { 446 synchronized (mLock) { 447 mHandler.removeMessages(MSG_TOGGLE_PANEL); 448 mHandler.obtainMessage(MSG_TOGGLE_PANEL, 0, 0).sendToTarget(); 449 } 450 } 451 animateExpandSettingsPanel(String subPanel)452 public void animateExpandSettingsPanel(String subPanel) { 453 synchronized (mLock) { 454 mHandler.removeMessages(MSG_EXPAND_SETTINGS); 455 mHandler.obtainMessage(MSG_EXPAND_SETTINGS, subPanel).sendToTarget(); 456 } 457 } 458 459 @Override setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis, int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds, boolean navbarColorManagedByIme)460 public void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis, 461 int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds, 462 boolean navbarColorManagedByIme) { 463 synchronized (mLock) { 464 // Don't coalesce these, since it might have one time flags set such as 465 // STATUS_BAR_UNHIDE which might get lost. 466 SomeArgs args = SomeArgs.obtain(); 467 args.argi1 = displayId; 468 args.argi2 = vis; 469 args.argi3 = fullscreenStackVis; 470 args.argi4 = dockedStackVis; 471 args.argi5 = mask; 472 args.argi6 = navbarColorManagedByIme ? 1 : 0; 473 args.arg1 = fullscreenStackBounds; 474 args.arg2 = dockedStackBounds; 475 mHandler.obtainMessage(MSG_SET_SYSTEMUI_VISIBILITY, args).sendToTarget(); 476 } 477 } 478 479 @Override topAppWindowChanged(int displayId, boolean menuVisible)480 public void topAppWindowChanged(int displayId, boolean menuVisible) { } 481 482 @Override setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher)483 public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, 484 boolean showImeSwitcher) { 485 synchronized (mLock) { 486 mHandler.removeMessages(MSG_SHOW_IME_BUTTON); 487 SomeArgs args = SomeArgs.obtain(); 488 args.argi1 = displayId; 489 args.argi2 = vis; 490 args.argi3 = backDisposition; 491 args.argi4 = showImeSwitcher ? 1 : 0; 492 args.arg1 = token; 493 Message m = mHandler.obtainMessage(MSG_SHOW_IME_BUTTON, args); 494 m.sendToTarget(); 495 } 496 } 497 showRecentApps(boolean triggeredFromAltTab)498 public void showRecentApps(boolean triggeredFromAltTab) { 499 synchronized (mLock) { 500 mHandler.removeMessages(MSG_SHOW_RECENT_APPS); 501 mHandler.obtainMessage(MSG_SHOW_RECENT_APPS, triggeredFromAltTab ? 1 : 0, 0, 502 null).sendToTarget(); 503 } 504 } 505 hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)506 public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { 507 synchronized (mLock) { 508 mHandler.removeMessages(MSG_HIDE_RECENT_APPS); 509 mHandler.obtainMessage(MSG_HIDE_RECENT_APPS, 510 triggeredFromAltTab ? 1 : 0, triggeredFromHomeKey ? 1 : 0, 511 null).sendToTarget(); 512 } 513 } 514 toggleSplitScreen()515 public void toggleSplitScreen() { 516 synchronized (mLock) { 517 mHandler.removeMessages(MSG_TOGGLE_APP_SPLIT_SCREEN); 518 mHandler.obtainMessage(MSG_TOGGLE_APP_SPLIT_SCREEN, 0, 0, null).sendToTarget(); 519 } 520 } 521 toggleRecentApps()522 public void toggleRecentApps() { 523 synchronized (mLock) { 524 mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS); 525 Message msg = mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null); 526 msg.setAsynchronous(true); 527 msg.sendToTarget(); 528 } 529 } 530 preloadRecentApps()531 public void preloadRecentApps() { 532 synchronized (mLock) { 533 mHandler.removeMessages(MSG_PRELOAD_RECENT_APPS); 534 mHandler.obtainMessage(MSG_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget(); 535 } 536 } 537 cancelPreloadRecentApps()538 public void cancelPreloadRecentApps() { 539 synchronized (mLock) { 540 mHandler.removeMessages(MSG_CANCEL_PRELOAD_RECENT_APPS); 541 mHandler.obtainMessage(MSG_CANCEL_PRELOAD_RECENT_APPS, 0, 0, null).sendToTarget(); 542 } 543 } 544 545 @Override dismissKeyboardShortcutsMenu()546 public void dismissKeyboardShortcutsMenu() { 547 synchronized (mLock) { 548 mHandler.removeMessages(MSG_DISMISS_KEYBOARD_SHORTCUTS); 549 mHandler.obtainMessage(MSG_DISMISS_KEYBOARD_SHORTCUTS).sendToTarget(); 550 } 551 } 552 553 @Override toggleKeyboardShortcutsMenu(int deviceId)554 public void toggleKeyboardShortcutsMenu(int deviceId) { 555 synchronized (mLock) { 556 mHandler.removeMessages(MSG_TOGGLE_KEYBOARD_SHORTCUTS); 557 mHandler.obtainMessage(MSG_TOGGLE_KEYBOARD_SHORTCUTS, deviceId, 0).sendToTarget(); 558 } 559 } 560 561 @Override showPictureInPictureMenu()562 public void showPictureInPictureMenu() { 563 synchronized (mLock) { 564 mHandler.removeMessages(MSG_SHOW_PICTURE_IN_PICTURE_MENU); 565 mHandler.obtainMessage(MSG_SHOW_PICTURE_IN_PICTURE_MENU).sendToTarget(); 566 } 567 } 568 569 @Override setWindowState(int displayId, int window, int state)570 public void setWindowState(int displayId, int window, int state) { 571 synchronized (mLock) { 572 // don't coalesce these 573 mHandler.obtainMessage(MSG_SET_WINDOW_STATE, displayId, window, state).sendToTarget(); 574 } 575 } 576 showScreenPinningRequest(int taskId)577 public void showScreenPinningRequest(int taskId) { 578 synchronized (mLock) { 579 mHandler.obtainMessage(MSG_SHOW_SCREEN_PIN_REQUEST, taskId, 0, null) 580 .sendToTarget(); 581 } 582 } 583 584 @Override appTransitionPending(int displayId)585 public void appTransitionPending(int displayId) { 586 appTransitionPending(displayId, false /* forced */); 587 } 588 589 /** 590 * Called to notify System UI that an application transition is pending. 591 * @see Callbacks#appTransitionPending(int, boolean) 592 */ appTransitionPending(int displayId, boolean forced)593 public void appTransitionPending(int displayId, boolean forced) { 594 synchronized (mLock) { 595 mHandler.obtainMessage(MSG_APP_TRANSITION_PENDING, displayId, forced ? 1 : 0) 596 .sendToTarget(); 597 } 598 } 599 600 @Override appTransitionCancelled(int displayId)601 public void appTransitionCancelled(int displayId) { 602 synchronized (mLock) { 603 mHandler.obtainMessage(MSG_APP_TRANSITION_CANCELLED, displayId, 0 /* unused */) 604 .sendToTarget(); 605 } 606 } 607 608 @Override appTransitionStarting(int displayId, long startTime, long duration)609 public void appTransitionStarting(int displayId, long startTime, long duration) { 610 appTransitionStarting(displayId, startTime, duration, false /* forced */); 611 } 612 613 /** 614 * Called to notify System UI that an application transition is starting. 615 * @see Callbacks#appTransitionStarting(int, long, long, boolean). 616 */ appTransitionStarting(int displayId, long startTime, long duration, boolean forced)617 public void appTransitionStarting(int displayId, long startTime, long duration, 618 boolean forced) { 619 synchronized (mLock) { 620 final SomeArgs args = SomeArgs.obtain(); 621 args.argi1 = displayId; 622 args.argi2 = forced ? 1 : 0; 623 args.arg1 = startTime; 624 args.arg2 = duration; 625 mHandler.obtainMessage(MSG_APP_TRANSITION_STARTING, args).sendToTarget(); 626 } 627 } 628 629 @Override appTransitionFinished(int displayId)630 public void appTransitionFinished(int displayId) { 631 synchronized (mLock) { 632 mHandler.obtainMessage(MSG_APP_TRANSITION_FINISHED, displayId, 0 /* unused */) 633 .sendToTarget(); 634 } 635 } 636 showAssistDisclosure()637 public void showAssistDisclosure() { 638 synchronized (mLock) { 639 mHandler.removeMessages(MSG_ASSIST_DISCLOSURE); 640 mHandler.obtainMessage(MSG_ASSIST_DISCLOSURE).sendToTarget(); 641 } 642 } 643 startAssist(Bundle args)644 public void startAssist(Bundle args) { 645 synchronized (mLock) { 646 mHandler.removeMessages(MSG_START_ASSIST); 647 mHandler.obtainMessage(MSG_START_ASSIST, args).sendToTarget(); 648 } 649 } 650 651 @Override onCameraLaunchGestureDetected(int source)652 public void onCameraLaunchGestureDetected(int source) { 653 synchronized (mLock) { 654 mHandler.removeMessages(MSG_CAMERA_LAUNCH_GESTURE); 655 mHandler.obtainMessage(MSG_CAMERA_LAUNCH_GESTURE, source, 0).sendToTarget(); 656 } 657 } 658 659 @Override addQsTile(ComponentName tile)660 public void addQsTile(ComponentName tile) { 661 synchronized (mLock) { 662 mHandler.obtainMessage(MSG_ADD_QS_TILE, tile).sendToTarget(); 663 } 664 } 665 666 @Override remQsTile(ComponentName tile)667 public void remQsTile(ComponentName tile) { 668 synchronized (mLock) { 669 mHandler.obtainMessage(MSG_REMOVE_QS_TILE, tile).sendToTarget(); 670 } 671 } 672 673 @Override clickQsTile(ComponentName tile)674 public void clickQsTile(ComponentName tile) { 675 synchronized (mLock) { 676 mHandler.obtainMessage(MSG_CLICK_QS_TILE, tile).sendToTarget(); 677 } 678 } 679 680 @Override handleSystemKey(int key)681 public void handleSystemKey(int key) { 682 synchronized (mLock) { 683 mHandler.obtainMessage(MSG_HANDLE_SYSTEM_KEY, key, 0).sendToTarget(); 684 } 685 } 686 687 @Override showPinningEnterExitToast(boolean entering)688 public void showPinningEnterExitToast(boolean entering) { 689 synchronized (mLock) { 690 mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ENTER_EXIT, entering).sendToTarget(); 691 } 692 } 693 694 @Override showPinningEscapeToast()695 public void showPinningEscapeToast() { 696 synchronized (mLock) { 697 mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ESCAPE).sendToTarget(); 698 } 699 } 700 701 702 @Override showGlobalActionsMenu()703 public void showGlobalActionsMenu() { 704 synchronized (mLock) { 705 mHandler.removeMessages(MSG_SHOW_GLOBAL_ACTIONS); 706 mHandler.obtainMessage(MSG_SHOW_GLOBAL_ACTIONS).sendToTarget(); 707 } 708 } 709 710 @Override setTopAppHidesStatusBar(boolean hidesStatusBar)711 public void setTopAppHidesStatusBar(boolean hidesStatusBar) { 712 mHandler.removeMessages(MSG_SET_TOP_APP_HIDES_STATUS_BAR); 713 mHandler.obtainMessage(MSG_SET_TOP_APP_HIDES_STATUS_BAR, hidesStatusBar ? 1 : 0, 0) 714 .sendToTarget(); 715 } 716 717 @Override showShutdownUi(boolean isReboot, String reason)718 public void showShutdownUi(boolean isReboot, String reason) { 719 synchronized (mLock) { 720 mHandler.removeMessages(MSG_SHOW_SHUTDOWN_UI); 721 mHandler.obtainMessage(MSG_SHOW_SHUTDOWN_UI, isReboot ? 1 : 0, 0, reason) 722 .sendToTarget(); 723 } 724 } 725 726 @Override showWirelessChargingAnimation(int batteryLevel)727 public void showWirelessChargingAnimation(int batteryLevel) { 728 mHandler.removeMessages(MSG_SHOW_CHARGING_ANIMATION); 729 mHandler.obtainMessage(MSG_SHOW_CHARGING_ANIMATION, batteryLevel, 0) 730 .sendToTarget(); 731 } 732 733 @Override onProposedRotationChanged(int rotation, boolean isValid)734 public void onProposedRotationChanged(int rotation, boolean isValid) { 735 synchronized (mLock) { 736 mHandler.removeMessages(MSG_ROTATION_PROPOSAL); 737 mHandler.obtainMessage(MSG_ROTATION_PROPOSAL, rotation, isValid ? 1 : 0, 738 null).sendToTarget(); 739 } 740 } 741 742 @Override showBiometricDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver, int type, boolean requireConfirmation, int userId)743 public void showBiometricDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver, 744 int type, boolean requireConfirmation, int userId) { 745 synchronized (mLock) { 746 SomeArgs args = SomeArgs.obtain(); 747 args.arg1 = bundle; 748 args.arg2 = receiver; 749 args.argi1 = type; 750 args.arg3 = requireConfirmation; 751 args.argi2 = userId; 752 mHandler.obtainMessage(MSG_BIOMETRIC_SHOW, args) 753 .sendToTarget(); 754 } 755 } 756 757 @Override onBiometricAuthenticated(boolean authenticated, String failureReason)758 public void onBiometricAuthenticated(boolean authenticated, String failureReason) { 759 synchronized (mLock) { 760 SomeArgs args = SomeArgs.obtain(); 761 args.arg1 = authenticated; 762 args.arg2 = failureReason; 763 mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATED, args).sendToTarget(); 764 } 765 } 766 767 @Override onBiometricHelp(String message)768 public void onBiometricHelp(String message) { 769 synchronized (mLock) { 770 mHandler.obtainMessage(MSG_BIOMETRIC_HELP, message).sendToTarget(); 771 } 772 } 773 774 @Override onBiometricError(String error)775 public void onBiometricError(String error) { 776 synchronized (mLock) { 777 mHandler.obtainMessage(MSG_BIOMETRIC_ERROR, error).sendToTarget(); 778 } 779 } 780 781 @Override hideBiometricDialog()782 public void hideBiometricDialog() { 783 synchronized (mLock) { 784 mHandler.obtainMessage(MSG_BIOMETRIC_HIDE).sendToTarget(); 785 } 786 } 787 788 @Override onDisplayReady(int displayId)789 public void onDisplayReady(int displayId) { 790 synchronized (mLock) { 791 mHandler.obtainMessage(MSG_DISPLAY_READY, displayId, 0).sendToTarget(); 792 } 793 } 794 795 @Override onRecentsAnimationStateChanged(boolean running)796 public void onRecentsAnimationStateChanged(boolean running) { 797 synchronized (mLock) { 798 mHandler.obtainMessage(MSG_RECENTS_ANIMATION_STATE_CHANGED, running ? 1 : 0, 0) 799 .sendToTarget(); 800 } 801 } 802 handleShowImeButton(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher)803 private void handleShowImeButton(int displayId, IBinder token, int vis, int backDisposition, 804 boolean showImeSwitcher) { 805 if (displayId == INVALID_DISPLAY) return; 806 807 if (!InputMethodSystemProperty.MULTI_CLIENT_IME_ENABLED 808 && mLastUpdatedImeDisplayId != displayId 809 && mLastUpdatedImeDisplayId != INVALID_DISPLAY) { 810 // Set previous NavBar's IME window status as invisible when IME 811 // window switched to another display for single-session IME case. 812 sendImeInvisibleStatusForPrevNavBar(); 813 } 814 for (int i = 0; i < mCallbacks.size(); i++) { 815 mCallbacks.get(i).setImeWindowStatus(displayId, token, vis, backDisposition, 816 showImeSwitcher); 817 } 818 mLastUpdatedImeDisplayId = displayId; 819 } 820 sendImeInvisibleStatusForPrevNavBar()821 private void sendImeInvisibleStatusForPrevNavBar() { 822 for (int i = 0; i < mCallbacks.size(); i++) { 823 mCallbacks.get(i).setImeWindowStatus(mLastUpdatedImeDisplayId, 824 null /* token */, IME_INVISIBLE, BACK_DISPOSITION_DEFAULT, 825 false /* showImeSwitcher */); 826 } 827 } 828 829 private final class H extends Handler { H(Looper l)830 private H(Looper l) { 831 super(l); 832 } 833 handleMessage(Message msg)834 public void handleMessage(Message msg) { 835 final int what = msg.what & MSG_MASK; 836 switch (what) { 837 case MSG_ICON: { 838 switch (msg.arg1) { 839 case OP_SET_ICON: { 840 Pair<String, StatusBarIcon> p = (Pair<String, StatusBarIcon>) msg.obj; 841 for (int i = 0; i < mCallbacks.size(); i++) { 842 mCallbacks.get(i).setIcon(p.first, p.second); 843 } 844 break; 845 } 846 case OP_REMOVE_ICON: 847 for (int i = 0; i < mCallbacks.size(); i++) { 848 mCallbacks.get(i).removeIcon((String) msg.obj); 849 } 850 break; 851 } 852 break; 853 } 854 case MSG_DISABLE: 855 SomeArgs args = (SomeArgs) msg.obj; 856 for (int i = 0; i < mCallbacks.size(); i++) { 857 mCallbacks.get(i).disable(args.argi1, args.argi2, args.argi3, 858 args.argi4 != 0 /* animate */); 859 } 860 break; 861 case MSG_EXPAND_NOTIFICATIONS: 862 for (int i = 0; i < mCallbacks.size(); i++) { 863 mCallbacks.get(i).animateExpandNotificationsPanel(); 864 } 865 break; 866 case MSG_COLLAPSE_PANELS: 867 for (int i = 0; i < mCallbacks.size(); i++) { 868 mCallbacks.get(i).animateCollapsePanels(msg.arg1, msg.arg2 != 0); 869 } 870 break; 871 case MSG_TOGGLE_PANEL: 872 for (int i = 0; i < mCallbacks.size(); i++) { 873 mCallbacks.get(i).togglePanel(); 874 } 875 break; 876 case MSG_EXPAND_SETTINGS: 877 for (int i = 0; i < mCallbacks.size(); i++) { 878 mCallbacks.get(i).animateExpandSettingsPanel((String) msg.obj); 879 } 880 break; 881 case MSG_SET_SYSTEMUI_VISIBILITY: 882 args = (SomeArgs) msg.obj; 883 for (int i = 0; i < mCallbacks.size(); i++) { 884 mCallbacks.get(i).setSystemUiVisibility(args.argi1, args.argi2, args.argi3, 885 args.argi4, args.argi5, (Rect) args.arg1, (Rect) args.arg2, 886 args.argi6 == 1); 887 } 888 args.recycle(); 889 break; 890 case MSG_SHOW_IME_BUTTON: 891 args = (SomeArgs) msg.obj; 892 handleShowImeButton(args.argi1 /* displayId */, (IBinder) args.arg1 /* token */, 893 args.argi2 /* vis */, args.argi3 /* backDisposition */, 894 args.argi4 != 0 /* showImeSwitcher */); 895 break; 896 case MSG_SHOW_RECENT_APPS: 897 for (int i = 0; i < mCallbacks.size(); i++) { 898 mCallbacks.get(i).showRecentApps(msg.arg1 != 0); 899 } 900 break; 901 case MSG_HIDE_RECENT_APPS: 902 for (int i = 0; i < mCallbacks.size(); i++) { 903 mCallbacks.get(i).hideRecentApps(msg.arg1 != 0, msg.arg2 != 0); 904 } 905 break; 906 case MSG_TOGGLE_RECENT_APPS: 907 for (int i = 0; i < mCallbacks.size(); i++) { 908 mCallbacks.get(i).toggleRecentApps(); 909 } 910 break; 911 case MSG_PRELOAD_RECENT_APPS: 912 for (int i = 0; i < mCallbacks.size(); i++) { 913 mCallbacks.get(i).preloadRecentApps(); 914 } 915 break; 916 case MSG_CANCEL_PRELOAD_RECENT_APPS: 917 for (int i = 0; i < mCallbacks.size(); i++) { 918 mCallbacks.get(i).cancelPreloadRecentApps(); 919 } 920 break; 921 case MSG_DISMISS_KEYBOARD_SHORTCUTS: 922 for (int i = 0; i < mCallbacks.size(); i++) { 923 mCallbacks.get(i).dismissKeyboardShortcutsMenu(); 924 } 925 break; 926 case MSG_TOGGLE_KEYBOARD_SHORTCUTS: 927 for (int i = 0; i < mCallbacks.size(); i++) { 928 mCallbacks.get(i).toggleKeyboardShortcutsMenu(msg.arg1); 929 } 930 break; 931 case MSG_SET_WINDOW_STATE: 932 for (int i = 0; i < mCallbacks.size(); i++) { 933 mCallbacks.get(i).setWindowState(msg.arg1, msg.arg2, (int) msg.obj); 934 } 935 break; 936 case MSG_SHOW_SCREEN_PIN_REQUEST: 937 for (int i = 0; i < mCallbacks.size(); i++) { 938 mCallbacks.get(i).showScreenPinningRequest(msg.arg1); 939 } 940 break; 941 case MSG_APP_TRANSITION_PENDING: 942 for (int i = 0; i < mCallbacks.size(); i++) { 943 mCallbacks.get(i).appTransitionPending(msg.arg1, msg.arg2 != 0); 944 } 945 break; 946 case MSG_APP_TRANSITION_CANCELLED: 947 for (int i = 0; i < mCallbacks.size(); i++) { 948 mCallbacks.get(i).appTransitionCancelled(msg.arg1); 949 } 950 break; 951 case MSG_APP_TRANSITION_STARTING: 952 args = (SomeArgs) msg.obj; 953 for (int i = 0; i < mCallbacks.size(); i++) { 954 mCallbacks.get(i).appTransitionStarting(args.argi1, (long) args.arg1, 955 (long) args.arg2, args.argi2 != 0 /* forced */); 956 } 957 break; 958 case MSG_APP_TRANSITION_FINISHED: 959 for (int i = 0; i < mCallbacks.size(); i++) { 960 mCallbacks.get(i).appTransitionFinished(msg.arg1); 961 } 962 break; 963 case MSG_ASSIST_DISCLOSURE: 964 for (int i = 0; i < mCallbacks.size(); i++) { 965 mCallbacks.get(i).showAssistDisclosure(); 966 } 967 break; 968 case MSG_START_ASSIST: 969 for (int i = 0; i < mCallbacks.size(); i++) { 970 mCallbacks.get(i).startAssist((Bundle) msg.obj); 971 } 972 break; 973 case MSG_CAMERA_LAUNCH_GESTURE: 974 for (int i = 0; i < mCallbacks.size(); i++) { 975 mCallbacks.get(i).onCameraLaunchGestureDetected(msg.arg1); 976 } 977 break; 978 case MSG_SHOW_PICTURE_IN_PICTURE_MENU: 979 for (int i = 0; i < mCallbacks.size(); i++) { 980 mCallbacks.get(i).showPictureInPictureMenu(); 981 } 982 break; 983 case MSG_ADD_QS_TILE: 984 for (int i = 0; i < mCallbacks.size(); i++) { 985 mCallbacks.get(i).addQsTile((ComponentName) msg.obj); 986 } 987 break; 988 case MSG_REMOVE_QS_TILE: 989 for (int i = 0; i < mCallbacks.size(); i++) { 990 mCallbacks.get(i).remQsTile((ComponentName) msg.obj); 991 } 992 break; 993 case MSG_CLICK_QS_TILE: 994 for (int i = 0; i < mCallbacks.size(); i++) { 995 mCallbacks.get(i).clickTile((ComponentName) msg.obj); 996 } 997 break; 998 case MSG_TOGGLE_APP_SPLIT_SCREEN: 999 for (int i = 0; i < mCallbacks.size(); i++) { 1000 mCallbacks.get(i).toggleSplitScreen(); 1001 } 1002 break; 1003 case MSG_HANDLE_SYSTEM_KEY: 1004 for (int i = 0; i < mCallbacks.size(); i++) { 1005 mCallbacks.get(i).handleSystemKey(msg.arg1); 1006 } 1007 break; 1008 case MSG_SHOW_GLOBAL_ACTIONS: 1009 for (int i = 0; i < mCallbacks.size(); i++) { 1010 mCallbacks.get(i).handleShowGlobalActionsMenu(); 1011 } 1012 break; 1013 case MSG_SHOW_SHUTDOWN_UI: 1014 for (int i = 0; i < mCallbacks.size(); i++) { 1015 mCallbacks.get(i).handleShowShutdownUi(msg.arg1 != 0, (String) msg.obj); 1016 } 1017 break; 1018 case MSG_SET_TOP_APP_HIDES_STATUS_BAR: 1019 for (int i = 0; i < mCallbacks.size(); i++) { 1020 mCallbacks.get(i).setTopAppHidesStatusBar(msg.arg1 != 0); 1021 } 1022 break; 1023 case MSG_ROTATION_PROPOSAL: 1024 for (int i = 0; i < mCallbacks.size(); i++) { 1025 mCallbacks.get(i).onRotationProposal(msg.arg1, msg.arg2 != 0); 1026 } 1027 break; 1028 case MSG_BIOMETRIC_SHOW: { 1029 mHandler.removeMessages(MSG_BIOMETRIC_ERROR); 1030 mHandler.removeMessages(MSG_BIOMETRIC_HELP); 1031 mHandler.removeMessages(MSG_BIOMETRIC_AUTHENTICATED); 1032 SomeArgs someArgs = (SomeArgs) msg.obj; 1033 for (int i = 0; i < mCallbacks.size(); i++) { 1034 mCallbacks.get(i).showBiometricDialog( 1035 (Bundle) someArgs.arg1, 1036 (IBiometricServiceReceiverInternal) someArgs.arg2, 1037 someArgs.argi1 /* type */, 1038 (boolean) someArgs.arg3 /* requireConfirmation */, 1039 someArgs.argi2 /* userId */); 1040 } 1041 someArgs.recycle(); 1042 break; 1043 } 1044 case MSG_BIOMETRIC_AUTHENTICATED: { 1045 SomeArgs someArgs = (SomeArgs) msg.obj; 1046 for (int i = 0; i < mCallbacks.size(); i++) { 1047 mCallbacks.get(i).onBiometricAuthenticated( 1048 (boolean) someArgs.arg1 /* authenticated */, 1049 (String) someArgs.arg2 /* failureReason */); 1050 } 1051 someArgs.recycle(); 1052 break; 1053 } 1054 case MSG_BIOMETRIC_HELP: 1055 for (int i = 0; i < mCallbacks.size(); i++) { 1056 mCallbacks.get(i).onBiometricHelp((String) msg.obj); 1057 } 1058 break; 1059 case MSG_BIOMETRIC_ERROR: 1060 for (int i = 0; i < mCallbacks.size(); i++) { 1061 mCallbacks.get(i).onBiometricError((String) msg.obj); 1062 } 1063 break; 1064 case MSG_BIOMETRIC_HIDE: 1065 for (int i = 0; i < mCallbacks.size(); i++) { 1066 mCallbacks.get(i).hideBiometricDialog(); 1067 } 1068 break; 1069 case MSG_SHOW_CHARGING_ANIMATION: 1070 for (int i = 0; i < mCallbacks.size(); i++) { 1071 mCallbacks.get(i).showWirelessChargingAnimation(msg.arg1); 1072 } 1073 break; 1074 case MSG_SHOW_PINNING_TOAST_ENTER_EXIT: 1075 for (int i = 0; i < mCallbacks.size(); i++) { 1076 mCallbacks.get(i).showPinningEnterExitToast((Boolean) msg.obj); 1077 } 1078 break; 1079 case MSG_SHOW_PINNING_TOAST_ESCAPE: 1080 for (int i = 0; i < mCallbacks.size(); i++) { 1081 mCallbacks.get(i).showPinningEscapeToast(); 1082 } 1083 break; 1084 case MSG_DISPLAY_READY: 1085 for (int i = 0; i < mCallbacks.size(); i++) { 1086 mCallbacks.get(i).onDisplayReady(msg.arg1); 1087 } 1088 break; 1089 case MSG_RECENTS_ANIMATION_STATE_CHANGED: 1090 for (int i = 0; i < mCallbacks.size(); i++) { 1091 mCallbacks.get(i).onRecentsAnimationStateChanged(msg.arg1 > 0); 1092 } 1093 break; 1094 } 1095 } 1096 } 1097 1098 // Need this class since CommandQueue already extends IStatusBar.Stub, so CommandQueueStart 1099 // is needed so it can extend SystemUI. 1100 public static class CommandQueueStart extends SystemUI { 1101 @Override start()1102 public void start() { 1103 putComponent(CommandQueue.class, new CommandQueue(mContext)); 1104 } 1105 } 1106 } 1107