Home | History | Annotate | Download | only in launcher2
      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 
     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 
     73     public Drawable getFullResDefaultActivityIcon() {
     74         return getFullResIcon(Resources.getSystem(),
     75                 com.android.internal.R.mipmap.sym_def_app_icon);
     76     }
     77 
     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 
     89     public Drawable getFullResIcon(String packageName, int iconId) {
     90         Resources resources;
     91         try {
     92             resources = mPackageManager.getResourcesForApplication(packageName);
     93         } catch (PackageManager.NameNotFoundException e) {
     94             resources = null;
     95         }
     96         if (resources != null) {
     97             if (iconId != 0) {
     98                 return getFullResIcon(resources, iconId);
     99             }
    100         }
    101         return getFullResDefaultActivityIcon();
    102     }
    103 
    104     public Drawable getFullResIcon(ResolveInfo info) {
    105         Resources resources;
    106         try {
    107             resources = mPackageManager.getResourcesForApplication(
    108                     info.activityInfo.applicationInfo);
    109         } catch (PackageManager.NameNotFoundException e) {
    110             resources = null;
    111         }
    112         if (resources != null) {
    113             int iconId = info.activityInfo.getIconResource();
    114             if (iconId != 0) {
    115                 return getFullResIcon(resources, iconId);
    116             }
    117         }
    118         return getFullResDefaultActivityIcon();
    119     }
    120 
    121     private Bitmap makeDefaultIcon() {
    122         Drawable d = getFullResDefaultActivityIcon();
    123         Bitmap b = Bitmap.createBitmap(Math.max(d.getIntrinsicWidth(), 1),
    124                 Math.max(d.getIntrinsicHeight(), 1),
    125                 Bitmap.Config.ARGB_8888);
    126         Canvas c = new Canvas(b);
    127         d.setBounds(0, 0, b.getWidth(), b.getHeight());
    128         d.draw(c);
    129         c.setBitmap(null);
    130         return b;
    131     }
    132 
    133     /**
    134      * Remove any records for the supplied ComponentName.
    135      */
    136     public void remove(ComponentName componentName) {
    137         synchronized (mCache) {
    138             mCache.remove(componentName);
    139         }
    140     }
    141 
    142     /**
    143      * Empty out the cache.
    144      */
    145     public void flush() {
    146         synchronized (mCache) {
    147             mCache.clear();
    148         }
    149     }
    150 
    151     /**
    152      * Fill in "application" with the icon and label for "info."
    153      */
    154     public void getTitleAndIcon(ApplicationInfo application, ResolveInfo info,
    155             HashMap<Object, CharSequence> labelCache) {
    156         synchronized (mCache) {
    157             CacheEntry entry = cacheLocked(application.componentName, info, labelCache);
    158 
    159             application.title = entry.title;
    160             application.iconBitmap = entry.icon;
    161         }
    162     }
    163 
    164     public Bitmap getIcon(Intent intent) {
    165         synchronized (mCache) {
    166             final ResolveInfo resolveInfo = mPackageManager.resolveActivity(intent, 0);
    167             ComponentName component = intent.getComponent();
    168 
    169             if (resolveInfo == null || component == null) {
    170                 return mDefaultIcon;
    171             }
    172 
    173             CacheEntry entry = cacheLocked(component, resolveInfo, null);
    174             return entry.icon;
    175         }
    176     }
    177 
    178     public Bitmap getIcon(ComponentName component, ResolveInfo resolveInfo,
    179             HashMap<Object, CharSequence> labelCache) {
    180         synchronized (mCache) {
    181             if (resolveInfo == null || component == null) {
    182                 return null;
    183             }
    184 
    185             CacheEntry entry = cacheLocked(component, resolveInfo, labelCache);
    186             return entry.icon;
    187         }
    188     }
    189 
    190     public boolean isDefaultIcon(Bitmap icon) {
    191         return mDefaultIcon == icon;
    192     }
    193 
    194     private CacheEntry cacheLocked(ComponentName componentName, ResolveInfo info,
    195             HashMap<Object, CharSequence> labelCache) {
    196         CacheEntry entry = mCache.get(componentName);
    197         if (entry == null) {
    198             entry = new CacheEntry();
    199 
    200             mCache.put(componentName, entry);
    201 
    202             ComponentName key = LauncherModel.getComponentNameFromResolveInfo(info);
    203             if (labelCache != null && labelCache.containsKey(key)) {
    204                 entry.title = labelCache.get(key).toString();
    205             } else {
    206                 entry.title = info.loadLabel(mPackageManager).toString();
    207                 if (labelCache != null) {
    208                     labelCache.put(key, entry.title);
    209                 }
    210             }
    211             if (entry.title == null) {
    212                 entry.title = info.activityInfo.name;
    213             }
    214 
    215             entry.icon = Utilities.createIconBitmap(
    216                     getFullResIcon(info), mContext);
    217         }
    218         return entry;
    219     }
    220 
    221     public HashMap<ComponentName,Bitmap> getAllIcons() {
    222         synchronized (mCache) {
    223             HashMap<ComponentName,Bitmap> set = new HashMap<ComponentName,Bitmap>();
    224             for (ComponentName cn : mCache.keySet()) {
    225                 final CacheEntry e = mCache.get(cn);
    226                 set.put(cn, e.icon);
    227             }
    228             return set;
    229         }
    230     }
    231 }
    232