Defining a dark theme for launcher

> Removing the code for LIGHT_STATUS_BAR as that will be controlled by the theme
> Updating icon cache to always use transparent background for low-res, as the
theme can change the bg color

Change-Id: Iab64ec29cab629ee515af22ec15b95d3f40a9df5
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index c0946a0..78030ce 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -542,11 +542,8 @@
     }
 
     public void setFolderLeaveBehindCell(int x, int y) {
-
-        DeviceProfile grid = mLauncher.getDeviceProfile();
         View child = getChildAt(x, y);
-
-        mFolderLeaveBehind.setup(getResources().getDisplayMetrics(), grid, null,
+        mFolderLeaveBehind.setup(mLauncher, null,
                 child.getMeasuredWidth(), child.getPaddingTop());
 
         mFolderLeaveBehind.delegateCellX = x;
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 1217030..ad816af 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -32,10 +32,6 @@
 import android.database.sqlite.SQLiteException;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Handler;
@@ -55,7 +51,6 @@
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.Provider;
 import com.android.launcher3.util.SQLiteCacheHelper;
-import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.Thunk;
 
 import java.util.Collections;
@@ -100,24 +95,14 @@
     @Thunk final UserManagerCompat mUserManager;
     private final LauncherAppsCompat mLauncherApps;
     private final HashMap<ComponentKey, CacheEntry> mCache =
-            new HashMap<ComponentKey, CacheEntry>(INITIAL_ICON_CACHE_CAPACITY);
+            new HashMap<>(INITIAL_ICON_CACHE_CAPACITY);
     private final int mIconDpi;
     @Thunk final IconDB mIconDb;
 
     @Thunk final Handler mWorkerHandler;
 
-    // The background color used for activity icons. Since these icons are displayed in all-apps
-    // and folders, this would be same as the light quantum panel background. This color
-    // is used to convert icons to RGB_565.
-    private final int mActivityBgColor;
-    // The background color used for package icons. These are displayed in widget tray, which
-    // has a dark quantum panel background.
-    private final int mPackageBgColor;
     private final BitmapFactory.Options mLowResOptions;
 
-    private Canvas mLowResCanvas;
-    private Paint mLowResPaint;
-
     public IconCache(Context context, InvariantDeviceProfile inv) {
         mContext = context;
         mPackageManager = context.getPackageManager();
@@ -125,16 +110,11 @@
         mLauncherApps = LauncherAppsCompat.getInstance(mContext);
         mIconDpi = inv.fillResIconDpi;
         mIconDb = new IconDB(context, inv.iconBitmapSize);
-        mLowResCanvas = new Canvas();
-        mLowResPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);
 
         mIconProvider = Utilities.getOverrideObject(
                 IconProvider.class, context, R.string.icon_provider_class);
         mWorkerHandler = new Handler(LauncherModel.getWorkerLooper());
 
-        mActivityBgColor = Themes.getColorPrimary(context, R.style.LauncherTheme);
-        mPackageBgColor = Themes.getColorPrimary(context, R.style.WidgetContainerTheme);
-
         mLowResOptions = new BitmapFactory.Options();
         // Always prefer RGB_565 config for low res. If the bitmap has transparency, it will
         // automatically be loaded as ALPHA_8888.
@@ -387,7 +367,7 @@
         entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, app.getUser());
         mCache.put(key, entry);
 
-        Bitmap lowResIcon = generateLowResIcon(entry.icon, mActivityBgColor);
+        Bitmap lowResIcon = generateLowResIcon(entry.icon);
         ContentValues values = newContentValues(entry.icon, lowResIcon, entry.title.toString(),
                 app.getApplicationInfo().packageName);
         addIconToDB(values, app.getComponentName(), info, userSerial);
@@ -637,7 +617,7 @@
                     // only keep the low resolution icon instead of the larger full-sized icon
                     Bitmap icon = LauncherIcons.createBadgedIconBitmap(
                             appInfo.loadIcon(mPackageManager), user, mContext, appInfo.targetSdkVersion);
-                    Bitmap lowResIcon =  generateLowResIcon(icon, mPackageBgColor);
+                    Bitmap lowResIcon =  generateLowResIcon(icon);
                     entry.title = appInfo.loadLabel(mPackageManager);
                     entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
                     entry.icon = useLowResIcon ? lowResIcon : icon;
@@ -769,7 +749,7 @@
     }
 
     private static final class IconDB extends SQLiteCacheHelper {
-        private final static int DB_VERSION = 13;
+        private final static int DB_VERSION = 14;
 
         private final static int RELEASE_VERSION = DB_VERSION +
                 (FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION ? 0 : 1);
@@ -822,24 +802,10 @@
     /**
      * Generates a new low-res icon given a high-res icon.
      */
-    private Bitmap generateLowResIcon(Bitmap icon, int lowResBackgroundColor) {
-        if (lowResBackgroundColor == Color.TRANSPARENT) {
-            return Bitmap.createScaledBitmap(icon,
-                            icon.getWidth() / LOW_RES_SCALE_FACTOR,
-                            icon.getHeight() / LOW_RES_SCALE_FACTOR, true);
-        } else {
-            Bitmap lowResIcon = Bitmap.createBitmap(icon.getWidth() / LOW_RES_SCALE_FACTOR,
-                    icon.getHeight() / LOW_RES_SCALE_FACTOR, Bitmap.Config.RGB_565);
-            synchronized (this) {
-                mLowResCanvas.setBitmap(lowResIcon);
-                mLowResCanvas.drawColor(lowResBackgroundColor);
-                mLowResCanvas.drawBitmap(icon, new Rect(0, 0, icon.getWidth(), icon.getHeight()),
-                        new Rect(0, 0, lowResIcon.getWidth(), lowResIcon.getHeight()),
-                        mLowResPaint);
-                mLowResCanvas.setBitmap(null);
-            }
-            return lowResIcon;
-        }
+    private Bitmap generateLowResIcon(Bitmap icon) {
+        return Bitmap.createScaledBitmap(icon,
+                icon.getWidth() / LOW_RES_SCALE_FACTOR,
+                icon.getHeight() / LOW_RES_SCALE_FACTOR, true);
     }
 
     private static Bitmap loadIconNoResize(Cursor c, int iconIndex, BitmapFactory.Options options) {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 5fe6c14..22aff64 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -491,13 +491,6 @@
             mExtractedColors.load(this);
             mHotseat.updateColor(mExtractedColors, !mPaused);
             mWorkspace.getPageIndicator().updateColor(mExtractedColors);
-            boolean lightStatusBar = (FeatureFlags.LIGHT_STATUS_BAR &&
-                    mExtractedColors.getColor(ExtractedColors.STATUS_BAR_INDEX) ==
-                            ExtractedColors.DEFAULT_LIGHT);
-            // It's possible that All Apps is visible when this is run,
-            // so always use light status bar in that case. Only change nav bar color to status bar
-            // color when All Apps is visible.
-            activateLightSystemBars(lightStatusBar || isAllAppsVisible(), true, isAllAppsVisible());
         }
     }
 
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index b006453..61c9707 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -650,11 +650,11 @@
     /**
      * @return creates a new alpha mask bitmap out of an existing bitmap
      */
-    public static Bitmap convertToAlphaMask(Bitmap b, float applyAlpha) {
+    public static Bitmap convertToAlphaMask(Bitmap b, int applyAlpha) {
         Bitmap a = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ALPHA_8);
         Canvas c = new Canvas(a);
         Paint paint = new Paint();
-        paint.setAlpha((int) (255f * applyAlpha));
+        paint.setAlpha(applyAlpha);
         c.drawBitmap(b, 0f, 0f, paint);
         return a;
     }
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 672203c..ea4a662 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -3166,11 +3166,8 @@
             this.cellX = cellX;
             this.cellY = cellY;
 
-            DeviceProfile grid = mLauncher.getDeviceProfile();
             BubbleTextView cell = (BubbleTextView) layout.getChildAt(cellX, cellY);
-
-            bg.setup(getResources().getDisplayMetrics(), grid, null,
-                    cell.getMeasuredWidth(), cell.getPaddingTop());
+            bg.setup(mLauncher, null, cell.getMeasuredWidth(), cell.getPaddingTop());
 
             // The full preview background should appear behind the icon
             bg.isClipping = false;
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 5182a5b..4f2e3d7 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -71,6 +71,7 @@
     private final Launcher mLauncher;
     private final VerticalPullDetector mDetector;
     private final ArgbEvaluator mEvaluator;
+    private final boolean mIsDarkTheme;
 
     // Animation in this class is controlled by a single variable {@link mProgress}.
     // Visually, it represents top y coordinate of the all apps container if multiplied with
@@ -112,6 +113,7 @@
         mEvaluator = new ArgbEvaluator();
         mAllAppsBackgroundColor = Themes.getAttrColor(l, android.R.attr.colorPrimary);
         mLauncher.getExtractedColors().addOnChangeListener(this);
+        mIsDarkTheme = Themes.getAttrBoolean(mLauncher, R.attr.isPrimaryColorDark);
     }
 
     @Override
@@ -275,9 +277,9 @@
     }
 
     private void updateLightStatusBar(float shift) {
-        // Do not modify status bar on landscape as all apps is not full bleed.
-        if (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS
-                && mLauncher.getDeviceProfile().isVerticalBarLayout()) {
+        // Do not modify status bar in dark theme or on landscape as all apps is not full bleed.
+        if (mIsDarkTheme || (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS
+                && mLauncher.getDeviceProfile().isVerticalBarLayout())) {
             return;
         }
         // Use a light status bar (dark icons) if all apps is behind at least half of the status
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index d795c56..236bf24 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -36,8 +36,10 @@
 import android.graphics.Shader;
 import android.graphics.drawable.Drawable;
 import android.os.Parcelable;
+import android.support.v4.graphics.ColorUtils;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
+import android.util.Log;
 import android.util.Property;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -75,6 +77,7 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.dragndrop.DragView;
+import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.widget.PendingAddShortcutInfo;
 
@@ -384,14 +387,11 @@
     private void computePreviewDrawingParams(int drawableSize, int totalSize) {
         if (mIntrinsicIconSize != drawableSize || mTotalWidth != totalSize ||
                 mPrevTopPadding != getPaddingTop()) {
-            DeviceProfile grid = mLauncher.getDeviceProfile();
-
             mIntrinsicIconSize = drawableSize;
             mTotalWidth = totalSize;
             mPrevTopPadding = getPaddingTop();
 
-            mBackground.setup(getResources().getDisplayMetrics(), grid, this, mTotalWidth,
-                    getPaddingTop());
+            mBackground.setup(mLauncher, this, mTotalWidth, getPaddingTop());
             mPreviewLayoutRule.init(mBackground.previewSize, mIntrinsicIconSize,
                     Utilities.isRtl(getResources()));
 
@@ -544,6 +544,7 @@
 
         private float mScale = 1f;
         private float mColorMultiplier = 1f;
+        private int mBgColor;
         private float mStrokeWidth;
         private int mStrokeAlpha = MAX_BG_OPACITY;
         private View mInvalidateDelegate;
@@ -567,7 +568,6 @@
         // Expressed on a scale from 0 to 255.
         private static final int BG_OPACITY = 160;
         private static final int MAX_BG_OPACITY = 225;
-        private static final int BG_INTENSITY = 245;
         private static final int SHADOW_OPACITY = 40;
 
         ValueAnimator mScaleAnimator;
@@ -587,10 +587,12 @@
                     }
                 };
 
-        public void setup(DisplayMetrics dm, DeviceProfile grid, View invalidateDelegate,
+        public void setup(Launcher launcher, View invalidateDelegate,
                    int availableSpace, int topPadding) {
             mInvalidateDelegate = invalidateDelegate;
+            mBgColor = Themes.getAttrColor(launcher, android.R.attr.colorPrimary);
 
+            DeviceProfile grid = launcher.getDeviceProfile();
             final int previewSize = grid.folderIconSizePx;
             final int previewPadding = grid.folderIconPreviewPadding;
 
@@ -600,7 +602,7 @@
             basePreviewOffsetY = previewPadding + grid.folderBackgroundOffset + topPadding;
 
             // Stroke width is 1dp
-            mStrokeWidth = dm.density;
+            mStrokeWidth = launcher.getResources().getDisplayMetrics().density;
 
             float radius = getScaledRadius();
             float shadowRadius = radius + mStrokeWidth;
@@ -655,7 +657,7 @@
         public void drawBackground(Canvas canvas) {
             mPaint.setStyle(Paint.Style.FILL);
             int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
-            mPaint.setColor(Color.argb(alpha, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY));
+            mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, alpha));
 
             drawCircle(canvas, 0 /* deltaRadius */);
 
@@ -700,7 +702,7 @@
                 mStrokeAlphaAnimator.cancel();
             }
             mStrokeAlphaAnimator = ObjectAnimator
-                    .ofArgb(this, STROKE_ALPHA, MAX_BG_OPACITY / 2, MAX_BG_OPACITY)
+                    .ofInt(this, STROKE_ALPHA, MAX_BG_OPACITY / 2, MAX_BG_OPACITY)
                     .setDuration(100);
             mStrokeAlphaAnimator.addListener(new AnimatorListenerAdapter() {
                 @Override
@@ -712,7 +714,7 @@
         }
 
         public void drawBackgroundStroke(Canvas canvas) {
-            mPaint.setColor(Color.argb(mStrokeAlpha, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY));
+            mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, mStrokeAlpha));
             mPaint.setStyle(Paint.Style.STROKE);
             mPaint.setStrokeWidth(mStrokeWidth);
             drawCircle(canvas, 1 /* deltaRadius */);
diff --git a/src/com/android/launcher3/graphics/GradientView.java b/src/com/android/launcher3/graphics/GradientView.java
index 8f16e93..8f9f871 100644
--- a/src/com/android/launcher3/graphics/GradientView.java
+++ b/src/com/android/launcher3/graphics/GradientView.java
@@ -42,7 +42,7 @@
 
     private static final int DEFAULT_COLOR = Color.WHITE;
     private static final float GRADIENT_ALPHA_MASK_LENGTH_DP = 300;
-    private static final float FINAL_GRADIENT_ALPHA = 0.75f;
+    private static final int FINAL_GRADIENT_ALPHA = 0xBF;
     private static final boolean DEBUG = false;
 
     private static Bitmap sFinalGradientMask;
diff --git a/src/com/android/launcher3/graphics/ScrimView.java b/src/com/android/launcher3/graphics/ScrimView.java
index 5c739ac..2c5b9ed 100644
--- a/src/com/android/launcher3/graphics/ScrimView.java
+++ b/src/com/android/launcher3/graphics/ScrimView.java
@@ -32,6 +32,7 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.util.Themes;
 
 public class ScrimView extends View {
 
@@ -39,9 +40,6 @@
 
     private static final int MASK_HEIGHT_DP = 300;
     private static final float MASK_START_LENGTH_FACTOR = 1f;
-    private static final float FINAL_ALPHA = 0.87f;
-    private static final int SCRIM_COLOR = ColorUtils.setAlphaComponent(
-            Color.WHITE, (int) (FINAL_ALPHA * 255));
     private static final boolean APPLY_ALPHA = true;
 
     private static Bitmap sFinalScrimMask;
@@ -63,18 +61,20 @@
         super(context, attrs);
         mMaskHeight = Utilities.pxFromDp(MASK_HEIGHT_DP, getResources().getDisplayMetrics());
         mHeadStart = (int) (mMaskHeight * MASK_START_LENGTH_FACTOR);
-        mPaint.setColor(SCRIM_COLOR);
         mAlphaStart = Launcher.getLauncher(context)
                 .getDeviceProfile().isVerticalBarLayout() ? 0 : 55;
 
+        int scrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
+        int scrimAlpha = Color.alpha(scrimColor);
+        mPaint.setColor(scrimColor);
         if (sFinalScrimMask == null) {
             sFinalScrimMask = Utilities.convertToAlphaMask(
-                    Utilities.createOnePixBitmap(), FINAL_ALPHA);
+                    Utilities.createOnePixBitmap(), scrimAlpha);
         }
         if (sAlphaScrimMask == null) {
             Bitmap alphaMaskFromResource = BitmapFactory.decodeResource(getResources(),
                     R.drawable.all_apps_alpha_mask);
-            sAlphaScrimMask = Utilities.convertToAlphaMask(alphaMaskFromResource, FINAL_ALPHA);
+            sAlphaScrimMask = Utilities.convertToAlphaMask(alphaMaskFromResource, scrimAlpha);
         }
     }
 
diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java
index d863339..9cf45b0 100644
--- a/src/com/android/launcher3/util/Themes.java
+++ b/src/com/android/launcher3/util/Themes.java
@@ -20,7 +20,6 @@
 import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.ColorMatrix;
-import android.view.ContextThemeWrapper;
 
 /**
  * Various utility methods associated with theming.
@@ -31,10 +30,6 @@
         return getAttrColor(context, android.R.attr.colorAccent);
     }
 
-    public static int getColorPrimary(Context context, int theme) {
-        return getAttrColor(new ContextThemeWrapper(context, theme), android.R.attr.colorPrimary);
-    }
-
     public static int getAttrColor(Context context, int attr) {
         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
         int colorAccent = ta.getColor(0, 0);
@@ -42,6 +37,13 @@
         return colorAccent;
     }
 
+    public static boolean getAttrBoolean(Context context, int attr) {
+        TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
+        boolean value = ta.getBoolean(0, false);
+        ta.recycle();
+        return value;
+    }
+
     /**
      * Returns the alpha corresponding to the theme attribute {@param attr}, in the range [0, 255].
      */