blob: a2d98307ffb95d1477f68cf275b3609eae072c31 [file] [log] [blame]
Joe Onorato9c1289c2009-08-17 11:03:03 -04001/*
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
17package com.android.launcher2;
18
19import android.content.ComponentName;
20import android.content.ContentResolver;
21import android.content.ContentValues;
22import android.content.Intent;
23import android.content.Context;
24import android.content.pm.ActivityInfo;
25import android.content.pm.PackageManager;
26import android.content.pm.ResolveInfo;
27import android.content.res.Resources;
28import android.database.Cursor;
29import android.graphics.Bitmap;
30import android.graphics.BitmapFactory;
31import android.graphics.drawable.Drawable;
32import android.graphics.drawable.BitmapDrawable;
33import android.net.Uri;
34import android.util.Log;
35import android.os.Process;
36
37import java.lang.ref.WeakReference;
38import java.util.ArrayList;
39import java.util.HashMap;
40import java.util.List;
41
42/**
43 * Cache of application icons. Icons can be made from any thread.
44 */
45public class AppInfoCache {
46 private static final String TAG = "Launcher.AppInfoCache";
47
48 private static final int INITIAL_ICON_CACHE_CAPACITY = 50;
49
50 private static final HashMap<ComponentName, ApplicationInfo> sCache =
51 new HashMap<ComponentName, ApplicationInfo>(INITIAL_ICON_CACHE_CAPACITY);
52
53 /**
54 * no public constructor.
55 */
56 private AppInfoCache() {
57 }
58
59 /**
60 * For the given ResolveInfo, return an ApplicationInfo and cache the result for later.
61 */
62 public static ApplicationInfo cache(ResolveInfo info, Context context,
63 Utilities.BubbleText bubble) {
64 synchronized (sCache) {
65 ComponentName componentName = new ComponentName(
66 info.activityInfo.applicationInfo.packageName,
67 info.activityInfo.name);
68 ApplicationInfo application = sCache.get(componentName);
69
70 if (application == null) {
71 application = new ApplicationInfo();
72 application.container = ItemInfo.NO_ID;
73
74 updateTitleAndIcon(info, application, context, bubble);
75
76 application.setActivity(componentName,
77 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
78
79 sCache.put(componentName, application);
80 }
81
82 return application;
83 }
84 }
85
86 /**
87 * Update the entry in the in the cache with its new metadata.
88 */
Joe Onoratof0be2132009-11-24 19:34:29 -050089 public static void update(ResolveInfo info, ApplicationInfo applicationInfo, Context context,
90 Utilities.BubbleText bubble) {
Joe Onorato9c1289c2009-08-17 11:03:03 -040091 synchronized (sCache) {
Joe Onoratof0be2132009-11-24 19:34:29 -050092 updateTitleAndIcon(info, applicationInfo, context, bubble);
Joe Onorato9c1289c2009-08-17 11:03:03 -040093
94 ComponentName componentName = new ComponentName(
95 info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
96 sCache.put(componentName, applicationInfo);
97 }
98 }
99
100 /**
101 * Remove any records for the supplied ComponentName.
102 */
103 public static void remove(ComponentName componentName) {
104 synchronized (sCache) {
105 sCache.remove(componentName);
106 }
107 }
108
109 /**
110 * Empty out the cache.
111 */
112 public static void flush() {
113 synchronized (sCache) {
114 sCache.clear();
115 }
116 }
117
118 /**
119 * Get the icon for the supplied ApplicationInfo. If that activity already
120 * exists in the cache, use that.
121 */
122 public static Drawable getIconDrawable(PackageManager packageManager, ApplicationInfo info) {
123 final ResolveInfo resolveInfo = packageManager.resolveActivity(info.intent, 0);
124 if (resolveInfo == null) {
125 return null;
126 }
127
128 ComponentName componentName = new ComponentName(
129 resolveInfo.activityInfo.applicationInfo.packageName,
130 resolveInfo.activityInfo.name);
131 ApplicationInfo cached;
132 synchronized (sCache) {
133 cached = sCache.get(componentName);
Joe Onorato5162ea92009-09-03 09:39:42 -0700134 if (cached != null) {
135 if (cached.icon == null) {
136 cached.icon = resolveInfo.activityInfo.loadIcon(packageManager);
137 }
138 return cached.icon;
139 } else {
140 return resolveInfo.activityInfo.loadIcon(packageManager);
141 }
Joe Onorato9c1289c2009-08-17 11:03:03 -0400142 }
143 }
144
145 /**
146 * Go through the cache and disconnect any of the callbacks in the drawables or we
147 * leak the previous Home screen on orientation change.
148 */
149 public static void unbindDrawables() {
150 synchronized (sCache) {
151 for (ApplicationInfo appInfo: sCache.values()) {
Joe Onorato533e2722009-09-22 17:31:51 -0700152 if (appInfo.icon != null) {
153 appInfo.icon.setCallback(null);
154 }
Joe Onorato9c1289c2009-08-17 11:03:03 -0400155 }
156 }
157 }
158
159 /**
160 * Update the title and icon. Don't keep a reference to the context!
161 */
162 private static void updateTitleAndIcon(ResolveInfo info, ApplicationInfo application,
163 Context context, Utilities.BubbleText bubble) {
164 final PackageManager packageManager = context.getPackageManager();
165
166 application.title = info.loadLabel(packageManager);
167 if (application.title == null) {
168 application.title = info.activityInfo.name;
169 }
170
Joe Onorato6665c0f2009-09-02 15:27:24 -0700171 application.iconBitmap = Utilities.createAllAppsBitmap(
172 info.activityInfo.loadIcon(packageManager), context);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400173
174 application.titleBitmap = bubble.createTextBitmap(application.title.toString());
175 }
176}
177