Allow forcing status bar state changes and do so when the screen turns off.

This adds a force flag, which we will use when turning the screen off to make sure that all UI components are reset to the SHADE state regardless.

Bug: 189575031
Test: make a call; lock screen; pull down shade
Merged-In: I79baeb71ac5d1ed45602ac55cdca996b3bed0ac3
Change-Id: I79baeb71ac5d1ed45602ac55cdca996b3bed0ac3
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index eb386dc..e090c0ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -114,11 +114,11 @@
     }
 
     @Override
-    public boolean setState(int state) {
+    public boolean setState(int state, boolean force) {
         if (state > MAX_STATE || state < MIN_STATE) {
             throw new IllegalArgumentException("Invalid state " + state);
         }
-        if (state == mState) {
+        if (!force && state == mState) {
             return false;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
index dc5e1e9..185c969 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
@@ -58,7 +58,19 @@
      * @param state see {@link StatusBarState} for valid options
      * @return {@code true} if the state changed, else {@code false}
      */
-    boolean setState(int state);
+    default boolean setState(int state) {
+        return setState(state, false /* force */);
+    }
+
+    /**
+     * Update the status bar state
+     * @param state see {@link StatusBarState} for valid options
+     * @param force whether to set the state even if it's the same as the current state. This will
+     *              dispatch the state to all StatusBarStateListeners, ensuring that all listening
+     *              components are reset to this state.
+     * @return {@code true} if the state was changed or set forcefully
+     */
+    boolean setState(int state, boolean force);
 
     /**
      * Update the dozing state from {@link StatusBar}'s perspective
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 9d0bb70..45f8db79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -2959,7 +2959,11 @@
         return mState == StatusBarState.FULLSCREEN_USER_SWITCHER;
     }
 
-    private boolean updateIsKeyguard() {
+    boolean updateIsKeyguard() {
+        return updateIsKeyguard(false /* force */);
+    }
+
+    boolean updateIsKeyguard(boolean force) {
         boolean wakeAndUnlocking = mBiometricUnlockController.getMode()
                 == BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
 
@@ -2982,7 +2986,7 @@
                 showKeyguardImpl();
             }
         } else {
-            return hideKeyguardImpl();
+            return hideKeyguardImpl(force);
         }
         return false;
     }
@@ -3124,11 +3128,11 @@
     /**
      * @return true if we would like to stay in the shade, false if it should go away entirely
      */
-    public boolean hideKeyguardImpl() {
+    public boolean hideKeyguardImpl(boolean force) {
         mIsKeyguard = false;
         Trace.beginSection("StatusBar#hideKeyguard");
         boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
-        if (!(mStatusBarStateController.setState(StatusBarState.SHADE))) {
+        if (!(mStatusBarStateController.setState(StatusBarState.SHADE, force))) {
             //TODO: StatusBarStateController should probably know about hiding the keyguard and
             // notify listeners.
 
@@ -3617,7 +3621,8 @@
                 // is correct.
                 mHandler.post(() -> onCameraLaunchGestureDetected(mLastCameraLaunchSource));
             }
-            updateIsKeyguard();
+            // When finished going to sleep, force the status bar state to avoid stale state.
+            updateIsKeyguard(true /* force */);
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 79e05c3..421f086 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -716,13 +716,15 @@
 
         // By default, showKeyguardImpl sets state to KEYGUARD.
         mStatusBar.showKeyguardImpl();
-        verify(mStatusBarStateController).setState(eq(StatusBarState.KEYGUARD));
+        verify(mStatusBarStateController).setState(
+                eq(StatusBarState.KEYGUARD), eq(false) /* force */);
 
         // If useFullscreenUserSwitcher is true, state is set to FULLSCREEN_USER_SWITCHER.
         mStatusBar.mUserSwitcherController = mock(UserSwitcherController.class);
         when(mStatusBar.mUserSwitcherController.useFullscreenUserSwitcher()).thenReturn(true);
         mStatusBar.showKeyguardImpl();
-        verify(mStatusBarStateController).setState(eq(StatusBarState.FULLSCREEN_USER_SWITCHER));
+        verify(mStatusBarStateController).setState(
+                eq(StatusBarState.FULLSCREEN_USER_SWITCHER), eq(false) /* force */);
     }
 
     @Test