Merge "Move status bar to CarNavigationBar" into rvc-dev
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
index bf1bf38..5e969ec 100644
--- a/packages/CarSystemUI/res/values/config.xml
+++ b/packages/CarSystemUI/res/values/config.xml
@@ -25,6 +25,7 @@
     <bool name="config_enableFullscreenUserSwitcher">true</bool>
 
     <!-- configure which system ui bars should be displayed -->
+    <bool name="config_enableTopNavigationBar">true</bool>
     <bool name="config_enableLeftNavigationBar">false</bool>
     <bool name="config_enableRightNavigationBar">false</bool>
     <bool name="config_enableBottomNavigationBar">true</bool>
@@ -83,7 +84,7 @@
         <item>com.android.systemui.recents.Recents</item>
         <item>com.android.systemui.volume.VolumeUI</item>
         <item>com.android.systemui.stackdivider.Divider</item>
-        <item>com.android.systemui.statusbar.phone.StatusBar</item>
+<!--        <item>com.android.systemui.statusbar.phone.StatusBar</item>-->
         <item>com.android.systemui.usb.StorageNotification</item>
         <item>com.android.systemui.power.PowerUI</item>
         <item>com.android.systemui.media.RingtonePlayer</item>
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
index df82753..9fdfc0f 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
@@ -17,14 +17,18 @@
 package com.android.systemui.navigationbar.car;
 
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.InsetsState.containsType;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.PixelFormat;
 import android.inputmethodservice.InputMethodService;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -35,6 +39,8 @@
 import android.view.ViewGroup;
 import android.view.WindowManager;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.RegisterStatusBarResult;
 import com.android.systemui.R;
@@ -49,6 +55,9 @@
 import com.android.systemui.statusbar.SuperStatusBarViewFactory;
 import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.BarTransitions;
+import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarSignalPolicy;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import java.io.FileDescriptor;
@@ -61,6 +70,7 @@
 /** Navigation bars customized for the automotive use case. */
 public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks {
 
+    private final Resources mResources;
     private final CarNavigationBarController mCarNavigationBarController;
     private final WindowManager mWindowManager;
     private final CarDeviceProvisionedController mCarDeviceProvisionedController;
@@ -72,9 +82,12 @@
     private final Lazy<NavigationBarController> mNavigationBarControllerLazy;
     private final SuperStatusBarViewFactory mSuperStatusBarViewFactory;
     private final ButtonSelectionStateController mButtonSelectionStateController;
+    private final PhoneStatusBarPolicy mIconPolicy;
+    private final StatusBarIconController mIconController;
 
     private final int mDisplayId;
 
+    private StatusBarSignalPolicy mSignalPolicy;
     private IStatusBarService mBarService;
     private ActivityManagerWrapper mActivityManagerWrapper;
 
@@ -97,11 +110,14 @@
     private boolean mDeviceIsSetUpForUser = true;
     private boolean mIsUserSetupInProgress = false;
 
+    private @BarTransitions.TransitionMode int mStatusBarMode;
     private @BarTransitions.TransitionMode int mNavigationBarMode;
-    private boolean mTransientShown;
+    private boolean mStatusBarTransientShown;
+    private boolean mNavBarTransientShown;
 
     @Inject
     public CarNavigationBar(Context context,
+            @Main Resources resources,
             CarNavigationBarController carNavigationBarController,
             WindowManager windowManager,
             CarDeviceProvisionedController deviceProvisionedController,
@@ -112,8 +128,12 @@
             Lazy<KeyguardStateController> keyguardStateControllerLazy,
             Lazy<NavigationBarController> navigationBarControllerLazy,
             SuperStatusBarViewFactory superStatusBarViewFactory,
-            ButtonSelectionStateController buttonSelectionStateController) {
+            ButtonSelectionStateController buttonSelectionStateController,
+            PhoneStatusBarPolicy iconPolicy,
+            StatusBarIconController iconController
+    ) {
         super(context);
+        mResources = resources;
         mCarNavigationBarController = carNavigationBarController;
         mWindowManager = windowManager;
         mCarDeviceProvisionedController = deviceProvisionedController;
@@ -125,14 +145,16 @@
         mNavigationBarControllerLazy = navigationBarControllerLazy;
         mSuperStatusBarViewFactory = superStatusBarViewFactory;
         mButtonSelectionStateController = buttonSelectionStateController;
+        mIconPolicy = iconPolicy;
+        mIconController = iconController;
 
-        mDisplayId = mWindowManager.getDefaultDisplay().getDisplayId();
+        mDisplayId = context.getDisplayId();
     }
 
     @Override
     public void start() {
         // Set initial state.
-        mHideNavBarForKeyboard = mContext.getResources().getBoolean(
+        mHideNavBarForKeyboard = mResources.getBoolean(
                 com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard);
         mBottomNavBarVisible = false;
 
@@ -150,6 +172,33 @@
             ex.rethrowFromSystemServer();
         }
 
+        // StatusBarManagerService has a back up of IME token and it's restored here.
+        setImeWindowStatus(mDisplayId, result.mImeToken, result.mImeWindowVis,
+                result.mImeBackDisposition, result.mShowImeSwitcher);
+
+        // Set up the initial icon state
+        int numIcons = result.mIcons.size();
+        for (int i = 0; i < numIcons; i++) {
+            mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i));
+        }
+
+        mAutoHideController.setStatusBar(new AutoHideUiElement() {
+            @Override
+            public void synchronizeState() {
+                // No op.
+            }
+
+            @Override
+            public boolean isVisible() {
+                return mStatusBarTransientShown;
+            }
+
+            @Override
+            public void hide() {
+                clearTransient();
+            }
+        });
+
         mAutoHideController.setNavigationBar(new AutoHideUiElement() {
             @Override
             public void synchronizeState() {
@@ -158,7 +207,7 @@
 
             @Override
             public boolean isVisible() {
-                return mTransientShown;
+                return mNavBarTransientShown;
             }
 
             @Override
@@ -193,6 +242,10 @@
         mActivityManagerWrapper.registerTaskStackListener(mButtonSelectionStateListener);
 
         mCarNavigationBarController.connectToHvac();
+
+        // Lastly, call to the icon policy to install/update all the icons.
+        mIconPolicy.init();
+        mSignalPolicy = new StatusBarSignalPolicy(mContext, mIconController);
     }
 
     private void restartNavBarsIfNecessary() {
@@ -274,9 +327,7 @@
     }
 
     private void buildNavBarWindows() {
-        mTopNavigationBarWindow = mSuperStatusBarViewFactory
-                .getStatusBarWindowView()
-                .findViewById(R.id.car_top_navigation_bar_container);
+        mTopNavigationBarWindow = mCarNavigationBarController.getTopWindow();
         mBottomNavigationBarWindow = mCarNavigationBarController.getBottomWindow();
         mLeftNavigationBarWindow = mCarNavigationBarController.getLeftWindow();
         mRightNavigationBarWindow = mCarNavigationBarController.getRightWindow();
@@ -305,6 +356,26 @@
     }
 
     private void attachNavBarWindows() {
+        if (mTopNavigationBarWindow != null) {
+            int height = mResources.getDimensionPixelSize(
+                    com.android.internal.R.dimen.status_bar_height);
+            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                    ViewGroup.LayoutParams.MATCH_PARENT,
+                    height,
+                    WindowManager.LayoutParams.TYPE_STATUS_BAR,
+                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                            | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                            | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
+                    PixelFormat.TRANSLUCENT);
+            lp.token = new Binder();
+            lp.gravity = Gravity.TOP;
+            lp.setFitInsetsTypes(0 /* types */);
+            lp.setTitle("TopCarNavigationBar");
+            lp.packageName = mContext.getPackageName();
+            lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+            mWindowManager.addView(mTopNavigationBarWindow, lp);
+        }
+
         if (mBottomNavigationBarWindow != null && !mBottomNavBarVisible) {
             mBottomNavBarVisible = true;
 
@@ -316,13 +387,13 @@
                             | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                             | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                     PixelFormat.TRANSLUCENT);
-            lp.setTitle("CarNavigationBar");
+            lp.setTitle("BottomCarNavigationBar");
             lp.windowAnimations = 0;
             mWindowManager.addView(mBottomNavigationBarWindow, lp);
         }
 
         if (mLeftNavigationBarWindow != null) {
-            int width = mContext.getResources().getDimensionPixelSize(
+            int width = mResources.getDimensionPixelSize(
                     R.dimen.car_left_navigation_bar_width);
             WindowManager.LayoutParams leftlp = new WindowManager.LayoutParams(
                     width, ViewGroup.LayoutParams.MATCH_PARENT,
@@ -340,7 +411,7 @@
             mWindowManager.addView(mLeftNavigationBarWindow, leftlp);
         }
         if (mRightNavigationBarWindow != null) {
-            int width = mContext.getResources().getDimensionPixelSize(
+            int width = mResources.getDimensionPixelSize(
                     R.dimen.car_right_navigation_bar_width);
             WindowManager.LayoutParams rightlp = new WindowManager.LayoutParams(
                     width, ViewGroup.LayoutParams.MATCH_PARENT,
@@ -371,7 +442,7 @@
             return;
         }
 
-        if (mContext.getDisplay().getDisplayId() != displayId) {
+        if (mContext.getDisplayId() != displayId) {
             return;
         }
 
@@ -385,13 +456,17 @@
         if (displayId != mDisplayId) {
             return;
         }
-        if (!containsType(types, ITYPE_NAVIGATION_BAR)) {
-            return;
+        if (containsType(types, ITYPE_STATUS_BAR)) {
+            if (!mStatusBarTransientShown) {
+                mStatusBarTransientShown = true;
+                handleTransientChanged();
+            }
         }
-
-        if (!mTransientShown) {
-            mTransientShown = true;
-            handleTransientChanged();
+        if (containsType(types, ITYPE_NAVIGATION_BAR)) {
+            if (!mNavBarTransientShown) {
+                mNavBarTransientShown = true;
+                handleTransientChanged();
+            }
         }
     }
 
@@ -400,17 +475,31 @@
         if (displayId != mDisplayId) {
             return;
         }
-        if (!containsType(types, ITYPE_NAVIGATION_BAR)) {
+        if (!containsType(types, ITYPE_STATUS_BAR) && !containsType(types, ITYPE_NAVIGATION_BAR)) {
             return;
         }
         clearTransient();
     }
 
     private void clearTransient() {
-        if (mTransientShown) {
-            mTransientShown = false;
+        if (mStatusBarTransientShown) {
+            mStatusBarTransientShown = false;
             handleTransientChanged();
         }
+        if (mNavBarTransientShown) {
+            mNavBarTransientShown = false;
+            handleTransientChanged();
+        }
+    }
+
+    @VisibleForTesting
+    boolean isStatusBarTransientShown() {
+        return mStatusBarTransientShown;
+    }
+
+    @VisibleForTesting
+    boolean isNavBarTransientShown() {
+        return mNavBarTransientShown;
     }
 
     @Override
@@ -422,11 +511,22 @@
     }
 
     private void handleTransientChanged() {
-        updateBarMode(mTransientShown ? MODE_SEMI_TRANSPARENT : MODE_TRANSPARENT);
+        updateStatusBarMode(mStatusBarTransientShown ? MODE_SEMI_TRANSPARENT : MODE_TRANSPARENT);
+        updateNavBarMode(mNavBarTransientShown ? MODE_SEMI_TRANSPARENT : MODE_TRANSPARENT);
     }
 
-    // Returns true if the bar mode is changed.
-    private boolean updateBarMode(int barMode) {
+    // Returns true if the status bar mode has changed.
+    private boolean updateStatusBarMode(int barMode) {
+        if (mStatusBarMode != barMode) {
+            mStatusBarMode = barMode;
+            mAutoHideController.touchAutoHide();
+            return true;
+        }
+        return false;
+    }
+
+    // Returns true if the nav bar mode has changed.
+    private boolean updateNavBarMode(int barMode) {
         if (mNavigationBarMode != barMode) {
             mNavigationBarMode = barMode;
             mAutoHideController.touchAutoHide();
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java
index fbcd878..37a8225 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java
@@ -40,6 +40,7 @@
     private final ButtonSelectionStateController mButtonSelectionStateController;
     private final Lazy<HvacController> mHvacControllerLazy;
 
+    private boolean mShowTop;
     private boolean mShowBottom;
     private boolean mShowLeft;
     private boolean mShowRight;
@@ -66,6 +67,7 @@
         mHvacControllerLazy = hvacControllerLazy;
 
         // Read configuration.
+        mShowTop = mContext.getResources().getBoolean(R.bool.config_enableTopNavigationBar);
         mShowBottom = mContext.getResources().getBoolean(R.bool.config_enableBottomNavigationBar);
         mShowLeft = mContext.getResources().getBoolean(R.bool.config_enableLeftNavigationBar);
         mShowRight = mContext.getResources().getBoolean(R.bool.config_enableRightNavigationBar);
@@ -105,6 +107,12 @@
         mHvacControllerLazy.get().removeAllComponents();
     }
 
+    /** Gets the top window if configured to do so. */
+    @Nullable
+    public ViewGroup getTopWindow() {
+        return mShowTop ? mNavigationBarViewFactory.getTopWindow() : null;
+    }
+
     /** Gets the bottom window if configured to do so. */
     @Nullable
     public ViewGroup getBottomWindow() {
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java
index 519b33a2..e47c5d1 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java
@@ -71,6 +71,11 @@
         mContext = context;
     }
 
+    /** Gets the top window. */
+    public ViewGroup getTopWindow() {
+        return getWindowCached(Type.TOP);
+    }
+
     /** Gets the bottom window. */
     public ViewGroup getBottomWindow() {
         return getWindowCached(Type.BOTTOM);
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarControllerTest.java
index e0c13ed..bbcd0d4 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarControllerTest.java
@@ -87,6 +87,40 @@
     }
 
     @Test
+    public void testGetTopWindow_topDisabled_returnsNull() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, false);
+        mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
+                mButtonSelectionStateController, () -> mHvacController);
+
+        ViewGroup window = mCarNavigationBar.getTopWindow();
+
+        assertThat(window).isNull();
+    }
+
+    @Test
+    public void testGetTopWindow_topEnabled_returnsWindow() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
+                mButtonSelectionStateController, () -> mHvacController);
+
+        ViewGroup window = mCarNavigationBar.getTopWindow();
+
+        assertThat(window).isNotNull();
+    }
+
+    @Test
+    public void testGetTopWindow_topEnabled_calledTwice_returnsSameWindow() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
+                mButtonSelectionStateController, () -> mHvacController);
+
+        ViewGroup window1 = mCarNavigationBar.getTopWindow();
+        ViewGroup window2 = mCarNavigationBar.getTopWindow();
+
+        assertThat(window1).isEqualTo(window2);
+    }
+
+    @Test
     public void testGetBottomWindow_bottomDisabled_returnsNull() {
         mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, false);
         mCarNavigationBar = new CarNavigationBarController(mContext, mNavigationBarViewFactory,
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java
index 76557fd..3ecb29f 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java
@@ -16,6 +16,11 @@
 
 package com.android.systemui.navigationbar.car;
 
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
+
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -23,7 +28,7 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableResources;
-import android.view.LayoutInflater;
+import android.view.Display;
 import android.view.WindowManager;
 
 import androidx.test.filters.SmallTest;
@@ -31,13 +36,12 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NavigationBarController;
 import com.android.systemui.statusbar.SuperStatusBarViewFactory;
 import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
-import com.android.systemui.statusbar.phone.StatusBarWindowView;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.Before;
@@ -74,30 +78,28 @@
     private SuperStatusBarViewFactory mSuperStatusBarViewFactory;
     @Mock
     private ButtonSelectionStateController mButtonSelectionStateController;
+    @Mock
+    private PhoneStatusBarPolicy mIconPolicy;
+    @Mock
+    private StatusBarIconController mIconController;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mTestableResources = mContext.getOrCreateTestableResources();
-        mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
         mHandler = Handler.getMain();
-        mCarNavigationBar = new CarNavigationBar(mContext, mCarNavigationBarController,
-                mWindowManager, mDeviceProvisionedController, new CommandQueue(mContext),
-                mAutoHideController, mButtonSelectionStateListener, mHandler,
-                () -> mKeyguardStateController, () -> mNavigationBarController,
-                mSuperStatusBarViewFactory, mButtonSelectionStateController);
-        StatusBarWindowView statusBarWindowView = (StatusBarWindowView) LayoutInflater.from(
-                mContext).inflate(R.layout.super_status_bar, /* root= */ null);
-        when(mSuperStatusBarViewFactory.getStatusBarWindowView()).thenReturn(statusBarWindowView);
-        when(mKeyguardStateController.isShowing()).thenReturn(false);
-        mDependency.injectMockDependency(WindowManager.class);
-        // Needed to inflate top navigation bar.
-        mDependency.injectMockDependency(DarkIconDispatcher.class);
-        mDependency.injectMockDependency(StatusBarIconController.class);
+        mCarNavigationBar = new CarNavigationBar(mContext, mTestableResources.getResources(),
+                mCarNavigationBarController, mWindowManager, mDeviceProvisionedController,
+                new CommandQueue(mContext), mAutoHideController, mButtonSelectionStateListener,
+                mHandler, () -> mKeyguardStateController, () -> mNavigationBarController,
+                mSuperStatusBarViewFactory, mButtonSelectionStateController, mIconPolicy,
+                mIconController);
     }
 
     @Test
     public void restartNavbars_refreshesTaskChanged() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
         ArgumentCaptor<CarDeviceProvisionedController.DeviceProvisionedListener>
                 deviceProvisionedCallbackCaptor = ArgumentCaptor.forClass(
                 CarDeviceProvisionedController.DeviceProvisionedListener.class);
@@ -115,6 +117,8 @@
 
     @Test
     public void restartNavBars_newUserNotSetupWithKeyguardShowing_showsKeyguardButtons() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
         ArgumentCaptor<CarDeviceProvisionedController.DeviceProvisionedListener>
                 deviceProvisionedCallbackCaptor = ArgumentCaptor.forClass(
                 CarDeviceProvisionedController.DeviceProvisionedListener.class);
@@ -133,6 +137,8 @@
 
     @Test
     public void restartNavbars_newUserIsSetupWithKeyguardHidden_hidesKeyguardButtons() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
         ArgumentCaptor<CarDeviceProvisionedController.DeviceProvisionedListener>
                 deviceProvisionedCallbackCaptor = ArgumentCaptor.forClass(
                 CarDeviceProvisionedController.DeviceProvisionedListener.class);
@@ -152,4 +158,147 @@
 
         verify(mCarNavigationBarController).hideAllKeyguardButtons(true);
     }
+
+    @Test
+    public void showTransient_wrongDisplayId_transientModeNotUpdated() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
+        when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
+        mCarNavigationBar.start();
+
+        int randomDisplay = Display.DEFAULT_DISPLAY + 10;
+        int[] insetTypes = new int[]{};
+        mCarNavigationBar.showTransient(randomDisplay, insetTypes);
+
+        assertThat(mCarNavigationBar.isStatusBarTransientShown()).isFalse();
+    }
+
+    @Test
+    public void showTransient_correctDisplayId_noStatusBarInset_transientModeNotUpdated() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
+        when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
+        mCarNavigationBar.start();
+
+        int[] insetTypes = new int[]{};
+        mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY, insetTypes);
+
+        assertThat(mCarNavigationBar.isStatusBarTransientShown()).isFalse();
+    }
+
+    @Test
+    public void showTransient_correctDisplayId_statusBarInset_transientModeUpdated() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
+        when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
+        mCarNavigationBar.start();
+
+        int[] insetTypes = new int[]{ITYPE_STATUS_BAR};
+        mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY, insetTypes);
+
+        assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
+    }
+
+    @Test
+    public void showTransient_correctDisplayId_noNavBarInset_transientModeNotUpdated() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
+        when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
+        mCarNavigationBar.start();
+
+        int[] insetTypes = new int[]{};
+        mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY, insetTypes);
+
+        assertThat(mCarNavigationBar.isNavBarTransientShown()).isFalse();
+    }
+
+    @Test
+    public void showTransient_correctDisplayId_navBarInset_transientModeUpdated() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
+        when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
+        mCarNavigationBar.start();
+
+        int[] insetTypes = new int[]{ITYPE_NAVIGATION_BAR};
+        mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY, insetTypes);
+
+        assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
+    }
+
+    @Test
+    public void abortTransient_wrongDisplayId_transientModeNotCleared() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
+        when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
+        mCarNavigationBar.start();
+        mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY,
+                new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR});
+        assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
+        assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
+
+        int[] insetTypes = new int[]{};
+        int randomDisplay = Display.DEFAULT_DISPLAY + 10;
+        mCarNavigationBar.abortTransient(randomDisplay, insetTypes);
+
+        // The transient booleans were not cleared.
+        assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
+        assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
+    }
+
+    @Test
+    public void abortTransient_correctDisplayId_noInsets_transientModeNotCleared() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
+        when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
+        mCarNavigationBar.start();
+        mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY,
+                new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR});
+        assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
+        assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
+
+        int[] insetTypes = new int[]{};
+        mCarNavigationBar.abortTransient(Display.DEFAULT_DISPLAY, insetTypes);
+
+        // The transient booleans were not cleared.
+        assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
+        assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
+    }
+
+    @Test
+    public void abortTransient_correctDisplayId_statusBarInset_transientModeCleared() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
+        when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
+        mCarNavigationBar.start();
+        mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY,
+                new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR});
+        assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
+        assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
+
+        int[] insetTypes = new int[]{ITYPE_STATUS_BAR};
+        mCarNavigationBar.abortTransient(Display.DEFAULT_DISPLAY, insetTypes);
+
+        // The transient booleans were cleared.
+        assertThat(mCarNavigationBar.isStatusBarTransientShown()).isFalse();
+        assertThat(mCarNavigationBar.isNavBarTransientShown()).isFalse();
+    }
+
+    @Test
+    public void abortTransient_correctDisplayId_navBarInset_transientModeCleared() {
+        mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
+        mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
+        when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
+        mCarNavigationBar.start();
+        mCarNavigationBar.showTransient(Display.DEFAULT_DISPLAY,
+                new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR});
+        assertThat(mCarNavigationBar.isStatusBarTransientShown()).isTrue();
+        assertThat(mCarNavigationBar.isNavBarTransientShown()).isTrue();
+
+        int[] insetTypes = new int[]{ITYPE_NAVIGATION_BAR};
+        mCarNavigationBar.abortTransient(Display.DEFAULT_DISPLAY, insetTypes);
+
+        // The transient booleans were cleared.
+        assertThat(mCarNavigationBar.isStatusBarTransientShown()).isFalse();
+        assertThat(mCarNavigationBar.isNavBarTransientShown()).isFalse();
+    }
 }