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 android.util;
17 
18 import android.annotation.UserIdInt;
19 import android.compat.annotation.UnsupportedAppUsage;
20 import android.content.Context;
21 import android.content.pm.ApplicationInfo;
22 import android.content.pm.PackageItemInfo;
23 import android.content.pm.PackageManager;
24 import android.content.res.Resources;
25 import android.graphics.drawable.Drawable;
26 import android.os.UserHandle;
27 import android.os.UserManager;
28 
29 import com.android.internal.annotations.VisibleForTesting;
30 
31 /**
32  * Utility class to load app drawables with appropriate badging.
33  *
34  * @hide
35  */
36 public class IconDrawableFactory {
37 
38     protected final Context mContext;
39     protected final PackageManager mPm;
40     protected final UserManager mUm;
41     protected final LauncherIcons mLauncherIcons;
42     protected final boolean mEmbedShadow;
43 
IconDrawableFactory(Context context, boolean embedShadow)44     private IconDrawableFactory(Context context, boolean embedShadow) {
45         mContext = context;
46         mPm = context.getPackageManager();
47         mUm = context.getSystemService(UserManager.class);
48         mLauncherIcons = new LauncherIcons(context);
49         mEmbedShadow = embedShadow;
50     }
51 
needsBadging(ApplicationInfo appInfo, @UserIdInt int userId)52     protected boolean needsBadging(ApplicationInfo appInfo, @UserIdInt int userId) {
53         return appInfo.isInstantApp() || mUm.isManagedProfile(userId);
54     }
55 
56     @UnsupportedAppUsage
getBadgedIcon(ApplicationInfo appInfo)57     public Drawable getBadgedIcon(ApplicationInfo appInfo) {
58         return getBadgedIcon(appInfo, UserHandle.getUserId(appInfo.uid));
59     }
60 
getBadgedIcon(ApplicationInfo appInfo, @UserIdInt int userId)61     public Drawable getBadgedIcon(ApplicationInfo appInfo, @UserIdInt int userId) {
62         return getBadgedIcon(appInfo, appInfo, userId);
63     }
64 
65     @UnsupportedAppUsage
getBadgedIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo, @UserIdInt int userId)66     public Drawable getBadgedIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo,
67             @UserIdInt int userId) {
68         Drawable icon = mPm.loadUnbadgedItemIcon(itemInfo, appInfo);
69         if (!mEmbedShadow && !needsBadging(appInfo, userId)) {
70             return icon;
71         }
72 
73         icon = getShadowedIcon(icon);
74         if (appInfo.isInstantApp()) {
75             int badgeColor = Resources.getSystem().getColor(
76                     com.android.internal.R.color.instant_app_badge, null);
77             icon = mLauncherIcons.getBadgedDrawable(icon,
78                     com.android.internal.R.drawable.ic_instant_icon_badge_bolt,
79                     badgeColor);
80         }
81         if (mUm.isManagedProfile(userId)) {
82             icon = mLauncherIcons.getBadgedDrawable(icon,
83                     com.android.internal.R.drawable.ic_corp_icon_badge_case,
84                     getUserBadgeColor(mUm, userId));
85         }
86         return icon;
87     }
88 
89     /**
90      * Add shadow to the icon if {@link AdaptiveIconDrawable}
91      */
getShadowedIcon(Drawable icon)92     public Drawable getShadowedIcon(Drawable icon) {
93         return mLauncherIcons.wrapIconDrawableWithShadow(icon);
94     }
95 
96     // Should have enough colors to cope with UserManagerService.getMaxManagedProfiles()
97     @VisibleForTesting
98     public static final int[] CORP_BADGE_COLORS = new int[] {
99             com.android.internal.R.color.profile_badge_1,
100             com.android.internal.R.color.profile_badge_2,
101             com.android.internal.R.color.profile_badge_3
102     };
103 
getUserBadgeColor(UserManager um, @UserIdInt int userId)104     public static int getUserBadgeColor(UserManager um, @UserIdInt int userId) {
105         int badge = um.getManagedProfileBadge(userId);
106         if (badge < 0) {
107             badge = 0;
108         }
109         int resourceId = CORP_BADGE_COLORS[badge % CORP_BADGE_COLORS.length];
110         return Resources.getSystem().getColor(resourceId, null);
111     }
112 
113     @UnsupportedAppUsage
newInstance(Context context)114     public static IconDrawableFactory newInstance(Context context) {
115         return new IconDrawableFactory(context, true);
116     }
117 
newInstance(Context context, boolean embedShadow)118     public static IconDrawableFactory newInstance(Context context, boolean embedShadow) {
119         return new IconDrawableFactory(context, embedShadow);
120     }
121 }
122