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