• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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.launcher2;
18 
19 import android.content.ComponentName;
20 import android.content.Intent;
21 import android.content.pm.PackageManager;
22 import android.content.pm.ResolveInfo;
23 import android.content.res.Resources;
24 import android.graphics.Bitmap;
25 import android.graphics.Canvas;
26 import android.graphics.drawable.Drawable;
27 import android.util.DisplayMetrics;
28 
29 import java.util.HashMap;
30 
31 /**
32  * Cache of application icons.  Icons can be made from any thread.
33  */
34 public class IconCache {
35     private static final String TAG = "Launcher.IconCache";
36 
37     private static final int INITIAL_ICON_CACHE_CAPACITY = 50;
38 
39     private static class CacheEntry {
40         public Bitmap icon;
41         public String title;
42     }
43 
44     private final Bitmap mDefaultIcon;
45     private final LauncherApplication mContext;
46     private final PackageManager mPackageManager;
47     private final HashMap<ComponentName, CacheEntry> mCache =
48             new HashMap<ComponentName, CacheEntry>(INITIAL_ICON_CACHE_CAPACITY);
49     private int mIconDpi;
50 
IconCache(LauncherApplication context)51     public IconCache(LauncherApplication context) {
52         mContext = context;
53         mPackageManager = context.getPackageManager();
54         int density = context.getResources().getDisplayMetrics().densityDpi;
55         if (LauncherApplication.isScreenLarge()) {
56             if (density == DisplayMetrics.DENSITY_LOW) {
57                 mIconDpi = DisplayMetrics.DENSITY_MEDIUM;
58             } else if (density == DisplayMetrics.DENSITY_MEDIUM) {
59                 mIconDpi = DisplayMetrics.DENSITY_HIGH;
60             } else if (density == DisplayMetrics.DENSITY_HIGH) {
61                 mIconDpi = DisplayMetrics.DENSITY_XHIGH;
62             } else if (density == DisplayMetrics.DENSITY_XHIGH) {
63                 // We'll need to use a denser icon, or some sort of a mipmap
64                 mIconDpi = DisplayMetrics.DENSITY_XHIGH;
65             }
66         } else {
67             mIconDpi = context.getResources().getDisplayMetrics().densityDpi;
68         }
69         // need to set mIconDpi before getting default icon
70         mDefaultIcon = makeDefaultIcon();
71     }
72 
getFullResDefaultActivityIcon()73     public Drawable getFullResDefaultActivityIcon() {
74         return getFullResIcon(Resources.getSystem(),
75                 com.android.internal.R.mipmap.sym_def_app_icon);
76     }
77 
getFullResIcon(Resources resources, int iconId)78     public Drawable getFullResIcon(Resources resources, int iconId) {
79         Drawable d;
80         try {
81             d = resources.getDrawableForDensity(iconId, mIconDpi);
82         } catch (Resources.NotFoundException e) {
83             d = null;
84         }
85 
86         return (d != null) ? d : getFullResDefaultActivityIcon();
87     }
88 
getFullResIcon(ResolveInfo info, PackageManager packageManager)89     public Drawable getFullResIcon(ResolveInfo info, PackageManager packageManager) {
90         Resources resources;
91         try {
92             resources = packageManager.getResourcesForApplication(
93                     info.activityInfo.applicationInfo);
94         } catch (PackageManager.NameNotFoundException e) {
95             resources = null;
96         }
97         if (resources != null) {
98             int iconId = info.activityInfo.getIconResource();
99             if (iconId != 0) {
100                 return getFullResIcon(resources, iconId);
101             }
102         }
103         return getFullResDefaultActivityIcon();
104     }
105 
makeDefaultIcon()106     private Bitmap makeDefaultIcon() {
107         Drawable d = getFullResDefaultActivityIcon();
108         Bitmap b = Bitmap.createBitmap(Math.max(d.getIntrinsicWidth(), 1),
109                 Math.max(d.getIntrinsicHeight(), 1),
110                 Bitmap.Config.ARGB_8888);
111         Canvas c = new Canvas(b);
112         d.setBounds(0, 0, b.getWidth(), b.getHeight());
113         d.draw(c);
114         c.setBitmap(null);
115         return b;
116     }
117 
118     /**
119      * Remove any records for the supplied ComponentName.
120      */
remove(ComponentName componentName)121     public void remove(ComponentName componentName) {
122         synchronized (mCache) {
123             mCache.remove(componentName);
124         }
125     }
126 
127     /**
128      * Empty out the cache.
129      */
flush()130     public void flush() {
131         synchronized (mCache) {
132             mCache.clear();
133         }
134     }
135 
136     /**
137      * Fill in "application" with the icon and label for "info."
138      */
getTitleAndIcon(ApplicationInfo application, ResolveInfo info, HashMap<Object, CharSequence> labelCache)139     public void getTitleAndIcon(ApplicationInfo application, ResolveInfo info,
140             HashMap<Object, CharSequence> labelCache) {
141         synchronized (mCache) {
142             CacheEntry entry = cacheLocked(application.componentName, info, labelCache);
143 
144             application.title = entry.title;
145             application.iconBitmap = entry.icon;
146         }
147     }
148 
getIcon(Intent intent)149     public Bitmap getIcon(Intent intent) {
150         synchronized (mCache) {
151             final ResolveInfo resolveInfo = mPackageManager.resolveActivity(intent, 0);
152             ComponentName component = intent.getComponent();
153 
154             if (resolveInfo == null || component == null) {
155                 return mDefaultIcon;
156             }
157 
158             CacheEntry entry = cacheLocked(component, resolveInfo, null);
159             return entry.icon;
160         }
161     }
162 
getIcon(ComponentName component, ResolveInfo resolveInfo, HashMap<Object, CharSequence> labelCache)163     public Bitmap getIcon(ComponentName component, ResolveInfo resolveInfo,
164             HashMap<Object, CharSequence> labelCache) {
165         synchronized (mCache) {
166             if (resolveInfo == null || component == null) {
167                 return null;
168             }
169 
170             CacheEntry entry = cacheLocked(component, resolveInfo, labelCache);
171             return entry.icon;
172         }
173     }
174 
isDefaultIcon(Bitmap icon)175     public boolean isDefaultIcon(Bitmap icon) {
176         return mDefaultIcon == icon;
177     }
178 
cacheLocked(ComponentName componentName, ResolveInfo info, HashMap<Object, CharSequence> labelCache)179     private CacheEntry cacheLocked(ComponentName componentName, ResolveInfo info,
180             HashMap<Object, CharSequence> labelCache) {
181         CacheEntry entry = mCache.get(componentName);
182         if (entry == null) {
183             entry = new CacheEntry();
184 
185             mCache.put(componentName, entry);
186 
187             ComponentName key = LauncherModel.getComponentNameFromResolveInfo(info);
188             if (labelCache != null && labelCache.containsKey(key)) {
189                 entry.title = labelCache.get(key).toString();
190             } else {
191                 entry.title = info.loadLabel(mPackageManager).toString();
192                 if (labelCache != null) {
193                     labelCache.put(key, entry.title);
194                 }
195             }
196             if (entry.title == null) {
197                 entry.title = info.activityInfo.name;
198             }
199 
200             entry.icon = Utilities.createIconBitmap(
201                     getFullResIcon(info, mPackageManager), mContext);
202         }
203         return entry;
204     }
205 
getAllIcons()206     public HashMap<ComponentName,Bitmap> getAllIcons() {
207         synchronized (mCache) {
208             HashMap<ComponentName,Bitmap> set = new HashMap<ComponentName,Bitmap>();
209             int i = 0;
210             for (ComponentName cn : mCache.keySet()) {
211                 final CacheEntry e = mCache.get(cn);
212                 set.put(cn, e.icon);
213             }
214             return set;
215         }
216     }
217 }
218