1 /* 2 * Copyright (C) 2020 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.car.systembar; 18 19 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; 20 import static android.view.InsetsState.ITYPE_STATUS_BAR; 21 import static android.view.InsetsState.containsType; 22 import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; 23 24 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT; 25 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT; 26 27 import android.app.StatusBarManager.Disable2Flags; 28 import android.app.StatusBarManager.DisableFlags; 29 import android.content.Context; 30 import android.inputmethodservice.InputMethodService; 31 import android.os.IBinder; 32 import android.os.RemoteException; 33 import android.view.Display; 34 import android.view.InsetsVisibilities; 35 import android.view.View; 36 import android.view.ViewGroup; 37 import android.view.WindowInsetsController; 38 import android.view.WindowManager; 39 40 import androidx.annotation.VisibleForTesting; 41 42 import com.android.internal.statusbar.IStatusBarService; 43 import com.android.internal.statusbar.RegisterStatusBarResult; 44 import com.android.internal.view.AppearanceRegion; 45 import com.android.systemui.SystemUI; 46 import com.android.systemui.car.CarDeviceProvisionedController; 47 import com.android.systemui.car.CarDeviceProvisionedListener; 48 import com.android.systemui.car.hvac.HvacController; 49 import com.android.systemui.dagger.qualifiers.Main; 50 import com.android.systemui.dagger.qualifiers.UiBackground; 51 import com.android.systemui.plugins.DarkIconDispatcher; 52 import com.android.systemui.shared.system.ActivityManagerWrapper; 53 import com.android.systemui.shared.system.TaskStackChangeListener; 54 import com.android.systemui.statusbar.AutoHideUiElement; 55 import com.android.systemui.statusbar.CommandQueue; 56 import com.android.systemui.statusbar.phone.AutoHideController; 57 import com.android.systemui.statusbar.phone.BarTransitions; 58 import com.android.systemui.statusbar.phone.LightBarController; 59 import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy; 60 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy; 61 import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher; 62 import com.android.systemui.statusbar.policy.KeyguardStateController; 63 import com.android.systemui.util.concurrency.DelayableExecutor; 64 65 import java.io.FileDescriptor; 66 import java.io.PrintWriter; 67 import java.util.concurrent.Executor; 68 69 import javax.inject.Inject; 70 71 import dagger.Lazy; 72 73 /** Navigation bars customized for the automotive use case. */ 74 public class CarSystemBar extends SystemUI implements CommandQueue.Callbacks { 75 private final CarSystemBarController mCarSystemBarController; 76 private final SysuiDarkIconDispatcher mStatusBarIconController; 77 private final WindowManager mWindowManager; 78 private final CarDeviceProvisionedController mCarDeviceProvisionedController; 79 private final CommandQueue mCommandQueue; 80 private final AutoHideController mAutoHideController; 81 private final ButtonSelectionStateListener mButtonSelectionStateListener; 82 private final DelayableExecutor mExecutor; 83 private final Executor mUiBgExecutor; 84 private final IStatusBarService mBarService; 85 private final Lazy<KeyguardStateController> mKeyguardStateControllerLazy; 86 private final Lazy<PhoneStatusBarPolicy> mIconPolicyLazy; 87 private final HvacController mHvacController; 88 private final int mDisplayId; 89 private final SystemBarConfigs mSystemBarConfigs; 90 91 private StatusBarSignalPolicy mSignalPolicy; 92 private ActivityManagerWrapper mActivityManagerWrapper; 93 94 // If the nav bar should be hidden when the soft keyboard is visible. 95 private boolean mHideTopBarForKeyboard; 96 private boolean mHideLeftBarForKeyboard; 97 private boolean mHideRightBarForKeyboard; 98 private boolean mHideBottomBarForKeyboard; 99 100 private boolean mBottomNavBarVisible; 101 102 // Nav bar views. 103 private ViewGroup mTopSystemBarWindow; 104 private ViewGroup mBottomSystemBarWindow; 105 private ViewGroup mLeftSystemBarWindow; 106 private ViewGroup mRightSystemBarWindow; 107 private CarSystemBarView mTopSystemBarView; 108 private CarSystemBarView mBottomSystemBarView; 109 private CarSystemBarView mLeftSystemBarView; 110 private CarSystemBarView mRightSystemBarView; 111 112 // To be attached to the navigation bars such that they can close the notification panel if 113 // it's open. 114 private boolean mDeviceIsSetUpForUser = true; 115 private boolean mIsUserSetupInProgress = false; 116 117 private AppearanceRegion[] mAppearanceRegions = new AppearanceRegion[0]; 118 @BarTransitions.TransitionMode 119 private int mStatusBarMode; 120 @BarTransitions.TransitionMode 121 private int mSystemBarMode; 122 private boolean mStatusBarTransientShown; 123 private boolean mNavBarTransientShown; 124 125 @Inject CarSystemBar(Context context, CarSystemBarController carSystemBarController, LightBarController lightBarController, DarkIconDispatcher darkIconDispatcher, WindowManager windowManager, CarDeviceProvisionedController deviceProvisionedController, CommandQueue commandQueue, AutoHideController autoHideController, ButtonSelectionStateListener buttonSelectionStateListener, @Main DelayableExecutor mainExecutor, @UiBackground Executor uiBgExecutor, IStatusBarService barService, Lazy<KeyguardStateController> keyguardStateControllerLazy, Lazy<PhoneStatusBarPolicy> iconPolicyLazy, StatusBarSignalPolicy signalPolicy, HvacController hvacController, SystemBarConfigs systemBarConfigs )126 public CarSystemBar(Context context, 127 CarSystemBarController carSystemBarController, 128 // TODO(b/156052638): Should not need to inject LightBarController 129 LightBarController lightBarController, 130 DarkIconDispatcher darkIconDispatcher, 131 WindowManager windowManager, 132 CarDeviceProvisionedController deviceProvisionedController, 133 CommandQueue commandQueue, 134 AutoHideController autoHideController, 135 ButtonSelectionStateListener buttonSelectionStateListener, 136 @Main DelayableExecutor mainExecutor, 137 @UiBackground Executor uiBgExecutor, 138 IStatusBarService barService, 139 Lazy<KeyguardStateController> keyguardStateControllerLazy, 140 Lazy<PhoneStatusBarPolicy> iconPolicyLazy, 141 StatusBarSignalPolicy signalPolicy, 142 HvacController hvacController, 143 SystemBarConfigs systemBarConfigs 144 ) { 145 super(context); 146 mCarSystemBarController = carSystemBarController; 147 mStatusBarIconController = (SysuiDarkIconDispatcher) darkIconDispatcher; 148 mWindowManager = windowManager; 149 mCarDeviceProvisionedController = deviceProvisionedController; 150 mCommandQueue = commandQueue; 151 mAutoHideController = autoHideController; 152 mButtonSelectionStateListener = buttonSelectionStateListener; 153 mExecutor = mainExecutor; 154 mUiBgExecutor = uiBgExecutor; 155 mBarService = barService; 156 mKeyguardStateControllerLazy = keyguardStateControllerLazy; 157 mIconPolicyLazy = iconPolicyLazy; 158 mHvacController = hvacController; 159 mSystemBarConfigs = systemBarConfigs; 160 mSignalPolicy = signalPolicy; 161 mDisplayId = context.getDisplayId(); 162 } 163 164 @Override start()165 public void start() { 166 // Set initial state. 167 mHideTopBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.TOP); 168 mHideBottomBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide( 169 SystemBarConfigs.BOTTOM); 170 mHideLeftBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.LEFT); 171 mHideRightBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide( 172 SystemBarConfigs.RIGHT); 173 174 mBottomNavBarVisible = false; 175 176 // Connect into the status bar manager service 177 mCommandQueue.addCallback(this); 178 179 RegisterStatusBarResult result = null; 180 try { 181 result = mBarService.registerStatusBar(mCommandQueue); 182 } catch (RemoteException ex) { 183 ex.rethrowFromSystemServer(); 184 } 185 186 onSystemBarAttributesChanged(mDisplayId, result.mAppearance, result.mAppearanceRegions, 187 result.mNavbarColorManagedByIme, result.mBehavior, result.mRequestedVisibilities, 188 result.mPackageName); 189 190 // StatusBarManagerService has a back up of IME token and it's restored here. 191 setImeWindowStatus(mDisplayId, result.mImeToken, result.mImeWindowVis, 192 result.mImeBackDisposition, result.mShowImeSwitcher); 193 194 // Set up the initial icon state 195 int numIcons = result.mIcons.size(); 196 for (int i = 0; i < numIcons; i++) { 197 mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i)); 198 } 199 200 mAutoHideController.setStatusBar(new AutoHideUiElement() { 201 @Override 202 public void synchronizeState() { 203 // No op. 204 } 205 206 @Override 207 public boolean isVisible() { 208 return mStatusBarTransientShown; 209 } 210 211 @Override 212 public void hide() { 213 clearTransient(); 214 } 215 }); 216 217 mAutoHideController.setNavigationBar(new AutoHideUiElement() { 218 @Override 219 public void synchronizeState() { 220 // No op. 221 } 222 223 @Override 224 public boolean isVisible() { 225 return mNavBarTransientShown; 226 } 227 228 @Override 229 public void hide() { 230 clearTransient(); 231 } 232 }); 233 234 mDeviceIsSetUpForUser = mCarDeviceProvisionedController.isCurrentUserSetup(); 235 mIsUserSetupInProgress = mCarDeviceProvisionedController.isCurrentUserSetupInProgress(); 236 mCarDeviceProvisionedController.addCallback( 237 new CarDeviceProvisionedListener() { 238 @Override 239 public void onUserSetupInProgressChanged() { 240 mExecutor.execute(() -> restartNavBarsIfNecessary()); 241 } 242 243 @Override 244 public void onUserSetupChanged() { 245 mExecutor.execute(() -> restartNavBarsIfNecessary()); 246 } 247 248 @Override 249 public void onUserSwitched() { 250 mExecutor.execute(() -> restartNavBarsIfNecessary()); 251 } 252 }); 253 254 createSystemBar(result); 255 256 mActivityManagerWrapper = ActivityManagerWrapper.getInstance(); 257 mActivityManagerWrapper.registerTaskStackListener(mButtonSelectionStateListener); 258 mActivityManagerWrapper.registerTaskStackListener(new TaskStackChangeListener() { 259 @Override 260 public void onLockTaskModeChanged(int mode) { 261 mCarSystemBarController.refreshSystemBarByLockTaskFeatures(); 262 } 263 }); 264 265 // Lastly, call to the icon policy to install/update all the icons. 266 // Must be called on the main thread due to the use of observeForever() in 267 // mIconPolicy.init(). 268 mExecutor.execute(() -> { 269 mIconPolicyLazy.get().init(); 270 }); 271 } 272 restartNavBarsIfNecessary()273 private void restartNavBarsIfNecessary() { 274 boolean currentUserSetup = mCarDeviceProvisionedController.isCurrentUserSetup(); 275 boolean currentUserSetupInProgress = mCarDeviceProvisionedController 276 .isCurrentUserSetupInProgress(); 277 if (mIsUserSetupInProgress != currentUserSetupInProgress 278 || mDeviceIsSetUpForUser != currentUserSetup) { 279 mDeviceIsSetUpForUser = currentUserSetup; 280 mIsUserSetupInProgress = currentUserSetupInProgress; 281 restartNavBars(); 282 } 283 } 284 285 /** 286 * Remove all content from navbars and rebuild them. Used to allow for different nav bars 287 * before and after the device is provisioned. . Also for change of density and font size. 288 */ restartNavBars()289 private void restartNavBars() { 290 // remove and reattach all components such that we don't keep a reference to unused ui 291 // elements 292 mCarSystemBarController.removeAll(); 293 294 if (mTopSystemBarWindow != null) { 295 mTopSystemBarWindow.removeAllViews(); 296 mHvacController.unregisterViews(mTopSystemBarView); 297 mTopSystemBarView = null; 298 } 299 300 if (mBottomSystemBarWindow != null) { 301 mBottomSystemBarWindow.removeAllViews(); 302 mHvacController.unregisterViews(mBottomSystemBarView); 303 mBottomSystemBarView = null; 304 } 305 306 if (mLeftSystemBarWindow != null) { 307 mLeftSystemBarWindow.removeAllViews(); 308 mHvacController.unregisterViews(mLeftSystemBarView); 309 mLeftSystemBarView = null; 310 } 311 312 if (mRightSystemBarWindow != null) { 313 mRightSystemBarWindow.removeAllViews(); 314 mHvacController.unregisterViews(mRightSystemBarView); 315 mRightSystemBarView = null; 316 } 317 318 buildNavBarContent(); 319 // If the UI was rebuilt (day/night change or user change) while the keyguard was up we need 320 // to correctly respect that state. 321 if (mKeyguardStateControllerLazy.get().isShowing()) { 322 mCarSystemBarController.showAllKeyguardButtons(isDeviceSetupForUser()); 323 } else { 324 mCarSystemBarController.showAllNavigationButtons(isDeviceSetupForUser()); 325 } 326 327 // Upon restarting the Navigation Bar, CarFacetButtonController should immediately apply the 328 // selection state that reflects the current task stack. 329 mButtonSelectionStateListener.onTaskStackChanged(); 330 } 331 isDeviceSetupForUser()332 private boolean isDeviceSetupForUser() { 333 return mDeviceIsSetUpForUser && !mIsUserSetupInProgress; 334 } 335 createSystemBar(RegisterStatusBarResult result)336 private void createSystemBar(RegisterStatusBarResult result) { 337 buildNavBarWindows(); 338 buildNavBarContent(); 339 attachNavBarWindows(); 340 341 // Try setting up the initial state of the nav bar if applicable. 342 if (result != null) { 343 setImeWindowStatus(Display.DEFAULT_DISPLAY, result.mImeToken, 344 result.mImeWindowVis, result.mImeBackDisposition, 345 result.mShowImeSwitcher); 346 } 347 } 348 buildNavBarWindows()349 private void buildNavBarWindows() { 350 mTopSystemBarWindow = mCarSystemBarController.getTopWindow(); 351 mBottomSystemBarWindow = mCarSystemBarController.getBottomWindow(); 352 mLeftSystemBarWindow = mCarSystemBarController.getLeftWindow(); 353 mRightSystemBarWindow = mCarSystemBarController.getRightWindow(); 354 } 355 buildNavBarContent()356 private void buildNavBarContent() { 357 mTopSystemBarView = mCarSystemBarController.getTopBar(isDeviceSetupForUser()); 358 if (mTopSystemBarView != null) { 359 mSystemBarConfigs.insetSystemBar(SystemBarConfigs.TOP, mTopSystemBarView); 360 mHvacController.registerHvacViews(mTopSystemBarView); 361 mTopSystemBarWindow.addView(mTopSystemBarView); 362 } 363 364 mBottomSystemBarView = mCarSystemBarController.getBottomBar(isDeviceSetupForUser()); 365 if (mBottomSystemBarView != null) { 366 mSystemBarConfigs.insetSystemBar(SystemBarConfigs.BOTTOM, mBottomSystemBarView); 367 mHvacController.registerHvacViews(mBottomSystemBarView); 368 mBottomSystemBarWindow.addView(mBottomSystemBarView); 369 } 370 371 mLeftSystemBarView = mCarSystemBarController.getLeftBar(isDeviceSetupForUser()); 372 if (mLeftSystemBarView != null) { 373 mSystemBarConfigs.insetSystemBar(SystemBarConfigs.LEFT, mLeftSystemBarView); 374 mHvacController.registerHvacViews(mLeftSystemBarView); 375 mLeftSystemBarWindow.addView(mLeftSystemBarView); 376 } 377 378 mRightSystemBarView = mCarSystemBarController.getRightBar(isDeviceSetupForUser()); 379 if (mRightSystemBarView != null) { 380 mSystemBarConfigs.insetSystemBar(SystemBarConfigs.RIGHT, mRightSystemBarView); 381 mHvacController.registerHvacViews(mRightSystemBarView); 382 mRightSystemBarWindow.addView(mRightSystemBarView); 383 } 384 } 385 attachNavBarWindows()386 private void attachNavBarWindows() { 387 mSystemBarConfigs.getSystemBarSidesByZOrder().forEach(this::attachNavBarBySide); 388 } 389 attachNavBarBySide(int side)390 private void attachNavBarBySide(int side) { 391 switch (side) { 392 case SystemBarConfigs.TOP: 393 if (mTopSystemBarWindow != null) { 394 mWindowManager.addView(mTopSystemBarWindow, 395 mSystemBarConfigs.getLayoutParamsBySide(SystemBarConfigs.TOP)); 396 } 397 break; 398 case SystemBarConfigs.BOTTOM: 399 if (mBottomSystemBarWindow != null && !mBottomNavBarVisible) { 400 mBottomNavBarVisible = true; 401 402 mWindowManager.addView(mBottomSystemBarWindow, 403 mSystemBarConfigs.getLayoutParamsBySide(SystemBarConfigs.BOTTOM)); 404 } 405 break; 406 case SystemBarConfigs.LEFT: 407 if (mLeftSystemBarWindow != null) { 408 mWindowManager.addView(mLeftSystemBarWindow, 409 mSystemBarConfigs.getLayoutParamsBySide(SystemBarConfigs.LEFT)); 410 } 411 break; 412 case SystemBarConfigs.RIGHT: 413 if (mRightSystemBarWindow != null) { 414 mWindowManager.addView(mRightSystemBarWindow, 415 mSystemBarConfigs.getLayoutParamsBySide(SystemBarConfigs.RIGHT)); 416 } 417 break; 418 default: 419 return; 420 } 421 } 422 423 /** 424 * We register for soft keyboard visibility events such that we can hide the navigation bar 425 * giving more screen space to the IME. Note: this is optional and controlled by 426 * {@code com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard}. 427 */ 428 @Override setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher)429 public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, 430 boolean showImeSwitcher) { 431 if (mContext.getDisplayId() != displayId) { 432 return; 433 } 434 435 boolean isKeyboardVisible = (vis & InputMethodService.IME_VISIBLE) != 0; 436 437 if (mHideTopBarForKeyboard) { 438 mCarSystemBarController.setTopWindowVisibility( 439 isKeyboardVisible ? View.GONE : View.VISIBLE); 440 } 441 442 if (mHideBottomBarForKeyboard) { 443 mCarSystemBarController.setBottomWindowVisibility( 444 isKeyboardVisible ? View.GONE : View.VISIBLE); 445 } 446 447 if (mHideLeftBarForKeyboard) { 448 mCarSystemBarController.setLeftWindowVisibility( 449 isKeyboardVisible ? View.GONE : View.VISIBLE); 450 } 451 if (mHideRightBarForKeyboard) { 452 mCarSystemBarController.setRightWindowVisibility( 453 isKeyboardVisible ? View.GONE : View.VISIBLE); 454 } 455 } 456 457 @Override onSystemBarAttributesChanged( int displayId, @WindowInsetsController.Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @WindowInsetsController.Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName)458 public void onSystemBarAttributesChanged( 459 int displayId, 460 @WindowInsetsController.Appearance int appearance, 461 AppearanceRegion[] appearanceRegions, 462 boolean navbarColorManagedByIme, 463 @WindowInsetsController.Behavior int behavior, 464 InsetsVisibilities requestedVisibilities, 465 String packageName) { 466 if (displayId != mDisplayId) { 467 return; 468 } 469 boolean barModeChanged = updateStatusBarMode( 470 mStatusBarTransientShown ? MODE_SEMI_TRANSPARENT : MODE_TRANSPARENT); 471 int numStacks = appearanceRegions.length; 472 boolean stackAppearancesChanged = mAppearanceRegions.length != numStacks; 473 for (int i = 0; i < numStacks && !stackAppearancesChanged; i++) { 474 stackAppearancesChanged |= !appearanceRegions[i].equals(mAppearanceRegions[i]); 475 } 476 if (stackAppearancesChanged || barModeChanged) { 477 mAppearanceRegions = appearanceRegions; 478 updateStatusBarAppearance(); 479 } 480 mCarSystemBarController.refreshSystemBarByLockTaskFeatures(); 481 } 482 483 @Override disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, boolean animate)484 public void disable(int displayId, @DisableFlags int state1, @Disable2Flags int state2, 485 boolean animate) { 486 if (displayId != mDisplayId) { 487 return; 488 } 489 mCarSystemBarController.setStatusBarState(state1); 490 } 491 updateStatusBarAppearance()492 private void updateStatusBarAppearance() { 493 int numStacks = mAppearanceRegions.length; 494 int numLightStacks = 0; 495 496 // We can only have maximum one light stack. 497 int indexLightStack = -1; 498 499 for (int i = 0; i < numStacks; i++) { 500 if (isLight(mAppearanceRegions[i].getAppearance())) { 501 numLightStacks++; 502 indexLightStack = i; 503 } 504 } 505 506 // If all stacks are light, all icons become dark. 507 if (numLightStacks == numStacks) { 508 mStatusBarIconController.setIconsDarkArea(null); 509 mStatusBarIconController.getTransitionsController().setIconsDark( 510 /* dark= */ true, /* animate= */ false); 511 } else if (numLightStacks == 0) { 512 // If no one is light, all icons become white. 513 mStatusBarIconController.getTransitionsController().setIconsDark( 514 /* dark= */ false, /* animate= */ false); 515 } else { 516 // Not the same for every stack, update icons in area only. 517 mStatusBarIconController.setIconsDarkArea( 518 mAppearanceRegions[indexLightStack].getBounds()); 519 mStatusBarIconController.getTransitionsController().setIconsDark( 520 /* dark= */ true, /* animate= */ false); 521 } 522 } 523 isLight(int appearance)524 private static boolean isLight(int appearance) { 525 return (appearance & APPEARANCE_LIGHT_STATUS_BARS) != 0; 526 } 527 528 @Override showTransient(int displayId, int[] types)529 public void showTransient(int displayId, int[] types) { 530 if (displayId != mDisplayId) { 531 return; 532 } 533 if (containsType(types, ITYPE_STATUS_BAR)) { 534 if (!mStatusBarTransientShown) { 535 mStatusBarTransientShown = true; 536 handleTransientChanged(); 537 } 538 } 539 if (containsType(types, ITYPE_NAVIGATION_BAR)) { 540 if (!mNavBarTransientShown) { 541 mNavBarTransientShown = true; 542 handleTransientChanged(); 543 } 544 } 545 } 546 547 @Override abortTransient(int displayId, int[] types)548 public void abortTransient(int displayId, int[] types) { 549 if (displayId != mDisplayId) { 550 return; 551 } 552 if (!containsType(types, ITYPE_STATUS_BAR) && !containsType(types, ITYPE_NAVIGATION_BAR)) { 553 return; 554 } 555 clearTransient(); 556 } 557 clearTransient()558 private void clearTransient() { 559 if (mStatusBarTransientShown) { 560 mStatusBarTransientShown = false; 561 handleTransientChanged(); 562 } 563 if (mNavBarTransientShown) { 564 mNavBarTransientShown = false; 565 handleTransientChanged(); 566 } 567 } 568 569 @VisibleForTesting isStatusBarTransientShown()570 boolean isStatusBarTransientShown() { 571 return mStatusBarTransientShown; 572 } 573 574 @VisibleForTesting isNavBarTransientShown()575 boolean isNavBarTransientShown() { 576 return mNavBarTransientShown; 577 } 578 579 @VisibleForTesting setSignalPolicy(StatusBarSignalPolicy signalPolicy)580 void setSignalPolicy(StatusBarSignalPolicy signalPolicy) { 581 mSignalPolicy = signalPolicy; 582 } 583 584 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)585 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 586 pw.print(" mTaskStackListener="); 587 pw.println(mButtonSelectionStateListener); 588 pw.print(" mBottomSystemBarView="); 589 pw.println(mBottomSystemBarView); 590 } 591 handleTransientChanged()592 private void handleTransientChanged() { 593 updateStatusBarMode(mStatusBarTransientShown ? MODE_SEMI_TRANSPARENT : MODE_TRANSPARENT); 594 updateNavBarMode(mNavBarTransientShown ? MODE_SEMI_TRANSPARENT : MODE_TRANSPARENT); 595 } 596 597 // Returns true if the status bar mode has changed. updateStatusBarMode(int barMode)598 private boolean updateStatusBarMode(int barMode) { 599 if (mStatusBarMode != barMode) { 600 mStatusBarMode = barMode; 601 mAutoHideController.touchAutoHide(); 602 return true; 603 } 604 return false; 605 } 606 607 // Returns true if the nav bar mode has changed. updateNavBarMode(int barMode)608 private boolean updateNavBarMode(int barMode) { 609 if (mSystemBarMode != barMode) { 610 mSystemBarMode = barMode; 611 mAutoHideController.touchAutoHide(); 612 return true; 613 } 614 return false; 615 } 616 } 617