LauncherModel.java revision 1d8e7bbe09e130af5e9534cc26a65f623be7a424
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
1931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.ComponentName;
2031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.ContentResolver;
2131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.ContentValues;
2231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Intent;
2331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context;
2431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.ActivityInfo;
2531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.PackageManager;
2631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.ResolveInfo;
2731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.res.Resources;
2831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.database.Cursor;
2931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Bitmap;
3031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.BitmapFactory;
31f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectimport android.graphics.drawable.Drawable;
3231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.net.Uri;
33f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectimport static android.util.Log.*;
349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.util.Log;
3531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.Process;
369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.os.SystemClock;
3731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport java.lang.ref.WeakReference;
399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport java.net.URISyntaxException;
409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport java.text.Collator;
4131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.ArrayList;
429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport java.util.Comparator;
439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport java.util.Collections;
4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.HashMap;
4531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.List;
4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
4731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/**
4831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Maintains in-memory state of the Launcher. It is expected that there should be only one
4931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * LauncherModel object held in a static. Also provide APIs for updating the database state
50bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project * for the Launcher.
5131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
5231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectpublic class LauncherModel {
53829f56a020a3e2ca851d7e532036b14004bf0234Romain Guy    static final boolean DEBUG_LOADERS = true;
549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static final String TAG = "Launcher.Model";
559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private final Object mLock = new Object();
579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private DeferredHandler mHandler = new DeferredHandler();
589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private Loader mLoader = new Loader();
599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private WeakReference<Callbacks> mCallbacks;
619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private AllAppsList mAllAppsList = new AllAppsList();
639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public interface Callbacks {
659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public int getCurrentWorkspaceScreen();
669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void startBinding();
679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end);
689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void finishBindingItems();
699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void bindAppWidget(LauncherAppWidgetInfo info);
709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void bindAllApplications(ArrayList<ApplicationInfo> apps);
719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void bindPackageAdded(ArrayList<ApplicationInfo> apps);
729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void bindPackageUpdated(String packageName, ArrayList<ApplicationInfo> apps);
739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void bindPackageRemoved(String packageName, ArrayList<ApplicationInfo> apps);
749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
7531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
7631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Adds an item to the DB if it was not created previously, or move it to a new
799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * <container, screen, cellX, cellY>
809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container,
829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            int screen, int cellX, int cellY) {
839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (item.container == ItemInfo.NO_ID) {
849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            // From all apps
859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            addItemToDatabase(context, item, container, screen, cellX, cellY, false);
869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        } else {
879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            // From somewhere else
889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            moveItemInDatabase(context, item, container, screen, cellX, cellY);
899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
9131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Move an item in the DB to a new <container, screen, cellX, cellY>
949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static void moveItemInDatabase(Context context, ItemInfo item, long container, int screen,
969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            int cellX, int cellY) {
979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.container = container;
989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.screen = screen;
999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.cellX = cellX;
1009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.cellY = cellY;
10131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentValues values = new ContentValues();
1039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
104bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
1059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        values.put(LauncherSettings.Favorites.CONTAINER, item.container);
1069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        values.put(LauncherSettings.Favorites.CELLX, item.cellX);
1079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        values.put(LauncherSettings.Favorites.CELLY, item.cellY);
1089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        values.put(LauncherSettings.Favorites.SCREEN, item.screen);
109ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
1109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
11131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
11231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
11331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
1149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Returns true if the shortcuts already exists in the database.
1159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * we identify a shortcut by its title and intent.
116bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     */
1179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static boolean shortcutExists(Context context, String title, Intent intent) {
1189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
1199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
1209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            new String[] { "title", "intent" }, "title=? and intent=?",
1219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            new String[] { title, intent.toUri(0) }, null);
1229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        boolean result = false;
1239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        try {
1249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            result = c.moveToFirst();
1259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        } finally {
1269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            c.close();
1279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
1289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        return result;
129bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    }
130bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
131bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    /**
1329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Find a folder in the db, creating the FolderInfo if necessary, and adding it to folderList.
13331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
1349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    FolderInfo getFolderById(Context context, HashMap<Long,FolderInfo> folderList, long id) {
1359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
1369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null,
1379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                "_id=? and (itemType=? or itemType=?)",
1389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                new String[] { String.valueOf(id),
1399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER),
1409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER) }, null);
141f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
1429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        try {
1439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (c.moveToFirst()) {
1449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
1459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
1469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
1479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
1489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
1499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
150f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
1519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                FolderInfo folderInfo = null;
1529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                switch (c.getInt(itemTypeIndex)) {
1539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
1549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        folderInfo = findOrMakeUserFolder(folderList, id);
1559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        break;
1569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
1579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        folderInfo = findOrMakeLiveFolder(folderList, id);
1589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        break;
1599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                folderInfo.title = c.getString(titleIndex);
1629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                folderInfo.id = id;
1639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                folderInfo.container = c.getInt(containerIndex);
1649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                folderInfo.screen = c.getInt(screenIndex);
1659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                folderInfo.cellX = c.getInt(cellXIndex);
1669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                folderInfo.cellY = c.getInt(cellYIndex);
167ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
1689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                return folderInfo;
1699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
1709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        } finally {
1719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            c.close();
1722fcbd686d1c2a9a9e520116a541c9caae0c2dc60Romain Guy        }
173ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
1749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        return null;
1759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
17631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
1789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Add an item to the database in a specified container. Sets the container, screen, cellX and
1799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * cellY fields of the item. Also assigns an ID to the item.
1809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
1819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static void addItemToDatabase(Context context, ItemInfo item, long container,
1829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            int screen, int cellX, int cellY, boolean notify) {
1839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.container = container;
1849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.screen = screen;
1859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.cellX = cellX;
1869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.cellY = cellY;
187ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
1889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentValues values = new ContentValues();
1899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
190ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
1919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.onAddToDatabase(values);
192ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
1939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        Uri result = cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI :
1949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values);
195ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
1969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (result != null) {
1979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            item.id = Integer.parseInt(result.getPathSegments().get(1));
19831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
19931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
20031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
2019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
2029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Update an item to the database in a specified container.
2039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
2049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static void updateItemInDatabase(Context context, ItemInfo item) {
2059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentValues values = new ContentValues();
2069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
207f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        item.onAddToDatabase(values);
209ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
2109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
21131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
21231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
2139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
2149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Removes the specified item from the database
2159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * @param context
2169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * @param item
2179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
2189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static void deleteItemFromDatabase(Context context, ItemInfo item) {
2199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
220f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        cr.delete(LauncherSettings.Favorites.getContentUri(item.id, false), null, null);
2229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
223f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
2259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Remove the contents of the specified folder from the database
2269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
2279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    static void deleteUserFolderContentsFromDatabase(Context context, UserFolderInfo info) {
2289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ContentResolver cr = context.getContentResolver();
229f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null);
2319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        cr.delete(LauncherSettings.Favorites.CONTENT_URI,
2329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
2339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
234f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
2369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Set this as the current Launcher activity object for the loader.
2379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
2389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void initialize(Callbacks callbacks) {
2399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        synchronized (mLock) {
2409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            mCallbacks = new WeakReference<Callbacks>(callbacks);
241f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
242f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
243f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void startLoader(Context context, boolean isLaunching) {
2459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        mLoader.startLoader(context, isLaunching);
2469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
247f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void stopLoader() {
2499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        mLoader.stopLoader();
2509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
251f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2521d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato    /**
2531d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato     * We pick up most of the changes to all apps.
2541d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato     */
2551d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato    public void setAllAppsDirty() {
2561d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato        mLoader.setAllAppsDirty();
2571d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato    }
2581d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato
2599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void setWorkspaceDirty() {
2609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        mLoader.setWorkspaceDirty();
2619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
262f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
2649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Call from the handler for ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and
2659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * ACTION_PACKAGE_CHANGED.
2669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
2679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void onReceiveIntent(Context context, Intent intent) {
2689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final String packageName = intent.getData().getSchemeSpecificPart();
2699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
2709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        ArrayList<ApplicationInfo> added = null;
2719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        ArrayList<ApplicationInfo> removed = null;
2729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        ArrayList<ApplicationInfo> modified = null;
2739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        boolean update = false;
2749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        boolean remove = false;
2759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
2769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        synchronized (mLock) {
2779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            final String action = intent.getAction();
2789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
2799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
2809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (packageName == null || packageName.length() == 0) {
2819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // they sent us a bad intent
2829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                return;
283f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
284f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
2859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
2869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mAllAppsList.updatePackage(context, packageName);
2879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                update = true;
2889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
2899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (!replacing) {
2909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mAllAppsList.removePackage(packageName);
2919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    remove = true;
2929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
2939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // else, we are replacing the package, so a PACKAGE_ADDED will be sent
2949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // later, we will update the package at this time
2959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            } else {
2969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (!replacing) {
2979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mAllAppsList.addPackage(context, packageName);
2989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                } else {
2999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mAllAppsList.updatePackage(context, packageName);
3009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    update = true;
3019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
302f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
303f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
3049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (mAllAppsList.added.size() > 0) {
3059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                added = mAllAppsList.added;
306efabe00e4a51bb792366c459d6acc46832e61fdcJoe Onorato                mAllAppsList.added = new ArrayList();
307f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
3089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (mAllAppsList.removed.size() > 0) {
3099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                removed = mAllAppsList.removed;
310efabe00e4a51bb792366c459d6acc46832e61fdcJoe Onorato                mAllAppsList.removed = new ArrayList();
3119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                for (ApplicationInfo info: removed) {
3129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    AppInfoCache.remove(info.intent.getComponent());
313f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                }
314f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
3159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (mAllAppsList.modified.size() > 0) {
3169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                modified = mAllAppsList.modified;
317efabe00e4a51bb792366c459d6acc46832e61fdcJoe Onorato                mAllAppsList.modified = new ArrayList();
3189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
319f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
3203c8b90d9eb149aae593c726893eb560900f302abMarco Nelissen            final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
3219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (callbacks == null) {
3229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                return;
3239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
324b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy
3259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (added != null) {
3269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final ArrayList<ApplicationInfo> addedFinal = added;
3279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mHandler.post(new Runnable() {
3289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    public void run() {
3299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        callbacks.bindPackageAdded(addedFinal);
3309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
3319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                });
3329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
3339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (update || modified != null) {
3349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final ArrayList<ApplicationInfo> modifiedFinal = modified;
3359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mHandler.post(new Runnable() {
3369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    public void run() {
3379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        callbacks.bindPackageUpdated(packageName, modifiedFinal);
3389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
3399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                });
3409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
3419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (remove || removed != null) {
3429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final ArrayList<ApplicationInfo> removedFinal = removed;
3439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mHandler.post(new Runnable() {
3449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    public void run() {
3459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        callbacks.bindPackageRemoved(packageName, removedFinal);
3469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
3479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                });
348f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
349f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
350f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
351f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
3529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public class Loader {
3539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private static final int ITEMS_CHUNK = 6;
354f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
3559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private LoaderThread mLoaderThread;
356f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
3579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private int mLastWorkspaceSeq = 0;
3589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private int mWorkspaceSeq = 1;
3599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
3609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private int mLastAllAppsSeq = 0;
3619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private int mAllAppsSeq = 1;
362f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
3639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ArrayList<ItemInfo> mItems = new ArrayList();
3649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ArrayList<LauncherAppWidgetInfo> mAppWidgets = new ArrayList();
3659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final HashMap<Long, FolderInfo> folders = new HashMap();
3669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
3679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        /**
3689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         * Call this from the ui thread so the handler is initialized on the correct thread.
3699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         */
3709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public Loader() {
371f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
372f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
3739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void startLoader(Context context, boolean isLaunching) {
3749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            synchronized (mLock) {
3759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                Log.d(TAG, "startLoader isLaunching=" + isLaunching);
3769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Don't bother to start the thread if we know it's not going to do anything
3779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (mCallbacks.get() != null) {
3789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    LoaderThread oldThread = mLoaderThread;
3799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (oldThread != null) {
3809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        if (oldThread.isLaunching()) {
3819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            // don't downgrade isLaunching if we're already running
3829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            isLaunching = true;
3839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
3849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        oldThread.stopLocked();
3859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
3869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mLoaderThread = new LoaderThread(context, oldThread, isLaunching);
3879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mLoaderThread.start();
3889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
389b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy            }
390b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy        }
391b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy
3929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void stopLoader() {
3939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            synchronized (mLock) {
3949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (mLoaderThread != null) {
3959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mLoaderThread.stopLocked();
3969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
3979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
398f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
399b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy
4009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void setWorkspaceDirty() {
4019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            synchronized (mLock) {
4029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mWorkspaceSeq++;
4039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
4049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
405f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void setAllAppsDirty() {
4079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            synchronized (mLock) {
4089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mAllAppsSeq++;
409f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
410f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
411f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        /**
4139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         * Runnable for the thread that loads the contents of the launcher:
4149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         *   - workspace icons
4159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         *   - widgets
4169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         *   - all apps icons
4179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato         */
4189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        private class LoaderThread extends Thread {
4199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private Context mContext;
4209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private Thread mWaitThread;
4219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private boolean mIsLaunching;
4229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private boolean mStopped;
4239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private boolean mWorkspaceDoneBinding;
4249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
4259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            LoaderThread(Context context, Thread waitThread, boolean isLaunching) {
4269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mContext = context;
4279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mWaitThread = waitThread;
4289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mIsLaunching = isLaunching;
4299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
430f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            boolean isLaunching() {
4329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                return mIsLaunching;
4339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
434f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            /**
4369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * If another LoaderThread was supplied, we need to wait for that to finish before
4379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * we start our processing.  This keeps the ordering of the setting and clearing
4389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * of the dirty flags correct by making sure we don't start processing stuff until
4399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * they've had a chance to re-set them.  We do this waiting the worker thread, not
4409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * the ui thread to avoid ANRs.
4419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             */
4429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private void waitForOtherThread() {
4439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (mWaitThread != null) {
4449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    boolean done = false;
4459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    while (!done) {
4469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        try {
4479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            mWaitThread.join();
448efabe00e4a51bb792366c459d6acc46832e61fdcJoe Onorato                            done = true;
4499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        } catch (InterruptedException ex) {
4509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
4519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
4529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mWaitThread = null;
4539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
4549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
455f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            public void run() {
4579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                waitForOtherThread();
458f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Elevate priority when Home launches for the first time to avoid
4609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // starving at boot time. Staring at a blank home is not cool.
4619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
4629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    android.os.Process.setThreadPriority(mIsLaunching
4639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            ? Process.THREAD_PRIORITY_DEFAULT : Process.THREAD_PRIORITY_BACKGROUND);
4649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
465f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Load the workspace only if it's dirty.
4679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                int workspaceSeq;
4689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                boolean workspaceDirty;
4699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
4709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    workspaceSeq = mWorkspaceSeq;
4719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    workspaceDirty = mWorkspaceSeq != mLastWorkspaceSeq;
4729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
4739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (workspaceDirty) {
4749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    loadWorkspace();
4759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
4769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
4779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    // If we're not stopped, and nobody has incremented mWorkspaceSeq.
4789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (mStopped) {
4799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        return;
4809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
4819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (workspaceSeq == mWorkspaceSeq) {
4829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        mLastWorkspaceSeq = mWorkspaceSeq;
4839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
4849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
485f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
4869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Bind the workspace
4879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                bindWorkspace();
4889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
4899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Wait until the either we're stopped or the other threads are done.
4909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // This way we don't start loading all apps until the workspace has settled
4919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // down.
4929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (LoaderThread.this) {
4939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mHandler.post(new Runnable() {
4949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            public void run() {
4959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                synchronized (LoaderThread.this) {
4969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    mWorkspaceDoneBinding = true;
4979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    Log.d(TAG, "done with workspace");
4989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    LoaderThread.this.notify();
4999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
5009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            }
5019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        });
5029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    Log.d(TAG, "waiting to be done with workspace");
5039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    while (!mStopped && !mWorkspaceDoneBinding) {
5049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        try {
5059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            this.wait();
5069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        } catch (InterruptedException ex) {
5079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
5089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
5099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    Log.d(TAG, "done waiting to be done with workspace");
5109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
511f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Load all apps if they're dirty
5139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                int allAppsSeq;
5149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                boolean allAppsDirty;
5159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
5169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    allAppsSeq = mAllAppsSeq;
5179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    allAppsDirty = mAllAppsSeq != mLastAllAppsSeq;
5189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
5199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (allAppsDirty) {
5209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    loadAllApps();
5219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
5229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
5239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    // If we're not stopped, and nobody has incremented mAllAppsSeq.
5249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (mStopped) {
5259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        return;
5269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
5279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (allAppsSeq == mAllAppsSeq) {
5289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        mLastAllAppsSeq = mAllAppsSeq;
5299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
5309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
531f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Bind all apps
53334b02499432896b60cdb9f78c9d1019c80ef6ef5Joe Onorato                if (allAppsDirty) {
53434b02499432896b60cdb9f78c9d1019c80ef6ef5Joe Onorato                    bindAllApps();
53534b02499432896b60cdb9f78c9d1019c80ef6ef5Joe Onorato                }
536f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Clear out this reference, otherwise we end up holding it until all of the
5389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // callback runnables are done.
5399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mContext = null;
540f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
5429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    // Setting the reference is atomic, but we can't do it inside the other critical
5439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    // sections.
5449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mLoaderThread = null;
5459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    return;
546f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                }
547f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
548f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            public void stopLocked() {
5509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (LoaderThread.this) {
5519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mStopped = true;
5529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    this.notify();
5539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
554f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
555f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            /**
5579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * Gets the callbacks object.  If we've been stopped, or if the launcher object
5589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * has somehow been garbage collected, return null instead.
5599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             */
5609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            Callbacks tryGetCallbacks() {
5619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
5629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (mStopped) {
5639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        return null;
5649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
5659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
5669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final Callbacks callbacks = mCallbacks.get();
5679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (callbacks == null) {
5689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        Log.w(TAG, "no mCallbacks");
5699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        return null;
5709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
571f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    return callbacks;
5739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
574f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
575f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private void loadWorkspace() {
5779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                long t = SystemClock.uptimeMillis();
578f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final Context context = mContext;
5809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final ContentResolver contentResolver = context.getContentResolver();
5819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final PackageManager manager = context.getPackageManager();
582f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                /* TODO
5849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (mLocaleChanged) {
5859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    updateShortcutLabels(contentResolver, manager);
5869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
5879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                */
588f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final Cursor c = contentResolver.query(
5909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        LauncherSettings.Favorites.CONTENT_URI, null, null, null, null);
591f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                try {
5939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
5949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int intentIndex = c.getColumnIndexOrThrow
5959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            (LauncherSettings.Favorites.INTENT);
5969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int titleIndex = c.getColumnIndexOrThrow
5979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            (LauncherSettings.Favorites.TITLE);
5989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int iconTypeIndex = c.getColumnIndexOrThrow(
5999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.ICON_TYPE);
6009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON);
6019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int iconPackageIndex = c.getColumnIndexOrThrow(
6029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.ICON_PACKAGE);
6039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int iconResourceIndex = c.getColumnIndexOrThrow(
6049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.ICON_RESOURCE);
6059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int containerIndex = c.getColumnIndexOrThrow(
6069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.CONTAINER);
6079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int itemTypeIndex = c.getColumnIndexOrThrow(
6089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.ITEM_TYPE);
6099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int appWidgetIdIndex = c.getColumnIndexOrThrow(
6109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.APPWIDGET_ID);
6119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int screenIndex = c.getColumnIndexOrThrow(
6129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.SCREEN);
6139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int cellXIndex = c.getColumnIndexOrThrow
6149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            (LauncherSettings.Favorites.CELLX);
6159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int cellYIndex = c.getColumnIndexOrThrow
6169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            (LauncherSettings.Favorites.CELLY);
6179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int spanXIndex = c.getColumnIndexOrThrow
6189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            (LauncherSettings.Favorites.SPANX);
6199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int spanYIndex = c.getColumnIndexOrThrow(
6209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.SPANY);
6219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
6229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int displayModeIndex = c.getColumnIndexOrThrow(
6239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            LauncherSettings.Favorites.DISPLAY_MODE);
6249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
6259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    ApplicationInfo info;
6269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    String intentDescription;
6279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    Widget widgetInfo;
6289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    LauncherAppWidgetInfo appWidgetInfo;
6299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    int container;
6309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    long id;
6319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    Intent intent;
6329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
6339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    while (!mStopped && c.moveToNext()) {
6349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        try {
6359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            int itemType = c.getInt(itemTypeIndex);
636f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            switch (itemType) {
6389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
6399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
6409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                intentDescription = c.getString(intentIndex);
6419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                try {
6429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    intent = Intent.parseUri(intentDescription, 0);
6439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                } catch (URISyntaxException e) {
6449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    continue;
6459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
646f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
6489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info = getApplicationInfo(manager, intent, context);
6499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                } else {
6509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info = getApplicationInfoShortcut(c, context, iconTypeIndex,
6519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                            iconPackageIndex, iconResourceIndex, iconIndex);
6529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
653f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                if (info == null) {
6559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info = new ApplicationInfo();
6569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info.icon = manager.getDefaultActivityIcon();
6579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
658f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                if (info != null) {
6609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info.title = c.getString(titleIndex);
6619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info.intent = intent;
6629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
6639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info.id = c.getLong(idIndex);
6649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    container = c.getInt(containerIndex);
6659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info.container = container;
6669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info.screen = c.getInt(screenIndex);
6679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info.cellX = c.getInt(cellXIndex);
6689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    info.cellY = c.getInt(cellYIndex);
6699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
6709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    switch (container) {
6719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    case LauncherSettings.Favorites.CONTAINER_DESKTOP:
6729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        mItems.add(info);
6739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        break;
6749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    default:
6759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        // Item is in a user folder
6769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        UserFolderInfo folderInfo =
6779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                                findOrMakeUserFolder(folders, container);
6789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        folderInfo.add(info);
6799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        break;
6809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    }
6819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
6829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                break;
6839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
684f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                id = c.getLong(idIndex);
6869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                UserFolderInfo folderInfo = findOrMakeUserFolder(folders, id);
687f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                folderInfo.title = c.getString(titleIndex);
689f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                folderInfo.id = id;
6919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                container = c.getInt(containerIndex);
6929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                folderInfo.container = container;
6939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                folderInfo.screen = c.getInt(screenIndex);
6949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                folderInfo.cellX = c.getInt(cellXIndex);
6959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                folderInfo.cellY = c.getInt(cellYIndex);
696f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
6979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                switch (container) {
6989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    case LauncherSettings.Favorites.CONTAINER_DESKTOP:
6999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        mItems.add(folderInfo);
7009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        break;
7019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
7029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                break;
7039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
7049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
7059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                id = c.getLong(idIndex);
7069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(folders, id);
7079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
7089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                intentDescription = c.getString(intentIndex);
7099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                intent = null;
7109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                if (intentDescription != null) {
7119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    try {
7129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        intent = Intent.parseUri(intentDescription, 0);
7139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    } catch (URISyntaxException e) {
7149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        // Ignore, a live folder might not have a base intent
7159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    }
7169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
717f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
7189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                liveFolderInfo.title = c.getString(titleIndex);
7199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                liveFolderInfo.id = id;
7209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                container = c.getInt(containerIndex);
7219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                liveFolderInfo.container = container;
7229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                liveFolderInfo.screen = c.getInt(screenIndex);
7239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                liveFolderInfo.cellX = c.getInt(cellXIndex);
7249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                liveFolderInfo.cellY = c.getInt(cellYIndex);
7259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                liveFolderInfo.uri = Uri.parse(c.getString(uriIndex));
7269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                liveFolderInfo.baseIntent = intent;
7279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                liveFolderInfo.displayMode = c.getInt(displayModeIndex);
728f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
7299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                loadLiveFolderIcon(context, c, iconTypeIndex, iconPackageIndex,
7309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        iconResourceIndex, liveFolderInfo);
7319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
7329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                switch (container) {
7339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    case LauncherSettings.Favorites.CONTAINER_DESKTOP:
7349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        mItems.add(liveFolderInfo);
7359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                        break;
7369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
7379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                break;
7389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
7399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                widgetInfo = Widget.makeSearch();
74031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
7419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                container = c.getInt(containerIndex);
7429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
7439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    Log.e(TAG, "Widget found where container "
7449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                            + "!= CONTAINER_DESKTOP  ignoring!");
7459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    continue;
7469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
74731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
7489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                widgetInfo.id = c.getLong(idIndex);
7499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                widgetInfo.screen = c.getInt(screenIndex);
7509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                widgetInfo.container = container;
7519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                widgetInfo.cellX = c.getInt(cellXIndex);
7529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                widgetInfo.cellY = c.getInt(cellYIndex);
7539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
7549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                mItems.add(widgetInfo);
7559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                break;
7569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
7579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                // Read all Launcher-specific widget details
7589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                int appWidgetId = c.getInt(appWidgetIdIndex);
7599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId);
7609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                appWidgetInfo.id = c.getLong(idIndex);
7619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                appWidgetInfo.screen = c.getInt(screenIndex);
7629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                appWidgetInfo.cellX = c.getInt(cellXIndex);
7639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                appWidgetInfo.cellY = c.getInt(cellYIndex);
7649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                appWidgetInfo.spanX = c.getInt(spanXIndex);
7659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                appWidgetInfo.spanY = c.getInt(spanYIndex);
76631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
7679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                container = c.getInt(containerIndex);
7689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
7699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    Log.e(TAG, "Widget found where container "
7709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                            + "!= CONTAINER_DESKTOP -- ignoring!");
7719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    continue;
7729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
7739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                appWidgetInfo.container = c.getInt(containerIndex);
77431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
7759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                mAppWidgets.add(appWidgetInfo);
7769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                break;
7779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            }
7789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        } catch (Exception e) {
7799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            Log.w(TAG, "Desktop items loading interrupted:", e);
7809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
7819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
7829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                } finally {
7839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    c.close();
7849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
7859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms");
7869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
78731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
7889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            /**
7899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             * Read everything out of our database.
7909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato             */
7919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private void bindWorkspace() {
7929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final long t = SystemClock.uptimeMillis();
7939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
7949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Don't use these two variables in any of the callback runnables.
7959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Otherwise we hold a reference to them.
7969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                Callbacks callbacks = mCallbacks.get();
7979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (callbacks == null) {
7989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    // This launcher has exited and nobody bothered to tell us.  Just bail.
7999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    Log.w(TAG, "LoaderThread running with no launcher");
8009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    return;
8019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
80231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
8039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                int N;
8049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Tell the workspace that we're about to start firing items at it
8059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mHandler.post(new Runnable() {
8069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    public void run() {
8079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        Callbacks callbacks = tryGetCallbacks();
8089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        if (callbacks != null) {
8099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            callbacks.startBinding();
8109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
8119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
8129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                });
8139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Add the items to the workspace.
8149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                N = mItems.size();
8159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                for (int i=0; i<N; i+=ITEMS_CHUNK) {
8169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int start = i;
8179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final int chunkSize = (i+ITEMS_CHUNK <= N) ? ITEMS_CHUNK : (N-i);
8189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mHandler.post(new Runnable() {
8199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        public void run() {
8209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            Callbacks callbacks = tryGetCallbacks();
8219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            if (callbacks != null) {
8229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                callbacks.bindItems(mItems, start, start+chunkSize);
8239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            }
8249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
8259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    });
8269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
8279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Wait until the queue goes empty.
8289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mHandler.postIdle(new Runnable() {
8299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    public void run() {
8309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        Log.d(TAG, "Going to start binding widgets soon.");
8319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
8329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                });
8339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Bind the widgets, one at a time.
8349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // WARNING: this is calling into the workspace from the background thread,
8359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // but since getCurrentScreen() just returns the int, we should be okay.  This
8369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // is just a hint for the order, and if it's wrong, we'll be okay.
8379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // TODO: instead, we should have that push the current screen into here.
8389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int currentScreen = callbacks.getCurrentWorkspaceScreen();
8399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                N = mAppWidgets.size();
8409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // once for the current screen
8419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                for (int i=0; i<N; i++) {
8429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final LauncherAppWidgetInfo widget = mAppWidgets.get(i);
8439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (widget.screen == currentScreen) {
8449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        mHandler.post(new Runnable() {
8459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            public void run() {
8469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                Callbacks callbacks = tryGetCallbacks();
8479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                if (callbacks != null) {
8489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    callbacks.bindAppWidget(widget);
8499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
8509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            }
8519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        });
8529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
8539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
8549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // once for the other screens
8559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                for (int i=0; i<N; i++) {
8569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final LauncherAppWidgetInfo widget = mAppWidgets.get(i);
8579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (widget.screen != currentScreen) {
8589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        mHandler.post(new Runnable() {
8599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            public void run() {
8609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                Callbacks callbacks = tryGetCallbacks();
8619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                if (callbacks != null) {
8629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                    callbacks.bindAppWidget(widget);
8639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                }
8649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            }
8659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        });
8669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
8679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
8689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // TODO: Bind the folders
8699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // Tell the workspace that we're done.
8709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mHandler.post(new Runnable() {
8719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    public void run() {
8729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        Callbacks callbacks = tryGetCallbacks();
8739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        if (callbacks != null) {
8749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            callbacks.finishBindingItems();
8759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
8769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
8779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                });
8789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                // If we're profiling, this is the last thing in the queue.
8799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mHandler.post(new Runnable() {
8809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    public void run() {
8819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        Log.d(TAG, "bound workspace in " + (SystemClock.uptimeMillis()-t) + "ms");
8829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        if (Launcher.PROFILE_ROTATE) {
8839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            android.os.Debug.stopMethodTracing();
8849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
8859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    }
8869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                });
8879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
88831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
8899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private void loadAllApps() {
8909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
8919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
89231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
8939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final Callbacks callbacks = tryGetCallbacks();
8949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                if (callbacks == null) {
8959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    return;
8969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
89731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
8989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final Context context = mContext;
8999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final PackageManager packageManager = context.getPackageManager();
90031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final List<ResolveInfo> apps = packageManager.queryIntentActivities(mainIntent, 0);
90231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
9049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mAllAppsList.clear();
9059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    if (apps != null) {
9069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        long t = SystemClock.uptimeMillis();
90731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        int N = apps.size();
9099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        Utilities.BubbleText bubble = new Utilities.BubbleText(context);
9109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        for (int i=0; i<N && !mStopped; i++) {
9119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            // This builds the icon bitmaps.
9129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            mAllAppsList.add(AppInfoCache.cache(apps.get(i), context, bubble));
9139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
9149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        Collections.sort(mAllAppsList.data, sComparator);
9159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        Collections.sort(mAllAppsList.added, sComparator);
9169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        Log.d(TAG, "cached app icons in " + (SystemClock.uptimeMillis()-t) + "ms");
917ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project                    }
91831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
91931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
92031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            private void bindAllApps() {
9229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                synchronized (mLock) {
9239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    final ArrayList<ApplicationInfo> results = mAllAppsList.added;
9249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mAllAppsList.added = new ArrayList();
9259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    mHandler.post(new Runnable() {
9269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        public void run() {
92734b02499432896b60cdb9f78c9d1019c80ef6ef5Joe Onorato                            final long t = SystemClock.uptimeMillis();
92834b02499432896b60cdb9f78c9d1019c80ef6ef5Joe Onorato                            final int count = results.size();
9299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
9309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            Callbacks callbacks = tryGetCallbacks();
9319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            if (callbacks != null) {
9329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                callbacks.bindAllApplications(results);
9339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                            }
9349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
93534b02499432896b60cdb9f78c9d1019c80ef6ef5Joe Onorato                            Log.d(TAG, "bound app " + count + " icons in "
9369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                + (SystemClock.uptimeMillis()-t) + "ms");
9379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        }
9389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    });
9399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                }
94031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
94131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
94231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
94331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
9459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Make an ApplicationInfo object for an application.
9469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
9479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private static ApplicationInfo getApplicationInfo(PackageManager manager, Intent intent,
9489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                                                      Context context) {
9499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ResolveInfo resolveInfo = manager.resolveActivity(intent, 0);
95031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (resolveInfo == null) {
9529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            return null;
95331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
95431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ApplicationInfo info = new ApplicationInfo();
9569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ActivityInfo activityInfo = resolveInfo.activityInfo;
9576665c0f1fec6ec0962896622986340081df992e7Joe Onorato        info.icon = Utilities.createIconThumbnail(activityInfo.loadIcon(manager), context);
9589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (info.title == null || info.title.length() == 0) {
9599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            info.title = activityInfo.loadLabel(manager);
9609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
9619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (info.title == null) {
9629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            info.title = "";
9639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
9649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
9659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        return info;
9669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
96731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
9699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Make an ApplicationInfo object for a sortcut
9709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
9719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private static ApplicationInfo getApplicationInfoShortcut(Cursor c, Context context,
9729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex) {
97331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        final ApplicationInfo info = new ApplicationInfo();
9759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
9767376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project
9779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        int iconType = c.getInt(iconTypeIndex);
9789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        switch (iconType) {
9799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
9809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            String packageName = c.getString(iconPackageIndex);
9819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            String resourceName = c.getString(iconResourceIndex);
9829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            PackageManager packageManager = context.getPackageManager();
9839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            try {
9849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                Resources resources = packageManager.getResourcesForApplication(packageName);
9859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int id = resources.getIdentifier(resourceName, null, null);
9866665c0f1fec6ec0962896622986340081df992e7Joe Onorato                info.icon = Utilities.createIconThumbnail(resources.getDrawable(id), context);
9879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            } catch (Exception e) {
9889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                info.icon = packageManager.getDefaultActivityIcon();
9897376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project            }
9909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            info.iconResource = new Intent.ShortcutIconResource();
9919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            info.iconResource.packageName = packageName;
9929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            info.iconResource.resourceName = resourceName;
9939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            info.customIcon = false;
9949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            break;
9959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        case LauncherSettings.Favorites.ICON_TYPE_BITMAP:
9969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            byte[] data = c.getBlob(iconIndex);
9979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            try {
9989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
9999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                info.icon = new FastBitmapDrawable(
10009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        Utilities.createBitmapThumbnail(bitmap, context));
10019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            } catch (Exception e) {
10029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                packageManager = context.getPackageManager();
10039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                info.icon = packageManager.getDefaultActivityIcon();
10049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
10059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            info.filtered = true;
10069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            info.customIcon = true;
10079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            break;
10089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        default:
10099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            info.icon = context.getPackageManager().getDefaultActivityIcon();
10109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            info.customIcon = false;
10119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            break;
101231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
10139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        return info;
1014f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
101531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
10169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private static void loadLiveFolderIcon(Context context, Cursor c, int iconTypeIndex,
10179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            int iconPackageIndex, int iconResourceIndex, LiveFolderInfo liveFolderInfo) {
101831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
10199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        int iconType = c.getInt(iconTypeIndex);
10209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        switch (iconType) {
10219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
10229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            String packageName = c.getString(iconPackageIndex);
10239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            String resourceName = c.getString(iconResourceIndex);
10249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            PackageManager packageManager = context.getPackageManager();
10259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            try {
10269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                Resources resources = packageManager.getResourcesForApplication(packageName);
10279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                final int id = resources.getIdentifier(resourceName, null, null);
10289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                liveFolderInfo.icon = resources.getDrawable(id);
10299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            } catch (Exception e) {
10309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                liveFolderInfo.icon =
10319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                        context.getResources().getDrawable(R.drawable.ic_launcher_folder);
10329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
10339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            liveFolderInfo.iconResource = new Intent.ShortcutIconResource();
10349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            liveFolderInfo.iconResource.packageName = packageName;
10359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            liveFolderInfo.iconResource.resourceName = resourceName;
10369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            break;
10379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        default:
10389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            liveFolderInfo.icon =
10399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    context.getResources().getDrawable(R.drawable.ic_launcher_folder);
10409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
104131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
1042bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
104331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
10449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Return an existing UserFolderInfo object if we have encountered this ID previously,
10459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * or make a new one.
104631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
10479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private static UserFolderInfo findOrMakeUserFolder(HashMap<Long, FolderInfo> folders, long id) {
10489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        // See if a placeholder was created for us already
10499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        FolderInfo folderInfo = folders.get(id);
10509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (folderInfo == null || !(folderInfo instanceof UserFolderInfo)) {
10519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            // No placeholder -- create a new instance
10529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            folderInfo = new UserFolderInfo();
10539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            folders.put(id, folderInfo);
105431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
10559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        return (UserFolderInfo) folderInfo;
10569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
105731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
10589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /**
10599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
10609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     * new one.
10619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato     */
10629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private static LiveFolderInfo findOrMakeLiveFolder(HashMap<Long, FolderInfo> folders, long id) {
10639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        // See if a placeholder was created for us already
10649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        FolderInfo folderInfo = folders.get(id);
10659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (folderInfo == null || !(folderInfo instanceof LiveFolderInfo)) {
10669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            // No placeholder -- create a new instance
10679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            folderInfo = new LiveFolderInfo();
10689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            folders.put(id, folderInfo);
106931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
10709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        return (LiveFolderInfo) folderInfo;
107131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
107231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
107331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static void updateShortcutLabels(ContentResolver resolver, PackageManager manager) {
107431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final Cursor c = resolver.query(LauncherSettings.Favorites.CONTENT_URI,
107573b979d8c141c7ceac82dad7c5b271a6a42afa67Romain Guy                new String[] { LauncherSettings.Favorites._ID, LauncherSettings.Favorites.TITLE,
107631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        LauncherSettings.Favorites.INTENT, LauncherSettings.Favorites.ITEM_TYPE },
107731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                null, null, null);
107831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
107973b979d8c141c7ceac82dad7c5b271a6a42afa67Romain Guy        final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
108031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
108131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
108231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
108331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
108431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // boolean changed = false;
108531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
108631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        try {
108731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            while (c.moveToNext()) {
108831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                try {
108931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    if (c.getInt(itemTypeIndex) !=
109031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
109131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        continue;
109231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    }
109331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
109431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    final String intentUri = c.getString(intentIndex);
109531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    if (intentUri != null) {
10961ce1a24cba4dc41bccfeab6fccb2f3355423841aRomain Guy                        final Intent shortcut = Intent.parseUri(intentUri, 0);
109731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        if (Intent.ACTION_MAIN.equals(shortcut.getAction())) {
109831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            final ComponentName name = shortcut.getComponent();
109931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (name != null) {
110031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                final ActivityInfo activityInfo = manager.getActivityInfo(name, 0);
110131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                final String title = c.getString(titleIndex);
110231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                String label = getLabel(manager, activityInfo);
110331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
110431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                if (title == null || !title.equals(label)) {
110531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    final ContentValues values = new ContentValues();
110631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    values.put(LauncherSettings.Favorites.TITLE, label);
110731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1108fedc4fcebc28feb5553bbfb4f0856676cb8f320dRomain Guy                                    resolver.update(
1109fedc4fcebc28feb5553bbfb4f0856676cb8f320dRomain Guy                                            LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION,
111031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                            values, "_id=?",
111131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                            new String[] { String.valueOf(c.getLong(idIndex)) });
111231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
111331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    // changed = true;
111431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                }
111531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
111631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        }
111731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    }
111831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                } catch (URISyntaxException e) {
111931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    // Ignore
112031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                } catch (PackageManager.NameNotFoundException e) {
112131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    // Ignore
112231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
112331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
112431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        } finally {
112531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            c.close();
112631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
112731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
112831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // if (changed) resolver.notifyChange(Settings.Favorites.CONTENT_URI, null);
112931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
113031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
113131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static String getLabel(PackageManager manager, ActivityInfo activityInfo) {
113231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        String label = activityInfo.loadLabel(manager).toString();
113331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (label == null) {
113431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            label = manager.getApplicationLabel(activityInfo.applicationInfo).toString();
113531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (label == null) {
113631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                label = activityInfo.name;
113731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
113831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
113931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return label;
114031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
114131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
11429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private static final Collator sCollator = Collator.getInstance();
11439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private static final Comparator<ApplicationInfo> sComparator
11449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            = new Comparator<ApplicationInfo>() {
11459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public final int compare(ApplicationInfo a, ApplicationInfo b) {
11469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            return sCollator.compare(a.title.toString(), b.title.toString());
114731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
11489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    };
114931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project}
1150