• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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.documentsui;
18 
19 import static com.android.documentsui.util.FlagUtils.isUseMaterial3FlagEnabled;
20 
21 import android.content.Context;
22 import android.content.pm.PackageManager;
23 import android.content.pm.ProviderInfo;
24 import android.content.res.Resources;
25 import android.graphics.Outline;
26 import android.graphics.drawable.Drawable;
27 import android.graphics.drawable.Icon;
28 import android.util.TypedValue;
29 import android.view.View;
30 import android.view.ViewOutlineProvider;
31 import android.widget.ImageView;
32 
33 import com.android.documentsui.base.UserId;
34 import com.android.documentsui.util.ColorUtils;
35 
36 import java.util.HashMap;
37 import java.util.Map;
38 
39 public class IconUtils {
40     // key: drawable resource id, value: color attribute id
41     private static final Map<Integer, Integer> sCustomIconColorMap = new HashMap<>();
42 
43     static {
44         if (isUseMaterial3FlagEnabled()) {
45             // Use Resources.getSystem().getIdentifier() here instead of R.drawable.ic_doc_folder
46             // because com.android.internal.R is not public.
47             sCustomIconColorMap.put(
48                     Resources.getSystem().getIdentifier("ic_doc_folder", "drawable", "android"),
49                     com.google.android.material.R.attr.colorPrimaryFixedDim);
50             sCustomIconColorMap.put(
51                     Resources.getSystem().getIdentifier("ic_doc_generic", "drawable", "android"),
52                     com.google.android.material.R.attr.colorOutline);
53             sCustomIconColorMap.put(
54                     Resources.getSystem()
55                             .getIdentifier("ic_doc_certificate", "drawable", "android"),
56                     com.google.android.material.R.attr.colorOutline);
57             sCustomIconColorMap.put(
58                     Resources.getSystem().getIdentifier("ic_doc_codes", "drawable", "android"),
59                     com.google.android.material.R.attr.colorOutline);
60             sCustomIconColorMap.put(
61                     Resources.getSystem().getIdentifier("ic_doc_contact", "drawable", "android"),
62                     com.google.android.material.R.attr.colorOutline);
63             sCustomIconColorMap.put(
64                     Resources.getSystem().getIdentifier("ic_doc_font", "drawable", "android"),
65                     com.google.android.material.R.attr.colorOutline);
66         }
67     }
68 
loadPackageIcon(Context context, UserId userId, String authority, int icon, boolean maybeShowBadge)69     public static Drawable loadPackageIcon(Context context, UserId userId, String authority,
70             int icon, boolean maybeShowBadge) {
71         if (icon != 0) {
72             final PackageManager pm = userId.getPackageManager(context);
73             Drawable packageIcon = null;
74             if (authority != null) {
75                 final ProviderInfo info = pm.resolveContentProvider(authority, 0);
76                 if (info != null) {
77                     packageIcon = pm.getDrawable(info.packageName, icon, info.applicationInfo);
78                 }
79             } else {
80                 packageIcon = userId.getDrawable(context, icon);
81             }
82             if (packageIcon != null && maybeShowBadge) {
83                 return userId.getUserBadgedIcon(context, packageIcon);
84             } else {
85                 return packageIcon;
86             }
87         }
88 
89         return null;
90     }
91 
loadMimeIcon( Context context, String mimeType, String authority, String docId, int mode)92     public static Drawable loadMimeIcon(
93             Context context, String mimeType, String authority, String docId, int mode) {
94         return loadMimeIcon(context, mimeType);
95     }
96 
97     /**
98      * Load mime type drawable from system MimeIconUtils.
99      * @param context activity context to obtain resource
100      * @param mimeType specific mime type string of file
101      * @return drawable of mime type files from system default
102      */
loadMimeIcon(Context context, String mimeType)103     public static Drawable loadMimeIcon(Context context, String mimeType) {
104         if (mimeType == null) return null;
105         Icon icon = context.getContentResolver().getTypeInfo(mimeType).getIcon();
106         Drawable drawable = icon.loadDrawable(context);
107         // TODO(b/400263417): Remove this once RRO mime icons support dynamic colors.
108         if (isUseMaterial3FlagEnabled()
109                 && drawable != null
110                 && sCustomIconColorMap.containsKey(icon.getResId())) {
111             drawable.setTint(
112                     ColorUtils.resolveMaterialColorAttribute(
113                             context, sCustomIconColorMap.get(icon.getResId())));
114         }
115         return drawable;
116     }
117 
applyTintColor(Context context, int drawableId, int tintColorId)118     public static Drawable applyTintColor(Context context, int drawableId, int tintColorId) {
119         final Drawable icon = context.getDrawable(drawableId);
120         return applyTintColor(context, icon, tintColorId);
121     }
122 
applyTintColor(Context context, Drawable icon, int tintColorId)123     public static Drawable applyTintColor(Context context, Drawable icon, int tintColorId) {
124         icon.mutate();
125         icon.setTintList(context.getColorStateList(tintColorId));
126         return icon;
127     }
128 
applyTintAttr(Context context, int drawableId, int tintAttrId)129     public static Drawable applyTintAttr(Context context, int drawableId, int tintAttrId) {
130         final TypedValue outValue = new TypedValue();
131         context.getTheme().resolveAttribute(tintAttrId, outValue, true);
132         return applyTintColor(context, drawableId, outValue.resourceId);
133     }
134 
135     /**
136      * When a ImageView loads a thumbnail from a bitmap, we usually uses a CardView to wrap it to
137      * apply CardView's corner radius to the ImageView. This causes the corner pixelation of the
138      * thumbnail especially when there's a border (stroke) around the CardView. This method creates
139      * a custom clip outline with the correct shape to fix this issue.
140      *
141      * @param imageView ImageView to apply clip outline.
142      * @param strokeWidth stroke width of the thumbnail.
143      * @param cornerRadius corner radius of the thumbnail.
144      */
applyThumbnailClipOutline( ImageView imageView, int strokeWidth, int cornerRadius)145     public static void applyThumbnailClipOutline(
146             ImageView imageView, int strokeWidth, int cornerRadius) {
147         ViewOutlineProvider outlineProvider =
148                 new ViewOutlineProvider() {
149                     @Override
150                     public void getOutline(View view, Outline outline) {
151                         outline.setRoundRect(
152                                 strokeWidth,
153                                 strokeWidth,
154                                 view.getWidth() - strokeWidth,
155                                 view.getHeight() - strokeWidth,
156                                 cornerRadius);
157                     }
158                 };
159         imageView.setOutlineProvider(outlineProvider);
160         imageView.setClipToOutline(true);
161     }
162 }
163