1 /* 2 * Copyright (C) 2017 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.Configuration; 20 import android.graphics.Bitmap; 21 import android.graphics.Bitmap.Config; 22 import android.graphics.Canvas; 23 24 import androidx.annotation.IntDef; 25 import androidx.annotation.NonNull; 26 import androidx.annotation.Nullable; 27 28 import com.android.launcher3.util.FlagOp; 29 30 public class BitmapInfo { 31 32 static final int FLAG_WORK = 1 << 0; 33 static final int FLAG_INSTANT = 1 << 1; 34 static final int FLAG_CLONE = 1 << 2; 35 @IntDef(flag = true, value = { 36 FLAG_WORK, 37 FLAG_INSTANT, 38 FLAG_CLONE 39 }) 40 @interface BitmapInfoFlags {} 41 42 public static final int FLAG_THEMED = 1 << 0; 43 public static final int FLAG_NO_BADGE = 1 << 1; 44 @IntDef(flag = true, value = { 45 FLAG_THEMED, 46 FLAG_NO_BADGE, 47 }) 48 public @interface DrawableCreationFlags {} 49 50 public static final Bitmap LOW_RES_ICON = Bitmap.createBitmap(1, 1, Config.ALPHA_8); 51 public static final BitmapInfo LOW_RES_INFO = fromBitmap(LOW_RES_ICON); 52 53 public static final String TAG = "BitmapInfo"; 54 55 public final Bitmap icon; 56 public final int color; 57 58 @Nullable 59 protected Bitmap mMono; 60 protected Bitmap mWhiteShadowLayer; 61 62 public @BitmapInfoFlags int flags; 63 private BitmapInfo badgeInfo; 64 BitmapInfo(Bitmap icon, int color)65 public BitmapInfo(Bitmap icon, int color) { 66 this.icon = icon; 67 this.color = color; 68 } 69 withBadgeInfo(BitmapInfo badgeInfo)70 public BitmapInfo withBadgeInfo(BitmapInfo badgeInfo) { 71 BitmapInfo result = clone(); 72 result.badgeInfo = badgeInfo; 73 return result; 74 } 75 76 /** 77 * Returns a bitmapInfo with the flagOP applied 78 */ withFlags(@onNull FlagOp op)79 public BitmapInfo withFlags(@NonNull FlagOp op) { 80 if (op == FlagOp.NO_OP) { 81 return this; 82 } 83 BitmapInfo result = clone(); 84 result.flags = op.apply(result.flags); 85 return result; 86 } 87 copyInternalsTo(BitmapInfo target)88 protected BitmapInfo copyInternalsTo(BitmapInfo target) { 89 target.mMono = mMono; 90 target.mWhiteShadowLayer = mWhiteShadowLayer; 91 target.flags = flags; 92 target.badgeInfo = badgeInfo; 93 return target; 94 } 95 96 @Override clone()97 public BitmapInfo clone() { 98 return copyInternalsTo(new BitmapInfo(icon, color)); 99 } 100 setMonoIcon(Bitmap mono, BaseIconFactory iconFactory)101 public void setMonoIcon(Bitmap mono, BaseIconFactory iconFactory) { 102 mMono = mono; 103 mWhiteShadowLayer = iconFactory.getWhiteShadowLayer(); 104 } 105 106 /** 107 * Ideally icon should not be null, except in cases when generating hardware bitmap failed 108 */ isNullOrLowRes()109 public final boolean isNullOrLowRes() { 110 return icon == null || icon == LOW_RES_ICON; 111 } 112 isLowRes()113 public final boolean isLowRes() { 114 return LOW_RES_ICON == icon; 115 } 116 117 /** 118 * BitmapInfo can be stored on disk or other persistent storage 119 */ canPersist()120 public boolean canPersist() { 121 return !isNullOrLowRes(); 122 } 123 getMono()124 public Bitmap getMono() { 125 return mMono; 126 } 127 128 /** 129 * Creates a drawable for the provided BitmapInfo 130 */ newIcon(Context context)131 public FastBitmapDrawable newIcon(Context context) { 132 return newIcon(context, 0); 133 } 134 135 /** 136 * Creates a drawable for the provided BitmapInfo 137 */ newIcon(Context context, @DrawableCreationFlags int creationFlags)138 public FastBitmapDrawable newIcon(Context context, @DrawableCreationFlags int creationFlags) { 139 FastBitmapDrawable drawable; 140 if (isLowRes()) { 141 drawable = new PlaceHolderIconDrawable(this, context); 142 } else if ((creationFlags & FLAG_THEMED) != 0 && mMono != null) { 143 drawable = ThemedIconDrawable.newDrawable(this, context); 144 } else { 145 drawable = new FastBitmapDrawable(this); 146 } 147 applyFlags(context, drawable, creationFlags); 148 return drawable; 149 } 150 applyFlags(Context context, FastBitmapDrawable drawable, @DrawableCreationFlags int creationFlags)151 protected void applyFlags(Context context, FastBitmapDrawable drawable, 152 @DrawableCreationFlags int creationFlags) { 153 drawable.mDisabledAlpha = GraphicsUtils.getFloat(context, R.attr.disabledIconAlpha, 1f); 154 if ((creationFlags & FLAG_NO_BADGE) == 0) { 155 if (badgeInfo != null) { 156 drawable.setBadge(badgeInfo.newIcon(context, creationFlags)); 157 } else if ((flags & FLAG_INSTANT) != 0) { 158 drawable.setBadge(context.getDrawable(drawable.isThemed() 159 ? R.drawable.ic_instant_app_badge_themed 160 : R.drawable.ic_instant_app_badge)); 161 } else if ((flags & FLAG_WORK) != 0) { 162 drawable.setBadge(context.getDrawable(drawable.isThemed() 163 ? R.drawable.ic_work_app_badge_themed 164 : R.drawable.ic_work_app_badge)); 165 } else if ((flags & FLAG_CLONE) != 0) { 166 drawable.setBadge(context.getDrawable(drawable.isThemed() 167 ? R.drawable.ic_clone_app_badge_themed 168 : R.drawable.ic_clone_app_badge)); 169 } 170 } 171 } 172 fromBitmap(@onNull Bitmap bitmap)173 public static BitmapInfo fromBitmap(@NonNull Bitmap bitmap) { 174 return of(bitmap, 0); 175 } 176 of(@onNull Bitmap bitmap, int color)177 public static BitmapInfo of(@NonNull Bitmap bitmap, int color) { 178 return new BitmapInfo(bitmap, color); 179 } 180 181 /** 182 * Interface to be implemented by drawables to provide a custom BitmapInfo 183 */ 184 public interface Extender { 185 186 /** 187 * Called for creating a custom BitmapInfo 188 */ getExtendedInfo(Bitmap bitmap, int color, BaseIconFactory iconFactory, float normalizationScale)189 BitmapInfo getExtendedInfo(Bitmap bitmap, int color, 190 BaseIconFactory iconFactory, float normalizationScale); 191 192 /** 193 * Called to draw the UI independent of any runtime configurations like time or theme 194 */ drawForPersistence(Canvas canvas)195 void drawForPersistence(Canvas canvas); 196 } 197 } 198