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