IconCache.java revision 30be2cd2a4b9cedfcbb6c317449c11bb0dcc64cc
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 } 44 45 private final Bitmap mDefaultIcon; 46 private final LauncherApplication mContext; 47 private final PackageManager mPackageManager; 48 private final Utilities.BubbleText mBubble; 49 private final HashMap<ComponentName, CacheEntry> mCache = 50 new HashMap<ComponentName, CacheEntry>(INITIAL_ICON_CACHE_CAPACITY); 51 private int mIconDpi; 52 53 public IconCache(LauncherApplication context) { 54 mContext = context; 55 mPackageManager = context.getPackageManager(); 56 mBubble = new Utilities.BubbleText(context); 57 if (LauncherApplication.isScreenLarge()) { 58 mIconDpi = DisplayMetrics.DENSITY_HIGH; 59 } else { 60 mIconDpi = context.getResources().getDisplayMetrics().densityDpi; 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 com.android.internal.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(ResolveInfo info, PackageManager packageManager) { 83 Resources resources; 84 try { 85 resources = packageManager.getResourcesForApplication( 86 info.activityInfo.applicationInfo); 87 } catch (PackageManager.NameNotFoundException e) { 88 resources = null; 89 } 90 if (resources != null) { 91 int iconId = info.activityInfo.getIconResource(); 92 if (iconId != 0) { 93 return getFullResIcon(resources, iconId); 94 } 95 } 96 return getFullResDefaultActivityIcon(); 97 } 98 99 private Bitmap makeDefaultIcon() { 100 Drawable d = getFullResDefaultActivityIcon(); 101 Bitmap b = Bitmap.createBitmap(Math.max(d.getIntrinsicWidth(), 1), 102 Math.max(d.getIntrinsicHeight(), 1), 103 Bitmap.Config.ARGB_8888); 104 Canvas c = new Canvas(b); 105 d.setBounds(0, 0, b.getWidth(), b.getHeight()); 106 d.draw(c); 107 return b; 108 } 109 110 /** 111 * Remove any records for the supplied ComponentName. 112 */ 113 public void remove(ComponentName componentName) { 114 synchronized (mCache) { 115 mCache.remove(componentName); 116 } 117 } 118 119 /** 120 * Empty out the cache. 121 */ 122 public void flush() { 123 synchronized (mCache) { 124 mCache.clear(); 125 } 126 } 127 128 /** 129 * Fill in "application" with the icon and label for "info." 130 */ 131 public void getTitleAndIcon(ApplicationInfo application, ResolveInfo info, 132 HashMap<Object, CharSequence> labelCache) { 133 synchronized (mCache) { 134 CacheEntry entry = cacheLocked(application.componentName, info, labelCache); 135 136 application.title = entry.title; 137 application.iconBitmap = entry.icon; 138 } 139 } 140 141 public Bitmap getIcon(Intent intent) { 142 synchronized (mCache) { 143 final ResolveInfo resolveInfo = mPackageManager.resolveActivity(intent, 0); 144 ComponentName component = intent.getComponent(); 145 146 if (resolveInfo == null || component == null) { 147 return mDefaultIcon; 148 } 149 150 CacheEntry entry = cacheLocked(component, resolveInfo, null); 151 return entry.icon; 152 } 153 } 154 155 public Bitmap getIcon(ComponentName component, ResolveInfo resolveInfo) { 156 synchronized (mCache) { 157 if (resolveInfo == null || component == null) { 158 return null; 159 } 160 161 CacheEntry entry = cacheLocked(component, resolveInfo, null); 162 return entry.icon; 163 } 164 } 165 166 public boolean isDefaultIcon(Bitmap icon) { 167 return mDefaultIcon == icon; 168 } 169 170 private CacheEntry cacheLocked(ComponentName componentName, ResolveInfo info, 171 HashMap<Object, CharSequence> labelCache) { 172 CacheEntry entry = mCache.get(componentName); 173 if (entry == null) { 174 entry = new CacheEntry(); 175 176 mCache.put(componentName, entry); 177 178 if (labelCache != null && labelCache.containsKey(info)) { 179 entry.title = labelCache.get(info).toString(); 180 } else { 181 entry.title = info.loadLabel(mPackageManager).toString(); 182 if (labelCache != null) { 183 labelCache.put(info, entry.title); 184 } 185 } 186 if (entry.title == null) { 187 entry.title = info.activityInfo.name; 188 } 189 190 entry.icon = Utilities.createIconBitmap( 191 getFullResIcon(info, mPackageManager), mContext); 192 } 193 return entry; 194 } 195 196 public HashMap<ComponentName,Bitmap> getAllIcons() { 197 synchronized (mCache) { 198 HashMap<ComponentName,Bitmap> set = new HashMap<ComponentName,Bitmap>(); 199 int i = 0; 200 for (ComponentName cn : mCache.keySet()) { 201 final CacheEntry e = mCache.get(cn); 202 set.put(cn, e.icon); 203 } 204 return set; 205 } 206 } 207} 208