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(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 
    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      */
    121     public void remove(ComponentName componentName) {
    122         synchronized (mCache) {
    123             mCache.remove(componentName);
    124         }
    125     }
    126 
    127     /**
    128      * Empty out the cache.
    129      */
    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      */
    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 
    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 
    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 
    175     public boolean isDefaultIcon(Bitmap icon) {
    176         return mDefaultIcon == icon;
    177     }
    178 
    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 
    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