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