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