Enable light status bar when top of wallpaper is light.

(Light status bar = dark icons)

Bug: 29452834
Change-Id: I9f61a05d80158827761c8b62ab40fc50971e27a6
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 2b64d42..d059da2 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -277,9 +277,10 @@
     private LauncherAccessibilityDelegate mAccessibilityDelegate;
     private boolean mIsResumeFromActionScreenOff;
     @Thunk boolean mUserPresent = true;
-    private boolean mVisible = false;
-    private boolean mHasFocus = false;
-    private boolean mAttached = false;
+    private boolean mVisible;
+    private boolean mHasFocus;
+    private boolean mAttached;
+    private boolean mIsLightStatusBar;
 
     /** Maps launcher activity components to their list of shortcut ids. */
     private MultiHashMap<ComponentKey, String> mDeepShortcutMap = new MultiHashMap<>();
@@ -488,9 +489,31 @@
             mExtractedColors.load(this);
             mHotseat.updateColor(mExtractedColors, !mPaused);
             mWorkspace.getPageIndicator().updateColor(mExtractedColors);
+            setLightStatusBar(shouldBeLightStatusBar());
         }
     }
 
+    /** Returns whether a light status bar (dark icons) should be used based on the wallpaper. */
+    public boolean shouldBeLightStatusBar() {
+        return mExtractedColors.getColor(ExtractedColors.STATUS_BAR_INDEX,
+                ExtractedColors.DEFAULT_LIGHT) == ExtractedColors.DEFAULT_LIGHT;
+    }
+
+    public void setLightStatusBar(boolean lightStatusBar) {
+        // Already set correctly
+        if (mIsLightStatusBar == lightStatusBar) {
+            return;
+        }
+        mIsLightStatusBar = lightStatusBar;
+        int systemUiFlags = getWindow().getDecorView().getSystemUiVisibility();
+        if (lightStatusBar) {
+            systemUiFlags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+        } else {
+            systemUiFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
+        }
+        getWindow().getDecorView().setSystemUiVisibility(systemUiFlags);
+    }
+
     private LauncherCallbacks mLauncherCallbacks;
 
     public void onPostCreate(Bundle savedInstanceState) {
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 1719b05..fb15afe 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -86,8 +86,6 @@
     private AnimatorSet mCurrentAnimation;
     private boolean mNoIntercept;
 
-    private boolean mLightStatusBar;
-
     // Used in discovery bounce animation to provide the transition without workspace changing.
     private boolean mIsTranslateWithoutWorkspace = false;
     private AnimatorSet mDiscoBounceAnimation;
@@ -273,26 +271,14 @@
     }
 
     private void updateLightStatusBar(float shift) {
-        boolean enable = shift <= mStatusBarHeight / 2;
         // Do not modify status bar on landscape as all apps is not full bleed.
         if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
             return;
         }
-        // Already set correctly
-        if (mLightStatusBar == enable) {
-            return;
-        }
-        int systemUiFlags = mLauncher.getWindow().getDecorView().getSystemUiVisibility();
-        if (enable) {
-            mLauncher.getWindow().getDecorView().setSystemUiVisibility(systemUiFlags
-                    | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
-
-        } else {
-            mLauncher.getWindow().getDecorView().setSystemUiVisibility(systemUiFlags
-                    & ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR));
-
-        }
-        mLightStatusBar = enable;
+        // Use a light status bar (dark icons) if all apps is behind at least half of the status
+        // bar. If the status bar is already light due to wallpaper extraction, keep it that way.
+        boolean enable = shift <= mStatusBarHeight / 2 || mLauncher.shouldBeLightStatusBar();
+        mLauncher.setLightStatusBar(enable);
     }
 
     /**
diff --git a/src/com/android/launcher3/dynamicui/ColorExtractionService.java b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
index 89594f4..c15b710 100644
--- a/src/com/android/launcher3/dynamicui/ColorExtractionService.java
+++ b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
@@ -26,6 +26,7 @@
 
 import com.android.launcher3.LauncherProvider;
 import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.R;
 
 /**
  * Extracts colors from the wallpaper, and saves results to {@link LauncherProvider}.
@@ -52,16 +53,21 @@
             Bitmap wallpaper = ((BitmapDrawable) wallpaperManager.getDrawable()).getBitmap();
             Palette palette = Palette.from(wallpaper).generate();
             extractedColors.updatePalette(palette);
-            // We extract colors for the hotseat separately,
-            // since it only considers the lower part of the wallpaper.
-            // TODO(twickham): update Palette library to 23.3.1 or higher,
-            // which fixes a bug with using regions (b/28349435).
+            // We extract colors for the hotseat and status bar separately,
+            // since they only consider part of the wallpaper.
             Palette hotseatPalette = Palette.from(wallpaper)
                     .setRegion(0, (int) (wallpaper.getHeight() * (1f - HOTSEAT_FRACTION)),
                             wallpaper.getWidth(), wallpaper.getHeight())
                     .clearFilters()
                     .generate();
             extractedColors.updateHotseatPalette(hotseatPalette);
+
+            int statusBarHeight = getResources().getDimensionPixelSize(R.dimen.status_bar_height);
+            Palette statusBarPalette = Palette.from(wallpaper)
+                    .setRegion(0, 0, wallpaper.getWidth(), statusBarHeight)
+                    .clearFilters()
+                    .generate();
+            extractedColors.updateStatusBarPalette(statusBarPalette);
         }
 
         // Save the extracted colors and wallpaper id to LauncherProvider.
diff --git a/src/com/android/launcher3/dynamicui/ExtractedColors.java b/src/com/android/launcher3/dynamicui/ExtractedColors.java
index e545288..4db0797 100644
--- a/src/com/android/launcher3/dynamicui/ExtractedColors.java
+++ b/src/com/android/launcher3/dynamicui/ExtractedColors.java
@@ -38,6 +38,7 @@
     // loading extracted colors. New colors should always be added at the end.
     public static final int VERSION_INDEX = 0;
     public static final int HOTSEAT_INDEX = 1;
+    public static final int STATUS_BAR_INDEX = 2;
     // public static final int VIBRANT_INDEX = 2;
     // public static final int VIBRANT_DARK_INDEX = 3;
     // public static final int VIBRANT_LIGHT_INDEX = 4;
@@ -45,8 +46,8 @@
     // public static final int MUTED_DARK_INDEX = 6;
     // public static final int MUTED_LIGHT_INDEX = 7;
 
-    public static final int NUM_COLOR_PROFILES = 1;
-    private static final int VERSION = 1;
+    public static final int NUM_COLOR_PROFILES = 2;
+    private static final int VERSION = 2;
 
     private static final String COLOR_SEPARATOR = ",";
 
@@ -156,4 +157,9 @@
         }
         setColorAtIndex(HOTSEAT_INDEX, hotseatColor);
     }
+
+    public void updateStatusBarPalette(Palette statusBarPalette) {
+        setColorAtIndex(STATUS_BAR_INDEX, ExtractionUtils.isSuperLight(statusBarPalette) ?
+                DEFAULT_LIGHT : DEFAULT_DARK);
+    }
 }