FileDocCategorySizeDatePackage
LauncherModel.javaAPI DocAndroid 1.5 API54992Wed May 06 22:42:46 BST 2009com.android.launcher

LauncherModel

public class LauncherModel extends Object
Maintains in-memory state of the Launcher. It is expected that there should be only one LauncherModel object held in a static. Also provide APIs for updating the database state for the Launcher.

Fields Summary
static final boolean
DEBUG_LOADERS
static final String
LOG_TAG
private static final int
UI_NOTIFICATION_RATE
private static final int
DEFAULT_APPLICATIONS_NUMBER
private static final long
APPLICATION_NOT_RESPONDING_TIMEOUT
private static final int
INITIAL_ICON_CACHE_CAPACITY
private static final Collator
sCollator
private boolean
mApplicationsLoaded
private boolean
mDesktopItemsLoaded
private ArrayList
mDesktopItems
private ArrayList
mDesktopAppWidgets
private HashMap
mFolders
private ArrayList
mApplications
private ApplicationsAdapter
mApplicationsAdapter
private ApplicationsLoader
mApplicationsLoader
private DesktopItemsLoader
mDesktopItemsLoader
private Thread
mApplicationsLoaderThread
private Thread
mDesktopLoaderThread
private final HashMap
mAppInfoCache
Constructors Summary
Methods Summary
synchronized voidabortLoaders()


       
        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
            mApplicationsLoader.stop();
            mApplicationsLoaded = false;
        }

        if (mDesktopItemsLoader != null && mDesktopItemsLoader.isRunning()) {
            mDesktopItemsLoader.stop();
            mDesktopItemsLoaded = false;
        }
    
voidaddDesktopAppWidget(LauncherAppWidgetInfo info)
Add a widget to the desktop

        mDesktopAppWidgets.add(info);
    
voidaddDesktopItem(ItemInfo info)
Add an item to the desktop

param
info

        // TODO: write to DB; also check that folder has been added to folders list
        mDesktopItems.add(info);
    
private booleanaddEnabledAndUpdateActivities(java.util.List matches, ApplicationsAdapter adapter, Launcher launcher)


        final List<ApplicationInfo> toAdd = new ArrayList<ApplicationInfo>();
        final int count = matches.size();

        boolean changed = false;

        for (int i = 0; i < count; i++) {
            final ResolveInfo info = matches.get(i);
            final ApplicationInfo applicationInfo = findIntent(adapter,
                    info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
            if (applicationInfo == null) {
                toAdd.add(makeAndCacheApplicationInfo(launcher.getPackageManager(),
                        mAppInfoCache, info));
                changed = true;
            } else {
                updateAndCacheApplicationInfo(launcher.getPackageManager(), info, applicationInfo);
                changed = true;
            }
        }

        for (ApplicationInfo info : toAdd) {
            adapter.setNotifyOnChange(false);
            adapter.add(info);
        }

        return changed;
    
voidaddFolder(FolderInfo info)

        mFolders.put(info.id, info);
    
static voidaddItemToDatabase(android.content.Context context, ItemInfo item, long container, int screen, int cellX, int cellY, boolean notify)
Add an item to the database in a specified container. Sets the container, screen, cellX and cellY fields of the item. Also assigns an ID to the item.

        item.container = container;
        item.screen = screen;
        item.cellX = cellX;
        item.cellY = cellY;
        
        final ContentValues values = new ContentValues();
        final ContentResolver cr = context.getContentResolver();
        
        item.onAddToDatabase(values);
        
        Uri result = cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI :
                LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values);

        if (result != null) {
            item.id = Integer.parseInt(result.getPathSegments().get(1));
        }
    
static voidaddOrMoveItemInDatabase(android.content.Context context, ItemInfo item, long container, int screen, int cellX, int cellY)
Adds an item to the DB if it was not created previously, or move it to a new

        if (item.container == ItemInfo.NO_ID) {
            // From all apps
            addItemToDatabase(context, item, container, screen, cellX, cellY, false);
        } else {
            // From somewhere else
            moveItemInDatabase(context, item, container, screen, cellX, cellY);
        }
    
synchronized voidaddPackage(Launcher launcher, java.lang.String packageName)

        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
            startApplicationsLoader(launcher);
            return;
        }

        if (packageName != null && packageName.length() > 0) {
            final PackageManager packageManager = launcher.getPackageManager();
            final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);

            if (matches.size() > 0) {
                final ApplicationsAdapter adapter = mApplicationsAdapter;
                final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;

                for (ResolveInfo info : matches) {
                    adapter.setNotifyOnChange(false);
                    adapter.add(makeAndCacheApplicationInfo(packageManager, cache, info));
                }

                adapter.sort(new ApplicationInfoComparator());
                adapter.notifyDataSetChanged();
            }
        }
    
static voiddeleteItemFromDatabase(android.content.Context context, ItemInfo item)
Removes the specified item from the database

param
context
param
item

        final ContentResolver cr = context.getContentResolver();

        cr.delete(LauncherSettings.Favorites.getContentUri(item.id, false), null, null);
    
static voiddeleteUserFolderContentsFromDatabase(android.content.Context context, UserFolderInfo info)
Remove the contents of the specified folder from the database

        final ContentResolver cr = context.getContentResolver();

        cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null);
        cr.delete(LauncherSettings.Favorites.CONTENT_URI,
                LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
    
synchronized voiddropApplicationCache()
Drop our cache of components to their lables & icons. We do this from Launcher when applications are added/removed. It's a bit overkill, but it's a rare operation anyway.

        mAppInfoCache.clear();
    
private static java.util.ListfindActivitiesForPackage(android.content.pm.PackageManager packageManager, java.lang.String packageName)


        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);

        final List<ResolveInfo> apps = packageManager.queryIntentActivities(mainIntent, 0);
        final List<ResolveInfo> matches = new ArrayList<ResolveInfo>();

        if (apps != null) {
            // Find all activities that match the packageName
            int count = apps.size();
            for (int i = 0; i < count; i++) {
                final ResolveInfo info = apps.get(i);
                final ActivityInfo activityInfo = info.activityInfo;
                if (packageName.equals(activityInfo.packageName)) {
                    matches.add(info);
                }
            }
        }

        return matches;
    
FolderInfofindFolderById(long id)
Finds the user folder defined by the specified id.

param
id The id of the folder to look for.
return
A UserFolderInfo if the folder exists or null otherwise.

        return mFolders.get(id);
    
private static ApplicationInfofindIntent(ApplicationsAdapter adapter, java.lang.String packageName, java.lang.String name)


        final int count = adapter.getCount();
        for (int i = 0; i < count; i++) {
            final ApplicationInfo applicationInfo = adapter.getItem(i);
            final Intent intent = applicationInfo.intent;
            final ComponentName component = intent.getComponent();
            if (packageName.equals(component.getPackageName()) &&
                    name.equals(component.getClassName())) {
                return applicationInfo;
            }
        }

        return null;
    
private static booleanfindIntent(java.util.List apps, android.content.ComponentName component)

        final String className = component.getClassName();
        for (ResolveInfo info : apps) {
            final ActivityInfo activityInfo = info.activityInfo;
            if (activityInfo.name.equals(className)) {
                return true;
            }
        }
        return false;
    
private LiveFolderInfofindOrMakeLiveFolder(java.util.HashMap folders, long id)
Return an existing UserFolderInfo object if we have encountered this ID previously, or make a new one.

        // See if a placeholder was created for us already
        FolderInfo folderInfo = folders.get(id);
        if (folderInfo == null || !(folderInfo instanceof LiveFolderInfo)) {
            // No placeholder -- create a new instance
            folderInfo = new LiveFolderInfo();
            folders.put(id, folderInfo);
        }
        return (LiveFolderInfo) folderInfo;
    
private UserFolderInfofindOrMakeUserFolder(java.util.HashMap folders, long id)
Return an existing UserFolderInfo object if we have encountered this ID previously, or make a new one.

        // See if a placeholder was created for us already
        FolderInfo folderInfo = folders.get(id);
        if (folderInfo == null || !(folderInfo instanceof UserFolderInfo)) {
            // No placeholder -- create a new instance
            folderInfo = new UserFolderInfo();
            folders.put(id, folderInfo);
        }
        return (UserFolderInfo) folderInfo;
    
private static ApplicationInfogetApplicationInfo(android.content.pm.PackageManager manager, android.content.Intent intent)
Make an ApplicationInfo object for an application

        final ResolveInfo resolveInfo = manager.resolveActivity(intent, 0);

        if (resolveInfo == null) {
            return null;
        }
        
        final ApplicationInfo info = new ApplicationInfo();
        final ActivityInfo activityInfo = resolveInfo.activityInfo;
        info.icon = activityInfo.loadIcon(manager);
        if (info.title == null || info.title.length() == 0) {
            info.title = activityInfo.loadLabel(manager);
        }
        if (info.title == null) {
            info.title = "";
        }
        info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
        return info;
    
android.graphics.drawable.DrawablegetApplicationInfoIcon(android.content.pm.PackageManager manager, ApplicationInfo info)

        final ResolveInfo resolveInfo = manager.resolveActivity(info.intent, 0);
        if (resolveInfo == null) {
            return null;
        }

        ComponentName componentName = new ComponentName(
                resolveInfo.activityInfo.applicationInfo.packageName,
                resolveInfo.activityInfo.name);
        ApplicationInfo application = mAppInfoCache.get(componentName);

        if (application == null) {
            return resolveInfo.activityInfo.loadIcon(manager);
        }

        return application.icon;
    
private ApplicationInfogetApplicationInfoShortcut(android.database.Cursor c, Launcher launcher, int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex)
Make an ApplicationInfo object for a sortcut


        final ApplicationInfo info = new ApplicationInfo();
        info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;

        int iconType = c.getInt(iconTypeIndex);
        switch (iconType) {
            case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
                String packageName = c.getString(iconPackageIndex);
                String resourceName = c.getString(iconResourceIndex);
                PackageManager packageManager = launcher.getPackageManager();
                try {
                    Resources resources = packageManager.getResourcesForApplication(packageName);
                    final int id = resources.getIdentifier(resourceName, null, null);
                    info.icon = resources.getDrawable(id);
                } catch (Exception e) {
                    info.icon = packageManager.getDefaultActivityIcon();
                }
                info.iconResource = new Intent.ShortcutIconResource();
                info.iconResource.packageName = packageName;
                info.iconResource.resourceName = resourceName;
                info.customIcon = false;
                break;
            case LauncherSettings.Favorites.ICON_TYPE_BITMAP:
                byte[] data = c.getBlob(iconIndex);
                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                info.icon = new FastBitmapDrawable(
                        Utilities.createBitmapThumbnail(bitmap, launcher));
                info.filtered = true;
                info.customIcon = true;
                break;
            default:
                info.icon = launcher.getPackageManager().getDefaultActivityIcon();
                info.customIcon = false;
                break;
        }
        return info;
    
ApplicationsAdaptergetApplicationsAdapter()

return
The current list of applications

        return mApplicationsAdapter;
    
java.util.ArrayListgetDesktopAppWidgets()

return
The current list of desktop items

        return mDesktopAppWidgets;
    
java.util.ArrayListgetDesktopItems()

return
The current list of desktop items

        return mDesktopItems;
    
FolderInfogetFolderById(android.content.Context context, long id)

        final ContentResolver cr = context.getContentResolver();
        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null,
                "_id=? and (itemType=? or itemType=?)",
                new String[] { String.valueOf(id),
                        String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER),
                        String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER) }, null);

        try {
            if (c.moveToFirst()) {
                final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
                final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
                final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
                final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
                final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
                final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);

                FolderInfo folderInfo = null;
                switch (c.getInt(itemTypeIndex)) {
                    case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
                        folderInfo = findOrMakeUserFolder(mFolders, id);
                        break;
                    case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
                        folderInfo = findOrMakeLiveFolder(mFolders, id);
                        break;
                }

                folderInfo.title = c.getString(titleIndex);
                folderInfo.id = id;
                folderInfo.container = c.getInt(containerIndex);
                folderInfo.screen = c.getInt(screenIndex);
                folderInfo.cellX = c.getInt(cellXIndex);
                folderInfo.cellY = c.getInt(cellYIndex);

                return folderInfo;
            }
        } finally {
            c.close();
        }

        return null;
    
private static java.lang.StringgetLabel(android.content.pm.PackageManager manager, android.content.pm.ActivityInfo activityInfo)

        String label = activityInfo.loadLabel(manager).toString();
        if (label == null) {
            label = manager.getApplicationLabel(activityInfo.applicationInfo).toString();
            if (label == null) {
                label = activityInfo.name;
            }
        }
        return label;
    
booleanisDesktopLoaded()

        return mDesktopItems != null && mDesktopAppWidgets != null && mDesktopItemsLoaded;
    
synchronized booleanloadApplications(boolean isLaunching, Launcher launcher, boolean localeChanged)
Loads the list of installed applications in mApplications.

return
true if the applications loader must be started (see startApplicationsLoader()), false otherwise.


        if (DEBUG_LOADERS) d(LOG_TAG, "load applications");

        if (isLaunching && mApplicationsLoaded && !localeChanged) {
            mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
            if (DEBUG_LOADERS) d(LOG_TAG, "  --> applications loaded, return");
            return false;
        }

        stopAndWaitForApplicationsLoader();

        if (localeChanged) {
            dropApplicationCache();
        }        

        if (mApplicationsAdapter == null || isLaunching || localeChanged) {
            mApplications = new ArrayList<ApplicationInfo>(DEFAULT_APPLICATIONS_NUMBER);
            mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
        }

        mApplicationsLoaded = false;

        if (!isLaunching) {
            startApplicationsLoader(launcher);
            return false;
        }

        return true;
    
private static voidloadLiveFolderIcon(Launcher launcher, android.database.Cursor c, int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, LiveFolderInfo liveFolderInfo)


        int iconType = c.getInt(iconTypeIndex);
        switch (iconType) {
            case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
                String packageName = c.getString(iconPackageIndex);
                String resourceName = c.getString(iconResourceIndex);
                PackageManager packageManager = launcher.getPackageManager();
                try {
                    Resources resources = packageManager.getResourcesForApplication(packageName);
                    final int id = resources.getIdentifier(resourceName, null, null);
                    liveFolderInfo.icon = resources.getDrawable(id);
                } catch (Exception e) {
                    liveFolderInfo.icon =
                            launcher.getResources().getDrawable(R.drawable.ic_launcher_folder);
                }
                liveFolderInfo.iconResource = new Intent.ShortcutIconResource();
                liveFolderInfo.iconResource.packageName = packageName;
                liveFolderInfo.iconResource.resourceName = resourceName;
                break;
            default:
                liveFolderInfo.icon =
                        launcher.getResources().getDrawable(R.drawable.ic_launcher_folder);
        }
    
voidloadUserItems(boolean isLaunching, Launcher launcher, boolean localeChanged, boolean loadApplications)
Loads all of the items on the desktop, in folders, or in the dock. These can be apps, shortcuts or widgets

        if (DEBUG_LOADERS) d(LOG_TAG, "loading user items");

        if (isLaunching && isDesktopLoaded()) {
            if (DEBUG_LOADERS) d(LOG_TAG, "  --> items loaded, return");
            if (loadApplications) startApplicationsLoader(launcher);
            // We have already loaded our data from the DB
            launcher.onDesktopItemsLoaded();
            return;
        }

        if (mDesktopItemsLoader != null && mDesktopItemsLoader.isRunning()) {
            if (DEBUG_LOADERS) d(LOG_TAG, "  --> stopping workspace loader");
            mDesktopItemsLoader.stop();
            // Wait for the currently running thread to finish, this can take a little
            // time but it should be well below the timeout limit
            try {
                mDesktopLoaderThread.join(APPLICATION_NOT_RESPONDING_TIMEOUT);
            } catch (InterruptedException e) {
                // Empty
            }

            // If the thread we are interrupting was tasked to load the list of
            // applications make sure we keep that information in the new loader
            // spawned below
            // note: we don't apply this to localeChanged because the thread can
            // only be stopped *after* the localeChanged handling has occured
            loadApplications = mDesktopItemsLoader.mLoadApplications;
        }

        if (DEBUG_LOADERS) d(LOG_TAG, "  --> starting workspace loader");
        mDesktopItemsLoaded = false;
        mDesktopItemsLoader = new DesktopItemsLoader(launcher, localeChanged, loadApplications);
        mDesktopLoaderThread = new Thread(mDesktopItemsLoader, "Desktop Items Loader");
        mDesktopLoaderThread.start();
    
private static ApplicationInfomakeAndCacheApplicationInfo(android.content.pm.PackageManager manager, java.util.HashMap appInfoCache, android.content.pm.ResolveInfo info)


        ComponentName componentName = new ComponentName(
                info.activityInfo.applicationInfo.packageName,
                info.activityInfo.name);
        ApplicationInfo application = appInfoCache.get(componentName);

        if (application == null) {
            application = new ApplicationInfo();
            application.container = ItemInfo.NO_ID;

            updateApplicationInfoTitleAndIcon(manager, info, application);

            application.setActivity(componentName,
                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

            appInfoCache.put(componentName, application);
        }

        return application;
    
static voidmoveItemInDatabase(android.content.Context context, ItemInfo item, long container, int screen, int cellX, int cellY)
Move an item in the DB to a new

        item.container = container;
        item.screen = screen;
        item.cellX = cellX;
        item.cellY = cellY;
     
        final ContentValues values = new ContentValues();
        final ContentResolver cr = context.getContentResolver();

        values.put(LauncherSettings.Favorites.CONTAINER, item.container);
        values.put(LauncherSettings.Favorites.CELLX, item.cellX);
        values.put(LauncherSettings.Favorites.CELLY, item.cellY);
        values.put(LauncherSettings.Favorites.SCREEN, item.screen);

        cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
    
voidremoveDesktopAppWidget(LauncherAppWidgetInfo info)
Remove a widget from the desktop

        mDesktopAppWidgets.remove(info);
    
voidremoveDesktopItem(ItemInfo info)
Remove an item from the desktop

param
info

        // TODO: write to DB; figure out if we should remove folder from folders list
        mDesktopItems.remove(info);
    
private booleanremoveDisabledActivities(java.lang.String packageName, java.util.List matches, ApplicationsAdapter adapter)


        final List<ApplicationInfo> toRemove = new ArrayList<ApplicationInfo>();
        final int count = adapter.getCount();

        boolean changed = false;

        for (int i = 0; i < count; i++) {
            final ApplicationInfo applicationInfo = adapter.getItem(i);
            final Intent intent = applicationInfo.intent;
            final ComponentName component = intent.getComponent();
            if (packageName.equals(component.getPackageName())) {
                if (!findIntent(matches, component)) {
                    toRemove.add(applicationInfo);
                    changed = true;
                }
            }
        }

        final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
        for (ApplicationInfo info : toRemove) {
            adapter.setNotifyOnChange(false);
            adapter.remove(info);
            cache.remove(info.intent.getComponent());
        }

        return changed;
    
synchronized voidremovePackage(Launcher launcher, java.lang.String packageName)

        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
            dropApplicationCache(); // TODO: this could be optimized
            startApplicationsLoader(launcher);
            return;
        }

        if (packageName != null && packageName.length() > 0) {
            final ApplicationsAdapter adapter = mApplicationsAdapter;

            final List<ApplicationInfo> toRemove = new ArrayList<ApplicationInfo>();
            final int count = adapter.getCount();

            for (int i = 0; i < count; i++) {
                final ApplicationInfo applicationInfo = adapter.getItem(i);
                final Intent intent = applicationInfo.intent;
                final ComponentName component = intent.getComponent();
                if (packageName.equals(component.getPackageName())) {
                    toRemove.add(applicationInfo);
                }
            }

            final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
            for (ApplicationInfo info : toRemove) {
                adapter.setNotifyOnChange(false);
                adapter.remove(info);
                cache.remove(info.intent.getComponent());
            }

            if (toRemove.size() > 0) {
                adapter.sort(new ApplicationInfoComparator());
                adapter.notifyDataSetChanged();
            }
        }
    
voidremoveUserFolder(UserFolderInfo userFolderInfo)
Removes a UserFolder from the in-memory list of folders. Does not change the DB.

param
userFolderInfo

        mFolders.remove(userFolderInfo.id);
    
voidremoveUserFolderItem(UserFolderInfo folder, ItemInfo info)
Remove an item from the in-memory represention of a user folder. Does not change the DB.

        //noinspection SuspiciousMethodCalls
        folder.contents.remove(info);
    
static booleanshortcutExists(android.content.Context context, java.lang.String title, android.content.Intent intent)
Returns true if the shortcuts already exists in the database. we identify a shortcut by its title and intent.

        final ContentResolver cr = context.getContentResolver();
        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
            new String[] { "title", "intent" }, "title=? and intent=?",
            new String[] { title, intent.toURI() }, null);
        boolean result = false;
        try {
            result = c.moveToFirst();
        } finally {
            c.close();
        }
        return result;
    
private synchronized voidstartApplicationsLoader(Launcher launcher)

        if (DEBUG_LOADERS) d(LOG_TAG, "  --> starting applications loader");

        stopAndWaitForApplicationsLoader();

        mApplicationsLoader = new ApplicationsLoader(launcher);
        mApplicationsLoaderThread = new Thread(mApplicationsLoader, "Applications Loader");
        mApplicationsLoaderThread.start();
    
private synchronized voidstopAndWaitForApplicationsLoader()

        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
            if (DEBUG_LOADERS) d(LOG_TAG, "  --> wait for applications loader");

            mApplicationsLoader.stop();
            // Wait for the currently running thread to finish, this can take a little
            // time but it should be well below the timeout limit
            try {
                mApplicationsLoaderThread.join(APPLICATION_NOT_RESPONDING_TIMEOUT);
            } catch (InterruptedException e) {
                // EMpty
            }
        }
    
synchronized voidsyncPackage(Launcher launcher, java.lang.String packageName)

        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
            startApplicationsLoader(launcher);
            return;
        }

        if (packageName != null && packageName.length() > 0) {
            final PackageManager packageManager = launcher.getPackageManager();
            final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);

            if (matches.size() > 0) {
                final ApplicationsAdapter adapter = mApplicationsAdapter;

                // Find disabled activities and remove them from the adapter
                boolean removed = removeDisabledActivities(packageName, matches, adapter);
                // Find enable activities and add them to the adapter
                // Also updates existing activities with new labels/icons
                boolean added = addEnabledAndUpdateActivities(matches, adapter, launcher);

                if (added || removed) {
                    adapter.sort(new ApplicationInfoComparator());
                    adapter.notifyDataSetChanged();
                }
            }
        }
    
voidunbind()
Remove the callback for the cached drawables or we leak the previous Home screen on orientation change.

        // Interrupt the applications loader before setting the adapter to null
        stopAndWaitForApplicationsLoader();
        mApplicationsAdapter = null;
        unbindAppDrawables(mApplications);
        unbindDrawables(mDesktopItems);
        unbindAppWidgetHostViews(mDesktopAppWidgets);
        unbindCachedIconDrawables();
    
private voidunbindAppDrawables(java.util.ArrayList applications)
Remove the callback for the cached drawables or we leak the previous Home screen on orientation change.

        if (applications != null) {
            final int count = applications.size();
            for (int i = 0; i < count; i++) {
                applications.get(i).icon.setCallback(null);
            }
        }
    
private voidunbindAppWidgetHostViews(java.util.ArrayList appWidgets)
Remove any {@link LauncherAppWidgetHostView} references in our widgets.

        if (appWidgets != null) {
            final int count = appWidgets.size();
            for (int i = 0; i < count; i++) {
                LauncherAppWidgetInfo launcherInfo = appWidgets.get(i);
                launcherInfo.hostView = null;
            }
        }
    
private voidunbindCachedIconDrawables()
Remove the callback for the cached drawables or we leak the previous Home screen on orientation change.

        for (ApplicationInfo appInfo : mAppInfoCache.values()) {
            appInfo.icon.setCallback(null);
        }
    
private voidunbindDrawables(java.util.ArrayList desktopItems)
Remove the callback for the cached drawables or we leak the previous Home screen on orientation change.

        if (desktopItems != null) {
            final int count = desktopItems.size();
            for (int i = 0; i < count; i++) {
                ItemInfo item = desktopItems.get(i);
                switch (item.itemType) {
                case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
                case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
                    ((ApplicationInfo)item).icon.setCallback(null);
                    break;
                }
            }
        }
    
private voidupdateAndCacheApplicationInfo(android.content.pm.PackageManager packageManager, android.content.pm.ResolveInfo info, ApplicationInfo applicationInfo)


        updateApplicationInfoTitleAndIcon(packageManager, info, applicationInfo);

        ComponentName componentName = new ComponentName(
                info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
        mAppInfoCache.put(componentName, applicationInfo);
    
private static voidupdateApplicationInfoTitleAndIcon(android.content.pm.PackageManager manager, android.content.pm.ResolveInfo info, ApplicationInfo application)


        application.title = info.loadLabel(manager);
        if (application.title == null) {
            application.title = info.activityInfo.name;
        }

        application.icon = info.activityInfo.loadIcon(manager);
        application.filtered = false;
    
static voidupdateItemInDatabase(android.content.Context context, ItemInfo item)
Update an item to the database in a specified container.

        final ContentValues values = new ContentValues();
        final ContentResolver cr = context.getContentResolver();

        item.onAddToDatabase(values);

        cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
    
synchronized voidupdatePackage(Launcher launcher, java.lang.String packageName)

        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
            startApplicationsLoader(launcher);
            return;
        }

        if (packageName != null && packageName.length() > 0) {
            final PackageManager packageManager = launcher.getPackageManager();
            final ApplicationsAdapter adapter = mApplicationsAdapter;

            final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);
            final int count = matches.size();

            boolean changed = false;

            for (int i = 0; i < count; i++) {
                final ResolveInfo info = matches.get(i);
                final ApplicationInfo applicationInfo = findIntent(adapter,
                        info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
                if (applicationInfo != null) {
                    updateAndCacheApplicationInfo(packageManager, info, applicationInfo);
                    changed = true;
                }
            }

            if (changed) {
                adapter.sort(new ApplicationInfoComparator());
                adapter.notifyDataSetChanged();
            }
        }
    
private static voidupdateShortcutLabels(android.content.ContentResolver resolver, android.content.pm.PackageManager manager)

        final Cursor c = resolver.query(LauncherSettings.Favorites.CONTENT_URI,
                new String[] { LauncherSettings.Favorites.ID, LauncherSettings.Favorites.TITLE,
                        LauncherSettings.Favorites.INTENT, LauncherSettings.Favorites.ITEM_TYPE },
                null, null, null);

        final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID);
        final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
        final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
        final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);

        // boolean changed = false;

        try {
            while (c.moveToNext()) {
                try {
                    if (c.getInt(itemTypeIndex) !=
                            LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
                        continue;
                    }

                    final String intentUri = c.getString(intentIndex);
                    if (intentUri != null) {
                        final Intent shortcut = Intent.getIntent(intentUri);
                        if (Intent.ACTION_MAIN.equals(shortcut.getAction())) {
                            final ComponentName name = shortcut.getComponent();
                            if (name != null) {
                                final ActivityInfo activityInfo = manager.getActivityInfo(name, 0);
                                final String title = c.getString(titleIndex);
                                String label = getLabel(manager, activityInfo);

                                if (title == null || !title.equals(label)) {
                                    final ContentValues values = new ContentValues();
                                    values.put(LauncherSettings.Favorites.TITLE, label);

                                    resolver.update(
                                            LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION,
                                            values, "_id=?",
                                            new String[] { String.valueOf(c.getLong(idIndex)) });

                                    // changed = true;
                                }
                            }
                        }
                    }
                } catch (URISyntaxException e) {
                    // Ignore
                } catch (PackageManager.NameNotFoundException e) {
                    // Ignore
                }
            }
        } finally {
            c.close();
        }

        // if (changed) resolver.notifyChange(Settings.Favorites.CONTENT_URI, null);