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