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