• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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