| /* |
| * 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.content.ComponentName; |
| import android.content.ContentResolver; |
| import android.content.ContentValues; |
| import android.content.Intent; |
| import android.content.Context; |
| import android.content.pm.ActivityInfo; |
| import android.content.pm.PackageManager; |
| import android.content.pm.ResolveInfo; |
| import android.content.res.Resources; |
| import android.database.Cursor; |
| import android.graphics.Bitmap; |
| import android.graphics.BitmapFactory; |
| import android.graphics.drawable.Drawable; |
| import android.graphics.drawable.BitmapDrawable; |
| import android.net.Uri; |
| import android.util.Log; |
| import android.os.Process; |
| |
| import java.lang.ref.WeakReference; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| |
| /** |
| * Cache of application icons. Icons can be made from any thread. |
| */ |
| public class AppInfoCache { |
| private static final String TAG = "Launcher.AppInfoCache"; |
| |
| private static final int INITIAL_ICON_CACHE_CAPACITY = 50; |
| |
| private static final HashMap<ComponentName, ApplicationInfo> sCache = |
| new HashMap<ComponentName, ApplicationInfo>(INITIAL_ICON_CACHE_CAPACITY); |
| |
| /** |
| * no public constructor. |
| */ |
| private AppInfoCache() { |
| } |
| |
| /** |
| * For the given ResolveInfo, return an ApplicationInfo and cache the result for later. |
| */ |
| public static ApplicationInfo cache(ResolveInfo info, Context context, |
| Utilities.BubbleText bubble) { |
| synchronized (sCache) { |
| ComponentName componentName = new ComponentName( |
| info.activityInfo.applicationInfo.packageName, |
| info.activityInfo.name); |
| ApplicationInfo application = sCache.get(componentName); |
| |
| if (application == null) { |
| application = new ApplicationInfo(); |
| application.container = ItemInfo.NO_ID; |
| |
| updateTitleAndIcon(info, application, context, bubble); |
| |
| application.setActivity(componentName, |
| Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); |
| |
| sCache.put(componentName, application); |
| } |
| |
| return application; |
| } |
| } |
| |
| /** |
| * Update the entry in the in the cache with its new metadata. |
| */ |
| public static void update(ResolveInfo info, ApplicationInfo applicationInfo, Context context) { |
| synchronized (sCache) { |
| updateTitleAndIcon(info, applicationInfo, context, new Utilities.BubbleText(context)); |
| |
| ComponentName componentName = new ComponentName( |
| info.activityInfo.applicationInfo.packageName, info.activityInfo.name); |
| sCache.put(componentName, applicationInfo); |
| } |
| } |
| |
| /** |
| * Remove any records for the supplied ComponentName. |
| */ |
| public static void remove(ComponentName componentName) { |
| synchronized (sCache) { |
| sCache.remove(componentName); |
| } |
| } |
| |
| /** |
| * Empty out the cache. |
| */ |
| public static void flush() { |
| synchronized (sCache) { |
| sCache.clear(); |
| } |
| } |
| |
| /** |
| * Get the icon for the supplied ApplicationInfo. If that activity already |
| * exists in the cache, use that. |
| */ |
| public static Drawable getIconDrawable(PackageManager packageManager, ApplicationInfo info) { |
| final ResolveInfo resolveInfo = packageManager.resolveActivity(info.intent, 0); |
| if (resolveInfo == null) { |
| return null; |
| } |
| |
| ComponentName componentName = new ComponentName( |
| resolveInfo.activityInfo.applicationInfo.packageName, |
| resolveInfo.activityInfo.name); |
| ApplicationInfo cached; |
| synchronized (sCache) { |
| cached = sCache.get(componentName); |
| if (cached != null) { |
| if (cached.icon == null) { |
| cached.icon = resolveInfo.activityInfo.loadIcon(packageManager); |
| } |
| return cached.icon; |
| } else { |
| return resolveInfo.activityInfo.loadIcon(packageManager); |
| } |
| } |
| } |
| |
| /** |
| * Go through the cache and disconnect any of the callbacks in the drawables or we |
| * leak the previous Home screen on orientation change. |
| */ |
| public static void unbindDrawables() { |
| synchronized (sCache) { |
| for (ApplicationInfo appInfo: sCache.values()) { |
| if (appInfo.icon != null) { |
| appInfo.icon.setCallback(null); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Update the title and icon. Don't keep a reference to the context! |
| */ |
| private static void updateTitleAndIcon(ResolveInfo info, ApplicationInfo application, |
| Context context, Utilities.BubbleText bubble) { |
| final PackageManager packageManager = context.getPackageManager(); |
| |
| application.title = info.loadLabel(packageManager); |
| if (application.title == null) { |
| application.title = info.activityInfo.name; |
| } |
| |
| application.iconBitmap = Utilities.createAllAppsBitmap( |
| info.activityInfo.loadIcon(packageManager), context); |
| |
| application.titleBitmap = bubble.createTextBitmap(application.title.toString()); |
| } |
| } |
| |