Add some ways to detect color bars.

1) Check insets before running tests;
2) Check background color to detect if bars can change their colors per
app request.

Bug: 110826584
Bug: 110826585
Test: Test runs and passes on walleye, and is skipped on devices that
doesn't have color bars.

Change-Id: I85c3c9ccb9487ff23b141551b4fb746406e51c02
Merged-In: I85c3c9ccb9487ff23b141551b4fb746406e51c02
diff --git a/tests/tests/systemui/res/values/colors.xml b/tests/tests/systemui/res/values/colors.xml
index 6f0558a..d16ae02 100644
--- a/tests/tests/systemui/res/values/colors.xml
+++ b/tests/tests/systemui/res/values/colors.xml
@@ -15,5 +15,6 @@
   ~ limitations under the License
   -->
 <resources>
+    <color name="navigationBarColor">#0000ff</color>
     <color name="navigationBarDividerColor">#ff0000</color>
 </resources>
\ No newline at end of file
diff --git a/tests/tests/systemui/res/values/styles.xml b/tests/tests/systemui/res/values/styles.xml
index dd95114..3a546b3 100644
--- a/tests/tests/systemui/res/values/styles.xml
+++ b/tests/tests/systemui/res/values/styles.xml
@@ -19,7 +19,7 @@
     <style name="LightBarTheme" parent="@android:style/Theme.Material.Light.NoActionBar">
         <item name="android:windowLightStatusBar">true</item>
         <item name="android:windowLightNavigationBar">true</item>
-        <item name="android:navigationBarColor">@android:color/white</item>
+        <item name="android:navigationBarColor">@color/navigationBarColor</item>
         <item name="android:navigationBarDividerColor">@color/navigationBarDividerColor</item>
     </style>
 </resources>
\ No newline at end of file
diff --git a/tests/tests/systemui/src/android/systemui/cts/LightBarBaseActivity.java b/tests/tests/systemui/src/android/systemui/cts/LightBarBaseActivity.java
index 1b228f3..b4c4e38 100644
--- a/tests/tests/systemui/src/android/systemui/cts/LightBarBaseActivity.java
+++ b/tests/tests/systemui/src/android/systemui/cts/LightBarBaseActivity.java
@@ -16,10 +16,12 @@
 
 package android.systemui.cts;
 
+import android.annotation.MainThread;
 import android.app.Activity;
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
+import android.view.WindowInsets;
 
 public class LightBarBaseActivity extends Activity {
 
@@ -34,6 +36,11 @@
         setContentView(mContent);
     }
 
+    @MainThread
+    public WindowInsets getRootWindowInsets() {
+        return getWindow().getDecorView().getRootWindowInsets();
+    }
+
     public int getSystemUiVisibility() {
         return mContent.getWindowSystemUiVisibility();
     }
diff --git a/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java b/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java
index 10ce913..c88e7d1 100644
--- a/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java
+++ b/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java
@@ -27,9 +27,11 @@
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
 import android.util.Log;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
+import android.view.WindowInsets;
 
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -71,10 +73,15 @@
         }
     }
 
-    private boolean hasVirtualNavigationBar() {
+    private boolean hasVirtualNavigationBar(ActivityTestRule<? extends LightBarBaseActivity> rule)
+            throws Throwable {
         boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
         boolean hasHomeKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME);
-        return !hasBackKey || !hasHomeKey;
+        final WindowInsets[] inset = new WindowInsets[1];
+        rule.runOnUiThread(()-> {
+            inset[0] = rule.getActivity().getRootWindowInsets();
+        });
+        return !hasBackKey || !hasHomeKey || inset[0].getStableInsetBottom() == 0;
     }
 
     private boolean isRunningInVr() {
@@ -101,24 +108,43 @@
         assumeTrue(ActivityManager.isHighEndGfx());
     }
 
-    protected void assumeHasColoredStatusBar() {
+    protected void assumeHasColoredStatusBar(ActivityTestRule<? extends LightBarBaseActivity> rule)
+            throws Throwable {
         assumeBasics();
 
         // No status bar when running in Vr
         assumeFalse(isRunningInVr());
+
+        // Status bar exists only when top stable inset is positive
+        final WindowInsets[] inset = new WindowInsets[1];
+        rule.runOnUiThread(()-> {
+            inset[0] = rule.getActivity().getRootWindowInsets();
+        });
+        assumeTrue("Top stable inset is non-positive.", inset[0].getStableInsetTop() > 0);
     }
 
-    protected void assumeHasColorNavigationBar() {
+    protected void assumeHasColoredNavigationBar(
+            ActivityTestRule<? extends LightBarBaseActivity> rule) throws Throwable {
         assumeBasics();
 
         // No virtual navigation bar, so no effect.
-        assumeTrue(hasVirtualNavigationBar());
+        assumeTrue(hasVirtualNavigationBar(rule));
     }
 
-    protected void checkNavigationBarDivider(LightBarBaseActivity activity, int dividerColor) {
+    protected void checkNavigationBarDivider(LightBarBaseActivity activity, int dividerColor,
+            int backgroundColor) {
         final Bitmap bitmap = takeNavigationBarScreenshot(activity);
         int[] pixels = new int[bitmap.getHeight() * bitmap.getWidth()];
         bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
+
+        int backgroundColorPixelCount = 0;
+        for (int i = 0; i < pixels.length; i++) {
+            if (pixels[i] == backgroundColor) {
+                backgroundColorPixelCount++;
+            }
+        }
+        assumeNavigationBarChangesColor(backgroundColorPixelCount, pixels.length);
+
         for (int col = 0; col < bitmap.getWidth(); col++) {
             if (dividerColor != pixels[col]) {
                 dumpBitmap(bitmap);
@@ -126,4 +152,9 @@
             }
         }
     }
+
+    protected void assumeNavigationBarChangesColor(int backgroundColorPixelCount, int totalPixel) {
+        assumeTrue("Not enough background pixels. The navigation bar may not be able to change "
+                + "color.", backgroundColorPixelCount > 0.3f * totalPixel);
+    }
 }
diff --git a/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java b/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java
index 32dd235..2c5d468 100644
--- a/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java
+++ b/tests/tests/systemui/src/android/systemui/cts/LightBarTests.java
@@ -70,7 +70,7 @@
     @Test
     @AppModeFull // Instant apps cannot create notifications
     public void testLightStatusBarIcons() throws Throwable {
-        assumeHasColoredStatusBar();
+        assumeHasColoredStatusBar(mActivityRule);
 
         mNm = (NotificationManager) getInstrumentation().getContext()
                 .getSystemService(Context.NOTIFICATION_SERVICE);
@@ -102,7 +102,7 @@
 
     @Test
     public void testLightNavigationBar() throws Throwable {
-        assumeHasColorNavigationBar();
+        assumeHasColoredNavigationBar(mActivityRule);
 
         requestLightBars(Color.RED /* background */);
         Thread.sleep(WAIT_TIME);
@@ -120,7 +120,7 @@
 
     @Test
     public void testNavigationBarDivider() throws Throwable {
-        assumeHasColorNavigationBar();
+        assumeHasColoredNavigationBar(mActivityRule);
 
         mActivityRule.runOnUiThread(() -> {
             mActivityRule.getActivity().getWindow().setNavigationBarColor(Color.RED);
@@ -128,7 +128,7 @@
         });
         Thread.sleep(WAIT_TIME);
 
-        checkNavigationBarDivider(mActivityRule.getActivity(), Color.WHITE);
+        checkNavigationBarDivider(mActivityRule.getActivity(), Color.WHITE, Color.RED);
     }
 
     private void injectCanceledTap(int x, int y) {
@@ -149,9 +149,7 @@
     private void assertLightStats(Bitmap bitmap, Stats s) {
         boolean success = false;
         try {
-            assertMoreThan("Not enough background pixels", 0.3f,
-                    (float) s.backgroundPixels / s.totalPixels(),
-                    "Is the bar background showing correctly (solid red)?");
+            assumeNavigationBarChangesColor(s.backgroundPixels, s.totalPixels());
 
             assertMoreThan("Not enough pixels colored as in the spec", 0.3f,
                     (float) s.iconPixels / s.foregroundPixels(),
diff --git a/tests/tests/systemui/src/android/systemui/cts/LightBarThemeTest.java b/tests/tests/systemui/src/android/systemui/cts/LightBarThemeTest.java
index 496e3f8..4d20dfb 100644
--- a/tests/tests/systemui/src/android/systemui/cts/LightBarThemeTest.java
+++ b/tests/tests/systemui/src/android/systemui/cts/LightBarThemeTest.java
@@ -22,6 +22,7 @@
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeFalse;
 
+import android.content.Context;
 import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.support.test.rule.ActivityTestRule;
@@ -61,21 +62,23 @@
     }
 
     @Test
-    public void testGetNavigationBarDividerColor() throws Exception {
-        assumeHasColorNavigationBar();
+    public void testGetNavigationBarDividerColor() throws Throwable {
+        assumeHasColoredNavigationBar(mActivityRule);
 
         assertEquals(getInstrumentation().getContext().getColor(R.color.navigationBarDividerColor),
                 mActivityRule.getActivity().getWindow().getNavigationBarDividerColor());
     }
 
     @Test
-    public void testNavigationBarDividerColor() throws Exception {
-        assumeHasColorNavigationBar();
+    public void testNavigationBarDividerColor() throws Throwable {
+        assumeHasColoredNavigationBar(mActivityRule);
 
         // Wait until the activity is fully visible
         mDevice.waitForIdle();
 
+        final Context instrumentationContext = getInstrumentation().getContext();
         checkNavigationBarDivider(mActivityRule.getActivity(),
-                getInstrumentation().getContext().getColor(R.color.navigationBarDividerColor));
+                instrumentationContext.getColor(R.color.navigationBarDividerColor),
+                instrumentationContext.getColor(R.color.navigationBarColor));
     }
 }