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