LauncherModel.java revision ac03330c9684f98b4dd067a87ca70d3e0be1cfed
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 65f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato private final LauncherApplication mApp; 669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private final Object mLock = new Object(); 679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private DeferredHandler mHandler = new DeferredHandler(); 689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private Loader mLoader = new Loader(); 699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 70f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato private boolean mBeforeFirstLoad = true; 719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private WeakReference<Callbacks> mCallbacks; 729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 730589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private AllAppsList mAllAppsList; 740589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private IconCache mIconCache; 750589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 760589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private Bitmap mDefaultIcon; 779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public interface Callbacks { 799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public int getCurrentWorkspaceScreen(); 809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void startBinding(); 819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end); 82ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato public void bindFolders(HashMap<Long,FolderInfo> folders); 839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void finishBindingItems(); 849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void bindAppWidget(LauncherAppWidgetInfo info); 859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void bindAllApplications(ArrayList<ApplicationInfo> apps); 8664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato public void bindAppsAdded(ArrayList<ApplicationInfo> apps); 8764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato public void bindAppsUpdated(ArrayList<ApplicationInfo> apps); 8864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato public void bindAppsRemoved(ArrayList<ApplicationInfo> apps); 899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 910589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato LauncherModel(LauncherApplication app, IconCache iconCache) { 92f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato mApp = app; 930589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mAllAppsList = new AllAppsList(iconCache); 940589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mIconCache = iconCache; 950589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 960589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mDefaultIcon = Utilities.createIconBitmap( 970589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato app.getPackageManager().getDefaultActivityIcon(), app); 980589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 990589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 10056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public Bitmap getFallbackIcon() { 1010589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return Bitmap.createBitmap(mDefaultIcon); 102f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato } 10331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 1059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Adds an item to the DB if it was not created previously, or move it to a new 1069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * <container, screen, cellX, cellY> 1079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 1089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container, 1099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int screen, int cellX, int cellY) { 1109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (item.container == ItemInfo.NO_ID) { 1119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // From all apps 1129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato addItemToDatabase(context, item, container, screen, cellX, cellY, false); 1139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } else { 1149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // From somewhere else 1159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato moveItemInDatabase(context, item, container, screen, cellX, cellY); 1169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 11831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 1209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Move an item in the DB to a new <container, screen, cellX, cellY> 1219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 1229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void moveItemInDatabase(Context context, ItemInfo item, long container, int screen, 1239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int cellX, int cellY) { 1249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.container = container; 1259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.screen = screen; 1269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellX = cellX; 1279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellY = cellY; 12831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 1309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 131bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project 1329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato values.put(LauncherSettings.Favorites.CONTAINER, item.container); 1339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato values.put(LauncherSettings.Favorites.CELLX, item.cellX); 1349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato values.put(LauncherSettings.Favorites.CELLY, item.cellY); 1359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato values.put(LauncherSettings.Favorites.SCREEN, item.screen); 136ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 1379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null); 13831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 13931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 1419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Returns true if the shortcuts already exists in the database. 1429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * we identify a shortcut by its title and intent. 143bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project */ 1449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static boolean shortcutExists(Context context, String title, Intent intent) { 1459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 1469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, 1479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato new String[] { "title", "intent" }, "title=? and intent=?", 1489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato new String[] { title, intent.toUri(0) }, null); 1499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato boolean result = false; 1509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 1519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato result = c.moveToFirst(); 1529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } finally { 1539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato c.close(); 1549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return result; 156bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project } 157bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project 158bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project /** 1599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Find a folder in the db, creating the FolderInfo if necessary, and adding it to folderList. 16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo getFolderById(Context context, HashMap<Long,FolderInfo> folderList, long id) { 1629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 1639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null, 1649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato "_id=? and (itemType=? or itemType=?)", 1659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato new String[] { String.valueOf(id), 1669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER), 1679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER) }, null); 168f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 1709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (c.moveToFirst()) { 1719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE); 1729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE); 1739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER); 1749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN); 1759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX); 1769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY); 177f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo folderInfo = null; 1799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (c.getInt(itemTypeIndex)) { 1809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER: 1819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo = findOrMakeUserFolder(folderList, id); 1829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 1839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER: 1849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo = findOrMakeLiveFolder(folderList, id); 1859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 1869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 18731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.title = c.getString(titleIndex); 1899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.id = id; 1909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.container = c.getInt(containerIndex); 1919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.screen = c.getInt(screenIndex); 1929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.cellX = c.getInt(cellXIndex); 1939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.cellY = c.getInt(cellYIndex); 194ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 1959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return folderInfo; 1969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } finally { 1989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato c.close(); 1992fcbd686d1c2a9a9e520116a541c9caae0c2dc60Romain Guy } 200ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 2019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 2029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 20331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 2059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Add an item to the database in a specified container. Sets the container, screen, cellX and 2069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * cellY fields of the item. Also assigns an ID to the item. 2079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 2089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void addItemToDatabase(Context context, ItemInfo item, long container, 2099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int screen, int cellX, int cellY, boolean notify) { 2109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.container = container; 2119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.screen = screen; 2129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellX = cellX; 2139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellY = cellY; 214ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 2159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 2169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 217ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 2189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.onAddToDatabase(values); 219ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 2209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Uri result = cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI : 2219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values); 222ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 2239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (result != null) { 2249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.id = Integer.parseInt(result.getPathSegments().get(1)); 22531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 2299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Update an item to the database in a specified container. 2309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 2319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void updateItemInDatabase(Context context, ItemInfo item) { 2329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 2339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 234f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.onAddToDatabase(values); 236ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 2379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null); 23831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 2419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Removes the specified item from the database 2429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * @param context 2439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * @param item 2449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 2459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void deleteItemFromDatabase(Context context, ItemInfo item) { 2469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 247f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato cr.delete(LauncherSettings.Favorites.getContentUri(item.id, false), null, null); 2499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 250f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 2529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Remove the contents of the specified folder from the database 2539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 2549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void deleteUserFolderContentsFromDatabase(Context context, UserFolderInfo info) { 2559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 256f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null); 2589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato cr.delete(LauncherSettings.Favorites.CONTENT_URI, 2599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.CONTAINER + "=" + info.id, null); 2609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 261f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 2639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Set this as the current Launcher activity object for the loader. 2649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 2659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void initialize(Callbacks callbacks) { 2669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 2679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mCallbacks = new WeakReference<Callbacks>(callbacks); 268f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 269f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 270f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void startLoader(Context context, boolean isLaunching) { 2729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoader.startLoader(context, isLaunching); 2739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 274f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void stopLoader() { 2769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoader.stopLoader(); 2779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 278f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2791d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato /** 2801d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato * We pick up most of the changes to all apps. 2811d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato */ 2821d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato public void setAllAppsDirty() { 2831d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato mLoader.setAllAppsDirty(); 2841d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato } 2851d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato 2869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void setWorkspaceDirty() { 2879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoader.setWorkspaceDirty(); 2889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 289f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 2919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Call from the handler for ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and 2929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * ACTION_PACKAGE_CHANGED. 2939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 294f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato public void onReceive(Context context, Intent intent) { 295f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato // Use the app as the context. 296f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato context = mApp; 297f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato 2989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato ArrayList<ApplicationInfo> added = null; 2999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato ArrayList<ApplicationInfo> removed = null; 3009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato ArrayList<ApplicationInfo> modified = null; 3019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 3029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 303f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato if (mBeforeFirstLoad) { 304f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato // If we haven't even loaded yet, don't bother, since we'll just pick 305f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato // up the changes. 306f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato return; 307f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato } 308f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato 3099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final String action = intent.getAction(); 3109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 31164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (Intent.ACTION_PACKAGE_CHANGED.equals(action) 31264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato || Intent.ACTION_PACKAGE_REMOVED.equals(action) 31364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato || Intent.ACTION_PACKAGE_ADDED.equals(action)) { 31464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato final String packageName = intent.getData().getSchemeSpecificPart(); 31564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 316f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 31764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName == null || packageName.length() == 0) { 31864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato // they sent us a bad intent 31964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato return; 3209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 32164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato 32264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) { 3239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mAllAppsList.updatePackage(context, packageName); 32464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { 32564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (!replacing) { 32664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato mAllAppsList.removePackage(packageName); 32764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 32864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato // else, we are replacing the package, so a PACKAGE_ADDED will be sent 32964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato // later, we will update the package at this time 33064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { 33164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (!replacing) { 33264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato mAllAppsList.addPackage(context, packageName); 33364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } else { 33464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato mAllAppsList.updatePackage(context, packageName); 33564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 33664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 33756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 33856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (mAllAppsList.added.size() > 0) { 33956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato added = mAllAppsList.added; 34056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mAllAppsList.added = new ArrayList<ApplicationInfo>(); 34156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 34256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (mAllAppsList.removed.size() > 0) { 34356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato removed = mAllAppsList.removed; 34456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mAllAppsList.removed = new ArrayList<ApplicationInfo>(); 34556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato for (ApplicationInfo info: removed) { 34656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mIconCache.remove(info.intent.getComponent()); 34756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 34856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 34956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (mAllAppsList.modified.size() > 0) { 35056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato modified = mAllAppsList.modified; 35156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mAllAppsList.modified = new ArrayList<ApplicationInfo>(); 35256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 35356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 35456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null; 35556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (callbacks == null) { 35656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Log.w(TAG, "Nobody to tell about the new app. Launcher is probably loading."); 35756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato return; 35856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 35956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 36056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (added != null) { 36156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final ArrayList<ApplicationInfo> addedFinal = added; 36256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mHandler.post(new Runnable() { 36356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public void run() { 36456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato callbacks.bindAppsAdded(addedFinal); 36556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 36656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato }); 36756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 36856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (modified != null) { 36956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final ArrayList<ApplicationInfo> modifiedFinal = modified; 37056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mHandler.post(new Runnable() { 37156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public void run() { 37256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato callbacks.bindAppsUpdated(modifiedFinal); 37356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 37456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato }); 37556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 37656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (removed != null) { 37756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final ArrayList<ApplicationInfo> removedFinal = removed; 37856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato mHandler.post(new Runnable() { 37956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public void run() { 38056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato callbacks.bindAppsRemoved(removedFinal); 38156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 38256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato }); 38356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 38464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } else { 38564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { 38664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato String packages[] = intent.getStringArrayExtra( 38764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato Intent.EXTRA_CHANGED_PACKAGE_LIST); 38864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packages == null || packages.length == 0) { 38964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato return; 39064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 39156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato setAllAppsDirty(); 39256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato setWorkspaceDirty(); 39356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato startLoader(context, false); 39464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 39564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato String packages[] = intent.getStringArrayExtra( 39664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato Intent.EXTRA_CHANGED_PACKAGE_LIST); 39764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packages == null || packages.length == 0) { 39864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato return; 39964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 40056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato setAllAppsDirty(); 40156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato setWorkspaceDirty(); 40256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato startLoader(context, false); 403f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 404f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 405f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 406f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 407f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public class Loader { 4099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private static final int ITEMS_CHUNK = 6; 410f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private LoaderThread mLoaderThread; 412f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private int mLastWorkspaceSeq = 0; 4149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private int mWorkspaceSeq = 1; 4159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 4169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private int mLastAllAppsSeq = 0; 4179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private int mAllAppsSeq = 1; 418f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 41984f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy final ArrayList<ItemInfo> mItems = new ArrayList<ItemInfo>(); 42084f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy final ArrayList<LauncherAppWidgetInfo> mAppWidgets = new ArrayList<LauncherAppWidgetInfo>(); 421ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato final HashMap<Long, FolderInfo> mFolders = new HashMap<Long, FolderInfo>(); 4229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 4239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 4249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Call this from the ui thread so the handler is initialized on the correct thread. 4259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 4269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public Loader() { 427f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 428f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void startLoader(Context context, boolean isLaunching) { 4309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 431a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 432a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "startLoader isLaunching=" + isLaunching); 433a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 4349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Don't bother to start the thread if we know it's not going to do anything 435ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato if (mCallbacks != null && mCallbacks.get() != null) { 4369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LoaderThread oldThread = mLoaderThread; 4379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (oldThread != null) { 4389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (oldThread.isLaunching()) { 4399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // don't downgrade isLaunching if we're already running 4409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato isLaunching = true; 4419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 4429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato oldThread.stopLocked(); 4439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 4449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoaderThread = new LoaderThread(context, oldThread, isLaunching); 4459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoaderThread.start(); 4469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 447b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy } 448b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy } 449b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy 4509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void stopLoader() { 4519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 4529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (mLoaderThread != null) { 4539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoaderThread.stopLocked(); 4549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 4559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 456f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 457b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy 4589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void setWorkspaceDirty() { 4599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 4609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mWorkspaceSeq++; 4619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 4629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 463f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void setAllAppsDirty() { 4659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 4669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mAllAppsSeq++; 467f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 468f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 469f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 4719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Runnable for the thread that loads the contents of the launcher: 4729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * - workspace icons 4739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * - widgets 4749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * - all apps icons 4759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 4769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private class LoaderThread extends Thread { 4779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private Context mContext; 4789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private Thread mWaitThread; 4799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private boolean mIsLaunching; 4809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private boolean mStopped; 4819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private boolean mWorkspaceDoneBinding; 4829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 4839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LoaderThread(Context context, Thread waitThread, boolean isLaunching) { 4849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mContext = context; 4859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mWaitThread = waitThread; 4869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mIsLaunching = isLaunching; 4879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 488f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato boolean isLaunching() { 4909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return mIsLaunching; 4919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 492f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 4939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 4949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * If another LoaderThread was supplied, we need to wait for that to finish before 4959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * we start our processing. This keeps the ordering of the setting and clearing 4969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * of the dirty flags correct by making sure we don't start processing stuff until 4979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * they've had a chance to re-set them. We do this waiting the worker thread, not 4989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * the ui thread to avoid ANRs. 4999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 5009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private void waitForOtherThread() { 5019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (mWaitThread != null) { 5029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato boolean done = false; 5039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato while (!done) { 5049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 5059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mWaitThread.join(); 506efabe00e4a51bb792366c459d6acc46832e61fdcJoe Onorato done = true; 5079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } catch (InterruptedException ex) { 50884f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy // Ignore 5099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mWaitThread = null; 5129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 514f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 5159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 5169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato waitForOtherThread(); 517f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 5189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Elevate priority when Home launches for the first time to avoid 5199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // starving at boot time. Staring at a blank home is not cool. 5209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 5219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato android.os.Process.setThreadPriority(mIsLaunching 5229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato ? Process.THREAD_PRIORITY_DEFAULT : Process.THREAD_PRIORITY_BACKGROUND); 5239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 524f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 5259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Load the workspace only if it's dirty. 5269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int workspaceSeq; 5279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato boolean workspaceDirty; 5289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 5299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato workspaceSeq = mWorkspaceSeq; 5309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato workspaceDirty = mWorkspaceSeq != mLastWorkspaceSeq; 5319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (workspaceDirty) { 5339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato loadWorkspace(); 5349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 5369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // If we're not stopped, and nobody has incremented mWorkspaceSeq. 5379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (mStopped) { 5389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return; 5399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (workspaceSeq == mWorkspaceSeq) { 5419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLastWorkspaceSeq = mWorkspaceSeq; 5429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 544f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 5459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Bind the workspace 5469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato bindWorkspace(); 5479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 5489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Wait until the either we're stopped or the other threads are done. 5499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // This way we don't start loading all apps until the workspace has settled 5509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // down. 5519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (LoaderThread.this) { 552080d9b614e609826dce2606f9e474af674ead933Joe Onorato mHandler.postIdle(new Runnable() { 5539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 5549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (LoaderThread.this) { 5559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mWorkspaceDoneBinding = true; 556a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 557a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "done with workspace"); 558a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 5599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LoaderThread.this.notify(); 5609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 563a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 564a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "waiting to be done with workspace"); 565a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 5669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato while (!mStopped && !mWorkspaceDoneBinding) { 5679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 5689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato this.wait(); 5699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } catch (InterruptedException ex) { 57084f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy // Ignore 5719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 573a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 574a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "done waiting to be done with workspace"); 575a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 5769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 577f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 5789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Load all apps if they're dirty 5799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int allAppsSeq; 5809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato boolean allAppsDirty; 5819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 5829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato allAppsSeq = mAllAppsSeq; 5839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato allAppsDirty = mAllAppsSeq != mLastAllAppsSeq; 584a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 585a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "mAllAppsSeq=" + mAllAppsSeq 586a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato + " mLastAllAppsSeq=" + mLastAllAppsSeq + " allAppsDirty"); 587a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 5889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (allAppsDirty) { 5909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato loadAllApps(); 5919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 5939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // If we're not stopped, and nobody has incremented mAllAppsSeq. 5949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (mStopped) { 5959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return; 5969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (allAppsSeq == mAllAppsSeq) { 5989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLastAllAppsSeq = mAllAppsSeq; 5999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 6009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 601f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Bind all apps 60334b02499432896b60cdb9f78c9d1019c80ef6ef5Joe Onorato if (allAppsDirty) { 60434b02499432896b60cdb9f78c9d1019c80ef6ef5Joe Onorato bindAllApps(); 60534b02499432896b60cdb9f78c9d1019c80ef6ef5Joe Onorato } 606f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Clear out this reference, otherwise we end up holding it until all of the 6089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // callback runnables are done. 6099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mContext = null; 610f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 6129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Setting the reference is atomic, but we can't do it inside the other critical 6139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // sections. 6149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mLoaderThread = null; 615f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 616f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 617f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void stopLocked() { 6199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (LoaderThread.this) { 6209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mStopped = true; 6219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato this.notify(); 6229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 623f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 624f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 6269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Gets the callbacks object. If we've been stopped, or if the launcher object 627c131b74922e6323331c374856bda830010d761c8Joe Onorato * has somehow been garbage collected, return null instead. Pass in the Callbacks 628c131b74922e6323331c374856bda830010d761c8Joe Onorato * object that was around when the deferred message was scheduled, and if there's 629c131b74922e6323331c374856bda830010d761c8Joe Onorato * a new Callbacks object around then also return null. This will save us from 630c131b74922e6323331c374856bda830010d761c8Joe Onorato * calling onto it with data that will be ignored. 6319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 632c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks tryGetCallbacks(Callbacks oldCallbacks) { 6339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 6349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (mStopped) { 6359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 6369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 6379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 638ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato if (mCallbacks == null) { 639ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato return null; 640ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato } 641ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato 6429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Callbacks callbacks = mCallbacks.get(); 643c131b74922e6323331c374856bda830010d761c8Joe Onorato if (callbacks != oldCallbacks) { 644c131b74922e6323331c374856bda830010d761c8Joe Onorato return null; 645c131b74922e6323331c374856bda830010d761c8Joe Onorato } 6469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks == null) { 6479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Log.w(TAG, "no mCallbacks"); 6489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 6499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 650f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return callbacks; 6529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 653f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 654f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private void loadWorkspace() { 6569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato long t = SystemClock.uptimeMillis(); 657f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Context context = mContext; 6599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver contentResolver = context.getContentResolver(); 6609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final PackageManager manager = context.getPackageManager(); 661629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final AppWidgetManager widgets = AppWidgetManager.getInstance(context); 6625c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy final boolean isSafeMode = manager.isSafeMode(); 663f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6643c2f7e105d8daab439bff2c362a727ad348d8a44Joe Onorato mItems.clear(); 665511ab64d25ee45518b816afa9110b3160edf3f7bJoe Onorato mAppWidgets.clear(); 6661db7a972bfa8786fc8b58d57f832a378fa731eb0Joe Onorato mFolders.clear(); 6673c2f7e105d8daab439bff2c362a727ad348d8a44Joe Onorato 6685c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy final ArrayList<Long> itemsToRemove = new ArrayList<Long>(); 6695c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 6709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Cursor c = contentResolver.query( 6719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.CONTENT_URI, null, null, null, null); 672f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 6749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID); 6759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int intentIndex = c.getColumnIndexOrThrow 6769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato (LauncherSettings.Favorites.INTENT); 6779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int titleIndex = c.getColumnIndexOrThrow 6789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato (LauncherSettings.Favorites.TITLE); 6799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int iconTypeIndex = c.getColumnIndexOrThrow( 6809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.ICON_TYPE); 6819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON); 6829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int iconPackageIndex = c.getColumnIndexOrThrow( 6839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.ICON_PACKAGE); 6849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int iconResourceIndex = c.getColumnIndexOrThrow( 6859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.ICON_RESOURCE); 6869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int containerIndex = c.getColumnIndexOrThrow( 6879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.CONTAINER); 6889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int itemTypeIndex = c.getColumnIndexOrThrow( 6899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.ITEM_TYPE); 6909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int appWidgetIdIndex = c.getColumnIndexOrThrow( 6919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.APPWIDGET_ID); 6929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int screenIndex = c.getColumnIndexOrThrow( 6939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.SCREEN); 6949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellXIndex = c.getColumnIndexOrThrow 6959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato (LauncherSettings.Favorites.CELLX); 6969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellYIndex = c.getColumnIndexOrThrow 6979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato (LauncherSettings.Favorites.CELLY); 6989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int spanXIndex = c.getColumnIndexOrThrow 6999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato (LauncherSettings.Favorites.SPANX); 7009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int spanYIndex = c.getColumnIndexOrThrow( 7019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.SPANY); 7029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI); 7039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int displayModeIndex = c.getColumnIndexOrThrow( 7049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherSettings.Favorites.DISPLAY_MODE); 7059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 7060589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutInfo info; 7079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String intentDescription; 7089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato LauncherAppWidgetInfo appWidgetInfo; 7099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int container; 7109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato long id; 7119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Intent intent; 7129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 7139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato while (!mStopped && c.moveToNext()) { 7149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 7159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int itemType = c.getInt(itemTypeIndex); 716f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 7179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (itemType) { 7189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 7199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 7209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato intentDescription = c.getString(intentIndex); 7219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 7229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato intent = Intent.parseUri(intentDescription, 0); 7239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } catch (URISyntaxException e) { 7249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato continue; 7259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 726f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 7279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { 72856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info = getShortcutInfo(manager, intent, context, c, iconIndex, 72956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato titleIndex); 7309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } else { 7310589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info = getShortcutInfo(c, context, iconTypeIndex, 73256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato iconPackageIndex, iconResourceIndex, iconIndex, 73356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato titleIndex); 7349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 735f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 7369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (info != null) { 73756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato updateSavedIcon(context, info, c, iconIndex); 7389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 73956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.intent = intent; 7409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.id = c.getLong(idIndex); 7419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato container = c.getInt(containerIndex); 7429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.container = container; 7439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.screen = c.getInt(screenIndex); 7449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.cellX = c.getInt(cellXIndex); 7459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.cellY = c.getInt(cellYIndex); 7469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 7479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (container) { 7489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.CONTAINER_DESKTOP: 7499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mItems.add(info); 7509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 7519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato default: 7529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Item is in a user folder 7539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato UserFolderInfo folderInfo = 754ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato findOrMakeUserFolder(mFolders, container); 7559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.add(info); 7569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 7579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 75856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } else { 75956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // Failed to load the shortcut, probably because the 76056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // activity manager couldn't resolve it (maybe the app 76156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // was uninstalled), or the db row was somehow screwed up. 76256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // Delete it. 76356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato id = c.getLong(idIndex); 76456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Log.e(TAG, "Error loading shortcut " + id + ", removing it"); 76556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato contentResolver.delete(LauncherSettings.Favorites.getContentUri( 76656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato id, false), null, null); 7679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 7689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 769f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 770ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER: 7719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato id = c.getLong(idIndex); 772ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato UserFolderInfo folderInfo = findOrMakeUserFolder(mFolders, id); 773f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 7749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.title = c.getString(titleIndex); 775f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 7769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.id = id; 7779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato container = c.getInt(containerIndex); 7789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.container = container; 7799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.screen = c.getInt(screenIndex); 7809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.cellX = c.getInt(cellXIndex); 7819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.cellY = c.getInt(cellYIndex); 782f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 7839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (container) { 7849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.CONTAINER_DESKTOP: 7859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mItems.add(folderInfo); 7869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 7879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 788ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato 789ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato mFolders.put(folderInfo.id, folderInfo); 7909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 791ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato 7929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER: 7939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato id = c.getLong(idIndex); 7945c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy Uri uri = Uri.parse(c.getString(uriIndex)); 7959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 7965c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy // Make sure the live folder exists 7975c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy final ProviderInfo providerInfo = 7985c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy context.getPackageManager().resolveContentProvider( 7995c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy uri.getAuthority(), 0); 800f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 8015c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy if (providerInfo == null && !isSafeMode) { 8025c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy itemsToRemove.add(id); 8035c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } else { 8045c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(mFolders, id); 8055c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 8065c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy intentDescription = c.getString(intentIndex); 8075c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy intent = null; 8085c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy if (intentDescription != null) { 8095c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy try { 8105c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy intent = Intent.parseUri(intentDescription, 0); 8115c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } catch (URISyntaxException e) { 8125c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy // Ignore, a live folder might not have a base intent 8135c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 8145c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 8155c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 8165c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.title = c.getString(titleIndex); 8175c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.id = id; 8185c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.uri = uri; 8195c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy container = c.getInt(containerIndex); 8205c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.container = container; 8215c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.screen = c.getInt(screenIndex); 8225c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.cellX = c.getInt(cellXIndex); 8235c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.cellY = c.getInt(cellYIndex); 8245c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.baseIntent = intent; 8255c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy liveFolderInfo.displayMode = c.getInt(displayModeIndex); 8265c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 8275c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy loadLiveFolderIcon(context, c, iconTypeIndex, iconPackageIndex, 8285c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy iconResourceIndex, liveFolderInfo); 8295c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 8305c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy switch (container) { 8315c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy case LauncherSettings.Favorites.CONTAINER_DESKTOP: 8325c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy mItems.add(liveFolderInfo); 8335c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy break; 8345c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 8355c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy mFolders.put(liveFolderInfo.id, liveFolderInfo); 8369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 8379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 838ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato 8399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 8409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Read all Launcher-specific widget details 8419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int appWidgetId = c.getInt(appWidgetIdIndex); 842629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy id = c.getLong(idIndex); 84331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 844629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final AppWidgetProviderInfo provider = 845629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy widgets.getAppWidgetInfo(appWidgetId); 846629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 847629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (!isSafeMode && (provider == null || provider.provider == null || 848629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy provider.provider.getPackageName() == null)) { 8498ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato Log.e(TAG, "Deleting widget that isn't installed anymore: id=" 8508ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato + id + " appWidgetId=" + appWidgetId); 851629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy itemsToRemove.add(id); 852629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else { 853629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId); 854629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.id = id; 855629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.screen = c.getInt(screenIndex); 856629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.cellX = c.getInt(cellXIndex); 857629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.cellY = c.getInt(cellYIndex); 858629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.spanX = c.getInt(spanXIndex); 859629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.spanY = c.getInt(spanYIndex); 860629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 861629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy container = c.getInt(containerIndex); 862629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) { 863629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy Log.e(TAG, "Widget found where container " 864629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy + "!= CONTAINER_DESKTOP -- ignoring!"); 865629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy continue; 866629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 867629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy appWidgetInfo.container = c.getInt(containerIndex); 868629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 869629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy mAppWidgets.add(appWidgetInfo); 8709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 8719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 8729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 8739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } catch (Exception e) { 8749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Log.w(TAG, "Desktop items loading interrupted:", e); 8759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 8769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 8779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } finally { 8789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato c.close(); 8799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 8805c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 8815c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy if (itemsToRemove.size() > 0) { 8825c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy ContentProviderClient client = contentResolver.acquireContentProviderClient( 8835c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy LauncherSettings.Favorites.CONTENT_URI); 8845c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy // Remove dead items 8855c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy for (long id : itemsToRemove) { 8865c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy if (DEBUG_LOADERS) { 8875c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy Log.d(TAG, "Removed id = " + id); 8885c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 8895c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy // Don't notify content observers 8905c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy try { 8915c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy client.delete(LauncherSettings.Favorites.getContentUri(id, false), 8925c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy null, null); 8935c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } catch (RemoteException e) { 8945c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy Log.w(TAG, "Could not remove id = " + id); 8955c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 8965c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 8975c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 8985c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 899a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 900a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms"); 901a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 9029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 90331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 9059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Read everything out of our database. 9069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 9079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private void bindWorkspace() { 9089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final long t = SystemClock.uptimeMillis(); 9099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 9109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Don't use these two variables in any of the callback runnables. 9119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Otherwise we hold a reference to them. 912c131b74922e6323331c374856bda830010d761c8Joe Onorato final Callbacks oldCallbacks = mCallbacks.get(); 913c131b74922e6323331c374856bda830010d761c8Joe Onorato if (oldCallbacks == null) { 9149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // This launcher has exited and nobody bothered to tell us. Just bail. 9159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Log.w(TAG, "LoaderThread running with no launcher"); 9169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return; 9179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 91831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int N; 9209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Tell the workspace that we're about to start firing items at it 9219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.post(new Runnable() { 9229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 923c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 9249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 9259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato callbacks.startBinding(); 9269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 9299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Add the items to the workspace. 9309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato N = mItems.size(); 9319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato for (int i=0; i<N; i+=ITEMS_CHUNK) { 9329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int start = i; 9339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int chunkSize = (i+ITEMS_CHUNK <= N) ? ITEMS_CHUNK : (N-i); 9349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.post(new Runnable() { 9359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 936c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 9379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 9389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato callbacks.bindItems(mItems, start, start+chunkSize); 9399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 9429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 943ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato mHandler.post(new Runnable() { 944ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato public void run() { 945c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 946ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato if (callbacks != null) { 947ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato callbacks.bindFolders(mFolders); 948ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato } 949ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato } 950ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato }); 9519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Wait until the queue goes empty. 9529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.postIdle(new Runnable() { 9539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 954a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 955a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "Going to start binding widgets soon."); 956a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 9579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 9599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Bind the widgets, one at a time. 9609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // WARNING: this is calling into the workspace from the background thread, 9619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // but since getCurrentScreen() just returns the int, we should be okay. This 9629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // is just a hint for the order, and if it's wrong, we'll be okay. 9639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // TODO: instead, we should have that push the current screen into here. 964c131b74922e6323331c374856bda830010d761c8Joe Onorato final int currentScreen = oldCallbacks.getCurrentWorkspaceScreen(); 9659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato N = mAppWidgets.size(); 9669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // once for the current screen 9679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato for (int i=0; i<N; i++) { 9689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final LauncherAppWidgetInfo widget = mAppWidgets.get(i); 9699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (widget.screen == currentScreen) { 9709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.post(new Runnable() { 9719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 972c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 9739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 9749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato callbacks.bindAppWidget(widget); 9759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 9789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // once for the other screens 9819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato for (int i=0; i<N; i++) { 9829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final LauncherAppWidgetInfo widget = mAppWidgets.get(i); 9839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (widget.screen != currentScreen) { 9849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.post(new Runnable() { 9859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 986c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 9879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 9889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato callbacks.bindAppWidget(widget); 9899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 9929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // Tell the workspace that we're done. 9959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.post(new Runnable() { 9969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 997c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 9989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 9999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato callbacks.finishBindingItems(); 10009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 10019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 10029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 10039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // If we're profiling, this is the last thing in the queue. 10049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.post(new Runnable() { 10059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 1006a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 1007a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "bound workspace in " 1008a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato + (SystemClock.uptimeMillis()-t) + "ms"); 1009a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 10109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (Launcher.PROFILE_ROTATE) { 10119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato android.os.Debug.stopMethodTracing(); 10129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 10139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 10149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 10159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 101631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private void loadAllApps() { 10189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); 10199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); 102031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1021c131b74922e6323331c374856bda830010d761c8Joe Onorato final Callbacks callbacks = mCallbacks.get(); 10229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks == null) { 10239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return; 10249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 102531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10260589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final PackageManager packageManager = mContext.getPackageManager(); 10279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final List<ResolveInfo> apps = packageManager.queryIntentActivities(mainIntent, 0); 102831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 1030f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato mBeforeFirstLoad = false; 1031f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato 10329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mAllAppsList.clear(); 10339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (apps != null) { 10349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato long t = SystemClock.uptimeMillis(); 103531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int N = apps.size(); 10379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato for (int i=0; i<N && !mStopped; i++) { 10389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // This builds the icon bitmaps. 10390589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mAllAppsList.add(new ApplicationInfo(apps.get(i), mIconCache)); 10409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1041b0c27f254a9929be208d5e04554f438076c833bcJoe Onorato Collections.sort(mAllAppsList.data, APP_NAME_COMPARATOR); 1042b0c27f254a9929be208d5e04554f438076c833bcJoe Onorato Collections.sort(mAllAppsList.added, APP_NAME_COMPARATOR); 1043a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 1044a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "cached app icons in " 1045a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato + (SystemClock.uptimeMillis()-t) + "ms"); 1046a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 1047ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project } 104831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 104931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 105031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private void bindAllApps() { 10529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 10530c4513e55904b022a161456d699d6c1f414f0936Joe Onorato final ArrayList<ApplicationInfo> results 10545c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy = (ArrayList<ApplicationInfo>) mAllAppsList.data.clone(); 10550c4513e55904b022a161456d699d6c1f414f0936Joe Onorato // We're adding this now, so clear out this so we don't re-send them. 105684f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy mAllAppsList.added = new ArrayList<ApplicationInfo>(); 1057c131b74922e6323331c374856bda830010d761c8Joe Onorato final Callbacks old = mCallbacks.get(); 10589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.post(new Runnable() { 10599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 106034b02499432896b60cdb9f78c9d1019c80ef6ef5Joe Onorato final long t = SystemClock.uptimeMillis(); 106134b02499432896b60cdb9f78c9d1019c80ef6ef5Joe Onorato final int count = results.size(); 10629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 1063c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(old); 10649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 10659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato callbacks.bindAllApplications(results); 10669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 10679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 1068a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato if (DEBUG_LOADERS) { 1069a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(TAG, "bound app " + count + " icons in " 10705c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy + (SystemClock.uptimeMillis() - t) + "ms"); 1071a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 10729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 10739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }); 10749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 107531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1076be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato 1077be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato public void dumpState() { 1078be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLoaderThread.mContext=" + mContext); 1079be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLoaderThread.mWaitThread=" + mWaitThread); 1080be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLoaderThread.mIsLaunching=" + mIsLaunching); 1081be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLoaderThread.mStopped=" + mStopped); 1082be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLoaderThread.mWorkspaceDoneBinding=" + mWorkspaceDoneBinding); 1083be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 1084be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 1085be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato 1086be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato public void dumpState() { 1087be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLastWorkspaceSeq=" + mLoader.mLastWorkspaceSeq); 1088be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mWorkspaceSeq=" + mLoader.mWorkspaceSeq); 1089be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLastAllAppsSeq=" + mLoader.mLastAllAppsSeq); 1090be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mAllAppsSeq=" + mLoader.mAllAppsSeq); 1091be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mItems size=" + mLoader.mItems.size()); 1092be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato if (mLoaderThread != null) { 1093be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato mLoaderThread.dumpState(); 1094be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } else { 1095be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mLoader.mLoaderThread=null"); 1096be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 109731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 109831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 109931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 110156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * This is called from the code that adds shortcuts from the intent receiver. This 110256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * doesn't have a Cursor, but 11039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 110456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public ShortcutInfo getShortcutInfo(PackageManager manager, Intent intent, Context context) { 1105e74daedc3b41d958315f7d5bf69deb232ca89468Joe Onorato return getShortcutInfo(manager, intent, context, null, -1, -1); 110656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 110756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 110856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato /** 110956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * Make an ShortcutInfo object for a shortcut that is an application. 111056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * 111156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * If c is not null, then it will be used to fill in missing data like the title and icon. 111256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato */ 111356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public ShortcutInfo getShortcutInfo(PackageManager manager, Intent intent, Context context, 111456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Cursor c, int iconIndex, int titleIndex) { 111556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap icon = null; 111656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final ShortcutInfo info = new ShortcutInfo(); 111731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 111856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato ComponentName componentName = intent.getComponent(); 111956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (componentName == null) { 11209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 112131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 112231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11238ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato // TODO: See if the PackageManager knows about this case. If it doesn't 11248ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato // then return null & delete this. 11258ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato 112656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the resource -- This may implicitly give us back the fallback icon, 112756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // but don't worry about that. All we're doing with usingFallbackIcon is 112856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // to avoid saving lots of copies of that in the database, and most apps 112956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // have icons anyway. 113056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final ResolveInfo resolveInfo = manager.resolveActivity(intent, 0); 113156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (resolveInfo != null) { 113256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = mIconCache.getIcon(componentName, resolveInfo); 113356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 113456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the db 113556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 113656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (c != null) { 113756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getIconFromCursor(c, iconIndex); 113856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 11399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 114056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the fallback icon 114156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 114256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getFallbackIcon(); 114356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 114456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 114556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.setIcon(icon); 114656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 114756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // from the resource 114856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (resolveInfo != null) { 114956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = resolveInfo.activityInfo.loadLabel(manager); 115056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 115156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // from the db 115256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (info.title == null) { 115356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (c != null) { 115456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = c.getString(titleIndex); 115556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 115656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 115756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // fall back to the class name of the activity 11589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (info.title == null) { 115956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = componentName.getClassName(); 11609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 11619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; 11629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return info; 11639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 116431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 11660589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * Make an ShortcutInfo object for a shortcut that isn't an application. 11679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 11680589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private ShortcutInfo getShortcutInfo(Cursor c, Context context, 116956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex, 117056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato int titleIndex) { 117131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 117256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap icon = null; 11730589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ShortcutInfo info = new ShortcutInfo(); 11749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; 11757376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project 11768ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato // TODO: If there's an explicit component and we can't install that, delete it. 11778ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato 117856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = c.getString(titleIndex); 117956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 11809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int iconType = c.getInt(iconTypeIndex); 11819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (iconType) { 11829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ICON_TYPE_RESOURCE: 11839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String packageName = c.getString(iconPackageIndex); 11849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String resourceName = c.getString(iconResourceIndex); 11859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato PackageManager packageManager = context.getPackageManager(); 118656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.customIcon = false; 118756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the resource 11889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 11899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Resources resources = packageManager.getResourcesForApplication(packageName); 119056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (resources != null) { 119156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final int id = resources.getIdentifier(resourceName, null, null); 119256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = Utilities.createIconBitmap(resources.getDrawable(id), context); 119356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 11949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } catch (Exception e) { 119556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // drop this. we have other places to look for icons 119656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 119756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the db 119856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 119956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getIconFromCursor(c, iconIndex); 120056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 120156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the fallback icon 120256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 120356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getFallbackIcon(); 120456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 12057376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project } 12069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 12079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ICON_TYPE_BITMAP: 120856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getIconFromCursor(c, iconIndex); 120956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 121056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getFallbackIcon(); 121156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.customIcon = false; 121256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 121356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } else { 121456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.customIcon = true; 12159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 12169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 12179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato default: 1218d8d22da5ca3e8d3e8d2e3616305b038d37486f32Joe Onorato icon = getFallbackIcon(); 121956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 12209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.customIcon = false; 12219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 122231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1223d8d22da5ca3e8d3e8d2e3616305b038d37486f32Joe Onorato info.setIcon(icon); 12249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return info; 1225f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 122631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 122756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap getIconFromCursor(Cursor c, int iconIndex) { 122856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (false) { 122956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Log.d(TAG, "getIconFromCursor app=" 123056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato + c.getString(c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE))); 123156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 123256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato byte[] data = c.getBlob(iconIndex); 123356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato try { 123456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato return BitmapFactory.decodeByteArray(data, 0, data.length); 123556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } catch (Exception e) { 123656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato return null; 123756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 123856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 123956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 12400589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutInfo addShortcut(Context context, Intent data, 12410589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato CellLayout.CellInfo cellInfo, boolean notify) { 12420589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 12430589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ShortcutInfo info = infoFromShortcutIntent(context, data); 12440589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato addItemToDatabase(context, info, LauncherSettings.Favorites.CONTAINER_DESKTOP, 12450589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato cellInfo.screen, cellInfo.cellX, cellInfo.cellY, notify); 12460589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 12470589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return info; 12480589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 12490589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 12500589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private ShortcutInfo infoFromShortcutIntent(Context context, Intent data) { 12510589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); 12520589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); 12530589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON); 12540589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 12550589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Bitmap icon = null; 12560589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato boolean filtered = false; 12570589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato boolean customIcon = false; 12580589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutIconResource iconResource = null; 12590589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 12600589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (bitmap != null && bitmap instanceof Bitmap) { 12610589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato icon = Utilities.createIconBitmap(new FastBitmapDrawable((Bitmap)bitmap), context); 12620589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato filtered = true; 12630589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato customIcon = true; 12640589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } else { 12650589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE); 12660589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (extra != null && extra instanceof ShortcutIconResource) { 12670589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato try { 12680589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato iconResource = (ShortcutIconResource) extra; 12690589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final PackageManager packageManager = context.getPackageManager(); 12700589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Resources resources = packageManager.getResourcesForApplication( 12710589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato iconResource.packageName); 12720589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final int id = resources.getIdentifier(iconResource.resourceName, null, null); 12730589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato icon = Utilities.createIconBitmap(resources.getDrawable(id), context); 12740589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } catch (Exception e) { 12750589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Log.w(TAG, "Could not load shortcut icon: " + extra); 12760589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 12770589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 12780589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 12790589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 128056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final ShortcutInfo info = new ShortcutInfo(); 128156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 12820589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (icon == null) { 128356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getFallbackIcon(); 128456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 12850589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 12860589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.setIcon(icon); 128756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 12880589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.title = name; 12890589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.intent = intent; 12900589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.customIcon = customIcon; 12910589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.iconResource = iconResource; 12920589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 12930589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return info; 12940589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 12950589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 12969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private static void loadLiveFolderIcon(Context context, Cursor c, int iconTypeIndex, 12979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int iconPackageIndex, int iconResourceIndex, LiveFolderInfo liveFolderInfo) { 129831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 12999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int iconType = c.getInt(iconTypeIndex); 13009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (iconType) { 13019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ICON_TYPE_RESOURCE: 13029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String packageName = c.getString(iconPackageIndex); 13039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String resourceName = c.getString(iconResourceIndex); 13049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato PackageManager packageManager = context.getPackageManager(); 13059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 13069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Resources resources = packageManager.getResourcesForApplication(packageName); 13079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int id = resources.getIdentifier(resourceName, null, null); 13080589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato liveFolderInfo.icon = Utilities.createIconBitmap(resources.getDrawable(id), 13090589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato context); 13109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } catch (Exception e) { 13110589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato liveFolderInfo.icon = Utilities.createIconBitmap( 13120589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato context.getResources().getDrawable(R.drawable.ic_launcher_folder), 13130589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato context); 13149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 13159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato liveFolderInfo.iconResource = new Intent.ShortcutIconResource(); 13169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato liveFolderInfo.iconResource.packageName = packageName; 13179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato liveFolderInfo.iconResource.resourceName = resourceName; 13189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 13199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato default: 13200589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato liveFolderInfo.icon = Utilities.createIconBitmap( 13210589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato context.getResources().getDrawable(R.drawable.ic_launcher_folder), 13220589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato context); 13239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 132431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1325bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project 132656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato void updateSavedIcon(Context context, ShortcutInfo info, Cursor c, int iconIndex) { 132756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // If this icon doesn't have a custom icon, check to see 132856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // what's stored in the DB, and if it doesn't match what 132956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // we're going to show, store what we are going to show back 133056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // into the DB. We do this so when we're loading, if the 133156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // package manager can't find an icon (for example because 133256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the app is on SD) then we can use that instead. 133356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (info.onExternalStorage && !info.customIcon && !info.usingFallbackIcon) { 133456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato boolean needSave; 133556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato byte[] data = c.getBlob(iconIndex); 133656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato try { 133756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (data != null) { 133856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap saved = BitmapFactory.decodeByteArray(data, 0, data.length); 133956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap loaded = info.getIcon(mIconCache); 134056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato needSave = !saved.sameAs(loaded); 134156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } else { 134256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato needSave = true; 134356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 134456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } catch (Exception e) { 134556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato needSave = true; 134656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 134756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (needSave) { 134856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Log.d(TAG, "going to save icon bitmap for info=" + info); 134956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // This is slower than is ideal, but this only happens either 135056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // after the froyo OTA or when the app is updated with a new 135156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // icon. 135256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato updateItemInDatabase(context, info); 135356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 135456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 135556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 135656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 135731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 13589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Return an existing UserFolderInfo object if we have encountered this ID previously, 13599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * or make a new one. 136031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 13619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private static UserFolderInfo findOrMakeUserFolder(HashMap<Long, FolderInfo> folders, long id) { 13629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // See if a placeholder was created for us already 13639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo folderInfo = folders.get(id); 13649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (folderInfo == null || !(folderInfo instanceof UserFolderInfo)) { 13659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // No placeholder -- create a new instance 13669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo = new UserFolderInfo(); 13679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folders.put(id, folderInfo); 136831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 13699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return (UserFolderInfo) folderInfo; 13709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 137131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 13729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 13739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a 13749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * new one. 13759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 13769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private static LiveFolderInfo findOrMakeLiveFolder(HashMap<Long, FolderInfo> folders, long id) { 13779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // See if a placeholder was created for us already 13789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo folderInfo = folders.get(id); 13799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (folderInfo == null || !(folderInfo instanceof LiveFolderInfo)) { 13809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // No placeholder -- create a new instance 13819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo = new LiveFolderInfo(); 13829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folders.put(id, folderInfo); 138331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 13849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return (LiveFolderInfo) folderInfo; 138531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 138631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 138731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static String getLabel(PackageManager manager, ActivityInfo activityInfo) { 138831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String label = activityInfo.loadLabel(manager).toString(); 138931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (label == null) { 139031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project label = manager.getApplicationLabel(activityInfo.applicationInfo).toString(); 139131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (label == null) { 139231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project label = activityInfo.name; 139331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 139431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 139531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return label; 139631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 139731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 13989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private static final Collator sCollator = Collator.getInstance(); 1399b0c27f254a9929be208d5e04554f438076c833bcJoe Onorato public static final Comparator<ApplicationInfo> APP_NAME_COMPARATOR 14009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato = new Comparator<ApplicationInfo>() { 14019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public final int compare(ApplicationInfo a, ApplicationInfo b) { 14029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return sCollator.compare(a.title.toString(), b.title.toString()); 140331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 14049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato }; 1405be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato 1406be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato public void dumpState() { 1407be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mBeforeFirstLoad=" + mBeforeFirstLoad); 1408be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mCallbacks=" + mCallbacks); 1409be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.data", mAllAppsList.data); 1410be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.added", mAllAppsList.added); 1411be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.removed", mAllAppsList.removed); 1412be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.modified", mAllAppsList.modified); 1413be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato mLoader.dumpState(); 1414be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 141531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 1416