Merge "Respect light nav bar flag set by IME on keyguard" into pi-dev
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 52d458c..60f153a 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -24,6 +24,7 @@
 import android.view.ViewGroup;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.util.function.TriConsumer;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.keyguard.ViewMediatorCallback;
@@ -53,6 +54,7 @@
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
 import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.ScrimState;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -104,12 +106,12 @@
     }
 
     public ScrimController createScrimController(ScrimView scrimBehind, ScrimView scrimInFront,
-            LockscreenWallpaper lockscreenWallpaper, Consumer<Float> scrimBehindAlphaListener,
-            Consumer<GradientColors> scrimInFrontColorListener,
+            LockscreenWallpaper lockscreenWallpaper,
+            TriConsumer<ScrimState, Float, GradientColors> scrimStateListener,
             Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
             AlarmManager alarmManager) {
-        return new ScrimController(scrimBehind, scrimInFront, scrimBehindAlphaListener,
-                scrimInFrontColorListener, scrimVisibleListener, dozeParameters, alarmManager);
+        return new ScrimController(scrimBehind, scrimInFront, scrimStateListener,
+                scrimVisibleListener, dozeParameters, alarmManager);
     }
 
     public NotificationIconAreaController createNotificationIconAreaController(Context context,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index d61d6e2..8b8cbfe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -66,9 +66,12 @@
      * scrim alpha yet.
      */
     private boolean mHasLightNavigationBar;
-    private boolean mScrimAlphaBelowThreshold;
-    private boolean mInvertLightNavBarWithScrim;
-    private float mScrimAlpha;
+
+    /**
+     * {@code true} if {@link #mHasLightNavigationBar} should be ignored and forcefully make
+     * {@link #mNavigationLight} {@code false}.
+     */
+    private boolean mForceDarkForScrim;
 
     private final Rect mLastFullscreenBounds = new Rect();
     private final Rect mLastDockedBounds = new Rect();
@@ -129,9 +132,7 @@
             boolean last = mNavigationLight;
             mHasLightNavigationBar = isLight(vis, navigationBarMode,
                     View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
-            mNavigationLight = mHasLightNavigationBar
-                    && (mScrimAlphaBelowThreshold || !mInvertLightNavBarWithScrim)
-                    && !mQsCustomizing;
+            mNavigationLight = mHasLightNavigationBar && !mForceDarkForScrim && !mQsCustomizing;
             if (mNavigationLight != last) {
                 updateNavigation();
             }
@@ -154,20 +155,17 @@
         reevaluate();
     }
 
-    public void setScrimAlpha(float alpha) {
-        mScrimAlpha = alpha;
-        boolean belowThresholdBefore = mScrimAlphaBelowThreshold;
-        mScrimAlphaBelowThreshold = mScrimAlpha < NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD;
-        if (mHasLightNavigationBar && belowThresholdBefore != mScrimAlphaBelowThreshold) {
-            reevaluate();
-        }
-    }
-
-    public void setScrimColor(GradientColors colors) {
-        boolean invertLightNavBarWithScrimBefore = mInvertLightNavBarWithScrim;
-        mInvertLightNavBarWithScrim = !colors.supportsDarkText();
-        if (mHasLightNavigationBar
-                && invertLightNavBarWithScrimBefore != mInvertLightNavBarWithScrim) {
+    public void setScrimState(ScrimState scrimState, float scrimBehindAlpha,
+            GradientColors scrimInFrontColor) {
+        boolean forceDarkForScrimLast = mForceDarkForScrim;
+        // For BOUNCER/BOUNCER_SCRIMMED cases, we assume that alpha is always below threshold.
+        // This enables IMEs to control the navigation bar color.
+        // For other cases, scrim should be able to veto the light navigation bar.
+        mForceDarkForScrim = scrimState != ScrimState.BOUNCER
+                && scrimState != ScrimState.BOUNCER_SCRIMMED
+                && scrimBehindAlpha >= NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD
+                && !scrimInFrontColor.supportsDarkText();
+        if (mHasLightNavigationBar && (mForceDarkForScrim != forceDarkForScrimLast)) {
             reevaluate();
         }
     }
@@ -257,8 +255,9 @@
         pw.print(" mLastStatusBarMode="); pw.print(mLastStatusBarMode);
         pw.print(" mLastNavigationBarMode="); pw.println(mLastNavigationBarMode);
 
-        pw.print(" mScrimAlpha="); pw.print(mScrimAlpha);
-        pw.print(" mScrimAlphaBelowThreshold="); pw.println(mScrimAlphaBelowThreshold);
+        pw.print(" mForceDarkForScrim="); pw.print(mForceDarkForScrim);
+        pw.print(" mQsCustomizing="); pw.println(mQsCustomizing);
+
         pw.println();
 
         LightBarTransitionsController transitionsController =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index cc143bb..4e8003e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -41,6 +41,7 @@
 import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener;
 import com.android.internal.graphics.ColorUtils;
+import com.android.internal.util.function.TriConsumer;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
@@ -144,8 +145,7 @@
     private int mCurrentBehindTint;
     private boolean mWallpaperVisibilityTimedOut;
     private int mScrimsVisibility;
-    private final Consumer<GradientColors> mScrimInFrontColorListener;
-    private final Consumer<Float> mScrimBehindAlphaListener;
+    private final TriConsumer<ScrimState, Float, GradientColors> mScrimStateListener;
     private final Consumer<Integer> mScrimVisibleListener;
     private boolean mBlankScreen;
     private boolean mScreenBlankingCallbackCalled;
@@ -163,14 +163,12 @@
     private boolean mKeyguardOccluded;
 
     public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront,
-            Consumer<Float> scrimBehindAlphaListener,
-            Consumer<GradientColors> scrimInFrontColorListener,
+            TriConsumer<ScrimState, Float, GradientColors> scrimStateListener,
             Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
             AlarmManager alarmManager) {
         mScrimBehind = scrimBehind;
         mScrimInFront = scrimInFront;
-        mScrimBehindAlphaListener = scrimBehindAlphaListener;
-        mScrimInFrontColorListener = scrimInFrontColorListener;
+        mScrimStateListener = scrimStateListener;
         mScrimVisibleListener = scrimVisibleListener;
         mContext = scrimBehind.getContext();
         mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
@@ -300,6 +298,8 @@
         } else {
             scheduleUpdate();
         }
+
+        dispatchScrimState(mScrimBehind.getViewAlpha());
     }
 
     public ScrimState getState() {
@@ -375,7 +375,7 @@
             setOrAdaptCurrentAnimation(mScrimBehind);
             setOrAdaptCurrentAnimation(mScrimInFront);
 
-            mScrimBehindAlphaListener.accept(mScrimBehind.getViewAlpha());
+            dispatchScrimState(mScrimBehind.getViewAlpha());
         }
     }
 
@@ -484,7 +484,7 @@
             float minOpacity = ColorUtils.calculateMinimumBackgroundAlpha(textColor, mainColor,
                     4.5f /* minimumContrast */) / 255f;
             mScrimBehindAlpha = Math.max(mScrimBehindAlphaResValue, minOpacity);
-            mScrimInFrontColorListener.accept(mScrimInFront.getColors());
+            dispatchScrimState(mScrimBehind.getViewAlpha());
         }
 
         // We want to override the back scrim opacity for the AOD state
@@ -503,6 +503,10 @@
         dispatchScrimsVisible();
     }
 
+    private void dispatchScrimState(float alpha) {
+        mScrimStateListener.accept(mState, alpha, mScrimInFront.getColors());
+    }
+
     private void dispatchScrimsVisible() {
         final int currentScrimVisibility;
         if (mScrimInFront.getViewAlpha() == 1 || mScrimBehind.getViewAlpha() == 1) {
@@ -712,7 +716,7 @@
         }
 
         if (scrim == mScrimBehind) {
-            mScrimBehindAlphaListener.accept(alpha);
+            dispatchScrimState(alpha);
         }
 
         final boolean wantsAlphaUpdate = alpha != currentAlpha;
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 a3da807..27e5732b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -918,12 +918,7 @@
         ScrimView scrimInFront = mStatusBarWindow.findViewById(R.id.scrim_in_front);
         mScrimController = SystemUIFactory.getInstance().createScrimController(
                 scrimBehind, scrimInFront, mLockscreenWallpaper,
-                scrimBehindAlpha -> {
-                    mLightBarController.setScrimAlpha(scrimBehindAlpha);
-                },
-                scrimInFrontColor -> {
-                    mLightBarController.setScrimColor(scrimInFrontColor);
-                },
+                (state, alpha, color) -> mLightBarController.setScrimState(state, alpha, color),
                 scrimsVisible -> {
                     if (mStatusBarWindowManager != null) {
                         mStatusBarWindowManager.setScrimsVisibility(scrimsVisible);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 0416232..69508ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -43,6 +43,7 @@
 import android.view.View;
 
 import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.util.function.TriConsumer;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.ScrimView;
@@ -66,9 +67,7 @@
     private SynchronousScrimController mScrimController;
     private ScrimView mScrimBehind;
     private ScrimView mScrimInFront;
-    private Consumer<Float> mScrimBehindAlphaCallback;
-    private Consumer<GradientColors> mScrimInFrontColorCallback;
-    private Consumer<Integer> mScrimVisibilityCallback;
+    private ScrimState mScrimState;
     private float mScrimBehindAlpha;
     private GradientColors mScrimInFrontColor;
     private int mScrimVisibility;
@@ -77,6 +76,7 @@
     private boolean mAlwaysOnEnabled;
     private AlarmManager mAlarmManager;
 
+
     @Before
     public void setup() {
         mScrimBehind = spy(new ScrimView(getContext()));
@@ -84,15 +84,16 @@
         mWakeLock = mock(WakeLock.class);
         mAlarmManager = mock(AlarmManager.class);
         mAlwaysOnEnabled = true;
-        mScrimBehindAlphaCallback = (Float alpha) -> mScrimBehindAlpha = alpha;
-        mScrimInFrontColorCallback = (GradientColors color) -> mScrimInFrontColor = color;
-        mScrimVisibilityCallback = (Integer visible) -> mScrimVisibility = visible;
         mDozeParamenters = mock(DozeParameters.class);
         when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled);
         when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true);
         mScrimController = new SynchronousScrimController(mScrimBehind, mScrimInFront,
-                mScrimBehindAlphaCallback, mScrimInFrontColorCallback, mScrimVisibilityCallback,
-                mDozeParamenters, mAlarmManager);
+                (scrimState, scrimBehindAlpha, scrimInFrontColor) -> {
+                    mScrimState = scrimState;
+                    mScrimBehindAlpha = scrimBehindAlpha;
+                    mScrimInFrontColor = scrimInFrontColor;
+                },
+                visible -> mScrimVisibility = visible, mDozeParamenters, mAlarmManager);
     }
 
     @Test
@@ -211,6 +212,21 @@
     }
 
     @Test
+    public void scrimStateCallback() {
+        mScrimController.transitionTo(ScrimState.UNLOCKED);
+        mScrimController.finishAnimationsImmediately();
+        Assert.assertEquals(mScrimState, ScrimState.UNLOCKED);
+
+        mScrimController.transitionTo(ScrimState.BOUNCER);
+        mScrimController.finishAnimationsImmediately();
+        Assert.assertEquals(mScrimState, ScrimState.BOUNCER);
+
+        mScrimController.transitionTo(ScrimState.BOUNCER_SCRIMMED);
+        mScrimController.finishAnimationsImmediately();
+        Assert.assertEquals(mScrimState, ScrimState.BOUNCER_SCRIMMED);
+    }
+
+    @Test
     public void panelExpansion() {
         mScrimController.setPanelExpansion(0f);
         mScrimController.setPanelExpansion(0.5f);
@@ -559,12 +575,11 @@
         boolean mOnPreDrawCalled;
 
         SynchronousScrimController(ScrimView scrimBehind, ScrimView scrimInFront,
-                Consumer<Float> scrimBehindAlphaListener,
-                Consumer<GradientColors> scrimInFrontColorListener,
+                TriConsumer<ScrimState, Float, GradientColors> scrimStateListener,
                 Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
                 AlarmManager alarmManager) {
-            super(scrimBehind, scrimInFront, scrimBehindAlphaListener, scrimInFrontColorListener,
-                    scrimVisibleListener, dozeParameters, alarmManager);
+            super(scrimBehind, scrimInFront, scrimStateListener, scrimVisibleListener,
+                    dozeParameters, alarmManager);
             mHandler = new FakeHandler(Looper.myLooper());
         }