1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.launcher3.icons; 17 18 import android.content.Context; 19 import android.content.res.Resources; 20 import android.graphics.Bitmap; 21 import android.graphics.BlendMode; 22 import android.graphics.BlendModeColorFilter; 23 import android.graphics.Canvas; 24 import android.graphics.ColorFilter; 25 import android.graphics.Paint; 26 import android.graphics.Rect; 27 28 /** 29 * Class to handle monochrome themed app icons 30 */ 31 @SuppressWarnings("NewApi") 32 public class ThemedIconDrawable extends FastBitmapDrawable { 33 34 public static final String TAG = "ThemedIconDrawable"; 35 36 final BitmapInfo bitmapInfo; 37 final int colorFg, colorBg; 38 39 // The foreground/monochrome icon for the app 40 private final Bitmap mMonoIcon; 41 private final Paint mMonoPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); 42 43 private final Bitmap mBgBitmap; 44 private final Paint mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); 45 46 private final ColorFilter mBgFilter, mMonoFilter; 47 ThemedIconDrawable(ThemedConstantState constantState)48 protected ThemedIconDrawable(ThemedConstantState constantState) { 49 super(constantState.mBitmap, constantState.colorFg); 50 bitmapInfo = constantState.bitmapInfo; 51 colorBg = constantState.colorBg; 52 colorFg = constantState.colorFg; 53 54 mMonoIcon = bitmapInfo.mMono; 55 mMonoFilter = new BlendModeColorFilter(colorFg, BlendMode.SRC_IN); 56 mMonoPaint.setColorFilter(mMonoFilter); 57 58 mBgBitmap = bitmapInfo.mWhiteShadowLayer; 59 mBgFilter = new BlendModeColorFilter(colorBg, BlendMode.SRC_IN); 60 mBgPaint.setColorFilter(mBgFilter); 61 } 62 63 @Override drawInternal(Canvas canvas, Rect bounds)64 protected void drawInternal(Canvas canvas, Rect bounds) { 65 canvas.drawBitmap(mBgBitmap, null, bounds, mBgPaint); 66 canvas.drawBitmap(mMonoIcon, null, bounds, mMonoPaint); 67 } 68 69 @Override updateFilter()70 protected void updateFilter() { 71 super.updateFilter(); 72 int alpha = mIsDisabled ? (int) (mDisabledAlpha * FULLY_OPAQUE) : FULLY_OPAQUE; 73 mBgPaint.setAlpha(alpha); 74 mBgPaint.setColorFilter(mIsDisabled ? new BlendModeColorFilter( 75 getDisabledColor(colorBg), BlendMode.SRC_IN) : mBgFilter); 76 77 mMonoPaint.setAlpha(alpha); 78 mMonoPaint.setColorFilter(mIsDisabled ? new BlendModeColorFilter( 79 getDisabledColor(colorFg), BlendMode.SRC_IN) : mMonoFilter); 80 } 81 82 @Override isThemed()83 public boolean isThemed() { 84 return true; 85 } 86 87 @Override newConstantState()88 public FastBitmapConstantState newConstantState() { 89 return new ThemedConstantState(bitmapInfo, colorBg, colorFg); 90 } 91 92 static class ThemedConstantState extends FastBitmapConstantState { 93 94 final BitmapInfo bitmapInfo; 95 final int colorFg, colorBg; 96 ThemedConstantState(BitmapInfo bitmapInfo, int colorBg, int colorFg)97 public ThemedConstantState(BitmapInfo bitmapInfo, int colorBg, int colorFg) { 98 super(bitmapInfo.icon, bitmapInfo.color); 99 this.bitmapInfo = bitmapInfo; 100 this.colorBg = colorBg; 101 this.colorFg = colorFg; 102 } 103 104 @Override createDrawable()105 public FastBitmapDrawable createDrawable() { 106 return new ThemedIconDrawable(this); 107 } 108 } 109 newDrawable(BitmapInfo info, Context context)110 public static FastBitmapDrawable newDrawable(BitmapInfo info, Context context) { 111 int[] colors = getColors(context); 112 return new ThemedConstantState(info, colors[0], colors[1]).newDrawable(); 113 } 114 115 /** 116 * Get an int array representing background and foreground colors for themed icons 117 */ getColors(Context context)118 public static int[] getColors(Context context) { 119 Resources res = context.getResources(); 120 int[] colors = new int[2]; 121 colors[0] = res.getColor(R.color.themed_icon_background_color); 122 colors[1] = res.getColor(R.color.themed_icon_color); 123 return colors; 124 } 125 126 @Override getIconColor()127 public int getIconColor() { 128 return colorFg; 129 } 130 } 131