LauncherModel.java revision d65d08e709ec0916446100bae0a7276d0800382f
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
65d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato    private int mBatchSize; // 0 is all apps at once
662ff10b3b0137d258569ce5471808842e88696133Daniel Sandler    private int mAllAppsLoadDelay; // milliseconds between batches
67dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler
68f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato    private final LauncherApplication mApp;
699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private final Object mLock = new Object();
709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private DeferredHandler mHandler = new DeferredHandler();
719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private Loader mLoader = new Loader();
729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
73d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato    private boolean mBeforeFirstLoad = true; // only access this from main thread
749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private WeakReference<Callbacks> mCallbacks;
759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
760589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato    private AllAppsList mAllAppsList;
770589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato    private IconCache mIconCache;
780589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato
790589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato    private Bitmap mDefaultIcon;
809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public interface Callbacks {
829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public int getCurrentWorkspaceScreen();
839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void startBinding();
849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end);
85ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato        public void bindFolders(HashMap<Long,FolderInfo> folders);
869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void finishBindingItems();
879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void bindAppWidget(LauncherAppWidgetInfo info);
889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void bindAllApplications(ArrayList<ApplicationInfo> apps);
8964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato        public void bindAppsAdded(ArrayList<ApplicationInfo> apps);
9064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato        public void bindAppsUpdated(ArrayList<ApplicationInfo> apps);
9164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato        public void bindAppsRemoved(ArrayList<ApplicationInfo> apps);
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);
103d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato
104d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato        mBatchSize = app.getResources().getInteger(R.integer.config_allAppsBatchSize);
1050589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato    }
1060589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato
10756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato    public Bitmap getFallbackIcon() {
1080589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        return Bitmap.createBitmap(mDefaultIcon);
109f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato    }
11031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
1129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Adds an item to the DB if it was not created previously, or move it to a new
1139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * <container, screen, cellX, cellY>
1149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
1159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container,
1169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            int screen, int cellX, int cellY) {
1179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (item.container == ItemInfo.NO_ID) {
1189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            // From all apps
1199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            addItemToDatabase(context, item, container, screen, cellX, cellY, false);
1209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        } else {
1219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            // From somewhere else
1229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            moveItemInDatabase(context, item, container, screen, cellX, cellY);
1239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
1249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
12531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
1279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Move an item in the DB to a new <container, screen, cellX, cellY>
1289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
1299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static void moveItemInDatabase(Context context, ItemInfo item, long container, int screen,
1309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            int cellX, int cellY) {
1319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.container = container;
1329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.screen = screen;
1339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.cellX = cellX;
1349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.cellY = cellY;
13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentValues values = new ContentValues();
1379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
138bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
1399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        values.put(LauncherSettings.Favorites.CONTAINER, item.container);
1409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        values.put(LauncherSettings.Favorites.CELLX, item.cellX);
1419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        values.put(LauncherSettings.Favorites.CELLY, item.cellY);
1429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        values.put(LauncherSettings.Favorites.SCREEN, item.screen);
143ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
1449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
14531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
14631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
14731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
1489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Returns true if the shortcuts already exists in the database.
1499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * we identify a shortcut by its title and intent.
150bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     */
1519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static boolean shortcutExists(Context context, String title, Intent intent) {
1529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
1539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
1549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            new String[] { "title", "intent" }, "title=? and intent=?",
1559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            new String[] { title, intent.toUri(0) }, null);
1569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        boolean result = false;
1579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        try {
1589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            result = c.moveToFirst();
1599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        } finally {
1609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            c.close();
1619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
1629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        return result;
163bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    }
164bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
165bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    /**
1669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Find a folder in the db, creating the FolderInfo if necessary, and adding it to folderList.
16731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
1689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    FolderInfo getFolderById(Context context, HashMap<Long,FolderInfo> folderList, long id) {
1699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
1709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null,
1719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                "_id=? and (itemType=? or itemType=?)",
1729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                new String[] { String.valueOf(id),
1739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER),
1749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER) }, null);
175f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
1769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        try {
1779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (c.moveToFirst()) {
1789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
1799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
1809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
1819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
1829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
1839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
184f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
1859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                FolderInfo folderInfo = null;
1869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                switch (c.getInt(itemTypeIndex)) {
1879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
1889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        folderInfo = findOrMakeUserFolder(folderList, id);
1899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        break;
1909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
1919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        folderInfo = findOrMakeLiveFolder(folderList, id);
1929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        break;
1939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
19431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                folderInfo.title = c.getString(titleIndex);
1969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                folderInfo.id = id;
1979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                folderInfo.container = c.getInt(containerIndex);
1989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                folderInfo.screen = c.getInt(screenIndex);
1999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                folderInfo.cellX = c.getInt(cellXIndex);
2009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                folderInfo.cellY = c.getInt(cellYIndex);
201ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
2029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                return folderInfo;
2039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
2049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        } finally {
2059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            c.close();
2062fcbd686d1c2a9a9e520116a541c9caae0c2dc60Romain Guy        }
207ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
2089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        return null;
2099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
21031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
2119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
2129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Add an item to the database in a specified container. Sets the container, screen, cellX and
2139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * cellY fields of the item. Also assigns an ID to the item.
2149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
2159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static void addItemToDatabase(Context context, ItemInfo item, long container,
2169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            int screen, int cellX, int cellY, boolean notify) {
2179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.container = container;
2189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.screen = screen;
2199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.cellX = cellX;
2209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.cellY = cellY;
221ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
2229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentValues values = new ContentValues();
2239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
224ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
2259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.onAddToDatabase(values);
226ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
2279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        Uri result = cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI :
2289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values);
229ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
2309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (result != null) {
2319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            item.id = Integer.parseInt(result.getPathSegments().get(1));
23231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
23331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
23431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
2359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
2369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Update an item to the database in a specified container.
2379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
2389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static void updateItemInDatabase(Context context, ItemInfo item) {
2399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentValues values = new ContentValues();
2409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
241f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.onAddToDatabase(values);
243ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
2449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
24531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
24631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
2479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
2489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Removes the specified item from the database
2499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * @param context
2509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * @param item
2519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
2529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static void deleteItemFromDatabase(Context context, ItemInfo item) {
2539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
254f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        cr.delete(LauncherSettings.Favorites.getContentUri(item.id, false), null, null);
2569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
257f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
2599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Remove the contents of the specified folder from the database
2609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
2619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static void deleteUserFolderContentsFromDatabase(Context context, UserFolderInfo info) {
2629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
263f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null);
2659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        cr.delete(LauncherSettings.Favorites.CONTENT_URI,
2669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
2679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
268f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
2709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Set this as the current Launcher activity object for the loader.
2719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
2729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void initialize(Callbacks callbacks) {
2739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        synchronized (mLock) {
2749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            mCallbacks = new WeakReference<Callbacks>(callbacks);
275f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
276f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
277f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void startLoader(Context context, boolean isLaunching) {
2799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        mLoader.startLoader(context, isLaunching);
2809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
281f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void stopLoader() {
2839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        mLoader.stopLoader();
2849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
285f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2861d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato    /**
2871d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato     * We pick up most of the changes to all apps.
2881d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato     */
2891d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato    public void setAllAppsDirty() {
2901d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato        mLoader.setAllAppsDirty();
2911d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato    }
2921d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato
2939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void setWorkspaceDirty() {
2949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        mLoader.setWorkspaceDirty();
2959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
296f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
2989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Call from the handler for ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and
2999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * ACTION_PACKAGE_CHANGED.
3009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
301f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato    public void onReceive(Context context, Intent intent) {
302f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato        // Use the app as the context.
303f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato        context = mApp;
304f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato
3059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        ArrayList<ApplicationInfo> added = null;
3069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        ArrayList<ApplicationInfo> removed = null;
3079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        ArrayList<ApplicationInfo> modified = null;
3089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
3099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        synchronized (mLock) {
310f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato            if (mBeforeFirstLoad) {
311f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato                // If we haven't even loaded yet, don't bother, since we'll just pick
312f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato                // up the changes.
313f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato                return;
314f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato            }
315f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato
3169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            final String action = intent.getAction();
3179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
31864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato            if (Intent.ACTION_PACKAGE_CHANGED.equals(action)
31964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                    || Intent.ACTION_PACKAGE_REMOVED.equals(action)
32064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                    || Intent.ACTION_PACKAGE_ADDED.equals(action)) {
32164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                final String packageName = intent.getData().getSchemeSpecificPart();
32264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
323f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
32464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                if (packageName == null || packageName.length() == 0) {
32564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                    // they sent us a bad intent
32664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                    return;
3279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
32864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato
32964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
3309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mAllAppsList.updatePackage(context, packageName);
33164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
33264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                    if (!replacing) {
33364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                        mAllAppsList.removePackage(packageName);
33464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                    }
33564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                    // else, we are replacing the package, so a PACKAGE_ADDED will be sent
33664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                    // later, we will update the package at this time
33764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
33864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                    if (!replacing) {
33964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                        mAllAppsList.addPackage(context, packageName);
34064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                    } else {
34164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                        mAllAppsList.updatePackage(context, packageName);
34264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                    }
34364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                }
34456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato
34556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                if (mAllAppsList.added.size() > 0) {
34656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    added = mAllAppsList.added;
34756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    mAllAppsList.added = new ArrayList<ApplicationInfo>();
34856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                }
34956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                if (mAllAppsList.removed.size() > 0) {
35056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    removed = mAllAppsList.removed;
35156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    mAllAppsList.removed = new ArrayList<ApplicationInfo>();
35256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    for (ApplicationInfo info: removed) {
35356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                        mIconCache.remove(info.intent.getComponent());
35456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    }
35556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                }
35656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                if (mAllAppsList.modified.size() > 0) {
35756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    modified = mAllAppsList.modified;
35856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    mAllAppsList.modified = new ArrayList<ApplicationInfo>();
35956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                }
36056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato
36156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
36256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                if (callbacks == null) {
36356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    Log.w(TAG, "Nobody to tell about the new app.  Launcher is probably loading.");
36456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    return;
36556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                }
36656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato
36756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                if (added != null) {
36856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    final ArrayList<ApplicationInfo> addedFinal = added;
36956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    mHandler.post(new Runnable() {
37056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                        public void run() {
37156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                            callbacks.bindAppsAdded(addedFinal);
37256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                        }
37356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    });
37456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                }
37556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                if (modified != null) {
37656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    final ArrayList<ApplicationInfo> modifiedFinal = modified;
37756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    mHandler.post(new Runnable() {
37856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                        public void run() {
37956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                            callbacks.bindAppsUpdated(modifiedFinal);
38056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                        }
38156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    });
38256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                }
38356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                if (removed != null) {
38456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    final ArrayList<ApplicationInfo> removedFinal = removed;
38556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    mHandler.post(new Runnable() {
38656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                        public void run() {
38756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                            callbacks.bindAppsRemoved(removedFinal);
38856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                        }
38956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    });
39056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                }
39164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato            } else {
39264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
39364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                     String packages[] = intent.getStringArrayExtra(
39464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                             Intent.EXTRA_CHANGED_PACKAGE_LIST);
39564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                     if (packages == null || packages.length == 0) {
39664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                         return;
39764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                     }
39856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                     setAllAppsDirty();
39956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                     setWorkspaceDirty();
40056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                     startLoader(context, false);
40164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
40264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                     String packages[] = intent.getStringArrayExtra(
40364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                             Intent.EXTRA_CHANGED_PACKAGE_LIST);
40464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                     if (packages == null || packages.length == 0) {
40564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                         return;
40664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                     }
40756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                     setAllAppsDirty();
40856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                     setWorkspaceDirty();
40956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                     startLoader(context, false);
410f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                }
411f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
412f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
413f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
414f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public class Loader {
4169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private static final int ITEMS_CHUNK = 6;
417f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private LoaderThread mLoaderThread;
419f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private int mLastWorkspaceSeq = 0;
4219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private int mWorkspaceSeq = 1;
4229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
4239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private int mLastAllAppsSeq = 0;
4249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private int mAllAppsSeq = 1;
425f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
42684f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy        final ArrayList<ItemInfo> mItems = new ArrayList<ItemInfo>();
42784f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy        final ArrayList<LauncherAppWidgetInfo> mAppWidgets = new ArrayList<LauncherAppWidgetInfo>();
428ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato        final HashMap<Long, FolderInfo> mFolders = new HashMap<Long, FolderInfo>();
4299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
4309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        /**
4319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         * Call this from the ui thread so the handler is initialized on the correct thread.
4329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         */
4339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public Loader() {
434f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
435f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void startLoader(Context context, boolean isLaunching) {
4379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            synchronized (mLock) {
438a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                if (DEBUG_LOADERS) {
439a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                    Log.d(TAG, "startLoader isLaunching=" + isLaunching);
440a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                }
4419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Don't bother to start the thread if we know it's not going to do anything
442ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato                if (mCallbacks != null && mCallbacks.get() != null) {
4439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    LoaderThread oldThread = mLoaderThread;
4449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (oldThread != null) {
4459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        if (oldThread.isLaunching()) {
4469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            // don't downgrade isLaunching if we're already running
4479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            isLaunching = true;
4489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
4499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        oldThread.stopLocked();
4509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
4519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mLoaderThread = new LoaderThread(context, oldThread, isLaunching);
4529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mLoaderThread.start();
4539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
454b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy            }
455b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy        }
456b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy
4579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void stopLoader() {
4589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            synchronized (mLock) {
4599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (mLoaderThread != null) {
4609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mLoaderThread.stopLocked();
4619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
4629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
463f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
464b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy
4659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void setWorkspaceDirty() {
4669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            synchronized (mLock) {
4679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mWorkspaceSeq++;
4689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
4699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
470f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void setAllAppsDirty() {
4729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            synchronized (mLock) {
4739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mAllAppsSeq++;
474f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
475f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
476f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        /**
4789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         * Runnable for the thread that loads the contents of the launcher:
4799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         *   - workspace icons
4809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         *   - widgets
4819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         *   - all apps icons
4829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         */
4839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private class LoaderThread extends Thread {
4849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private Context mContext;
4859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private Thread mWaitThread;
4869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private boolean mIsLaunching;
4879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private boolean mStopped;
4889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private boolean mWorkspaceDoneBinding;
4899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
4909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            LoaderThread(Context context, Thread waitThread, boolean isLaunching) {
4919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mContext = context;
4929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mWaitThread = waitThread;
4939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mIsLaunching = isLaunching;
4949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
495f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            boolean isLaunching() {
4979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                return mIsLaunching;
4989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
499f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            /**
5019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * If another LoaderThread was supplied, we need to wait for that to finish before
5029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * we start our processing.  This keeps the ordering of the setting and clearing
5039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * of the dirty flags correct by making sure we don't start processing stuff until
5049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * they've had a chance to re-set them.  We do this waiting the worker thread, not
5059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * the ui thread to avoid ANRs.
5069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             */
5079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private void waitForOtherThread() {
5089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (mWaitThread != null) {
5099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    boolean done = false;
5109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    while (!done) {
5119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        try {
5129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            mWaitThread.join();
513efabe00e4a51bb792366c459d6acc46832e61fdcJoe Onorato                            done = true;
5149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        } catch (InterruptedException ex) {
51584f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy                            // Ignore
5169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
5179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
5189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mWaitThread = null;
5199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
5209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
521f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            public void run() {
5239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                waitForOtherThread();
524f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Elevate priority when Home launches for the first time to avoid
5269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // starving at boot time. Staring at a blank home is not cool.
5279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
5289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    android.os.Process.setThreadPriority(mIsLaunching
5299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            ? Process.THREAD_PRIORITY_DEFAULT : Process.THREAD_PRIORITY_BACKGROUND);
5309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
531f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Load the workspace only if it's dirty.
5339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                int workspaceSeq;
5349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                boolean workspaceDirty;
5359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
5369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    workspaceSeq = mWorkspaceSeq;
5379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    workspaceDirty = mWorkspaceSeq != mLastWorkspaceSeq;
5389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
5399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (workspaceDirty) {
5409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    loadWorkspace();
5419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
5429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
5439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    // If we're not stopped, and nobody has incremented mWorkspaceSeq.
5449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (mStopped) {
5459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        return;
5469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
5479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (workspaceSeq == mWorkspaceSeq) {
5489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        mLastWorkspaceSeq = mWorkspaceSeq;
5499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
5509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
551f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Bind the workspace
5539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                bindWorkspace();
5549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
5559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Wait until the either we're stopped or the other threads are done.
5569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // This way we don't start loading all apps until the workspace has settled
5579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // down.
5589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (LoaderThread.this) {
559080d9b614e609826dce2606f9e474af674ead933Joe Onorato                    mHandler.postIdle(new Runnable() {
5609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            public void run() {
5619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                synchronized (LoaderThread.this) {
5629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    mWorkspaceDoneBinding = true;
563a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                                    if (DEBUG_LOADERS) {
564a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                                        Log.d(TAG, "done with workspace");
565a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                                        }
5669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    LoaderThread.this.notify();
5679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
5689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            }
5699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        });
570a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                    if (DEBUG_LOADERS) {
571a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                        Log.d(TAG, "waiting to be done with workspace");
572a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                    }
5739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    while (!mStopped && !mWorkspaceDoneBinding) {
5749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        try {
5759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            this.wait();
5769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        } catch (InterruptedException ex) {
57784f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy                            // Ignore
5789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
5799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
580a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                    if (DEBUG_LOADERS) {
581a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                        Log.d(TAG, "done waiting to be done with workspace");
582a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                    }
5839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
584f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
585dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                // Whew! Hard work done.
586dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                synchronized (mLock) {
587dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                    if (mIsLaunching) {
5882ff10b3b0137d258569ce5471808842e88696133Daniel Sandler                        android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
589dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                    }
590dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                }
591dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler
5929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Load all apps if they're dirty
5939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                int allAppsSeq;
5949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                boolean allAppsDirty;
5959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
5969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    allAppsSeq = mAllAppsSeq;
5979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    allAppsDirty = mAllAppsSeq != mLastAllAppsSeq;
598a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                    if (DEBUG_LOADERS) {
599a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                        Log.d(TAG, "mAllAppsSeq=" + mAllAppsSeq
600a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                                + " mLastAllAppsSeq=" + mLastAllAppsSeq + " allAppsDirty");
601a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                    }
6029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
6039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (allAppsDirty) {
604dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                    loadAndBindAllApps();
6059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
6069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
6079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    // If we're not stopped, and nobody has incremented mAllAppsSeq.
6089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (mStopped) {
6099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        return;
6109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
6119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (allAppsSeq == mAllAppsSeq) {
6129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        mLastAllAppsSeq = mAllAppsSeq;
6139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
6149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
615f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Clear out this reference, otherwise we end up holding it until all of the
6179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // callback runnables are done.
6189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mContext = null;
619f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
6219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    // Setting the reference is atomic, but we can't do it inside the other critical
6229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    // sections.
6239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mLoaderThread = null;
624f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                }
625f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
626f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            public void stopLocked() {
6289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (LoaderThread.this) {
6299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mStopped = true;
6309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    this.notify();
6319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
632f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
633f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            /**
6359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * Gets the callbacks object.  If we've been stopped, or if the launcher object
636c131b74922e6323331c374856bda830010d761c8Joe Onorato             * has somehow been garbage collected, return null instead.  Pass in the Callbacks
637c131b74922e6323331c374856bda830010d761c8Joe Onorato             * object that was around when the deferred message was scheduled, and if there's
638c131b74922e6323331c374856bda830010d761c8Joe Onorato             * a new Callbacks object around then also return null.  This will save us from
639c131b74922e6323331c374856bda830010d761c8Joe Onorato             * calling onto it with data that will be ignored.
6409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             */
641c131b74922e6323331c374856bda830010d761c8Joe Onorato            Callbacks tryGetCallbacks(Callbacks oldCallbacks) {
6429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
6439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (mStopped) {
6449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        return null;
6459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
6469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
647ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato                    if (mCallbacks == null) {
648ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato                        return null;
649ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato                    }
650ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato
6519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final Callbacks callbacks = mCallbacks.get();
652c131b74922e6323331c374856bda830010d761c8Joe Onorato                    if (callbacks != oldCallbacks) {
653c131b74922e6323331c374856bda830010d761c8Joe Onorato                        return null;
654c131b74922e6323331c374856bda830010d761c8Joe Onorato                    }
6559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (callbacks == null) {
6569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        Log.w(TAG, "no mCallbacks");
6579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        return null;
6589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
659f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    return callbacks;
6619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
662f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
663f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private void loadWorkspace() {
6659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                long t = SystemClock.uptimeMillis();
666f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final Context context = mContext;
6689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final ContentResolver contentResolver = context.getContentResolver();
6699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final PackageManager manager = context.getPackageManager();
670629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                final AppWidgetManager widgets = AppWidgetManager.getInstance(context);
6715c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                final boolean isSafeMode = manager.isSafeMode();
672f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6733c2f7e105d8daab439bff2c362a727ad348d8a44Joe Onorato                mItems.clear();
674511ab64d25ee45518b816afa9110b3160edf3f7bJoe Onorato                mAppWidgets.clear();
6751db7a972bfa8786fc8b58d57f832a378fa731eb0Joe Onorato                mFolders.clear();
6763c2f7e105d8daab439bff2c362a727ad348d8a44Joe Onorato
6775c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                final ArrayList<Long> itemsToRemove = new ArrayList<Long>();
6785c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy
6799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final Cursor c = contentResolver.query(
6809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        LauncherSettings.Favorites.CONTENT_URI, null, null, null, null);
681f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                try {
6839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
6849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int intentIndex = c.getColumnIndexOrThrow
6859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            (LauncherSettings.Favorites.INTENT);
6869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int titleIndex = c.getColumnIndexOrThrow
6879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            (LauncherSettings.Favorites.TITLE);
6889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int iconTypeIndex = c.getColumnIndexOrThrow(
6899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.ICON_TYPE);
6909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON);
6919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int iconPackageIndex = c.getColumnIndexOrThrow(
6929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.ICON_PACKAGE);
6939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int iconResourceIndex = c.getColumnIndexOrThrow(
6949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.ICON_RESOURCE);
6959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int containerIndex = c.getColumnIndexOrThrow(
6969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.CONTAINER);
6979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int itemTypeIndex = c.getColumnIndexOrThrow(
6989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.ITEM_TYPE);
6999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int appWidgetIdIndex = c.getColumnIndexOrThrow(
7009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.APPWIDGET_ID);
7019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int screenIndex = c.getColumnIndexOrThrow(
7029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.SCREEN);
7039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int cellXIndex = c.getColumnIndexOrThrow
7049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            (LauncherSettings.Favorites.CELLX);
7059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int cellYIndex = c.getColumnIndexOrThrow
7069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            (LauncherSettings.Favorites.CELLY);
7079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int spanXIndex = c.getColumnIndexOrThrow
7089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            (LauncherSettings.Favorites.SPANX);
7099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int spanYIndex = c.getColumnIndexOrThrow(
7109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.SPANY);
7119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
7129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int displayModeIndex = c.getColumnIndexOrThrow(
7139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.DISPLAY_MODE);
7149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
7150589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                    ShortcutInfo info;
7169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    String intentDescription;
7179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    LauncherAppWidgetInfo appWidgetInfo;
7189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    int container;
7199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    long id;
7209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    Intent intent;
7219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
7229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    while (!mStopped && c.moveToNext()) {
7239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        try {
7249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            int itemType = c.getInt(itemTypeIndex);
725f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
7269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            switch (itemType) {
7279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
7289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
7299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                intentDescription = c.getString(intentIndex);
7309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                try {
7319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    intent = Intent.parseUri(intentDescription, 0);
7329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                } catch (URISyntaxException e) {
7339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    continue;
7349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
735f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
7369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
73756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                    info = getShortcutInfo(manager, intent, context, c, iconIndex,
73856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                            titleIndex);
7399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                } else {
7400589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                                    info = getShortcutInfo(c, context, iconTypeIndex,
74156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                            iconPackageIndex, iconResourceIndex, iconIndex,
74256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                            titleIndex);
7439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
744f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
7459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                if (info != null) {
74656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                    updateSavedIcon(context, info, c, iconIndex);
7479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
74856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                    info.intent = intent;
7499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info.id = c.getLong(idIndex);
7509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    container = c.getInt(containerIndex);
7519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info.container = container;
7529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info.screen = c.getInt(screenIndex);
7539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info.cellX = c.getInt(cellXIndex);
7549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info.cellY = c.getInt(cellYIndex);
7559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
7569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    switch (container) {
7579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    case LauncherSettings.Favorites.CONTAINER_DESKTOP:
7589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        mItems.add(info);
7599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        break;
7609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    default:
7619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        // Item is in a user folder
7629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        UserFolderInfo folderInfo =
763ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato                                                findOrMakeUserFolder(mFolders, container);
7649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        folderInfo.add(info);
7659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        break;
7669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    }
76756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                } else {
76856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                    // Failed to load the shortcut, probably because the
76956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                    // activity manager couldn't resolve it (maybe the app
77056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                    // was uninstalled), or the db row was somehow screwed up.
77156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                    // Delete it.
77256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                    id = c.getLong(idIndex);
77356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                    Log.e(TAG, "Error loading shortcut " + id + ", removing it");
77456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                    contentResolver.delete(LauncherSettings.Favorites.getContentUri(
77556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                                                id, false), null, null);
7769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
7779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                break;
778f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
779ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato                            case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
7809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                id = c.getLong(idIndex);
781ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato                                UserFolderInfo folderInfo = findOrMakeUserFolder(mFolders, id);
782f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
7839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                folderInfo.title = c.getString(titleIndex);
784f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
7859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                folderInfo.id = id;
7869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                container = c.getInt(containerIndex);
7879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                folderInfo.container = container;
7889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                folderInfo.screen = c.getInt(screenIndex);
7899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                folderInfo.cellX = c.getInt(cellXIndex);
7909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                folderInfo.cellY = c.getInt(cellYIndex);
791f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
7929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                switch (container) {
7939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    case LauncherSettings.Favorites.CONTAINER_DESKTOP:
7949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        mItems.add(folderInfo);
7959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        break;
7969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
797ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato
798ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato                                mFolders.put(folderInfo.id, folderInfo);
7999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                break;
800ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato
8019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
8029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                id = c.getLong(idIndex);
8035c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                Uri uri = Uri.parse(c.getString(uriIndex));
8049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
8055c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                // Make sure the live folder exists
8065c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                final ProviderInfo providerInfo =
8075c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                        context.getPackageManager().resolveContentProvider(
8085c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                                uri.getAuthority(), 0);
809f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
8105c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                if (providerInfo == null && !isSafeMode) {
8115c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    itemsToRemove.add(id);
8125c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                } else {
8135c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(mFolders, id);
8145c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy
8155c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    intentDescription = c.getString(intentIndex);
8165c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    intent = null;
8175c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    if (intentDescription != null) {
8185c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                        try {
8195c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                            intent = Intent.parseUri(intentDescription, 0);
8205c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                        } catch (URISyntaxException e) {
8215c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                            // Ignore, a live folder might not have a base intent
8225c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                        }
8235c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    }
8245c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy
8255c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    liveFolderInfo.title = c.getString(titleIndex);
8265c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    liveFolderInfo.id = id;
8275c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    liveFolderInfo.uri = uri;
8285c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    container = c.getInt(containerIndex);
8295c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    liveFolderInfo.container = container;
8305c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    liveFolderInfo.screen = c.getInt(screenIndex);
8315c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    liveFolderInfo.cellX = c.getInt(cellXIndex);
8325c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    liveFolderInfo.cellY = c.getInt(cellYIndex);
8335c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    liveFolderInfo.baseIntent = intent;
8345c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    liveFolderInfo.displayMode = c.getInt(displayModeIndex);
8355c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy
8365c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    loadLiveFolderIcon(context, c, iconTypeIndex, iconPackageIndex,
8375c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                            iconResourceIndex, liveFolderInfo);
8385c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy
8395c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    switch (container) {
8405c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                        case LauncherSettings.Favorites.CONTAINER_DESKTOP:
8415c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                            mItems.add(liveFolderInfo);
8425c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                            break;
8435c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    }
8445c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    mFolders.put(liveFolderInfo.id, liveFolderInfo);
8459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
8469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                break;
847ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato
8489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
8499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                // Read all Launcher-specific widget details
8509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                int appWidgetId = c.getInt(appWidgetIdIndex);
851629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                id = c.getLong(idIndex);
85231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
853629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                final AppWidgetProviderInfo provider =
854629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                        widgets.getAppWidgetInfo(appWidgetId);
855629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy
856629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                if (!isSafeMode && (provider == null || provider.provider == null ||
857629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                        provider.provider.getPackageName() == null)) {
8588ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato                                    Log.e(TAG, "Deleting widget that isn't installed anymore: id="
8598ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato                                            + id + " appWidgetId=" + appWidgetId);
860629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    itemsToRemove.add(id);
861629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                } else {
862629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId);
863629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    appWidgetInfo.id = id;
864629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    appWidgetInfo.screen = c.getInt(screenIndex);
865629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    appWidgetInfo.cellX = c.getInt(cellXIndex);
866629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    appWidgetInfo.cellY = c.getInt(cellYIndex);
867629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    appWidgetInfo.spanX = c.getInt(spanXIndex);
868629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    appWidgetInfo.spanY = c.getInt(spanYIndex);
869629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy
870629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    container = c.getInt(containerIndex);
871629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
872629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                        Log.e(TAG, "Widget found where container "
873629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                                + "!= CONTAINER_DESKTOP -- ignoring!");
874629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                        continue;
875629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    }
876629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    appWidgetInfo.container = c.getInt(containerIndex);
877629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy
878629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    mAppWidgets.add(appWidgetInfo);
8799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
8809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                break;
8819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            }
8829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        } catch (Exception e) {
8839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            Log.w(TAG, "Desktop items loading interrupted:", e);
8849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
8859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
8869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                } finally {
8879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    c.close();
8889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
8895c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy
8905c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                if (itemsToRemove.size() > 0) {
8915c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                    ContentProviderClient client = contentResolver.acquireContentProviderClient(
8925c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    LauncherSettings.Favorites.CONTENT_URI);
8935c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                    // Remove dead items
8945c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                    for (long id : itemsToRemove) {
8955c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                        if (DEBUG_LOADERS) {
8965c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                            Log.d(TAG, "Removed id = " + id);
8975c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                        }
8985c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                        // Don't notify content observers
8995c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                        try {
9005c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                            client.delete(LauncherSettings.Favorites.getContentUri(id, false),
9015c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                                    null, null);
9025c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                        } catch (RemoteException e) {
9035c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                            Log.w(TAG, "Could not remove id = " + id);
9045c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                        }
9055c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                    }
9065c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                }
9075c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy
908a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                if (DEBUG_LOADERS) {
909a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                    Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms");
910a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                }
9119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
91231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            /**
9149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * Read everything out of our database.
9159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             */
9169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private void bindWorkspace() {
9179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final long t = SystemClock.uptimeMillis();
9189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
9199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Don't use these two variables in any of the callback runnables.
9209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Otherwise we hold a reference to them.
921c131b74922e6323331c374856bda830010d761c8Joe Onorato                final Callbacks oldCallbacks = mCallbacks.get();
922c131b74922e6323331c374856bda830010d761c8Joe Onorato                if (oldCallbacks == null) {
9239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    // This launcher has exited and nobody bothered to tell us.  Just bail.
9249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    Log.w(TAG, "LoaderThread running with no launcher");
9259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    return;
9269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
92731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                int N;
9299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Tell the workspace that we're about to start firing items at it
9309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mHandler.post(new Runnable() {
9319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    public void run() {
932c131b74922e6323331c374856bda830010d761c8Joe Onorato                        Callbacks callbacks = tryGetCallbacks(oldCallbacks);
9339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        if (callbacks != null) {
9349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            callbacks.startBinding();
9359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
9369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
9379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                });
9389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Add the items to the workspace.
9399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                N = mItems.size();
9409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                for (int i=0; i<N; i+=ITEMS_CHUNK) {
9419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int start = i;
9429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int chunkSize = (i+ITEMS_CHUNK <= N) ? ITEMS_CHUNK : (N-i);
9439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mHandler.post(new Runnable() {
9449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        public void run() {
945c131b74922e6323331c374856bda830010d761c8Joe Onorato                            Callbacks callbacks = tryGetCallbacks(oldCallbacks);
9469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            if (callbacks != null) {
9479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                callbacks.bindItems(mItems, start, start+chunkSize);
9489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            }
9499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
9509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    });
9519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
952ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato                mHandler.post(new Runnable() {
953ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato                    public void run() {
954c131b74922e6323331c374856bda830010d761c8Joe Onorato                        Callbacks callbacks = tryGetCallbacks(oldCallbacks);
955ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato                        if (callbacks != null) {
956ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato                            callbacks.bindFolders(mFolders);
957ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato                        }
958ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato                    }
959ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato                });
9609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Wait until the queue goes empty.
9619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mHandler.postIdle(new Runnable() {
9629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    public void run() {
963a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                        if (DEBUG_LOADERS) {
964a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                            Log.d(TAG, "Going to start binding widgets soon.");
965a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                        }
9669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
9679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                });
9689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Bind the widgets, one at a time.
9699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // WARNING: this is calling into the workspace from the background thread,
9709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // but since getCurrentScreen() just returns the int, we should be okay.  This
9719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // is just a hint for the order, and if it's wrong, we'll be okay.
9729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // TODO: instead, we should have that push the current screen into here.
973c131b74922e6323331c374856bda830010d761c8Joe Onorato                final int currentScreen = oldCallbacks.getCurrentWorkspaceScreen();
9749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                N = mAppWidgets.size();
9759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // once for the current screen
9769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                for (int i=0; i<N; i++) {
9779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final LauncherAppWidgetInfo widget = mAppWidgets.get(i);
9789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (widget.screen == currentScreen) {
9799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        mHandler.post(new Runnable() {
9809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            public void run() {
981c131b74922e6323331c374856bda830010d761c8Joe Onorato                                Callbacks callbacks = tryGetCallbacks(oldCallbacks);
9829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                if (callbacks != null) {
9839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    callbacks.bindAppWidget(widget);
9849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
9859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            }
9869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        });
9879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
9889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
9899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // once for the other screens
9909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                for (int i=0; i<N; i++) {
9919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final LauncherAppWidgetInfo widget = mAppWidgets.get(i);
9929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (widget.screen != currentScreen) {
9939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        mHandler.post(new Runnable() {
9949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            public void run() {
995c131b74922e6323331c374856bda830010d761c8Joe Onorato                                Callbacks callbacks = tryGetCallbacks(oldCallbacks);
9969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                if (callbacks != null) {
9979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    callbacks.bindAppWidget(widget);
9989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
9999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            }
10009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        });
10019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
10029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
10039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Tell the workspace that we're done.
10049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mHandler.post(new Runnable() {
10059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    public void run() {
1006c131b74922e6323331c374856bda830010d761c8Joe Onorato                        Callbacks callbacks = tryGetCallbacks(oldCallbacks);
10079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        if (callbacks != null) {
10089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            callbacks.finishBindingItems();
10099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
10109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
10119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                });
10129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // If we're profiling, this is the last thing in the queue.
10139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mHandler.post(new Runnable() {
10149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    public void run() {
1015a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                        if (DEBUG_LOADERS) {
1016a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                            Log.d(TAG, "bound workspace in "
1017a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                                + (SystemClock.uptimeMillis()-t) + "ms");
1018a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                        }
10199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        if (Launcher.PROFILE_ROTATE) {
10209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            android.os.Debug.stopMethodTracing();
10219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
10229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
10239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                });
10249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
102531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1026dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler            private void loadAndBindAllApps() {
1027dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                final long t = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
1028dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler
1029d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                // Don't use these two variables in any of the callback runnables.
1030d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                // Otherwise we hold a reference to them.
1031d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                final Callbacks oldCallbacks = mCallbacks.get();
1032d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                if (oldCallbacks == null) {
1033d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                    // This launcher has exited and nobody bothered to tell us.  Just bail.
1034d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                    Log.w(TAG, "LoaderThread running with no launcher (loadAndBindAllApps)");
10359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    return;
10369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
103731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1038d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
1039d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
104031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1041d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                final PackageManager packageManager = mContext.getPackageManager();
1042d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                List<ResolveInfo> apps = null;
1043dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler
1044d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                int N = Integer.MAX_VALUE;
1045dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler
1046d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                int startIndex;
1047dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                int i=0;
1048d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                int batchSize = -1;
1049dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                while (i < N && !mStopped) {
1050dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                    synchronized (mLock) {
1051d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                        if (i == 0) {
1052d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            // This needs to happen inside the same lock block as when we
1053d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            // prepare the first batch for bindAllApplications.  Otherwise
1054d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            // the package changed receiver can come in and double-add
1055d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            // (or miss one?).
1056d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            mAllAppsList.clear();
1057d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
1058d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            apps = packageManager.queryIntentActivities(mainIntent, 0);
1059d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            if (DEBUG_LOADERS) {
1060d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                Log.d(TAG, "queryIntentActivities took "
1061d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                        + (SystemClock.uptimeMillis()-qiaTime) + "ms");
1062d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            }
1063d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            if (apps == null) {
1064d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                return;
1065d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            }
1066d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            N = apps.size();
1067d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            if (DEBUG_LOADERS) {
1068d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                Log.d(TAG, "queryIntentActivities got " + N + " apps");
1069d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            }
1070d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            if (N == 0) {
1071d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                // There are no apps?!?
1072d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                return;
1073d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            }
1074d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            if (mBatchSize == 0) {
1075d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                batchSize = N;
1076d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            } else {
1077d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                batchSize = mBatchSize;
1078d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            }
1079d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato
1080d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            final long sortTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
1081d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            Collections.sort(apps,
1082d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                    new ResolveInfo.DisplayNameComparator(packageManager));
1083d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            if (DEBUG_LOADERS) {
1084d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                Log.d(TAG, "sort took "
1085d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                        + (SystemClock.uptimeMillis()-qiaTime) + "ms");
1086d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            }
1087d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                        }
1088d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato
1089dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                        final long t2 = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
109031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1091d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                        startIndex = i;
1092dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                        for (int j=0; i<N && j<batchSize; j++) {
10939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            // This builds the icon bitmaps.
10940589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                            mAllAppsList.add(new ApplicationInfo(apps.get(i), mIconCache));
1095dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                            i++;
10969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
1097d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato
1098d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                        final boolean first = i <= batchSize;
1099d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                        final ArrayList<ApplicationInfo> added = mAllAppsList.added;
1100d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                        mAllAppsList.added = new ArrayList<ApplicationInfo>();
1101d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato
1102d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                        mHandler.post(new Runnable() {
1103d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            public void run() {
1104d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                final long t = SystemClock.uptimeMillis();
1105d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
1106d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                if (first) {
1107d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                    mBeforeFirstLoad = false;
1108d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                    callbacks.bindAllApplications(added);
1109d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                } else {
1110d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                    callbacks.bindAppsAdded(added);
1111d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                }
1112d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                if (DEBUG_LOADERS) {
1113d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                    Log.d(TAG, "bound " + added.size() + " apps in "
1114d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                        + (SystemClock.uptimeMillis() - t) + "ms");
1115d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                }
1116d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            }
1117d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                        });
1118d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato
1119a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                        if (DEBUG_LOADERS) {
1120d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            Log.d(TAG, "batch of " + (i-startIndex) + " icons processed in "
1121dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                                    + (SystemClock.uptimeMillis()-t2) + "ms");
1122a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato                        }
1123ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project                    }
1124dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler
11252ff10b3b0137d258569ce5471808842e88696133Daniel Sandler                    if (mAllAppsLoadDelay > 0 && i < N) {
1126dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                        try {
1127d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            if (DEBUG_LOADERS) {
1128d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                                Log.d(TAG, "sleeping for " + mAllAppsLoadDelay + "ms");
1129d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato                            }
11302ff10b3b0137d258569ce5471808842e88696133Daniel Sandler                            Thread.sleep(mAllAppsLoadDelay);
1131dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                        } catch (InterruptedException exc) { }
1132dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                    }
1133dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                }
1134dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler
1135dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                if (DEBUG_LOADERS) {
1136dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler                    Log.d(TAG, "cached all " + N + " apps in "
11372ff10b3b0137d258569ce5471808842e88696133Daniel Sandler                            + (SystemClock.uptimeMillis()-t) + "ms"
11382ff10b3b0137d258569ce5471808842e88696133Daniel Sandler                            + (mAllAppsLoadDelay > 0 ? " (including delay)" : ""));
113931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
114031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
114131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1142be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato            public void dumpState() {
1143be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato                Log.d(TAG, "mLoader.mLoaderThread.mContext=" + mContext);
1144be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato                Log.d(TAG, "mLoader.mLoaderThread.mWaitThread=" + mWaitThread);
1145be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato                Log.d(TAG, "mLoader.mLoaderThread.mIsLaunching=" + mIsLaunching);
1146be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato                Log.d(TAG, "mLoader.mLoaderThread.mStopped=" + mStopped);
1147be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato                Log.d(TAG, "mLoader.mLoaderThread.mWorkspaceDoneBinding=" + mWorkspaceDoneBinding);
1148be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato            }
1149be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato        }
1150be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato
1151be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato        public void dumpState() {
1152be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato            Log.d(TAG, "mLoader.mLastWorkspaceSeq=" + mLoader.mLastWorkspaceSeq);
1153be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato            Log.d(TAG, "mLoader.mWorkspaceSeq=" + mLoader.mWorkspaceSeq);
1154be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato            Log.d(TAG, "mLoader.mLastAllAppsSeq=" + mLoader.mLastAllAppsSeq);
1155be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato            Log.d(TAG, "mLoader.mAllAppsSeq=" + mLoader.mAllAppsSeq);
1156be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato            Log.d(TAG, "mLoader.mItems size=" + mLoader.mItems.size());
1157be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato            if (mLoaderThread != null) {
1158be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato                mLoaderThread.dumpState();
1159be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato            } else {
1160be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato                Log.d(TAG, "mLoader.mLoaderThread=null");
1161be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato            }
116231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
116331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
116431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
11659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
116656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato     * This is called from the code that adds shortcuts from the intent receiver.  This
116756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato     * doesn't have a Cursor, but
11689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
116956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato    public ShortcutInfo getShortcutInfo(PackageManager manager, Intent intent, Context context) {
1170e74daedc3b41d958315f7d5bf69deb232ca89468Joe Onorato        return getShortcutInfo(manager, intent, context, null, -1, -1);
117156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato    }
117256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato
117356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato    /**
117456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato     * Make an ShortcutInfo object for a shortcut that is an application.
117556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato     *
117656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato     * If c is not null, then it will be used to fill in missing data like the title and icon.
117756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato     */
117856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato    public ShortcutInfo getShortcutInfo(PackageManager manager, Intent intent, Context context,
117956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            Cursor c, int iconIndex, int titleIndex) {
118056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        Bitmap icon = null;
118156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        final ShortcutInfo info = new ShortcutInfo();
118231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
118356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        ComponentName componentName = intent.getComponent();
118456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        if (componentName == null) {
11859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            return null;
118631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
118731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
11888ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato        // TODO: See if the PackageManager knows about this case.  If it doesn't
11898ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato        // then return null & delete this.
11908ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato
119156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // the resource -- This may implicitly give us back the fallback icon,
119256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // but don't worry about that.  All we're doing with usingFallbackIcon is
119356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // to avoid saving lots of copies of that in the database, and most apps
119456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // have icons anyway.
119556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        final ResolveInfo resolveInfo = manager.resolveActivity(intent, 0);
119656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        if (resolveInfo != null) {
119756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            icon = mIconCache.getIcon(componentName, resolveInfo);
119856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        }
119956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // the db
120056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        if (icon == null) {
120156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            if (c != null) {
120256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                icon = getIconFromCursor(c, iconIndex);
120356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            }
12049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
120556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // the fallback icon
120656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        if (icon == null) {
120756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            icon = getFallbackIcon();
120856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            info.usingFallbackIcon = true;
120956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        }
121056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        info.setIcon(icon);
121156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato
121256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // from the resource
121356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        if (resolveInfo != null) {
121456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            info.title = resolveInfo.activityInfo.loadLabel(manager);
121556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        }
121656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // from the db
121756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        if (info.title == null) {
121856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            if (c != null) {
121956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                info.title =  c.getString(titleIndex);
122056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            }
122156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        }
122256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // fall back to the class name of the activity
12239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (info.title == null) {
122456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            info.title = componentName.getClassName();
12259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
12269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
12279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        return info;
12289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
122931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
12309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
12310589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato     * Make an ShortcutInfo object for a shortcut that isn't an application.
12329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
12330589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato    private ShortcutInfo getShortcutInfo(Cursor c, Context context,
123456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex,
123556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            int titleIndex) {
123631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
123756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        Bitmap icon = null;
12380589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        final ShortcutInfo info = new ShortcutInfo();
12399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
12407376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project
12418ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato        // TODO: If there's an explicit component and we can't install that, delete it.
12428ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato
124356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        info.title = c.getString(titleIndex);
124456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato
12459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        int iconType = c.getInt(iconTypeIndex);
12469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        switch (iconType) {
12479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
12489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            String packageName = c.getString(iconPackageIndex);
12499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            String resourceName = c.getString(iconResourceIndex);
12509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            PackageManager packageManager = context.getPackageManager();
125156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            info.customIcon = false;
125256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            // the resource
12539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            try {
12549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                Resources resources = packageManager.getResourcesForApplication(packageName);
125556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                if (resources != null) {
125656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    final int id = resources.getIdentifier(resourceName, null, null);
125756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    icon = Utilities.createIconBitmap(resources.getDrawable(id), context);
125856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                }
12599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            } catch (Exception e) {
126056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                // drop this.  we have other places to look for icons
126156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            }
126256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            // the db
126356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            if (icon == null) {
126456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                icon = getIconFromCursor(c, iconIndex);
126556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            }
126656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            // the fallback icon
126756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            if (icon == null) {
126856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                icon = getFallbackIcon();
126956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                info.usingFallbackIcon = true;
12707376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project            }
12719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            break;
12729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        case LauncherSettings.Favorites.ICON_TYPE_BITMAP:
127356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            icon = getIconFromCursor(c, iconIndex);
127456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            if (icon == null) {
127556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                icon = getFallbackIcon();
127656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                info.customIcon = false;
127756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                info.usingFallbackIcon = true;
127856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            } else {
127956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                info.customIcon = true;
12809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
12819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            break;
12829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        default:
1283d8d22da5ca3e8d3e8d2e3616305b038d37486f32Joe Onorato            icon = getFallbackIcon();
128456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            info.usingFallbackIcon = true;
12859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            info.customIcon = false;
12869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            break;
128731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
1288d8d22da5ca3e8d3e8d2e3616305b038d37486f32Joe Onorato        info.setIcon(icon);
12899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        return info;
1290f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
129131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
129256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato    Bitmap getIconFromCursor(Cursor c, int iconIndex) {
129356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        if (false) {
129456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            Log.d(TAG, "getIconFromCursor app="
129556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    + c.getString(c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE)));
129656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        }
129756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        byte[] data = c.getBlob(iconIndex);
129856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        try {
129956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            return BitmapFactory.decodeByteArray(data, 0, data.length);
130056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        } catch (Exception e) {
130156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            return null;
130256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        }
130356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato    }
130456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato
13050589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato    ShortcutInfo addShortcut(Context context, Intent data,
13060589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato            CellLayout.CellInfo cellInfo, boolean notify) {
13070589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato
13080589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        final ShortcutInfo info = infoFromShortcutIntent(context, data);
13090589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        addItemToDatabase(context, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
13100589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                cellInfo.screen, cellInfo.cellX, cellInfo.cellY, notify);
13110589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato
13120589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        return info;
13130589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato    }
13140589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato
13150589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato    private ShortcutInfo infoFromShortcutIntent(Context context, Intent data) {
13160589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
13170589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
13180589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
13190589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato
13200589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        Bitmap icon = null;
13210589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        boolean filtered = false;
13220589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        boolean customIcon = false;
13230589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        ShortcutIconResource iconResource = null;
13240589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato
13250589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        if (bitmap != null && bitmap instanceof Bitmap) {
13260589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato            icon = Utilities.createIconBitmap(new FastBitmapDrawable((Bitmap)bitmap), context);
13270589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato            filtered = true;
13280589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato            customIcon = true;
13290589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        } else {
13300589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato            Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
13310589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato            if (extra != null && extra instanceof ShortcutIconResource) {
13320589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                try {
13330589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                    iconResource = (ShortcutIconResource) extra;
13340589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                    final PackageManager packageManager = context.getPackageManager();
13350589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                    Resources resources = packageManager.getResourcesForApplication(
13360589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                            iconResource.packageName);
13370589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                    final int id = resources.getIdentifier(iconResource.resourceName, null, null);
13380589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                    icon = Utilities.createIconBitmap(resources.getDrawable(id), context);
13390589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                } catch (Exception e) {
13400589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                    Log.w(TAG, "Could not load shortcut icon: " + extra);
13410589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                }
13420589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato            }
13430589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        }
13440589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato
134556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        final ShortcutInfo info = new ShortcutInfo();
134656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato
13470589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        if (icon == null) {
134856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            icon = getFallbackIcon();
134956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            info.usingFallbackIcon = true;
13500589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        }
13510589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        info.setIcon(icon);
135256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato
13530589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        info.title = name;
13540589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        info.intent = intent;
13550589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        info.customIcon = customIcon;
13560589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        info.iconResource = iconResource;
13570589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato
13580589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        return info;
13590589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato    }
13600589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato
13619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private static void loadLiveFolderIcon(Context context, Cursor c, int iconTypeIndex,
13629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            int iconPackageIndex, int iconResourceIndex, LiveFolderInfo liveFolderInfo) {
136331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
13649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        int iconType = c.getInt(iconTypeIndex);
13659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        switch (iconType) {
13669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
13679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            String packageName = c.getString(iconPackageIndex);
13689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            String resourceName = c.getString(iconResourceIndex);
13699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            PackageManager packageManager = context.getPackageManager();
13709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            try {
13719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                Resources resources = packageManager.getResourcesForApplication(packageName);
13729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int id = resources.getIdentifier(resourceName, null, null);
13730589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                liveFolderInfo.icon = Utilities.createIconBitmap(resources.getDrawable(id),
13740589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                        context);
13759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            } catch (Exception e) {
13760589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                liveFolderInfo.icon = Utilities.createIconBitmap(
13770589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                        context.getResources().getDrawable(R.drawable.ic_launcher_folder),
13780589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                        context);
13799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
13809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            liveFolderInfo.iconResource = new Intent.ShortcutIconResource();
13819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            liveFolderInfo.iconResource.packageName = packageName;
13829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            liveFolderInfo.iconResource.resourceName = resourceName;
13839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            break;
13849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        default:
13850589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato            liveFolderInfo.icon = Utilities.createIconBitmap(
13860589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                    context.getResources().getDrawable(R.drawable.ic_launcher_folder),
13870589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                    context);
13889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
138931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
1390bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
139156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato    void updateSavedIcon(Context context, ShortcutInfo info, Cursor c, int iconIndex) {
139256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // If this icon doesn't have a custom icon, check to see
139356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // what's stored in the DB, and if it doesn't match what
139456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // we're going to show, store what we are going to show back
139556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // into the DB.  We do this so when we're loading, if the
139656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // package manager can't find an icon (for example because
139756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        // the app is on SD) then we can use that instead.
139856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        if (info.onExternalStorage && !info.customIcon && !info.usingFallbackIcon) {
139956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            boolean needSave;
140056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            byte[] data = c.getBlob(iconIndex);
140156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            try {
140256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                if (data != null) {
140356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    Bitmap saved = BitmapFactory.decodeByteArray(data, 0, data.length);
140456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    Bitmap loaded = info.getIcon(mIconCache);
140556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    needSave = !saved.sameAs(loaded);
140656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                } else {
140756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                    needSave = true;
140856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                }
140956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            } catch (Exception e) {
141056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                needSave = true;
141156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            }
141256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            if (needSave) {
141356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                Log.d(TAG, "going to save icon bitmap for info=" + info);
141456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                // This is slower than is ideal, but this only happens either
141556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                // after the froyo OTA or when the app is updated with a new
141656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                // icon.
141756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato                updateItemInDatabase(context, info);
141856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato            }
141956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato        }
142056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato    }
142156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato
142231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
14239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Return an existing UserFolderInfo object if we have encountered this ID previously,
14249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * or make a new one.
142531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
14269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private static UserFolderInfo findOrMakeUserFolder(HashMap<Long, FolderInfo> folders, long id) {
14279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        // See if a placeholder was created for us already
14289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        FolderInfo folderInfo = folders.get(id);
14299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (folderInfo == null || !(folderInfo instanceof UserFolderInfo)) {
14309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            // No placeholder -- create a new instance
14319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            folderInfo = new UserFolderInfo();
14329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            folders.put(id, folderInfo);
143331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
14349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        return (UserFolderInfo) folderInfo;
14359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
143631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
14379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
14389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
14399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * new one.
14409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
14419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private static LiveFolderInfo findOrMakeLiveFolder(HashMap<Long, FolderInfo> folders, long id) {
14429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        // See if a placeholder was created for us already
14439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        FolderInfo folderInfo = folders.get(id);
14449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (folderInfo == null || !(folderInfo instanceof LiveFolderInfo)) {
14459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            // No placeholder -- create a new instance
14469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            folderInfo = new LiveFolderInfo();
14479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            folders.put(id, folderInfo);
144831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
14499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        return (LiveFolderInfo) folderInfo;
145031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
145131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
145231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static String getLabel(PackageManager manager, ActivityInfo activityInfo) {
145331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        String label = activityInfo.loadLabel(manager).toString();
145431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (label == null) {
145531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            label = manager.getApplicationLabel(activityInfo.applicationInfo).toString();
145631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (label == null) {
145731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                label = activityInfo.name;
145831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
145931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
146031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return label;
146131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
146231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
14639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private static final Collator sCollator = Collator.getInstance();
1464b0c27f254a9929be208d5e04554f438076c833bcJoe Onorato    public static final Comparator<ApplicationInfo> APP_NAME_COMPARATOR
14659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            = new Comparator<ApplicationInfo>() {
14669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public final int compare(ApplicationInfo a, ApplicationInfo b) {
14679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            return sCollator.compare(a.title.toString(), b.title.toString());
146831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
14699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    };
1470be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato
1471be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato    public void dumpState() {
1472be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato        Log.d(TAG, "mBeforeFirstLoad=" + mBeforeFirstLoad);
1473be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato        Log.d(TAG, "mCallbacks=" + mCallbacks);
1474be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato        ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.data", mAllAppsList.data);
1475be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato        ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.added", mAllAppsList.added);
1476be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato        ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.removed", mAllAppsList.removed);
1477be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato        ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.modified", mAllAppsList.modified);
1478be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato        mLoader.dumpState();
1479be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato    }
148031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project}
1481