10589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato/* 20589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * Copyright (C) 2008 The Android Open Source Project 30589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * 40589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 50589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * you may not use this file except in compliance with the License. 60589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * You may obtain a copy of the License at 70589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * 80589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * http://www.apache.org/licenses/LICENSE-2.0 90589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * 100589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * Unless required by applicable law or agreed to in writing, software 110589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 120589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * See the License for the specific language governing permissions and 140589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * limitations under the License. 150589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato */ 160589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 17325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerpackage com.android.launcher3; 180589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 190589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport android.content.ComponentName; 204fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyalimport android.content.ContentValues; 21d83f5f4db328fbd152491bbf9fa13abc94bd6f25Winson Chungimport android.content.Context; 220589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport android.content.Intent; 23dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurkaimport android.content.pm.ActivityInfo; 240fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyalimport android.content.pm.ApplicationInfo; 254fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyalimport android.content.pm.PackageInfo; 260589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport android.content.pm.PackageManager; 270fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyalimport android.content.pm.PackageManager.NameNotFoundException; 28c9a961952d1a057029874f8426b90181f6876034Michael Jurkaimport android.content.res.Resources; 294fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyalimport android.database.Cursor; 304fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyalimport android.database.sqlite.SQLiteDatabase; 316f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyalimport android.database.sqlite.SQLiteException; 320589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport android.graphics.Bitmap; 3334b6527cefd36fbd5da78464ce9771e379158552Sunny Goyalimport android.graphics.BitmapFactory; 34a28fd3fa7c82947d847c05ed11905f556b8dcfa2Romain Guyimport android.graphics.Canvas; 35360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyalimport android.graphics.Color; 36360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyalimport android.graphics.Paint; 37360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyalimport android.graphics.Rect; 380589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport android.graphics.drawable.Drawable; 3934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyalimport android.os.Handler; 4075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyalimport android.os.SystemClock; 41349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyalimport android.text.TextUtils; 426d0dde01f307051ee1849481c989d9e87774b894Chris Wrenimport android.util.Log; 436d0dde01f307051ee1849481c989d9e87774b894Chris Wren 44ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.LauncherActivityInfoCompat; 45ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.LauncherAppsCompat; 46ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.UserHandleCompat; 47ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.UserManagerCompat; 48d896ee43cd9195a2a2742324733b036ee72875bbSunny Goyalimport com.android.launcher3.config.FeatureFlags; 492bd3d7d1cb5e4d8d826982d11b456739fed6b817Hyunyoung Songimport com.android.launcher3.model.PackageItemInfo; 50b4cd42a1df69ec887d0c66e8fe6fe1f27ebbf9bcSunny Goyalimport com.android.launcher3.util.ComponentKey; 516f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyalimport com.android.launcher3.util.SQLiteCacheHelper; 52091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 53ed13187a745866483139e2878037e1f8427ce567Kenny Guy 544e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyalimport java.util.Collections; 550589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport java.util.HashMap; 566d0dde01f307051ee1849481c989d9e87774b894Chris Wrenimport java.util.HashSet; 574fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyalimport java.util.List; 580c9a354c9732585620569bafaec0973977baf614Sunny Goyalimport java.util.Locale; 594e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyalimport java.util.Set; 609ff980833d392244586ead8c27bbbba114e11ebbSunny Goyalimport java.util.Stack; 610589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 620589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato/** 630589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * Cache of application icons. Icons can be made from any thread. 640589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato */ 650589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratopublic class IconCache { 660fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal 670589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private static final String TAG = "Launcher.IconCache"; 680589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 690589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private static final int INITIAL_ICON_CACHE_CAPACITY = 50; 706d0dde01f307051ee1849481c989d9e87774b894Chris Wren 710fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal // Empty class name is used for storing package default entry. 720fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal private static final String EMPTY_CLASS_NAME = "."; 730fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal 74bbef77dbdf469c17f3be0817d0d09983a81b6123Sunny Goyal private static final boolean DEBUG = false; 750589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 76360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal private static final int LOW_RES_SCALE_FACTOR = 5; 7734b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 78316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk static final Object ICON_UPDATE_TOKEN = new Object(); 7975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal 80091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk static class CacheEntry { 810589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato public Bitmap icon; 82cdefc631f8b4b3e56ea3bd238d46d0bc9e28eabeWinson Chung public CharSequence title = ""; 83cdefc631f8b4b3e56ea3bd238d46d0bc9e28eabeWinson Chung public CharSequence contentDescription = ""; 8434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal public boolean isLowResIcon; 850589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 860589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 878758ea050a9202e9733520898dda5d290644839eSunny Goyal private final HashMap<UserHandleCompat, Bitmap> mDefaultIcons = new HashMap<>(); 88316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor(); 898758ea050a9202e9733520898dda5d290644839eSunny Goyal 90cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private final Context mContext; 91a28fd3fa7c82947d847c05ed11905f556b8dcfa2Romain Guy private final PackageManager mPackageManager; 92316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk final UserManagerCompat mUserManager; 93ed13187a745866483139e2878037e1f8427ce567Kenny Guy private final LauncherAppsCompat mLauncherApps; 94b4cd42a1df69ec887d0c66e8fe6fe1f27ebbf9bcSunny Goyal private final HashMap<ComponentKey, CacheEntry> mCache = 95b4cd42a1df69ec887d0c66e8fe6fe1f27ebbf9bcSunny Goyal new HashMap<ComponentKey, CacheEntry>(INITIAL_ICON_CACHE_CAPACITY); 964fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal private final int mIconDpi; 97316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk final IconDB mIconDb; 980589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 99316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk final Handler mWorkerHandler; 10034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 101360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal // The background color used for activity icons. Since these icons are displayed in all-apps 102360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal // and folders, this would be same as the light quantum panel background. This color 103360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal // is used to convert icons to RGB_565. 104360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal private final int mActivityBgColor; 105360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal // The background color used for package icons. These are displayed in widget tray, which 106360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal // has a dark quantum panel background. 107360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal private final int mPackageBgColor; 108360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal private final BitmapFactory.Options mLowResOptions; 109360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal 110360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal private String mSystemState; 111360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal private Bitmap mLowResBitmap; 112360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal private Canvas mLowResCanvas; 113360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal private Paint mLowResPaint; 114360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal 1152e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen public IconCache(Context context, InvariantDeviceProfile inv) { 1160589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mContext = context; 1170589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mPackageManager = context.getPackageManager(); 118ed13187a745866483139e2878037e1f8427ce567Kenny Guy mUserManager = UserManagerCompat.getInstance(mContext); 119ed13187a745866483139e2878037e1f8427ce567Kenny Guy mLauncherApps = LauncherAppsCompat.getInstance(mContext); 12053d7ee4285842732517edcccbdcaa92dccb1e107Sunny Goyal mIconDpi = inv.fillResIconDpi; 12116affbdf30b51ada08391d1ece721dca61ba3deaSunny Goyal mIconDb = new IconDB(context, inv.iconBitmapSize); 12234b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 123756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal mWorkerHandler = new Handler(LauncherModel.getWorkerLooper()); 124360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal 125360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal mActivityBgColor = context.getResources().getColor(R.color.quantum_panel_bg_color); 126360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal mPackageBgColor = context.getResources().getColor(R.color.quantum_panel_bg_color_dark); 127360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal mLowResOptions = new BitmapFactory.Options(); 128360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal // Always prefer RGB_565 config for low res. If the bitmap has transparency, it will 129360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal // automatically be loaded as ALPHA_8888. 130360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal mLowResOptions.inPreferredConfig = Bitmap.Config.RGB_565; 131360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal updateSystemStateString(); 132a28fd3fa7c82947d847c05ed11905f556b8dcfa2Romain Guy } 133a28fd3fa7c82947d847c05ed11905f556b8dcfa2Romain Guy 1344fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal private Drawable getFullResDefaultActivityIcon() { 135736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal return getFullResIcon(Resources.getSystem(), android.R.mipmap.sym_def_app_icon); 136c9a961952d1a057029874f8426b90181f6876034Michael Jurka } 137c9a961952d1a057029874f8426b90181f6876034Michael Jurka 138b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal private Drawable getFullResIcon(Resources resources, int iconId) { 139721d9725ad69b60ced5812ffce3afd1557f1180bMichael Jurka Drawable d; 1404842ed029c5861b1696a9c69caa45f9a6e6e5f7eMichael Jurka try { 141721d9725ad69b60ced5812ffce3afd1557f1180bMichael Jurka d = resources.getDrawableForDensity(iconId, mIconDpi); 1424842ed029c5861b1696a9c69caa45f9a6e6e5f7eMichael Jurka } catch (Resources.NotFoundException e) { 143721d9725ad69b60ced5812ffce3afd1557f1180bMichael Jurka d = null; 1444842ed029c5861b1696a9c69caa45f9a6e6e5f7eMichael Jurka } 145721d9725ad69b60ced5812ffce3afd1557f1180bMichael Jurka 146721d9725ad69b60ced5812ffce3afd1557f1180bMichael Jurka return (d != null) ? d : getFullResDefaultActivityIcon(); 147c9a961952d1a057029874f8426b90181f6876034Michael Jurka } 148c9a961952d1a057029874f8426b90181f6876034Michael Jurka 1490b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung public Drawable getFullResIcon(String packageName, int iconId) { 150c9a961952d1a057029874f8426b90181f6876034Michael Jurka Resources resources; 151c9a961952d1a057029874f8426b90181f6876034Michael Jurka try { 1520b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung resources = mPackageManager.getResourcesForApplication(packageName); 1530b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung } catch (PackageManager.NameNotFoundException e) { 1540b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung resources = null; 1550b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung } 1560b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung if (resources != null) { 1570b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung if (iconId != 0) { 1580b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung return getFullResIcon(resources, iconId); 1590b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung } 1600b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung } 1610b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung return getFullResDefaultActivityIcon(); 1620b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung } 1630b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung 164dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka public Drawable getFullResIcon(ActivityInfo info) { 1650b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung Resources resources; 1660b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung try { 1670b9fcf5686a24b237a1a52c13ef60ef776561b91Winson Chung resources = mPackageManager.getResourcesForApplication( 168dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka info.applicationInfo); 169c9a961952d1a057029874f8426b90181f6876034Michael Jurka } catch (PackageManager.NameNotFoundException e) { 170c9a961952d1a057029874f8426b90181f6876034Michael Jurka resources = null; 171c9a961952d1a057029874f8426b90181f6876034Michael Jurka } 172c9a961952d1a057029874f8426b90181f6876034Michael Jurka if (resources != null) { 173dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka int iconId = info.getIconResource(); 174c9a961952d1a057029874f8426b90181f6876034Michael Jurka if (iconId != 0) { 175c9a961952d1a057029874f8426b90181f6876034Michael Jurka return getFullResIcon(resources, iconId); 176c9a961952d1a057029874f8426b90181f6876034Michael Jurka } 177c9a961952d1a057029874f8426b90181f6876034Michael Jurka } 1786d0dde01f307051ee1849481c989d9e87774b894Chris Wren 179c9a961952d1a057029874f8426b90181f6876034Michael Jurka return getFullResDefaultActivityIcon(); 180c9a961952d1a057029874f8426b90181f6876034Michael Jurka } 181c9a961952d1a057029874f8426b90181f6876034Michael Jurka 182ed13187a745866483139e2878037e1f8427ce567Kenny Guy private Bitmap makeDefaultIcon(UserHandleCompat user) { 183ed13187a745866483139e2878037e1f8427ce567Kenny Guy Drawable unbadged = getFullResDefaultActivityIcon(); 1840b621156f336b40418120948aa93933dd26e548dSunny Goyal return Utilities.createBadgedIconBitmap(unbadged, user, mContext); 1850589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 1860589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 1870589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato /** 1880589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * Remove any records for the supplied ComponentName. 1890589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato */ 190736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal public synchronized void remove(ComponentName componentName, UserHandleCompat user) { 191b4cd42a1df69ec887d0c66e8fe6fe1f27ebbf9bcSunny Goyal mCache.remove(new ComponentKey(componentName, user)); 1920589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 1930589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 1940589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato /** 1954fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal * Remove any records for the supplied package name from memory. 1966d0dde01f307051ee1849481c989d9e87774b894Chris Wren */ 1974fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal private void removeFromMemCacheLocked(String packageName, UserHandleCompat user) { 198b4cd42a1df69ec887d0c66e8fe6fe1f27ebbf9bcSunny Goyal HashSet<ComponentKey> forDeletion = new HashSet<ComponentKey>(); 199b4cd42a1df69ec887d0c66e8fe6fe1f27ebbf9bcSunny Goyal for (ComponentKey key: mCache.keySet()) { 200ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (key.componentName.getPackageName().equals(packageName) 201ed13187a745866483139e2878037e1f8427ce567Kenny Guy && key.user.equals(user)) { 202ed13187a745866483139e2878037e1f8427ce567Kenny Guy forDeletion.add(key); 2036d0dde01f307051ee1849481c989d9e87774b894Chris Wren } 2046d0dde01f307051ee1849481c989d9e87774b894Chris Wren } 205b4cd42a1df69ec887d0c66e8fe6fe1f27ebbf9bcSunny Goyal for (ComponentKey condemned: forDeletion) { 206ed13187a745866483139e2878037e1f8427ce567Kenny Guy mCache.remove(condemned); 2076d0dde01f307051ee1849481c989d9e87774b894Chris Wren } 2086d0dde01f307051ee1849481c989d9e87774b894Chris Wren } 2096d0dde01f307051ee1849481c989d9e87774b894Chris Wren 2106d0dde01f307051ee1849481c989d9e87774b894Chris Wren /** 2114fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal * Updates the entries related to the given package in memory and persistent DB. 2124fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal */ 2134fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal public synchronized void updateIconsForPkg(String packageName, UserHandleCompat user) { 2144fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal removeIconsForPkg(packageName, user); 2154fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal try { 2164fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal PackageInfo info = mPackageManager.getPackageInfo(packageName, 2174fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal PackageManager.GET_UNINSTALLED_PACKAGES); 2184fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal long userSerial = mUserManager.getSerialNumberForUser(user); 2194fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal for (LauncherActivityInfoCompat app : mLauncherApps.getActivityList(packageName, user)) { 220d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal addIconToDBAndMemCache(app, info, userSerial); 2214fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 2224fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } catch (NameNotFoundException e) { 2234fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal Log.d(TAG, "Package not found", e); 2244fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal return; 2254fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 2264fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 2274fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 2284fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal /** 2294fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal * Removes the entries related to the given package in memory and persistent DB. 2304fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal */ 2314fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal public synchronized void removeIconsForPkg(String packageName, UserHandleCompat user) { 2324fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal removeFromMemCacheLocked(packageName, user); 2334fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal long userSerial = mUserManager.getSerialNumberForUser(user); 2346f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal mIconDb.delete( 2354fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal IconDB.COLUMN_COMPONENT + " LIKE ? AND " + IconDB.COLUMN_USER + " = ?", 2366f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal new String[]{packageName + "/%", Long.toString(userSerial)}); 2374fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 2384fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 2394e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal public void updateDbIcons(Set<String> ignorePackagesForMainUser) { 24075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal // Remove all active icon update tasks. 24175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal mWorkerHandler.removeCallbacksAndMessages(ICON_UPDATE_TOKEN); 24275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal 243360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal updateSystemStateString(); 24475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal for (UserHandleCompat user : mUserManager.getUserProfiles()) { 24575b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal // Query for the set of apps 24675b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal final List<LauncherActivityInfoCompat> apps = mLauncherApps.getActivityList(null, user); 24775b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal // Fail if we don't have any apps 24875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal // TODO: Fix this. Only fail for the current user. 24975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (apps == null || apps.isEmpty()) { 25075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal return; 25175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 25275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal 25375b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal // Update icon cache. This happens in segments and {@link #onPackageIconsUpdated} 25475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal // is called by the icon cache when the job is complete. 2554e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal updateDBIcons(user, apps, UserHandleCompat.myUserHandle().equals(user) 2564e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal ? ignorePackagesForMainUser : Collections.<String>emptySet()); 25775b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 25875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 25975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal 2604fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal /** 2614fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal * Updates the persistent DB, such that only entries corresponding to {@param apps} remain in 2624fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal * the DB and are updated. 2634fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal * @return The set of packages for which icons have updated. 2644fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal */ 2654e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal private void updateDBIcons(UserHandleCompat user, List<LauncherActivityInfoCompat> apps, 2664e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal Set<String> ignorePackages) { 2674fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal long userSerial = mUserManager.getSerialNumberForUser(user); 2684fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal PackageManager pm = mContext.getPackageManager(); 2694fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal HashMap<String, PackageInfo> pkgInfoMap = new HashMap<String, PackageInfo>(); 2704fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal for (PackageInfo info : pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES)) { 2714fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal pkgInfoMap.put(info.packageName, info); 2724fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 2734fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 2744fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal HashMap<ComponentName, LauncherActivityInfoCompat> componentMap = new HashMap<>(); 2754fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal for (LauncherActivityInfoCompat app : apps) { 2764fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal componentMap.put(app.getComponentName(), app); 2774fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 2784fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 2794fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal HashSet<Integer> itemsToRemove = new HashSet<Integer>(); 28075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Stack<LauncherActivityInfoCompat> appsToUpdate = new Stack<>(); 2814fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 2826f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal Cursor c = null; 2836f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal try { 2846f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal c = mIconDb.query( 2856f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal new String[]{IconDB.COLUMN_ROWID, IconDB.COLUMN_COMPONENT, 2866f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal IconDB.COLUMN_LAST_UPDATED, IconDB.COLUMN_VERSION, 2876f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal IconDB.COLUMN_SYSTEM_STATE}, 2886f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal IconDB.COLUMN_USER + " = ? ", 2896f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal new String[]{Long.toString(userSerial)}); 2906f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal 2916f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal final int indexComponent = c.getColumnIndex(IconDB.COLUMN_COMPONENT); 2926f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal final int indexLastUpdate = c.getColumnIndex(IconDB.COLUMN_LAST_UPDATED); 2936f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal final int indexVersion = c.getColumnIndex(IconDB.COLUMN_VERSION); 2946f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal final int rowIndex = c.getColumnIndex(IconDB.COLUMN_ROWID); 2956f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal final int systemStateIndex = c.getColumnIndex(IconDB.COLUMN_SYSTEM_STATE); 2966f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal 2976f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal while (c.moveToNext()) { 2986f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal String cn = c.getString(indexComponent); 2996f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal ComponentName component = ComponentName.unflattenFromString(cn); 3006f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal PackageInfo info = pkgInfoMap.get(component.getPackageName()); 3016f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal if (info == null) { 3026f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal if (!ignorePackages.contains(component.getPackageName())) { 3036f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal remove(component, user); 3046f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal itemsToRemove.add(c.getInt(rowIndex)); 3056f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal } 3066f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal continue; 3076f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal } 3086f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal if ((info.applicationInfo.flags & ApplicationInfo.FLAG_IS_DATA_ONLY) != 0) { 3096f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal // Application is not present 3106f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal continue; 3116f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal } 3126f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal 3136f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal long updateTime = c.getLong(indexLastUpdate); 3146f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal int version = c.getInt(indexVersion); 3156f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal LauncherActivityInfoCompat app = componentMap.remove(component); 3166f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal if (version == info.versionCode && updateTime == info.lastUpdateTime && 3176f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal TextUtils.equals(mSystemState, c.getString(systemStateIndex))) { 3186f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal continue; 3196f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal } 3206f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal if (app == null) { 3214e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal remove(component, user); 3224e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal itemsToRemove.add(c.getInt(rowIndex)); 3236f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal } else { 3246f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal appsToUpdate.add(app); 3254e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 3264fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 3276f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal } catch (SQLiteException e) { 3286f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal Log.d(TAG, "Error reading icon cache", e); 3296f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal // Continue updating whatever we have read so far 3306f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal } finally { 3316f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal if (c != null) { 3326f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal c.close(); 3334fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 3344fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 3354fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal if (!itemsToRemove.isEmpty()) { 3366f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal mIconDb.delete( 3376f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal Utilities.createDbSelectionQuery(IconDB.COLUMN_ROWID, itemsToRemove), null); 3384fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 3394fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 3404fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal // Insert remaining apps. 34175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (!componentMap.isEmpty() || !appsToUpdate.isEmpty()) { 34275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Stack<LauncherActivityInfoCompat> appsToAdd = new Stack<>(); 34375b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal appsToAdd.addAll(componentMap.values()); 34475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal new SerializedIconUpdateTask(userSerial, pkgInfoMap, 34575b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal appsToAdd, appsToUpdate).scheduleNext(); 3464fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 3474fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 3484fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 349316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk void addIconToDBAndMemCache(LauncherActivityInfoCompat app, PackageInfo info, 350d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal long userSerial) { 3519ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal // Reuse the existing entry if it already exists in the DB. This ensures that we do not 3529ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal // create bitmap if it was already created during loader. 3539ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal ContentValues values = updateCacheAndGetContentValues(app, false); 354d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal addIconToDB(values, app.getComponentName(), info, userSerial); 355d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal } 356d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal 357d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal /** 358d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal * Updates {@param values} to contain versoning information and adds it to the DB. 359d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal * @param values {@link ContentValues} containing icon & title 360d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal */ 361d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal private void addIconToDB(ContentValues values, ComponentName key, 362d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal PackageInfo info, long userSerial) { 363d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal values.put(IconDB.COLUMN_COMPONENT, key.flattenToString()); 3644fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal values.put(IconDB.COLUMN_USER, userSerial); 3654fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal values.put(IconDB.COLUMN_LAST_UPDATED, info.lastUpdateTime); 3664fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal values.put(IconDB.COLUMN_VERSION, info.versionCode); 3676f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal mIconDb.insertOrReplace(values); 3684fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 3694fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 370316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk ContentValues updateCacheAndGetContentValues(LauncherActivityInfoCompat app, 3719ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal boolean replaceExisting) { 3729ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal final ComponentKey key = new ComponentKey(app.getComponentName(), app.getUser()); 3739ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal CacheEntry entry = null; 3749ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal if (!replaceExisting) { 3759ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal entry = mCache.get(key); 3769ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal // We can't reuse the entry if the high-res icon is not present. 3779ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal if (entry == null || entry.isLowResIcon || entry.icon == null) { 3789ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal entry = null; 3799ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal } 3809ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal } 3819ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal if (entry == null) { 3829ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal entry = new CacheEntry(); 3830b621156f336b40418120948aa93933dd26e548dSunny Goyal entry.icon = Utilities.createBadgedIconBitmap( 3840b621156f336b40418120948aa93933dd26e548dSunny Goyal app.getIcon(mIconDpi), app.getUser(), mContext); 3859ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal } 3864fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal entry.title = app.getLabel(); 3874fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, app.getUser()); 388b4cd42a1df69ec887d0c66e8fe6fe1f27ebbf9bcSunny Goyal mCache.put(new ComponentKey(app.getComponentName(), app.getUser()), entry); 3894fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 390360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal return newContentValues(entry.icon, entry.title.toString(), mActivityBgColor); 3914fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 3924fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 3934fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal /** 39434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal * Fetches high-res icon for the provided ItemInfo and updates the caller when done. 39534b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal * @return a request ID that can be used to cancel the request. 3960589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato */ 39734b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal public IconLoadRequest updateIconInBackground(final BubbleTextView caller, final ItemInfo info) { 39834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal Runnable request = new Runnable() { 39934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 40034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal @Override 40134b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal public void run() { 40234b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal if (info instanceof AppInfo) { 40334b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal getTitleAndIcon((AppInfo) info, null, false); 40434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } else if (info instanceof ShortcutInfo) { 40534b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal ShortcutInfo st = (ShortcutInfo) info; 40634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal getTitleAndIcon(st, 40734b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal st.promisedIntent != null ? st.promisedIntent : st.intent, 40834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal st.user, false); 4090e08f166fafd5e2a0d32e27ea510516e3f762221Sunny Goyal } else if (info instanceof PackageItemInfo) { 4100e08f166fafd5e2a0d32e27ea510516e3f762221Sunny Goyal PackageItemInfo pti = (PackageItemInfo) info; 4110e08f166fafd5e2a0d32e27ea510516e3f762221Sunny Goyal getTitleAndIconForApp(pti.packageName, pti.user, false, pti); 41234b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 4138758ea050a9202e9733520898dda5d290644839eSunny Goyal mMainThreadExecutor.execute(new Runnable() { 41434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 41534b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal @Override 41634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal public void run() { 41734b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal caller.reapplyItemInfo(info); 41834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 41934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal }); 42034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 42134b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal }; 42234b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal mWorkerHandler.post(request); 42334b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal return new IconLoadRequest(request, mWorkerHandler); 42434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 4250589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 426756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal private Bitmap getNonNullIcon(CacheEntry entry, UserHandleCompat user) { 427756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal return entry.icon == null ? getDefaultIcon(user) : entry.icon; 428756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 429756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 43034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal /** 43134b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal * Fill in "application" with the icon and label for "info." 43234b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal */ 43334b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal public synchronized void getTitleAndIcon(AppInfo application, 43434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal LauncherActivityInfoCompat info, boolean useLowResIcon) { 435756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal UserHandleCompat user = info == null ? application.user : info.getUser(); 436756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal CacheEntry entry = cacheLocked(application.componentName, info, user, 43734b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal false, useLowResIcon); 43882b016cb56540fe26213e817dd0dd668099c8e20Winson Chung application.title = Utilities.trim(entry.title); 439756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal application.iconBitmap = getNonNullIcon(entry, user); 440736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal application.contentDescription = entry.contentDescription; 44134b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal application.usingLowResIcon = entry.isLowResIcon; 4426d0dde01f307051ee1849481c989d9e87774b894Chris Wren } 4436d0dde01f307051ee1849481c989d9e87774b894Chris Wren 44434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal /** 44577919b93b98f5afa1b39546861197d6065847224Sunny Goyal * Updates {@param application} only if a valid entry is found. 44677919b93b98f5afa1b39546861197d6065847224Sunny Goyal */ 44777919b93b98f5afa1b39546861197d6065847224Sunny Goyal public synchronized void updateTitleAndIcon(AppInfo application) { 44877919b93b98f5afa1b39546861197d6065847224Sunny Goyal CacheEntry entry = cacheLocked(application.componentName, null, application.user, 44977919b93b98f5afa1b39546861197d6065847224Sunny Goyal false, application.usingLowResIcon); 45077919b93b98f5afa1b39546861197d6065847224Sunny Goyal if (entry.icon != null && !isDefaultIcon(entry.icon, application.user)) { 45182b016cb56540fe26213e817dd0dd668099c8e20Winson Chung application.title = Utilities.trim(entry.title); 45277919b93b98f5afa1b39546861197d6065847224Sunny Goyal application.iconBitmap = entry.icon; 45377919b93b98f5afa1b39546861197d6065847224Sunny Goyal application.contentDescription = entry.contentDescription; 45477919b93b98f5afa1b39546861197d6065847224Sunny Goyal application.usingLowResIcon = entry.isLowResIcon; 45577919b93b98f5afa1b39546861197d6065847224Sunny Goyal } 45677919b93b98f5afa1b39546861197d6065847224Sunny Goyal } 45777919b93b98f5afa1b39546861197d6065847224Sunny Goyal 45877919b93b98f5afa1b39546861197d6065847224Sunny Goyal /** 45934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal * Returns a high res icon for the given intent and user 46034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal */ 461736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal public synchronized Bitmap getIcon(Intent intent, UserHandleCompat user) { 462736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal ComponentName component = intent.getComponent(); 463736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal // null info means not installed, but if we have a component from the intent then 464736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal // we should still look in the cache for restored app icons. 465736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal if (component == null) { 466736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal return getDefaultIcon(user); 467fad1fb5ed46473af0a6da4324e9e3fa45bd9f6e8Joe Onorato } 468736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal 469736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal LauncherActivityInfoCompat launcherActInfo = mLauncherApps.resolveActivity(intent, user); 47009d70195d7398f467f7efc5e0ed320b066865c76Sunny Goyal CacheEntry entry = cacheLocked(component, launcherActInfo, user, true, false /* useLowRes */); 471736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal return entry.icon; 4720589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 4730589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 474349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal /** 4754fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal * Fill in {@param shortcutInfo} with the icon and label for {@param intent}. If the 4764fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal * corresponding activity is not found, it reverts to the package icon. 477349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal */ 478736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal public synchronized void getTitleAndIcon(ShortcutInfo shortcutInfo, Intent intent, 47934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal UserHandleCompat user, boolean useLowResIcon) { 480736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal ComponentName component = intent.getComponent(); 481736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal // null info means not installed, but if we have a component from the intent then 482736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal // we should still look in the cache for restored app icons. 483736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal if (component == null) { 484736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal shortcutInfo.setIcon(getDefaultIcon(user)); 485736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal shortcutInfo.title = ""; 486736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal shortcutInfo.usingFallbackIcon = true; 48734b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal shortcutInfo.usingLowResIcon = false; 488736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal } else { 4894fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal LauncherActivityInfoCompat info = mLauncherApps.resolveActivity(intent, user); 49034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal getTitleAndIcon(shortcutInfo, component, info, user, true, useLowResIcon); 491349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 492349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 493349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 4944fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal /** 4954fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal * Fill in {@param shortcutInfo} with the icon and label for {@param info} 4964fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal */ 4974fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal public synchronized void getTitleAndIcon( 4984fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal ShortcutInfo shortcutInfo, ComponentName component, LauncherActivityInfoCompat info, 49934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal UserHandleCompat user, boolean usePkgIcon, boolean useLowResIcon) { 50034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal CacheEntry entry = cacheLocked(component, info, user, usePkgIcon, useLowResIcon); 501756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal shortcutInfo.setIcon(getNonNullIcon(entry, user)); 50282b016cb56540fe26213e817dd0dd668099c8e20Winson Chung shortcutInfo.title = Utilities.trim(entry.title); 5034fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal shortcutInfo.usingFallbackIcon = isDefaultIcon(entry.icon, user); 50434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal shortcutInfo.usingLowResIcon = entry.isLowResIcon; 5054fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 506349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 507d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal /** 508d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal * Fill in {@param appInfo} with the icon and label for {@param packageName} 509d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal */ 510d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal public synchronized void getTitleAndIconForApp( 5113f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song String packageName, UserHandleCompat user, boolean useLowResIcon, 5123f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song PackageItemInfo infoOut) { 513d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal CacheEntry entry = getEntryForPackageLocked(packageName, user, useLowResIcon); 514756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal infoOut.iconBitmap = getNonNullIcon(entry, user); 51582b016cb56540fe26213e817dd0dd668099c8e20Winson Chung infoOut.title = Utilities.trim(entry.title); 5163f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song infoOut.usingLowResIcon = entry.isLowResIcon; 5173f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song infoOut.contentDescription = entry.contentDescription; 518d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal } 519d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal 520736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal public synchronized Bitmap getDefaultIcon(UserHandleCompat user) { 521ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (!mDefaultIcons.containsKey(user)) { 522ed13187a745866483139e2878037e1f8427ce567Kenny Guy mDefaultIcons.put(user, makeDefaultIcon(user)); 523ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 524ed13187a745866483139e2878037e1f8427ce567Kenny Guy return mDefaultIcons.get(user); 525ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 526ed13187a745866483139e2878037e1f8427ce567Kenny Guy 527ed13187a745866483139e2878037e1f8427ce567Kenny Guy public boolean isDefaultIcon(Bitmap icon, UserHandleCompat user) { 528ed13187a745866483139e2878037e1f8427ce567Kenny Guy return mDefaultIcons.get(user) == icon; 529ddc9c1fb1ab426772add520d277ea9c2cd674094Joe Onorato } 530ddc9c1fb1ab426772add520d277ea9c2cd674094Joe Onorato 531736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal /** 532736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal * Retrieves the entry from the cache. If the entry is not present, it creates a new entry. 533736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal * This method is not thread safe, it must be called from a synchronized method. 534736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal */ 535ed13187a745866483139e2878037e1f8427ce567Kenny Guy private CacheEntry cacheLocked(ComponentName componentName, LauncherActivityInfoCompat info, 53634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal UserHandleCompat user, boolean usePackageIcon, boolean useLowResIcon) { 537b4cd42a1df69ec887d0c66e8fe6fe1f27ebbf9bcSunny Goyal ComponentKey cacheKey = new ComponentKey(componentName, user); 538ed13187a745866483139e2878037e1f8427ce567Kenny Guy CacheEntry entry = mCache.get(cacheKey); 53934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal if (entry == null || (entry.isLowResIcon && !useLowResIcon)) { 5400589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato entry = new CacheEntry(); 541ed13187a745866483139e2878037e1f8427ce567Kenny Guy mCache.put(cacheKey, entry); 54284f6a8d613cef3227afa508c77221959dcf2f2d7Joe Onorato 5434fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal // Check the DB first. 54453f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal if (!getEntryFromDB(cacheKey, entry, useLowResIcon)) { 5454fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal if (info != null) { 5460b621156f336b40418120948aa93933dd26e548dSunny Goyal entry.icon = Utilities.createBadgedIconBitmap( 5470b621156f336b40418120948aa93933dd26e548dSunny Goyal info.getIcon(mIconDpi), info.getUser(), mContext); 5486d0dde01f307051ee1849481c989d9e87774b894Chris Wren } else { 5490fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal if (usePackageIcon) { 550d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal CacheEntry packageEntry = getEntryForPackageLocked( 551d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal componentName.getPackageName(), user, false); 552349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (packageEntry != null) { 5530fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal if (DEBUG) Log.d(TAG, "using package default icon for " + 5540fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal componentName.toShortString()); 5550fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal entry.icon = packageEntry.icon; 556349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal entry.title = packageEntry.title; 5574fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal entry.contentDescription = packageEntry.contentDescription; 5580fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal } 5590fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal } 5600fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal if (entry.icon == null) { 5610fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal if (DEBUG) Log.d(TAG, "using default icon for " + 5620fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal componentName.toShortString()); 5630fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal entry.icon = getDefaultIcon(user); 5640fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal } 565c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 566c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 5674fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 5684fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal if (TextUtils.isEmpty(entry.title) && info != null) { 56982b016cb56540fe26213e817dd0dd668099c8e20Winson Chung entry.title = info.getLabel(); 5704fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user); 5714fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 5720589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 5730589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return entry; 5740589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 5754e1cd23a51f1d83c1fe5d3eed536641087671db7Daniel Sandler 5760fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal /** 577349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal * Adds a default package entry in the cache. This entry is not persisted and will be removed 578349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal * when the cache is flushed. 579349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal */ 580736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal public synchronized void cachePackageInstallInfo(String packageName, UserHandleCompat user, 581349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal Bitmap icon, CharSequence title) { 5824fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal removeFromMemCacheLocked(packageName, user); 583a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal 58453f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal ComponentKey cacheKey = getPackageKey(packageName, user); 58553f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal CacheEntry entry = mCache.get(cacheKey); 58653f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal 58753f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal // For icon caching, do not go through DB. Just update the in-memory entry. 58853f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal if (entry == null) { 58953f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal entry = new CacheEntry(); 59053f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal mCache.put(cacheKey, entry); 59153f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal } 592349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (!TextUtils.isEmpty(title)) { 593349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal entry.title = title; 594349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 595349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (icon != null) { 5962fce90c38a79d318e96a28107dea287e42509861Sunny Goyal entry.icon = Utilities.createIconBitmap(icon, mContext); 597349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 598349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 599349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 60053f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal private static ComponentKey getPackageKey(String packageName, UserHandleCompat user) { 60153f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal ComponentName cn = new ComponentName(packageName, packageName + EMPTY_CLASS_NAME); 60253f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal return new ComponentKey(cn, user); 60353f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal } 60453f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal 605349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal /** 6060fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal * Gets an entry for the package, which can be used as a fallback entry for various components. 607736f5af04cfb6f168c1f643874a7d3f82b5f51ccSunny Goyal * This method is not thread safe, it must be called from a synchronized method. 6080fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal */ 609d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal private CacheEntry getEntryForPackageLocked(String packageName, UserHandleCompat user, 610d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal boolean useLowResIcon) { 61153f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal ComponentKey cacheKey = getPackageKey(packageName, user); 6120fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal CacheEntry entry = mCache.get(cacheKey); 613091f0ffd929f7a0a9a6af7d202eae13c48c07daaSunny Goyal 614d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal if (entry == null || (entry.isLowResIcon && !useLowResIcon)) { 6150fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal entry = new CacheEntry(); 616cdefc631f8b4b3e56ea3bd238d46d0bc9e28eabeWinson Chung boolean entryUpdated = true; 6170fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal 618d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal // Check the DB first. 61953f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal if (!getEntryFromDB(cacheKey, entry, useLowResIcon)) { 620d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal try { 621a8b244e5b83e4e773411c134c7a8df2a2392fb44Sunny Goyal int flags = UserHandleCompat.myUserHandle().equals(user) ? 0 : 622a8b244e5b83e4e773411c134c7a8df2a2392fb44Sunny Goyal PackageManager.GET_UNINSTALLED_PACKAGES; 623a8b244e5b83e4e773411c134c7a8df2a2392fb44Sunny Goyal PackageInfo info = mPackageManager.getPackageInfo(packageName, flags); 624d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal ApplicationInfo appInfo = info.applicationInfo; 625d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal if (appInfo == null) { 626d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal throw new NameNotFoundException("ApplicationInfo is null"); 627d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal } 6280b621156f336b40418120948aa93933dd26e548dSunny Goyal entry.icon = Utilities.createBadgedIconBitmap( 6290b621156f336b40418120948aa93933dd26e548dSunny Goyal appInfo.loadIcon(mPackageManager), user, mContext); 630d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal entry.title = appInfo.loadLabel(mPackageManager); 631d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user); 632d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal entry.isLowResIcon = false; 633d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal 634d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal // Add the icon in the DB here, since these do not get written during 635d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal // package updates. 636d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal ContentValues values = 637360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal newContentValues(entry.icon, entry.title.toString(), mPackageBgColor); 63853f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal addIconToDB(values, cacheKey.componentName, info, 63953f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal mUserManager.getSerialNumberForUser(user)); 640d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal 641d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal } catch (NameNotFoundException e) { 642d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal if (DEBUG) Log.d(TAG, "Application not installed " + packageName); 643cdefc631f8b4b3e56ea3bd238d46d0bc9e28eabeWinson Chung entryUpdated = false; 644d180cf7e16d8dbd7d33980078baac7d09709b6cdSunny Goyal } 6450fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal } 646cdefc631f8b4b3e56ea3bd238d46d0bc9e28eabeWinson Chung 647cdefc631f8b4b3e56ea3bd238d46d0bc9e28eabeWinson Chung // Only add a filled-out entry to the cache 648cdefc631f8b4b3e56ea3bd238d46d0bc9e28eabeWinson Chung if (entryUpdated) { 649cdefc631f8b4b3e56ea3bd238d46d0bc9e28eabeWinson Chung mCache.put(cacheKey, entry); 650cdefc631f8b4b3e56ea3bd238d46d0bc9e28eabeWinson Chung } 6510fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal } 6520fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal return entry; 6530fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal } 6540fc1be164e982433e619bcbb16aa67e28ff681efSunny Goyal 6556d0dde01f307051ee1849481c989d9e87774b894Chris Wren /** 6566d0dde01f307051ee1849481c989d9e87774b894Chris Wren * Pre-load an icon into the persistent cache. 6576d0dde01f307051ee1849481c989d9e87774b894Chris Wren * 6586d0dde01f307051ee1849481c989d9e87774b894Chris Wren * <P>Queries for a component that does not exist in the package manager 6596d0dde01f307051ee1849481c989d9e87774b894Chris Wren * will be answered by the persistent cache. 6606d0dde01f307051ee1849481c989d9e87774b894Chris Wren * 6616d0dde01f307051ee1849481c989d9e87774b894Chris Wren * @param componentName the icon should be returned for this component 6626d0dde01f307051ee1849481c989d9e87774b894Chris Wren * @param icon the icon to be persisted 6636d0dde01f307051ee1849481c989d9e87774b894Chris Wren * @param dpi the native density of the icon 6646d0dde01f307051ee1849481c989d9e87774b894Chris Wren */ 6654fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal public void preloadIcon(ComponentName componentName, Bitmap icon, int dpi, String label, 666df6ccf81960ab73d46570d56443e94c4df48e0c8Sunny Goyal long userSerial, InvariantDeviceProfile idp) { 6676d0dde01f307051ee1849481c989d9e87774b894Chris Wren // TODO rescale to the correct native DPI 6686d0dde01f307051ee1849481c989d9e87774b894Chris Wren try { 6694fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal PackageManager packageManager = mContext.getPackageManager(); 6706d0dde01f307051ee1849481c989d9e87774b894Chris Wren packageManager.getActivityIcon(componentName); 6716d0dde01f307051ee1849481c989d9e87774b894Chris Wren // component is present on the system already, do nothing 6726d0dde01f307051ee1849481c989d9e87774b894Chris Wren return; 6736d0dde01f307051ee1849481c989d9e87774b894Chris Wren } catch (PackageManager.NameNotFoundException e) { 6746d0dde01f307051ee1849481c989d9e87774b894Chris Wren // pass 6756d0dde01f307051ee1849481c989d9e87774b894Chris Wren } 6766d0dde01f307051ee1849481c989d9e87774b894Chris Wren 677df6ccf81960ab73d46570d56443e94c4df48e0c8Sunny Goyal ContentValues values = newContentValues( 678df6ccf81960ab73d46570d56443e94c4df48e0c8Sunny Goyal Bitmap.createScaledBitmap(icon, idp.iconBitmapSize, idp.iconBitmapSize, true), 679df6ccf81960ab73d46570d56443e94c4df48e0c8Sunny Goyal label, Color.TRANSPARENT); 6804fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal values.put(IconDB.COLUMN_COMPONENT, componentName.flattenToString()); 6814fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal values.put(IconDB.COLUMN_USER, userSerial); 6826f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal mIconDb.insertOrReplace(values); 6834fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 6844fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 68553f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal private boolean getEntryFromDB(ComponentKey cacheKey, CacheEntry entry, boolean lowRes) { 6866f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal Cursor c = null; 6876f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal try { 6886f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal c = mIconDb.query( 6896f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal new String[]{lowRes ? IconDB.COLUMN_ICON_LOW_RES : IconDB.COLUMN_ICON, 69034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal IconDB.COLUMN_LABEL}, 6914fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal IconDB.COLUMN_COMPONENT + " = ? AND " + IconDB.COLUMN_USER + " = ?", 6926f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal new String[]{cacheKey.componentName.flattenToString(), 6936f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal Long.toString(mUserManager.getSerialNumberForUser(cacheKey.user))}); 6944fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal if (c.moveToNext()) { 695360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal entry.icon = loadIconNoResize(c, 0, lowRes ? mLowResOptions : null); 69634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal entry.isLowResIcon = lowRes; 6974fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal entry.title = c.getString(1); 6984fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal if (entry.title == null) { 6994fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal entry.title = ""; 7004fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal entry.contentDescription = ""; 7014fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } else { 70253f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal entry.contentDescription = mUserManager.getBadgedLabelForUser( 70353f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal entry.title, cacheKey.user); 7046d0dde01f307051ee1849481c989d9e87774b894Chris Wren } 7054fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal return true; 7066d0dde01f307051ee1849481c989d9e87774b894Chris Wren } 7076f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal } catch (SQLiteException e) { 7086f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal Log.d(TAG, "Error reading icon cache", e); 7094fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } finally { 7106f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal if (c != null) { 7116f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal c.close(); 7126f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal } 7136d0dde01f307051ee1849481c989d9e87774b894Chris Wren } 7144fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal return false; 7156d0dde01f307051ee1849481c989d9e87774b894Chris Wren } 7166d0dde01f307051ee1849481c989d9e87774b894Chris Wren 71734b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal public static class IconLoadRequest { 71834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal private final Runnable mRunnable; 71934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal private final Handler mHandler; 72034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 72134b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal IconLoadRequest(Runnable runnable, Handler handler) { 72234b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal mRunnable = runnable; 72334b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal mHandler = handler; 72434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 72534b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 72634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal public void cancel() { 72734b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal mHandler.removeCallbacks(mRunnable); 72834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 72934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 73034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 7319ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal /** 73275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal * A runnable that updates invalid icons and adds missing icons in the DB for the provided 73375b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal * LauncherActivityInfoCompat list. Items are updated/added one at a time, so that the 73475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal * worker thread doesn't get blocked. 7359ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal */ 736316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk class SerializedIconUpdateTask implements Runnable { 7379ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal private final long mUserSerial; 7389ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal private final HashMap<String, PackageInfo> mPkgInfoMap; 7399ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal private final Stack<LauncherActivityInfoCompat> mAppsToAdd; 74075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal private final Stack<LauncherActivityInfoCompat> mAppsToUpdate; 74175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal private final HashSet<String> mUpdatedPackages = new HashSet<String>(); 7429ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal 743316490e636aad788fcfbfc2e04dd4f0e145bdd00Sunny Goyal @Thunk SerializedIconUpdateTask(long userSerial, HashMap<String, PackageInfo> pkgInfoMap, 74475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Stack<LauncherActivityInfoCompat> appsToAdd, 74575b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Stack<LauncherActivityInfoCompat> appsToUpdate) { 7469ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal mUserSerial = userSerial; 7479ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal mPkgInfoMap = pkgInfoMap; 74875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal mAppsToAdd = appsToAdd; 74975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal mAppsToUpdate = appsToUpdate; 7509ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal } 7519ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal 7529ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal @Override 7539ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal public void run() { 75475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (!mAppsToUpdate.isEmpty()) { 75575b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal LauncherActivityInfoCompat app = mAppsToUpdate.pop(); 75675b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal String cn = app.getComponentName().flattenToString(); 75775b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal ContentValues values = updateCacheAndGetContentValues(app, true); 7586f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal mIconDb.update(values, 75975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal IconDB.COLUMN_COMPONENT + " = ? AND " + IconDB.COLUMN_USER + " = ?", 7606f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal new String[]{cn, Long.toString(mUserSerial)}); 76175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal mUpdatedPackages.add(app.getComponentName().getPackageName()); 76275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal 76375b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (mAppsToUpdate.isEmpty() && !mUpdatedPackages.isEmpty()) { 76475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal // No more app to update. Notify model. 76575b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal LauncherAppState.getInstance().getModel().onPackageIconsUpdated( 76675b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal mUpdatedPackages, mUserManager.getUserForSerialNumber(mUserSerial)); 76775b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 76875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal 76975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal // Let it run one more time. 77075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal scheduleNext(); 77175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } else if (!mAppsToAdd.isEmpty()) { 7729ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal LauncherActivityInfoCompat app = mAppsToAdd.pop(); 7739ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal PackageInfo info = mPkgInfoMap.get(app.getComponentName().getPackageName()); 7749ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal if (info != null) { 7759ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal synchronized (IconCache.this) { 7769ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal addIconToDBAndMemCache(app, info, mUserSerial); 7779ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal } 7789ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal } 77975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal 78075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (!mAppsToAdd.isEmpty()) { 78175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal scheduleNext(); 78275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 7839ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal } 78475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 78575b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal 78675b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal public void scheduleNext() { 78775b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal mWorkerHandler.postAtTime(this, ICON_UPDATE_TOKEN, SystemClock.uptimeMillis() + 1); 7889ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal } 7899ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal } 7909ff980833d392244586ead8c27bbbba114e11ebbSunny Goyal 791360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal private void updateSystemStateString() { 792360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal mSystemState = Locale.getDefault().toString(); 793360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal } 794360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal 7956f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal private static final class IconDB extends SQLiteCacheHelper { 7962b84b652b33977d82e0af4ab9fdc7a97cb8d5a33Sunny Goyal private final static int DB_VERSION = 7; 7976d0dde01f307051ee1849481c989d9e87774b894Chris Wren 798d896ee43cd9195a2a2742324733b036ee72875bbSunny Goyal private final static int RELEASE_VERSION = DB_VERSION + 799d896ee43cd9195a2a2742324733b036ee72875bbSunny Goyal (FeatureFlags.LAUNCHER3_ICON_NORMALIZATION ? 1 : 0); 800d896ee43cd9195a2a2742324733b036ee72875bbSunny Goyal 8014fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal private final static String TABLE_NAME = "icons"; 8024fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal private final static String COLUMN_ROWID = "rowid"; 8034fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal private final static String COLUMN_COMPONENT = "componentName"; 8044fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal private final static String COLUMN_USER = "profileId"; 8054fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal private final static String COLUMN_LAST_UPDATED = "lastUpdated"; 8064fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal private final static String COLUMN_VERSION = "version"; 8074fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal private final static String COLUMN_ICON = "icon"; 80834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal private final static String COLUMN_ICON_LOW_RES = "icon_low_res"; 8094fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal private final static String COLUMN_LABEL = "label"; 8100c9a354c9732585620569bafaec0973977baf614Sunny Goyal private final static String COLUMN_SYSTEM_STATE = "system_state"; 8110c9a354c9732585620569bafaec0973977baf614Sunny Goyal 81216affbdf30b51ada08391d1ece721dca61ba3deaSunny Goyal public IconDB(Context context, int iconPixelSize) { 81316affbdf30b51ada08391d1ece721dca61ba3deaSunny Goyal super(context, LauncherFiles.APP_ICONS_DB, 81416affbdf30b51ada08391d1ece721dca61ba3deaSunny Goyal (RELEASE_VERSION << 16) + iconPixelSize, 81516affbdf30b51ada08391d1ece721dca61ba3deaSunny Goyal TABLE_NAME); 816ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 817ed13187a745866483139e2878037e1f8427ce567Kenny Guy 8184fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal @Override 8196f70936f7fb7cb45ef6a2a3d1019b6ecf3e49440Sunny Goyal protected void onCreateTable(SQLiteDatabase db) { 8204fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" + 8214fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal COLUMN_COMPONENT + " TEXT NOT NULL, " + 8224fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal COLUMN_USER + " INTEGER NOT NULL, " + 8234fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal COLUMN_LAST_UPDATED + " INTEGER NOT NULL DEFAULT 0, " + 8244fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal COLUMN_VERSION + " INTEGER NOT NULL DEFAULT 0, " + 8254fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal COLUMN_ICON + " BLOB, " + 82634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal COLUMN_ICON_LOW_RES + " BLOB, " + 8274fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal COLUMN_LABEL + " TEXT, " + 8280c9a354c9732585620569bafaec0973977baf614Sunny Goyal COLUMN_SYSTEM_STATE + " TEXT, " + 8294fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal "PRIMARY KEY (" + COLUMN_COMPONENT + ", " + COLUMN_USER + ") " + 8304fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal ");"); 8316d0dde01f307051ee1849481c989d9e87774b894Chris Wren } 832360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal } 833360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal 834360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal private ContentValues newContentValues(Bitmap icon, String label, int lowResBackgroundColor) { 835360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal ContentValues values = new ContentValues(); 836360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal values.put(IconDB.COLUMN_ICON, Utilities.flattenBitmap(icon)); 837360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal 838360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal values.put(IconDB.COLUMN_LABEL, label); 839360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal values.put(IconDB.COLUMN_SYSTEM_STATE, mSystemState); 84034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 841360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal if (lowResBackgroundColor == Color.TRANSPARENT) { 842360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal values.put(IconDB.COLUMN_ICON_LOW_RES, Utilities.flattenBitmap( 843360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal Bitmap.createScaledBitmap(icon, 844360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal icon.getWidth() / LOW_RES_SCALE_FACTOR, 845360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal icon.getHeight() / LOW_RES_SCALE_FACTOR, true))); 846360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal } else { 847360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal synchronized (this) { 848360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal if (mLowResBitmap == null) { 849360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal mLowResBitmap = Bitmap.createBitmap(icon.getWidth() / LOW_RES_SCALE_FACTOR, 850360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal icon.getHeight() / LOW_RES_SCALE_FACTOR, Bitmap.Config.RGB_565); 851360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal mLowResCanvas = new Canvas(mLowResBitmap); 852360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal mLowResPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG); 853360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal } 854360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal mLowResCanvas.drawColor(lowResBackgroundColor); 855360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal mLowResCanvas.drawBitmap(icon, new Rect(0, 0, icon.getWidth(), icon.getHeight()), 856360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal new Rect(0, 0, mLowResBitmap.getWidth(), mLowResBitmap.getHeight()), 857360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal mLowResPaint); 858360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal values.put(IconDB.COLUMN_ICON_LOW_RES, Utilities.flattenBitmap(mLowResBitmap)); 859360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal } 86034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 861360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal return values; 86234b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 86334b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 864360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal private static Bitmap loadIconNoResize(Cursor c, int iconIndex, BitmapFactory.Options options) { 86534b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal byte[] data = c.getBlob(iconIndex); 86634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal try { 867360bc25ab6ae22869b867350b87ee7e82f06389aSunny Goyal return BitmapFactory.decodeByteArray(data, 0, data.length, options); 86834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } catch (Exception e) { 86934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal return null; 87034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 8716d0dde01f307051ee1849481c989d9e87774b894Chris Wren } 8720589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato} 873