/* * 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 mCache = new HashMap(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 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 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 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; } }