LauncherModel.java revision 2ff10b3b0137d258569ce5471808842e88696133
131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/* 231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License. 631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at 731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and 1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License. 1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17a5902524d4403885eb4c50360bf3465c6be796efJoe Onoratopackage com.android.launcher2; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.appwidget.AppWidgetManager; 20629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.appwidget.AppWidgetProviderInfo; 21f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onoratoimport android.content.BroadcastReceiver; 2231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.ComponentName; 235c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guyimport android.content.ContentProviderClient; 2431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.ContentResolver; 2531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.ContentValues; 2631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Intent; 270589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport android.content.Intent.ShortcutIconResource; 2831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 2931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.ActivityInfo; 3031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.PackageManager; 315c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guyimport android.content.pm.ProviderInfo; 3231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.ResolveInfo; 3331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.res.Resources; 3431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.database.Cursor; 3531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Bitmap; 3631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.BitmapFactory; 3731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.net.Uri; 380589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport android.os.Parcelable; 395c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guyimport android.os.RemoteException; 409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.util.Log; 4131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.Process; 429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.os.SystemClock; 4331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport java.lang.ref.WeakReference; 459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport java.net.URISyntaxException; 469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport java.text.Collator; 4731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.ArrayList; 4856d8291af6a28c6ba64113120efdf84a785e816cJoe Onoratoimport java.util.Arrays; 499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport java.util.Comparator; 509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport java.util.Collections; 5131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.HashMap; 5231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.List; 5331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 54edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guyimport com.android.launcher.R; 55edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 5631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 5731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Maintains in-memory state of the Launcher. It is expected that there should be only one 5831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * LauncherModel object held in a static. Also provide APIs for updating the database state 59bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project * for the Launcher. 6031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 61f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onoratopublic class LauncherModel extends BroadcastReceiver { 62a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato static final boolean DEBUG_LOADERS = false; 639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static final String TAG = "Launcher.Model"; 649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 652ff10b3b0137d258569ce5471808842e88696133Daniel Sandler private int mAllAppsLoadDelay; // milliseconds between batches 66dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 67f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato private final LauncherApplication mApp; 689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private final Object mLock = new Object(); 699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private DeferredHandler mHandler = new DeferredHandler(); 709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private Loader mLoader = new Loader(); 719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 72f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato private boolean mBeforeFirstLoad = true; 739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private WeakReference<Callbacks> mCallbacks; 749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 750589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private AllAppsList mAllAppsList; 760589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private IconCache mIconCache; 770589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 780589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private Bitmap mDefaultIcon; 799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public interface Callbacks { 819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public int getCurrentWorkspaceScreen(); 829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void startBinding(); 839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end); 84ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato public void bindFolders(HashMap<Long,FolderInfo> folders); 859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void finishBindingItems(); 869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void bindAppWidget(LauncherAppWidgetInfo info); 879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void bindAllApplications(ArrayList<ApplicationInfo> apps); 8864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato public void bindAppsAdded(ArrayList<ApplicationInfo> apps); 8964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato public void bindAppsUpdated(ArrayList<ApplicationInfo> apps); 9064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato public void bindAppsRemoved(ArrayList<ApplicationInfo> apps); 91dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler public int getAppBatchSize(); 929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 940589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato LauncherModel(LauncherApplication app, IconCache iconCache) { 95f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato mApp = app; 960589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mAllAppsList = new AllAppsList(iconCache); 970589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mIconCache = iconCache; 980589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 990589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mDefaultIcon = Utilities.createIconBitmap( 1000589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato app.getPackageManager().getDefaultActivityIcon(), app); 1012ff10b3b0137d258569ce5471808842e88696133Daniel Sandler 1022ff10b3b0137d258569ce5471808842e88696133Daniel Sandler mAllAppsLoadDelay = app.getResources().getInteger(R.integer.config_allAppsBatchLoadDelay); 1030589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 1040589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 10556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public Bitmap getFallbackIcon() { 1060589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return Bitmap.createBitmap(mDefaultIcon); 107f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato } 10831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 1109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Adds an item to the DB if it was not created previously, or move it to a new 1119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * <container, screen, cellX, cellY> 1129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 1139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container, 1149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int screen, int cellX, int cellY) { 1159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (item.container == ItemInfo.NO_ID) { 1169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // From all apps 1179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato addItemToDatabase(context, item, container, screen, cellX, cellY, false); 1189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } else { 1199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // From somewhere else 1209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato moveItemInDatabase(context, item, container, screen, cellX, cellY); 1219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 12331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 1259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Move an item in the DB to a new <container, screen, cellX, cellY> 1269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 1279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void moveItemInDatabase(Context context, ItemInfo item, long container, int screen, 1289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int cellX, int cellY) { 1299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.container = container; 1309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.screen = screen; 1319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellX = cellX; 1329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellY = cellY; 13331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 1359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 136bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project 1379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato values.put(LauncherSettings.Favorites.CONTAINER, item.container); 1389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato values.put(LauncherSettings.Favorites.CELLX, item.cellX); 1399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato values.put(LauncherSettings.Favorites.CELLY, item.cellY); 1409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato values.put(LauncherSettings.Favorites.SCREEN, item.screen); 141ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 1429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null); 14331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 14431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 1469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Returns true if the shortcuts already exists in the database. 1479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * we identify a shortcut by its title and intent. 148bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project */ 1499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static boolean shortcutExists(Context context, String title, Intent intent) { 1509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 1519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, 1529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato new String[] { "title", "intent" }, "title=? and intent=?", 1539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato new String[] { title, intent.toUri(0) }, null); 1549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato boolean result = false; 1559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 1569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato result = c.moveToFirst(); 1579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } finally { 1589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato c.close(); 1599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return result; 161bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project } 162bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project 163bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project /** 1649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Find a folder in the db, creating the FolderInfo if necessary, and adding it to folderList. 16531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo getFolderById(Context context, HashMap<Long,FolderInfo> folderList, long id) { 1679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 1689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null, 1699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato "_id=? and (itemType=? or itemType=?)", 1709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato new String[] { String.valueOf(id), 1719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER), 1729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER) }, null); 173f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 1759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (c.moveToFirst()) { 1769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE); 1779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE); 1789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER); 1799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN); 1809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX); 1819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY); 182f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo folderInfo = null; 1849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (c.getInt(itemTypeIndex)) { 1859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER: 1869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo = findOrMakeUserFolder(folderList, id); 1879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 1889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER: 1899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo = findOrMakeLiveFolder(folderList, id); 1909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 1919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 19231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.title = c.getString(titleIndex); 1949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.id = id; 1959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.container = c.getInt(containerIndex); 1969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.screen = c.getInt(screenIndex); 1979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.cellX = c.getInt(cellXIndex); 1989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.cellY = c.getInt(cellYIndex); 199ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 2009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return folderInfo; 2019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } finally { 2039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato c.close(); 2042fcbd686d1c2a9a9e520116a541c9caae0c2dc60Romain Guy } 205ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 2069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 2079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 20831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 2109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Add an item to the database in a specified container. Sets the container, screen, cellX and 2119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * cellY fields of the item. Also assigns an ID to the item. 2129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 2139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void addItemToDatabase(Context context, ItemInfo item, long container, 2149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int screen, int cellX, int cellY, boolean notify) { 2159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.container = container; 2169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.screen = screen; 2179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellX = cellX; 2189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellY = cellY; 219ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 2209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 2219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 222ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 2239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.onAddToDatabase(values); 224ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 2259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Uri result = cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI : 2269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values); 227ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 2289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (result != null) { 2299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.id = Integer.parseInt(result.getPathSegments().get(1)); 23031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 2349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Update an item to the database in a specified container. 2359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 2369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void updateItemInDatabase(Context context, ItemInfo item) { 2379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 2389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 239f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.onAddToDatabase(values); 241ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 2429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null); 24331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 24431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 2469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Removes the specified item from the database 2479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * @param context 2489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * @param item 2499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 2509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void deleteItemFromDatabase(Context context, ItemInfo item) { 2519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 252f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato cr.delete(LauncherSettings.Favorites.getContentUri(item.id, false), null, null); 2549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 255f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 2579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Remove the contents of the specified folder from the database 2589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 2599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void deleteUserFolderContentsFromDatabase(Context context, UserFolderInfo info) { 2609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 261f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null); 2639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato cr.delete(LauncherSettings.Favorites.CONTENT_URI, 2649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.CONTAINER + "=" + info.id, null); 2659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 266f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 2689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Set this as the current Launcher activity object for the loader. 2699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 2709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void initialize(Callbacks callbacks) { 2719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 2729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mCallbacks = new WeakReference<Callbacks>(callbacks); 273f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 274f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 275f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void startLoader(Context context, boolean isLaunching) { 2779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoader.startLoader(context, isLaunching); 2789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 279f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void stopLoader() { 2819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoader.stopLoader(); 2829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 283f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2841d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato /** 2851d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato * We pick up most of the changes to all apps. 2861d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato */ 2871d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato public void setAllAppsDirty() { 2881d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato mLoader.setAllAppsDirty(); 2891d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato } 2901d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato 2919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void setWorkspaceDirty() { 2929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoader.setWorkspaceDirty(); 2939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 294f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 2969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Call from the handler for ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and 2979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * ACTION_PACKAGE_CHANGED. 2989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 299f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato public void onReceive(Context context, Intent intent) { 300f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato // Use the app as the context. 301f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato context = mApp; 302f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato 3039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato ArrayList<ApplicationInfo> added = null; 3049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato ArrayList<ApplicationInfo> removed = null; 3059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato ArrayList<ApplicationInfo> modified = null; 3069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 3079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 308f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato if (mBeforeFirstLoad) { 309f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato // If we haven't even loaded yet, don't bother, since we'll just pick 310f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato // up the changes. 311f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato return; 312f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato } 313f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato 3149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final String action = intent.getAction(); 3159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 31664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (Intent.ACTION_PACKAGE_CHANGED.equals(action) 31764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato || Intent.ACTION_PACKAGE_REMOVED.equals(action) 31864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato || Intent.ACTION_PACKAGE_ADDED.equals(action)) { 31964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato final String packageName = intent.getData().getSchemeSpecificPart(); 32064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 321f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 32264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName == null || packageName.length() == 0) { 32364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato // they sent us a bad intent 32464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato return; 3259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 32664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato 32764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) { 3289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mAllAppsList.updatePackage(context, packageName); 32964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { 33064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (!replacing) { 33164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato mAllAppsList.removePackage(packageName); 33264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 33364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato // else, we are replacing the package, so a PACKAGE_ADDED will be sent 33464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato // later, we will update the package at this time 33564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { 33664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (!replacing) { 33764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato mAllAppsList.addPackage(context, packageName); 33864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } else { 33964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato mAllAppsList.updatePackage(context, packageName); 34064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 34164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 34256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 34356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (mAllAppsList.added.size() > 0) { 34456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato added = mAllAppsList.added; 34556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mAllAppsList.added = new ArrayList<ApplicationInfo>(); 34656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 34756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (mAllAppsList.removed.size() > 0) { 34856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato removed = mAllAppsList.removed; 34956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mAllAppsList.removed = new ArrayList<ApplicationInfo>(); 35056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato for (ApplicationInfo info: removed) { 35156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mIconCache.remove(info.intent.getComponent()); 35256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 35356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 35456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (mAllAppsList.modified.size() > 0) { 35556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato modified = mAllAppsList.modified; 35656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mAllAppsList.modified = new ArrayList<ApplicationInfo>(); 35756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 35856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 35956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null; 36056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (callbacks == null) { 36156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Log.w(TAG, "Nobody to tell about the new app. Launcher is probably loading."); 36256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato return; 36356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 36456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 36556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (added != null) { 36656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final ArrayList<ApplicationInfo> addedFinal = added; 36756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mHandler.post(new Runnable() { 36856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public void run() { 36956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato callbacks.bindAppsAdded(addedFinal); 37056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 37156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato }); 37256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 37356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (modified != null) { 37456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final ArrayList<ApplicationInfo> modifiedFinal = modified; 37556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mHandler.post(new Runnable() { 37656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public void run() { 37756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato callbacks.bindAppsUpdated(modifiedFinal); 37856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 37956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato }); 38056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 38156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (removed != null) { 38256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final ArrayList<ApplicationInfo> removedFinal = removed; 38356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mHandler.post(new Runnable() { 38456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public void run() { 38556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato callbacks.bindAppsRemoved(removedFinal); 38656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 38756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato }); 38856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 38964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } else { 39064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { 39164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato String packages[] = intent.getStringArrayExtra( 39264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato Intent.EXTRA_CHANGED_PACKAGE_LIST); 39364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packages == null || packages.length == 0) { 39464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato return; 39564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 39656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato setAllAppsDirty(); 39756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato setWorkspaceDirty(); 39856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato startLoader(context, false); 39964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 40064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato String packages[] = intent.getStringArrayExtra( 40164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato Intent.EXTRA_CHANGED_PACKAGE_LIST); 40264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packages == null || packages.length == 0) { 40364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato return; 40464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 40556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato setAllAppsDirty(); 40656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato setWorkspaceDirty(); 40756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato startLoader(context, false); 408f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 409f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 410f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 411f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 412f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public class Loader { 4149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private static final int ITEMS_CHUNK = 6; 415f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private LoaderThread mLoaderThread; 417f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private int mLastWorkspaceSeq = 0; 4199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private int mWorkspaceSeq = 1; 4209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 4219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private int mLastAllAppsSeq = 0; 4229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private int mAllAppsSeq = 1; 423f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 42484f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy final ArrayList<ItemInfo> mItems = new ArrayList<ItemInfo>(); 42584f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy final ArrayList<LauncherAppWidgetInfo> mAppWidgets = new ArrayList<LauncherAppWidgetInfo>(); 426ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato final HashMap<Long, FolderInfo> mFolders = new HashMap<Long, FolderInfo>(); 4279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 4289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 4299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Call this from the ui thread so the handler is initialized on the correct thread. 4309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 4319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public Loader() { 432f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 433f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void startLoader(Context context, boolean isLaunching) { 4359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 436a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 437a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "startLoader isLaunching=" + isLaunching); 438a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 4399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Don't bother to start the thread if we know it's not going to do anything 440ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato if (mCallbacks != null && mCallbacks.get() != null) { 4419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LoaderThread oldThread = mLoaderThread; 4429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (oldThread != null) { 4439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (oldThread.isLaunching()) { 4449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // don't downgrade isLaunching if we're already running 4459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato isLaunching = true; 4469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 4479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato oldThread.stopLocked(); 4489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 4499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoaderThread = new LoaderThread(context, oldThread, isLaunching); 4509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoaderThread.start(); 4519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 452b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy } 453b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy } 454b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy 4559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void stopLoader() { 4569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 4579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (mLoaderThread != null) { 4589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoaderThread.stopLocked(); 4599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 4609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 461f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 462b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy 4639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void setWorkspaceDirty() { 4649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 4659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mWorkspaceSeq++; 4669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 4679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 468f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void setAllAppsDirty() { 4709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 4719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mAllAppsSeq++; 472f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 473f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 474f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 4769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Runnable for the thread that loads the contents of the launcher: 4779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * - workspace icons 4789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * - widgets 4799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * - all apps icons 4809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 4819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private class LoaderThread extends Thread { 4829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private Context mContext; 4839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private Thread mWaitThread; 4849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private boolean mIsLaunching; 4859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private boolean mStopped; 4869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private boolean mWorkspaceDoneBinding; 4879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 4889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LoaderThread(Context context, Thread waitThread, boolean isLaunching) { 4899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mContext = context; 4909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mWaitThread = waitThread; 4919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mIsLaunching = isLaunching; 4929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 493f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato boolean isLaunching() { 4959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return mIsLaunching; 4969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 497f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 4999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * If another LoaderThread was supplied, we need to wait for that to finish before 5009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * we start our processing. This keeps the ordering of the setting and clearing 5019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * of the dirty flags correct by making sure we don't start processing stuff until 5029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * they've had a chance to re-set them. We do this waiting the worker thread, not 5039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * the ui thread to avoid ANRs. 5049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 5059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private void waitForOtherThread() { 5069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (mWaitThread != null) { 5079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato boolean done = false; 5089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato while (!done) { 5099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 5109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mWaitThread.join(); 511efabe00e4a51bb792366c459d6acc46832e61fdcJoe Onorato done = true; 5129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } catch (InterruptedException ex) { 51384f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy // Ignore 5149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mWaitThread = null; 5179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 519f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 5209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 5219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato waitForOtherThread(); 522f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 5239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Elevate priority when Home launches for the first time to avoid 5249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // starving at boot time. Staring at a blank home is not cool. 5259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 5269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato android.os.Process.setThreadPriority(mIsLaunching 5279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato ? Process.THREAD_PRIORITY_DEFAULT : Process.THREAD_PRIORITY_BACKGROUND); 5289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 529f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 5309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Load the workspace only if it's dirty. 5319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int workspaceSeq; 5329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato boolean workspaceDirty; 5339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 5349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato workspaceSeq = mWorkspaceSeq; 5359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato workspaceDirty = mWorkspaceSeq != mLastWorkspaceSeq; 5369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (workspaceDirty) { 5389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato loadWorkspace(); 5399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 5419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // If we're not stopped, and nobody has incremented mWorkspaceSeq. 5429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (mStopped) { 5439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return; 5449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (workspaceSeq == mWorkspaceSeq) { 5469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLastWorkspaceSeq = mWorkspaceSeq; 5479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 549f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 5509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Bind the workspace 5519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato bindWorkspace(); 5529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 5539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Wait until the either we're stopped or the other threads are done. 5549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // This way we don't start loading all apps until the workspace has settled 5559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // down. 5569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (LoaderThread.this) { 557080d9b614e609826dce2606f9e474af674ead933Joe Onorato mHandler.postIdle(new Runnable() { 5589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 5599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (LoaderThread.this) { 5609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mWorkspaceDoneBinding = true; 561a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 562a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "done with workspace"); 563a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 5649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LoaderThread.this.notify(); 5659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 568a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 569a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "waiting to be done with workspace"); 570a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 5719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato while (!mStopped && !mWorkspaceDoneBinding) { 5729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 5739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato this.wait(); 5749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } catch (InterruptedException ex) { 57584f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy // Ignore 5769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 578a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 579a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "done waiting to be done with workspace"); 580a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 5819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 582f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 583dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler // Whew! Hard work done. 584dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler synchronized (mLock) { 585dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler if (mIsLaunching) { 5862ff10b3b0137d258569ce5471808842e88696133Daniel Sandler android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 587dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 588dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 589dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 5909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Load all apps if they're dirty 5919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int allAppsSeq; 5929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato boolean allAppsDirty; 5939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 5949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato allAppsSeq = mAllAppsSeq; 5959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato allAppsDirty = mAllAppsSeq != mLastAllAppsSeq; 596a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 597a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "mAllAppsSeq=" + mAllAppsSeq 598a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato + " mLastAllAppsSeq=" + mLastAllAppsSeq + " allAppsDirty"); 599a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 6009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 6019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (allAppsDirty) { 602dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler loadAndBindAllApps(); 6039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 6049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 6059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // If we're not stopped, and nobody has incremented mAllAppsSeq. 6069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (mStopped) { 6079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return; 6089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 6099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (allAppsSeq == mAllAppsSeq) { 6109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLastAllAppsSeq = mAllAppsSeq; 6119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 6129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 613f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Clear out this reference, otherwise we end up holding it until all of the 6159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // callback runnables are done. 6169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mContext = null; 617f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 6199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Setting the reference is atomic, but we can't do it inside the other critical 6209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // sections. 6219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoaderThread = null; 622f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 623f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 624f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void stopLocked() { 6269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (LoaderThread.this) { 6279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mStopped = true; 6289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato this.notify(); 6299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 630f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 631f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 6339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Gets the callbacks object. If we've been stopped, or if the launcher object 634c131b74922e6323331c374856bda830010d761c8Joe Onorato * has somehow been garbage collected, return null instead. Pass in the Callbacks 635c131b74922e6323331c374856bda830010d761c8Joe Onorato * object that was around when the deferred message was scheduled, and if there's 636c131b74922e6323331c374856bda830010d761c8Joe Onorato * a new Callbacks object around then also return null. This will save us from 637c131b74922e6323331c374856bda830010d761c8Joe Onorato * calling onto it with data that will be ignored. 6389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 639c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks tryGetCallbacks(Callbacks oldCallbacks) { 6409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 6419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (mStopped) { 6429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 6439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 6449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 645ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato if (mCallbacks == null) { 646ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato return null; 647ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato } 648ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato 6499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Callbacks callbacks = mCallbacks.get(); 650c131b74922e6323331c374856bda830010d761c8Joe Onorato if (callbacks != oldCallbacks) { 651c131b74922e6323331c374856bda830010d761c8Joe Onorato return null; 652c131b74922e6323331c374856bda830010d761c8Joe Onorato } 6539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks == null) { 6549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Log.w(TAG, "no mCallbacks"); 6559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 6569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 657f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return callbacks; 6599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 660f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 661f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private void loadWorkspace() { 6639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato long t = SystemClock.uptimeMillis(); 664f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Context context = mContext; 6669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver contentResolver = context.getContentResolver(); 6679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final PackageManager manager = context.getPackageManager(); 668629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final AppWidgetManager widgets = AppWidgetManager.getInstance(context); 6695c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy final boolean isSafeMode = manager.isSafeMode(); 670f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6713c2f7e105d8daab439bff2c362a727ad348d8a44Joe Onorato mItems.clear(); 672511ab64d25ee45518b816afa9110b3160edf3f7bJoe Onorato mAppWidgets.clear(); 6731db7a972bfa8786fc8b58d57f832a378fa731eb0Joe Onorato mFolders.clear(); 6743c2f7e105d8daab439bff2c362a727ad348d8a44Joe Onorato 6755c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy final ArrayList<Long> itemsToRemove = new ArrayList<Long>(); 6765c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 6779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Cursor c = contentResolver.query( 6789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.CONTENT_URI, null, null, null, null); 679f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 6819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID); 6829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int intentIndex = c.getColumnIndexOrThrow 6839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato (LauncherSettings.Favorites.INTENT); 6849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int titleIndex = c.getColumnIndexOrThrow 6859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato (LauncherSettings.Favorites.TITLE); 6869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int iconTypeIndex = c.getColumnIndexOrThrow( 6879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.ICON_TYPE); 6889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON); 6899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int iconPackageIndex = c.getColumnIndexOrThrow( 6909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.ICON_PACKAGE); 6919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int iconResourceIndex = c.getColumnIndexOrThrow( 6929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.ICON_RESOURCE); 6939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int containerIndex = c.getColumnIndexOrThrow( 6949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.CONTAINER); 6959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int itemTypeIndex = c.getColumnIndexOrThrow( 6969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.ITEM_TYPE); 6979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int appWidgetIdIndex = c.getColumnIndexOrThrow( 6989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.APPWIDGET_ID); 6999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int screenIndex = c.getColumnIndexOrThrow( 7009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.SCREEN); 7019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellXIndex = c.getColumnIndexOrThrow 7029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato (LauncherSettings.Favorites.CELLX); 7039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellYIndex = c.getColumnIndexOrThrow 7049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato (LauncherSettings.Favorites.CELLY); 7059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int spanXIndex = c.getColumnIndexOrThrow 7069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato (LauncherSettings.Favorites.SPANX); 7079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int spanYIndex = c.getColumnIndexOrThrow( 7089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.SPANY); 7099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI); 7109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int displayModeIndex = c.getColumnIndexOrThrow( 7119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.DISPLAY_MODE); 7129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 7130589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutInfo info; 7149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String intentDescription; 7159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherAppWidgetInfo appWidgetInfo; 7169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int container; 7179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato long id; 7189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Intent intent; 7199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 7209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato while (!mStopped && c.moveToNext()) { 7219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 7229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int itemType = c.getInt(itemTypeIndex); 723f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 7249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (itemType) { 7259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 7269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 7279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato intentDescription = c.getString(intentIndex); 7289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 7299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato intent = Intent.parseUri(intentDescription, 0); 7309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } catch (URISyntaxException e) { 7319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato continue; 7329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 733f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 7349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { 73556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info = getShortcutInfo(manager, intent, context, c, iconIndex, 73656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato titleIndex); 7379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } else { 7380589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info = getShortcutInfo(c, context, iconTypeIndex, 73956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato iconPackageIndex, iconResourceIndex, iconIndex, 74056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato titleIndex); 7419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 742f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 7439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (info != null) { 74456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato updateSavedIcon(context, info, c, iconIndex); 7459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 74656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.intent = intent; 7479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.id = c.getLong(idIndex); 7489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato container = c.getInt(containerIndex); 7499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.container = container; 7509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.screen = c.getInt(screenIndex); 7519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.cellX = c.getInt(cellXIndex); 7529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.cellY = c.getInt(cellYIndex); 7539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 7549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (container) { 7559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.CONTAINER_DESKTOP: 7569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mItems.add(info); 7579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 7589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato default: 7599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Item is in a user folder 7609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato UserFolderInfo folderInfo = 761ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato findOrMakeUserFolder(mFolders, container); 7629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.add(info); 7639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 7649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 76556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } else { 76656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // Failed to load the shortcut, probably because the 76756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // activity manager couldn't resolve it (maybe the app 76856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // was uninstalled), or the db row was somehow screwed up. 76956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // Delete it. 77056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato id = c.getLong(idIndex); 77156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Log.e(TAG, "Error loading shortcut " + id + ", removing it"); 77256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato contentResolver.delete(LauncherSettings.Favorites.getContentUri( 77356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato id, false), null, null); 7749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 7759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 776f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 777ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER: 7789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato id = c.getLong(idIndex); 779ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato UserFolderInfo folderInfo = findOrMakeUserFolder(mFolders, id); 780f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 7819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.title = c.getString(titleIndex); 782f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 7839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.id = id; 7849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato container = c.getInt(containerIndex); 7859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.container = container; 7869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.screen = c.getInt(screenIndex); 7879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.cellX = c.getInt(cellXIndex); 7889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.cellY = c.getInt(cellYIndex); 789f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 7909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (container) { 7919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.CONTAINER_DESKTOP: 7929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mItems.add(folderInfo); 7939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 7949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 795ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato 796ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato mFolders.put(folderInfo.id, folderInfo); 7979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 798ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato 7999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER: 8009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato id = c.getLong(idIndex); 8015c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy Uri uri = Uri.parse(c.getString(uriIndex)); 8029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 8035c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy // Make sure the live folder exists 8045c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy final ProviderInfo providerInfo = 8055c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy context.getPackageManager().resolveContentProvider( 8065c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy uri.getAuthority(), 0); 807f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 8085c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy if (providerInfo == null && !isSafeMode) { 8095c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy itemsToRemove.add(id); 8105c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } else { 8115c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(mFolders, id); 8125c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 8135c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy intentDescription = c.getString(intentIndex); 8145c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy intent = null; 8155c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy if (intentDescription != null) { 8165c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy try { 8175c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy intent = Intent.parseUri(intentDescription, 0); 8185c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } catch (URISyntaxException e) { 8195c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy // Ignore, a live folder might not have a base intent 8205c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 8215c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 8225c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 8235c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.title = c.getString(titleIndex); 8245c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.id = id; 8255c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.uri = uri; 8265c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy container = c.getInt(containerIndex); 8275c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.container = container; 8285c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.screen = c.getInt(screenIndex); 8295c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.cellX = c.getInt(cellXIndex); 8305c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.cellY = c.getInt(cellYIndex); 8315c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.baseIntent = intent; 8325c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.displayMode = c.getInt(displayModeIndex); 8335c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 8345c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy loadLiveFolderIcon(context, c, iconTypeIndex, iconPackageIndex, 8355c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy iconResourceIndex, liveFolderInfo); 8365c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 8375c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy switch (container) { 8385c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy case LauncherSettings.Favorites.CONTAINER_DESKTOP: 8395c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy mItems.add(liveFolderInfo); 8405c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy break; 8415c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 8425c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy mFolders.put(liveFolderInfo.id, liveFolderInfo); 8439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 8449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 845ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato 8469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 8479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Read all Launcher-specific widget details 8489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int appWidgetId = c.getInt(appWidgetIdIndex); 849629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy id = c.getLong(idIndex); 85031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 851629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final AppWidgetProviderInfo provider = 852629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy widgets.getAppWidgetInfo(appWidgetId); 853629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 854629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (!isSafeMode && (provider == null || provider.provider == null || 855629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy provider.provider.getPackageName() == null)) { 8568ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato Log.e(TAG, "Deleting widget that isn't installed anymore: id=" 8578ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato + id + " appWidgetId=" + appWidgetId); 858629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy itemsToRemove.add(id); 859629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else { 860629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId); 861629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.id = id; 862629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.screen = c.getInt(screenIndex); 863629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.cellX = c.getInt(cellXIndex); 864629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.cellY = c.getInt(cellYIndex); 865629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.spanX = c.getInt(spanXIndex); 866629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.spanY = c.getInt(spanYIndex); 867629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 868629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy container = c.getInt(containerIndex); 869629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) { 870629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy Log.e(TAG, "Widget found where container " 871629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy + "!= CONTAINER_DESKTOP -- ignoring!"); 872629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy continue; 873629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 874629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.container = c.getInt(containerIndex); 875629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 876629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy mAppWidgets.add(appWidgetInfo); 8779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 8789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 8799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 8809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } catch (Exception e) { 8819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Log.w(TAG, "Desktop items loading interrupted:", e); 8829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 8839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 8849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } finally { 8859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato c.close(); 8869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 8875c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 8885c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy if (itemsToRemove.size() > 0) { 8895c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy ContentProviderClient client = contentResolver.acquireContentProviderClient( 8905c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy LauncherSettings.Favorites.CONTENT_URI); 8915c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy // Remove dead items 8925c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy for (long id : itemsToRemove) { 8935c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy if (DEBUG_LOADERS) { 8945c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy Log.d(TAG, "Removed id = " + id); 8955c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 8965c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy // Don't notify content observers 8975c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy try { 8985c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy client.delete(LauncherSettings.Favorites.getContentUri(id, false), 8995c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy null, null); 9005c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } catch (RemoteException e) { 9015c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy Log.w(TAG, "Could not remove id = " + id); 9025c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 9035c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 9045c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 9055c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 906a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 907a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms"); 908a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 9099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 91031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 9129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Read everything out of our database. 9139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 9149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private void bindWorkspace() { 9159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final long t = SystemClock.uptimeMillis(); 9169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 9179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Don't use these two variables in any of the callback runnables. 9189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Otherwise we hold a reference to them. 919c131b74922e6323331c374856bda830010d761c8Joe Onorato final Callbacks oldCallbacks = mCallbacks.get(); 920c131b74922e6323331c374856bda830010d761c8Joe Onorato if (oldCallbacks == null) { 9219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // This launcher has exited and nobody bothered to tell us. Just bail. 9229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Log.w(TAG, "LoaderThread running with no launcher"); 9239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return; 9249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 92531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int N; 9279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Tell the workspace that we're about to start firing items at it 9289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.post(new Runnable() { 9299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 930c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 9319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 9329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato callbacks.startBinding(); 9339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 9369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Add the items to the workspace. 9379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato N = mItems.size(); 9389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato for (int i=0; i<N; i+=ITEMS_CHUNK) { 9399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int start = i; 9409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int chunkSize = (i+ITEMS_CHUNK <= N) ? ITEMS_CHUNK : (N-i); 9419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.post(new Runnable() { 9429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 943c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 9449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 9459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato callbacks.bindItems(mItems, start, start+chunkSize); 9469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 9499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 950ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato mHandler.post(new Runnable() { 951ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato public void run() { 952c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 953ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato if (callbacks != null) { 954ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato callbacks.bindFolders(mFolders); 955ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato } 956ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato } 957ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato }); 9589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Wait until the queue goes empty. 9599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.postIdle(new Runnable() { 9609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 961a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 962a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "Going to start binding widgets soon."); 963a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 9649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 9669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Bind the widgets, one at a time. 9679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // WARNING: this is calling into the workspace from the background thread, 9689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // but since getCurrentScreen() just returns the int, we should be okay. This 9699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // is just a hint for the order, and if it's wrong, we'll be okay. 9709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // TODO: instead, we should have that push the current screen into here. 971c131b74922e6323331c374856bda830010d761c8Joe Onorato final int currentScreen = oldCallbacks.getCurrentWorkspaceScreen(); 9729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato N = mAppWidgets.size(); 9739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // once for the current screen 9749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato for (int i=0; i<N; i++) { 9759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final LauncherAppWidgetInfo widget = mAppWidgets.get(i); 9769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (widget.screen == currentScreen) { 9779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.post(new Runnable() { 9789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 979c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 9809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 9819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato callbacks.bindAppWidget(widget); 9829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 9859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // once for the other screens 9889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato for (int i=0; i<N; i++) { 9899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final LauncherAppWidgetInfo widget = mAppWidgets.get(i); 9909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (widget.screen != currentScreen) { 9919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.post(new Runnable() { 9929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 993c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 9949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 9959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato callbacks.bindAppWidget(widget); 9969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 9999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 10009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 10019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Tell the workspace that we're done. 10029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.post(new Runnable() { 10039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 1004c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 10059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 10069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato callbacks.finishBindingItems(); 10079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 10089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 10099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 10109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // If we're profiling, this is the last thing in the queue. 10119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.post(new Runnable() { 10129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 1013a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 1014a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "bound workspace in " 1015a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato + (SystemClock.uptimeMillis()-t) + "ms"); 1016a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 10179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (Launcher.PROFILE_ROTATE) { 10189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato android.os.Debug.stopMethodTracing(); 10199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 10209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 10219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 10229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 102331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1024dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler private void loadAndBindAllApps() { 1025dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler final long t = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 1026dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 10279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); 10289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); 102931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1030c131b74922e6323331c374856bda830010d761c8Joe Onorato final Callbacks callbacks = mCallbacks.get(); 10319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks == null) { 10329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return; 10339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 103431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10350589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final PackageManager packageManager = mContext.getPackageManager(); 10369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final List<ResolveInfo> apps = packageManager.queryIntentActivities(mainIntent, 0); 103731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1038dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler int N; 1039dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler int batchSize = callbacks.getAppBatchSize(); 1040dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 10419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 1042f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato mBeforeFirstLoad = false; 10439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mAllAppsList.clear(); 1044dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler if (apps == null) return; 1045dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler N = apps.size(); 1046dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler if (batchSize <= 0) 1047dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler batchSize = N; 1048dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 1049dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 1050dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler int i=0; 1051dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler while (i < N && !mStopped) { 1052dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler synchronized (mLock) { 1053dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler final long t2 = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 105431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1055dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler for (int j=0; i<N && j<batchSize; j++) { 10569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // This builds the icon bitmaps. 10570589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mAllAppsList.add(new ApplicationInfo(apps.get(i), mIconCache)); 1058dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler i++; 10599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1060a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 1061dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler Log.d(TAG, "batch of " + batchSize + " icons processed in " 1062dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler + (SystemClock.uptimeMillis()-t2) + "ms"); 1063a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 1064ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project } 1065dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 1066dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler mHandler.post(bindAllAppsTask); 1067dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 10682ff10b3b0137d258569ce5471808842e88696133Daniel Sandler if (mAllAppsLoadDelay > 0 && i < N) { 1069dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler try { 10702ff10b3b0137d258569ce5471808842e88696133Daniel Sandler Thread.sleep(mAllAppsLoadDelay); 1071dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } catch (InterruptedException exc) { } 1072dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 1073dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 1074dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 1075dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler if (DEBUG_LOADERS) { 1076dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler Log.d(TAG, "cached all " + N + " apps in " 10772ff10b3b0137d258569ce5471808842e88696133Daniel Sandler + (SystemClock.uptimeMillis()-t) + "ms" 10782ff10b3b0137d258569ce5471808842e88696133Daniel Sandler + (mAllAppsLoadDelay > 0 ? " (including delay)" : "")); 107931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 108031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 108131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1082dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler final Runnable bindAllAppsTask = new Runnable() { 1083dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler public void run() { 1084dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler final long t = SystemClock.uptimeMillis(); 1085dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler int count = 0; 1086dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler Callbacks callbacks = null; 1087dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler ArrayList<ApplicationInfo> results = null; 1088dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler synchronized (mLock) { 1089dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler mHandler.cancelRunnable(this); 1090dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 1091dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler results = (ArrayList<ApplicationInfo>) mAllAppsList.data.clone(); 1092dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler // We're adding this now, so clear out this so we don't re-send them. 1093dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler mAllAppsList.added = new ArrayList<ApplicationInfo>(); 1094dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler count = results.size(); 1095dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 1096dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler callbacks = tryGetCallbacks(mCallbacks.get()); 1097dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 10989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 1099dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler if (callbacks != null && count > 0) { 1100dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler callbacks.bindAllApplications(results); 1101dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 11029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 1103dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler if (DEBUG_LOADERS) { 1104dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler Log.d(TAG, "bound " + count + " apps in " 1105dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler + (SystemClock.uptimeMillis() - t) + "ms"); 1106dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 11079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1108dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler }; 1109be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato 1110be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato public void dumpState() { 1111be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLoaderThread.mContext=" + mContext); 1112be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLoaderThread.mWaitThread=" + mWaitThread); 1113be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLoaderThread.mIsLaunching=" + mIsLaunching); 1114be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLoaderThread.mStopped=" + mStopped); 1115be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLoaderThread.mWorkspaceDoneBinding=" + mWorkspaceDoneBinding); 1116be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 1117be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 1118be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato 1119be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato public void dumpState() { 1120be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLastWorkspaceSeq=" + mLoader.mLastWorkspaceSeq); 1121be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mWorkspaceSeq=" + mLoader.mWorkspaceSeq); 1122be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLastAllAppsSeq=" + mLoader.mLastAllAppsSeq); 1123be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mAllAppsSeq=" + mLoader.mAllAppsSeq); 1124be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mItems size=" + mLoader.mItems.size()); 1125be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato if (mLoaderThread != null) { 1126be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato mLoaderThread.dumpState(); 1127be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } else { 1128be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLoaderThread=null"); 1129be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 113031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 113131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 113231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 113456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * This is called from the code that adds shortcuts from the intent receiver. This 113556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * doesn't have a Cursor, but 11369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 113756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public ShortcutInfo getShortcutInfo(PackageManager manager, Intent intent, Context context) { 1138e74daedc3b41d958315f7d5bf69deb232ca89468Joe Onorato return getShortcutInfo(manager, intent, context, null, -1, -1); 113956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 114056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 114156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato /** 114256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * Make an ShortcutInfo object for a shortcut that is an application. 114356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * 114456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * If c is not null, then it will be used to fill in missing data like the title and icon. 114556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato */ 114656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public ShortcutInfo getShortcutInfo(PackageManager manager, Intent intent, Context context, 114756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Cursor c, int iconIndex, int titleIndex) { 114856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap icon = null; 114956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final ShortcutInfo info = new ShortcutInfo(); 115031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 115156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato ComponentName componentName = intent.getComponent(); 115256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (componentName == null) { 11539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 115431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 115531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11568ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato // TODO: See if the PackageManager knows about this case. If it doesn't 11578ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato // then return null & delete this. 11588ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato 115956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the resource -- This may implicitly give us back the fallback icon, 116056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // but don't worry about that. All we're doing with usingFallbackIcon is 116156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // to avoid saving lots of copies of that in the database, and most apps 116256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // have icons anyway. 116356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final ResolveInfo resolveInfo = manager.resolveActivity(intent, 0); 116456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (resolveInfo != null) { 116556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = mIconCache.getIcon(componentName, resolveInfo); 116656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 116756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the db 116856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 116956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (c != null) { 117056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getIconFromCursor(c, iconIndex); 117156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 11729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 117356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the fallback icon 117456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 117556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getFallbackIcon(); 117656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 117756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 117856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.setIcon(icon); 117956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 118056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // from the resource 118156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (resolveInfo != null) { 118256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = resolveInfo.activityInfo.loadLabel(manager); 118356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 118456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // from the db 118556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (info.title == null) { 118656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (c != null) { 118756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = c.getString(titleIndex); 118856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 118956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 119056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // fall back to the class name of the activity 11919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (info.title == null) { 119256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = componentName.getClassName(); 11939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 11949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; 11959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return info; 11969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 119731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 11990589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * Make an ShortcutInfo object for a shortcut that isn't an application. 12009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 12010589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private ShortcutInfo getShortcutInfo(Cursor c, Context context, 120256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex, 120356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato int titleIndex) { 120431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 120556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap icon = null; 12060589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ShortcutInfo info = new ShortcutInfo(); 12079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; 12087376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project 12098ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato // TODO: If there's an explicit component and we can't install that, delete it. 12108ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato 121156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = c.getString(titleIndex); 121256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 12139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int iconType = c.getInt(iconTypeIndex); 12149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (iconType) { 12159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ICON_TYPE_RESOURCE: 12169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String packageName = c.getString(iconPackageIndex); 12179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String resourceName = c.getString(iconResourceIndex); 12189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato PackageManager packageManager = context.getPackageManager(); 121956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.customIcon = false; 122056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the resource 12219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 12229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Resources resources = packageManager.getResourcesForApplication(packageName); 122356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (resources != null) { 122456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final int id = resources.getIdentifier(resourceName, null, null); 122556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = Utilities.createIconBitmap(resources.getDrawable(id), context); 122656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 12279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } catch (Exception e) { 122856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // drop this. we have other places to look for icons 122956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 123056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the db 123156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 123256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getIconFromCursor(c, iconIndex); 123356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 123456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the fallback icon 123556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 123656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getFallbackIcon(); 123756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 12387376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project } 12399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 12409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ICON_TYPE_BITMAP: 124156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getIconFromCursor(c, iconIndex); 124256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 124356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getFallbackIcon(); 124456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.customIcon = false; 124556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 124656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } else { 124756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.customIcon = true; 12489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 12499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 12509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato default: 1251d8d22da5ca3e8d3e8d2e3616305b038d37486f32Joe Onorato icon = getFallbackIcon(); 125256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 12539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.customIcon = false; 12549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 125531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1256d8d22da5ca3e8d3e8d2e3616305b038d37486f32Joe Onorato info.setIcon(icon); 12579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return info; 1258f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 125931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 126056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap getIconFromCursor(Cursor c, int iconIndex) { 126156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (false) { 126256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Log.d(TAG, "getIconFromCursor app=" 126356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato + c.getString(c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE))); 126456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 126556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato byte[] data = c.getBlob(iconIndex); 126656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato try { 126756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato return BitmapFactory.decodeByteArray(data, 0, data.length); 126856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } catch (Exception e) { 126956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato return null; 127056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 127156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 127256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 12730589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutInfo addShortcut(Context context, Intent data, 12740589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato CellLayout.CellInfo cellInfo, boolean notify) { 12750589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 12760589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ShortcutInfo info = infoFromShortcutIntent(context, data); 12770589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato addItemToDatabase(context, info, LauncherSettings.Favorites.CONTAINER_DESKTOP, 12780589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato cellInfo.screen, cellInfo.cellX, cellInfo.cellY, notify); 12790589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 12800589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return info; 12810589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 12820589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 12830589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private ShortcutInfo infoFromShortcutIntent(Context context, Intent data) { 12840589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); 12850589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); 12860589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON); 12870589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 12880589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Bitmap icon = null; 12890589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato boolean filtered = false; 12900589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato boolean customIcon = false; 12910589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutIconResource iconResource = null; 12920589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 12930589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (bitmap != null && bitmap instanceof Bitmap) { 12940589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato icon = Utilities.createIconBitmap(new FastBitmapDrawable((Bitmap)bitmap), context); 12950589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato filtered = true; 12960589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato customIcon = true; 12970589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } else { 12980589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE); 12990589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (extra != null && extra instanceof ShortcutIconResource) { 13000589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato try { 13010589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato iconResource = (ShortcutIconResource) extra; 13020589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final PackageManager packageManager = context.getPackageManager(); 13030589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Resources resources = packageManager.getResourcesForApplication( 13040589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato iconResource.packageName); 13050589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final int id = resources.getIdentifier(iconResource.resourceName, null, null); 13060589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato icon = Utilities.createIconBitmap(resources.getDrawable(id), context); 13070589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } catch (Exception e) { 13080589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Log.w(TAG, "Could not load shortcut icon: " + extra); 13090589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 13100589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 13110589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 13120589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 131356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final ShortcutInfo info = new ShortcutInfo(); 131456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 13150589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (icon == null) { 131656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getFallbackIcon(); 131756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 13180589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 13190589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.setIcon(icon); 132056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 13210589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.title = name; 13220589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.intent = intent; 13230589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.customIcon = customIcon; 13240589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.iconResource = iconResource; 13250589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 13260589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return info; 13270589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 13280589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 13299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private static void loadLiveFolderIcon(Context context, Cursor c, int iconTypeIndex, 13309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int iconPackageIndex, int iconResourceIndex, LiveFolderInfo liveFolderInfo) { 133131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 13329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int iconType = c.getInt(iconTypeIndex); 13339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (iconType) { 13349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ICON_TYPE_RESOURCE: 13359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String packageName = c.getString(iconPackageIndex); 13369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String resourceName = c.getString(iconResourceIndex); 13379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato PackageManager packageManager = context.getPackageManager(); 13389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 13399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Resources resources = packageManager.getResourcesForApplication(packageName); 13409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int id = resources.getIdentifier(resourceName, null, null); 13410589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato liveFolderInfo.icon = Utilities.createIconBitmap(resources.getDrawable(id), 13420589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato context); 13439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } catch (Exception e) { 13440589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato liveFolderInfo.icon = Utilities.createIconBitmap( 13450589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato context.getResources().getDrawable(R.drawable.ic_launcher_folder), 13460589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato context); 13479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 13489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato liveFolderInfo.iconResource = new Intent.ShortcutIconResource(); 13499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato liveFolderInfo.iconResource.packageName = packageName; 13509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato liveFolderInfo.iconResource.resourceName = resourceName; 13519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 13529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato default: 13530589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato liveFolderInfo.icon = Utilities.createIconBitmap( 13540589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato context.getResources().getDrawable(R.drawable.ic_launcher_folder), 13550589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato context); 13569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 135731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1358bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project 135956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato void updateSavedIcon(Context context, ShortcutInfo info, Cursor c, int iconIndex) { 136056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // If this icon doesn't have a custom icon, check to see 136156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // what's stored in the DB, and if it doesn't match what 136256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // we're going to show, store what we are going to show back 136356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // into the DB. We do this so when we're loading, if the 136456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // package manager can't find an icon (for example because 136556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the app is on SD) then we can use that instead. 136656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (info.onExternalStorage && !info.customIcon && !info.usingFallbackIcon) { 136756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato boolean needSave; 136856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato byte[] data = c.getBlob(iconIndex); 136956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato try { 137056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (data != null) { 137156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap saved = BitmapFactory.decodeByteArray(data, 0, data.length); 137256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap loaded = info.getIcon(mIconCache); 137356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato needSave = !saved.sameAs(loaded); 137456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } else { 137556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato needSave = true; 137656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 137756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } catch (Exception e) { 137856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato needSave = true; 137956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 138056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (needSave) { 138156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Log.d(TAG, "going to save icon bitmap for info=" + info); 138256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // This is slower than is ideal, but this only happens either 138356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // after the froyo OTA or when the app is updated with a new 138456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // icon. 138556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato updateItemInDatabase(context, info); 138656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 138756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 138856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 138956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 139031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 13919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Return an existing UserFolderInfo object if we have encountered this ID previously, 13929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * or make a new one. 139331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 13949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private static UserFolderInfo findOrMakeUserFolder(HashMap<Long, FolderInfo> folders, long id) { 13959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // See if a placeholder was created for us already 13969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo folderInfo = folders.get(id); 13979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (folderInfo == null || !(folderInfo instanceof UserFolderInfo)) { 13989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // No placeholder -- create a new instance 13999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo = new UserFolderInfo(); 14009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folders.put(id, folderInfo); 140131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 14029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return (UserFolderInfo) folderInfo; 14039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 140431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 14069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a 14079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * new one. 14089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 14099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private static LiveFolderInfo findOrMakeLiveFolder(HashMap<Long, FolderInfo> folders, long id) { 14109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // See if a placeholder was created for us already 14119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo folderInfo = folders.get(id); 14129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (folderInfo == null || !(folderInfo instanceof LiveFolderInfo)) { 14139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // No placeholder -- create a new instance 14149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo = new LiveFolderInfo(); 14159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folders.put(id, folderInfo); 141631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 14179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return (LiveFolderInfo) folderInfo; 141831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 141931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 142031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static String getLabel(PackageManager manager, ActivityInfo activityInfo) { 142131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String label = activityInfo.loadLabel(manager).toString(); 142231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (label == null) { 142331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project label = manager.getApplicationLabel(activityInfo.applicationInfo).toString(); 142431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (label == null) { 142531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project label = activityInfo.name; 142631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 142731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 142831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return label; 142931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 143031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private static final Collator sCollator = Collator.getInstance(); 1432b0c27f254a9929be208d5e04554f438076c833bcJoe Onorato public static final Comparator<ApplicationInfo> APP_NAME_COMPARATOR 14339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato = new Comparator<ApplicationInfo>() { 14349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public final int compare(ApplicationInfo a, ApplicationInfo b) { 14359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return sCollator.compare(a.title.toString(), b.title.toString()); 143631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 14379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }; 1438be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato 1439be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato public void dumpState() { 1440be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mBeforeFirstLoad=" + mBeforeFirstLoad); 1441be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mCallbacks=" + mCallbacks); 1442be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.data", mAllAppsList.data); 1443be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.added", mAllAppsList.added); 1444be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.removed", mAllAppsList.removed); 1445be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.modified", mAllAppsList.modified); 1446be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato mLoader.dumpState(); 1447be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 144831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 1449