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