| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.launcher2; |
| |
| import android.app.ActivityManager; |
| import android.content.ComponentName; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.pm.ActivityInfo; |
| import android.content.pm.LauncherActivityInfo; |
| import android.content.pm.LauncherApps; |
| import android.content.pm.PackageManager; |
| import android.content.pm.ResolveInfo; |
| import android.content.res.Resources; |
| import android.graphics.Bitmap; |
| import android.graphics.Canvas; |
| import android.graphics.drawable.Drawable; |
| import android.os.UserHandle; |
| |
| import java.util.HashMap; |
| |
| /** |
| * Cache of application icons. Icons can be made from any thread. |
| */ |
| public class IconCache { |
| @SuppressWarnings("unused") |
| private static final String TAG = "Launcher.IconCache"; |
| |
| private static final int INITIAL_ICON_CACHE_CAPACITY = 50; |
| |
| private static class CacheEntry { |
| public Bitmap icon; |
| public String title; |
| public CharSequence contentDescription; |
| } |
| |
| private static class CacheKey { |
| public ComponentName componentName; |
| public UserHandle user; |
| |
| CacheKey(ComponentName componentName, UserHandle user) { |
| this.componentName = componentName; |
| this.user = user; |
| } |
| |
| @Override |
| public int hashCode() { |
| return componentName.hashCode() + user.hashCode(); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| CacheKey other = (CacheKey) o; |
| return other.componentName.equals(componentName) && other.user.equals(user); |
| } |
| } |
| |
| private final Bitmap mDefaultIcon; |
| private final LauncherApplication mContext; |
| private final PackageManager mPackageManager; |
| private final HashMap<CacheKey, CacheEntry> mCache = |
| new HashMap<CacheKey, CacheEntry>(INITIAL_ICON_CACHE_CAPACITY); |
| private int mIconDpi; |
| |
| public IconCache(LauncherApplication context) { |
| ActivityManager activityManager = |
| (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); |
| |
| mContext = context; |
| mPackageManager = context.getPackageManager(); |
| mIconDpi = activityManager.getLauncherLargeIconDensity(); |
| // need to set mIconDpi before getting default icon |
| mDefaultIcon = makeDefaultIcon(); |
| } |
| |
| public Drawable getFullResDefaultActivityIcon() { |
| return getFullResIcon(Resources.getSystem(), |
| android.R.mipmap.sym_def_app_icon, android.os.Process.myUserHandle()); |
| } |
| |
| public Drawable getFullResIcon(Resources resources, int iconId, UserHandle user) { |
| Drawable d; |
| try { |
| d = resources.getDrawableForDensity(iconId, mIconDpi); |
| } catch (Resources.NotFoundException e) { |
| d = null; |
| } |
| |
| if (d == null) { |
| d = getFullResDefaultActivityIcon(); |
| } |
| return mPackageManager.getUserBadgedIcon(d, user); |
| } |
| |
| public Drawable getFullResIcon(String packageName, int iconId, UserHandle user) { |
| Resources resources; |
| try { |
| // TODO: Check if this needs to use the user param if we support |
| // shortcuts/widgets from other profiles. It won't work as is |
| // for packages that are only available in a different user profile. |
| resources = mPackageManager.getResourcesForApplication(packageName); |
| } catch (PackageManager.NameNotFoundException e) { |
| resources = null; |
| } |
| if (resources != null) { |
| if (iconId != 0) { |
| return getFullResIcon(resources, iconId, user); |
| } |
| } |
| return getFullResDefaultActivityIcon(); |
| } |
| |
| public Drawable getFullResIcon(ResolveInfo info, UserHandle user) { |
| return getFullResIcon(info.activityInfo, user); |
| } |
| |
| public Drawable getFullResIcon(ActivityInfo info, UserHandle user) { |
| Resources resources; |
| try { |
| resources = mPackageManager.getResourcesForApplication( |
| info.applicationInfo); |
| } catch (PackageManager.NameNotFoundException e) { |
| resources = null; |
| } |
| if (resources != null) { |
| int iconId = info.getIconResource(); |
| if (iconId != 0) { |
| return getFullResIcon(resources, iconId, user); |
| } |
| } |
| return getFullResDefaultActivityIcon(); |
| } |
| |
| private Bitmap makeDefaultIcon() { |
| Drawable d = getFullResDefaultActivityIcon(); |
| Bitmap b = Bitmap.createBitmap(Math.max(d.getIntrinsicWidth(), 1), |
| Math.max(d.getIntrinsicHeight(), 1), |
| Bitmap.Config.ARGB_8888); |
| Canvas c = new Canvas(b); |
| d.setBounds(0, 0, b.getWidth(), b.getHeight()); |
| d.draw(c); |
| c.setBitmap(null); |
| return b; |
| } |
| |
| /** |
| * Remove any records for the supplied ComponentName. |
| */ |
| public void remove(ComponentName componentName, UserHandle user) { |
| synchronized (mCache) { |
| mCache.remove(new CacheKey(componentName, user)); |
| } |
| } |
| |
| /** |
| * Empty out the cache. |
| */ |
| public void flush() { |
| synchronized (mCache) { |
| mCache.clear(); |
| } |
| } |
| |
| /** |
| * Fill in "application" with the icon and label for "info." |
| */ |
| public void getTitleAndIcon(ApplicationInfo application, LauncherActivityInfo info, |
| HashMap<Object, CharSequence> labelCache) { |
| synchronized (mCache) { |
| CacheEntry entry = cacheLocked(application.componentName, info, labelCache, |
| info.getUser()); |
| |
| application.title = entry.title; |
| application.iconBitmap = entry.icon; |
| application.contentDescription = entry.contentDescription; |
| } |
| } |
| |
| public Bitmap getIcon(Intent intent, UserHandle user) { |
| synchronized (mCache) { |
| LauncherApps launcherApps = (LauncherApps) |
| mContext.getSystemService(Context.LAUNCHER_APPS_SERVICE); |
| final LauncherActivityInfo launcherActInfo = |
| launcherApps.resolveActivity(intent, user); |
| ComponentName component = intent.getComponent(); |
| |
| if (launcherActInfo == null || component == null) { |
| return mDefaultIcon; |
| } |
| |
| CacheEntry entry = cacheLocked(component, launcherActInfo, null, user); |
| return entry.icon; |
| } |
| } |
| |
| public Bitmap getIcon(ComponentName component, LauncherActivityInfo info, |
| HashMap<Object, CharSequence> labelCache) { |
| synchronized (mCache) { |
| if (info == null || component == null) { |
| return null; |
| } |
| |
| CacheEntry entry = cacheLocked(component, info, labelCache, info.getUser()); |
| return entry.icon; |
| } |
| } |
| |
| public boolean isDefaultIcon(Bitmap icon) { |
| return mDefaultIcon == icon; |
| } |
| |
| private CacheEntry cacheLocked(ComponentName componentName, LauncherActivityInfo info, |
| HashMap<Object, CharSequence> labelCache, UserHandle user) { |
| CacheKey cacheKey = new CacheKey(componentName, user); |
| CacheEntry entry = mCache.get(cacheKey); |
| if (entry == null) { |
| entry = new CacheEntry(); |
| |
| mCache.put(cacheKey, entry); |
| |
| ComponentName key = info.getComponentName(); |
| if (labelCache != null && labelCache.containsKey(key)) { |
| entry.title = labelCache.get(key).toString(); |
| } else { |
| entry.title = info.getLabel().toString(); |
| if (labelCache != null) { |
| labelCache.put(key, entry.title); |
| } |
| } |
| if (entry.title == null) { |
| entry.title = info.getComponentName().getShortClassName(); |
| } |
| entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user); |
| entry.icon = Utilities.createIconBitmap(info.getBadgedIcon(mIconDpi), mContext); |
| } |
| return entry; |
| } |
| } |