• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 
17 package com.android.launcher3.graphics;
18 
19 import static com.android.launcher3.graphics.IconShape.getShapePath;
20 
21 import android.content.Context;
22 import android.content.pm.ActivityInfo;
23 import android.content.res.Resources;
24 import android.graphics.Bitmap;
25 import android.graphics.Canvas;
26 import android.graphics.Color;
27 import android.graphics.Rect;
28 import android.graphics.drawable.BitmapDrawable;
29 import android.graphics.drawable.Drawable;
30 import android.os.Process;
31 import android.os.UserHandle;
32 import android.util.ArrayMap;
33 
34 import com.android.launcher3.FastBitmapDrawable;
35 import com.android.launcher3.ItemInfoWithIcon;
36 import com.android.launcher3.R;
37 import com.android.launcher3.icons.BitmapInfo;
38 import com.android.launcher3.util.MainThreadInitializedObject;
39 import com.android.launcher3.util.ResourceBasedOverride;
40 
41 import androidx.annotation.UiThread;
42 
43 /**
44  * Factory for creating new drawables.
45  */
46 public class DrawableFactory implements ResourceBasedOverride {
47 
48     public static final MainThreadInitializedObject<DrawableFactory> INSTANCE =
49             new MainThreadInitializedObject<>(c -> Overrides.getObject(DrawableFactory.class,
50                         c.getApplicationContext(), R.string.drawable_factory_class));
51 
52     protected final UserHandle mMyUser = Process.myUserHandle();
53     protected final ArrayMap<UserHandle, Bitmap> mUserBadges = new ArrayMap<>();
54 
55     /**
56      * Returns a FastBitmapDrawable with the icon.
57      */
newIcon(Context context, ItemInfoWithIcon info)58     public FastBitmapDrawable newIcon(Context context, ItemInfoWithIcon info) {
59         FastBitmapDrawable drawable = info.usingLowResIcon()
60                 ? new PlaceHolderIconDrawable(info, getShapePath(), context)
61                 : new FastBitmapDrawable(info);
62         drawable.setIsDisabled(info.isDisabled());
63         return drawable;
64     }
65 
newIcon(Context context, BitmapInfo info, ActivityInfo target)66     public FastBitmapDrawable newIcon(Context context, BitmapInfo info, ActivityInfo target) {
67         return info.isLowRes()
68                 ? new PlaceHolderIconDrawable(info, getShapePath(), context)
69                 : new FastBitmapDrawable(info);
70     }
71 
72     /**
73      * Returns a FastBitmapDrawable with the icon.
74      */
newPendingIcon(Context context, ItemInfoWithIcon info)75     public PreloadIconDrawable newPendingIcon(Context context, ItemInfoWithIcon info) {
76         return new PreloadIconDrawable(info, getShapePath(), context);
77     }
78 
79     /**
80      * Returns a drawable that can be used as a badge for the user or null.
81      */
82     @UiThread
getBadgeForUser(UserHandle user, Context context)83     public Drawable getBadgeForUser(UserHandle user, Context context) {
84         if (mMyUser.equals(user)) {
85             return null;
86         }
87 
88         Bitmap badgeBitmap = getUserBadge(user, context);
89         FastBitmapDrawable d = new FastBitmapDrawable(badgeBitmap);
90         d.setFilterBitmap(true);
91         d.setBounds(0, 0, badgeBitmap.getWidth(), badgeBitmap.getHeight());
92         return d;
93     }
94 
getUserBadge(UserHandle user, Context context)95     protected synchronized Bitmap getUserBadge(UserHandle user, Context context) {
96         Bitmap badgeBitmap = mUserBadges.get(user);
97         if (badgeBitmap != null) {
98             return badgeBitmap;
99         }
100 
101         final Resources res = context.getApplicationContext().getResources();
102         int badgeSize = res.getDimensionPixelSize(R.dimen.profile_badge_size);
103         badgeBitmap = Bitmap.createBitmap(badgeSize, badgeSize, Bitmap.Config.ARGB_8888);
104 
105         Drawable drawable = context.getPackageManager().getUserBadgedDrawableForDensity(
106                 new BitmapDrawable(res, badgeBitmap), user, new Rect(0, 0, badgeSize, badgeSize),
107                 0);
108         if (drawable instanceof BitmapDrawable) {
109             badgeBitmap = ((BitmapDrawable) drawable).getBitmap();
110         } else {
111             badgeBitmap.eraseColor(Color.TRANSPARENT);
112             Canvas c = new Canvas(badgeBitmap);
113             drawable.setBounds(0, 0, badgeSize, badgeSize);
114             drawable.draw(c);
115             c.setBitmap(null);
116         }
117 
118         mUserBadges.put(user, badgeBitmap);
119         return badgeBitmap;
120     }
121 }
122