/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.launcher; import android.content.ComponentName; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Intent; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.util.Log; import android.os.Process; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Comparator; import java.lang.ref.WeakReference; import java.text.Collator; import java.net.URISyntaxException; /** * 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 */ public class LauncherModel { private static final int UI_NOTIFICATION_RATE = 4; private static final int DEFAULT_APPLICATIONS_NUMBER = 42; private static final long APPLICATION_NOT_RESPONDING_TIMEOUT = 5000; private final Collator sCollator = Collator.getInstance(); private boolean mApplicationsLoaded; private boolean mDesktopItemsLoaded; private ArrayList mDesktopItems; private HashMap mFolders; private ArrayList mApplications; private ApplicationsAdapter mApplicationsAdapter; private ApplicationsLoader mApplicationsLoader; private DesktopItemsLoader mDesktopItemsLoader; private Thread mLoader; private Thread mDesktopLoader; void abortLoaders() { if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) { mApplicationsLoader.stop(); mApplicationsLoaded = false; } if (mDesktopItemsLoader != null && mDesktopItemsLoader.isRunning()) { mDesktopItemsLoader.stop(); mDesktopItemsLoaded = false; } } /** * Loads the list of installed applications in mApplications. */ void loadApplications(boolean isLaunching, Launcher launcher, boolean localeChanged) { if (isLaunching && mApplicationsLoaded && !localeChanged) { mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications); return; } if (mApplicationsAdapter == null || isLaunching || localeChanged) { mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications = new ArrayList(DEFAULT_APPLICATIONS_NUMBER)); } if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) { 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 { mLoader.join(APPLICATION_NOT_RESPONDING_TIMEOUT); } catch (InterruptedException e) { // Empty } } mApplicationsLoaded = false; if (!isLaunching) { startApplicationsLoader(launcher); } } private void startApplicationsLoader(Launcher launcher) { mApplicationsLoader = new ApplicationsLoader(launcher); mLoader = new Thread(mApplicationsLoader, "Applications Loader"); mLoader.start(); } private class ApplicationsLoader implements Runnable { private final WeakReference mLauncher; private volatile boolean mStopped; private volatile boolean mRunning; ApplicationsLoader(Launcher launcher) { mLauncher = new WeakReference(launcher); } void stop() { mStopped = true; } boolean isRunning() { return mRunning; } public void run() { mRunning = true; android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); final Launcher launcher = mLauncher.get(); final PackageManager manager = launcher.getPackageManager(); final List apps = manager.queryIntentActivities(mainIntent, 0); if (apps != null && !mStopped) { final int count = apps.size(); final ApplicationsAdapter applicationList = mApplicationsAdapter; ChangeNotifier action = new ChangeNotifier(applicationList); for (int i = 0; i < count && !mStopped; i++) { ApplicationInfo application = new ApplicationInfo(); ResolveInfo info = apps.get(i); application.title = info.loadLabel(manager); if (application.title == null) { application.title = info.activityInfo.name; } application.setActivity(new ComponentName( info.activityInfo.applicationInfo.packageName, info.activityInfo.name), Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); application.icon = info.activityInfo.loadIcon(manager); application.container = ItemInfo.NO_ID; action.add(application); } action.sort(new Comparator() { public final int compare(ApplicationInfo a, ApplicationInfo b) { return sCollator.compare(a.title.toString(), b.title.toString()); } }); if (!mStopped) { launcher.runOnUiThread(action); } } if (!mStopped) { mApplicationsLoaded = true; } mRunning = false; } } private static class ChangeNotifier implements Runnable { private final ApplicationsAdapter mApplicationList; private ArrayList mBuffer; ChangeNotifier(ApplicationsAdapter applicationList) { mApplicationList = applicationList; mBuffer = new ArrayList(UI_NOTIFICATION_RATE); } public void run() { final ArrayList buffer = mBuffer; final ApplicationsAdapter applicationList = mApplicationList; final int count = buffer.size(); applicationList.clear(); for (int i = 0; i < count; i++) { applicationList.setNotifyOnChange(false); applicationList.add(buffer.get(i)); } applicationList.notifyDataSetChanged(); buffer.clear(); } void add(ApplicationInfo application) { mBuffer.add(application); } void sort(Comparator comparator) { Collections.sort(mBuffer, comparator); } } boolean isDesktopLoaded() { return mDesktopItems != null && mDesktopItemsLoaded; } /** * Loads all of the items on the desktop, in folders, or in the dock. * These can be apps, shortcuts or widgets */ void loadUserItems(boolean isLaunching, Launcher launcher, boolean localeChanged, boolean loadApplications) { if (isLaunching && mDesktopItems != null && mDesktopItemsLoaded) { if (loadApplications) startApplicationsLoader(launcher); // We have already loaded our data from the DB launcher.onDesktopItemsLoaded(); return; } if (mDesktopItemsLoader != null && mDesktopItemsLoader.isRunning()) { 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 { mDesktopLoader.join(APPLICATION_NOT_RESPONDING_TIMEOUT); } catch (InterruptedException e) { // Empty } } mDesktopItemsLoaded = false; mDesktopItemsLoader = new DesktopItemsLoader(launcher, localeChanged, loadApplications); mDesktopLoader = new Thread(mDesktopItemsLoader, "Desktop Items Loader"); mDesktopLoader.start(); } private static void updateShortcutLabels(ContentResolver resolver, 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); } private static String getLabel(PackageManager manager, 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; } private class DesktopItemsLoader implements Runnable { private volatile boolean mStopped; private volatile boolean mRunning; private final WeakReference mLauncher; private final boolean mLocaleChanged; private final boolean mLoadApplications; DesktopItemsLoader(Launcher launcher, boolean localeChanged, boolean loadApplications) { mLoadApplications = loadApplications; mLauncher = new WeakReference(launcher); mLocaleChanged = localeChanged; } void stop() { mStopped = true; } boolean isRunning() { return mRunning; } public void run() { mRunning = true; final Launcher launcher = mLauncher.get(); final ContentResolver contentResolver = launcher.getContentResolver(); final PackageManager manager = launcher.getPackageManager(); if (mLocaleChanged) { updateShortcutLabels(contentResolver, manager); } mDesktopItems = new ArrayList(); mFolders = new HashMap(); final ArrayList desktopItems = mDesktopItems; final Cursor c = contentResolver.query( LauncherSettings.Favorites.CONTENT_URI, null, null, null, null); try { final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID); final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT); final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE); final int iconTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_TYPE); final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON); final int iconPackageIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_PACKAGE); final int iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE); final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER); final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE); final int gadgetIdIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.GADGET_ID); final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN); final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX); final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY); final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX); final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY); final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI); final int displayModeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE); ApplicationInfo info; String intentDescription; Widget widgetInfo = null; LauncherGadgetInfo gadgetInfo = null; int container; long id; Intent intent; final HashMap folders = mFolders; while (!mStopped && c.moveToNext()) { try { int itemType = c.getInt(itemTypeIndex); switch (itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: intentDescription = c.getString(intentIndex); try { intent = Intent.getIntent(intentDescription); } catch (java.net.URISyntaxException e) { continue; } if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { info = getApplicationInfo(manager, intent); } else { info = getApplicationInfoShortcut(c, launcher, iconTypeIndex, iconPackageIndex, iconResourceIndex, iconIndex); } if (info == null) { info = new ApplicationInfo(); info.icon = manager.getDefaultActivityIcon(); } if (info != null) { info.title = c.getString(titleIndex); info.intent = intent; info.id = c.getLong(idIndex); container = c.getInt(containerIndex); info.container = container; info.screen = c.getInt(screenIndex); info.cellX = c.getInt(cellXIndex); info.cellY = c.getInt(cellYIndex); switch (container) { case LauncherSettings.Favorites.CONTAINER_DESKTOP: desktopItems.add(info); break; default: // Item is in a user folder UserFolderInfo folderInfo = findOrMakeUserFolder(folders, container); folderInfo.add(info); break; } } break; case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER: id = c.getLong(idIndex); UserFolderInfo folderInfo = findOrMakeUserFolder(folders, id); folderInfo.title = c.getString(titleIndex); folderInfo.id = id; container = c.getInt(containerIndex); folderInfo.container = container; folderInfo.screen = c.getInt(screenIndex); folderInfo.cellX = c.getInt(cellXIndex); folderInfo.cellY = c.getInt(cellYIndex); switch (container) { case LauncherSettings.Favorites.CONTAINER_DESKTOP: desktopItems.add(folderInfo); break; } break; case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER: id = c.getLong(idIndex); LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(folders, id); intentDescription = c.getString(intentIndex); intent = null; if (intentDescription != null) { try { intent = Intent.getIntent(intentDescription); } catch (java.net.URISyntaxException e) { // Ignore, a live folder might not have a base intent } } liveFolderInfo.title = c.getString(titleIndex); liveFolderInfo.id = id; container = c.getInt(containerIndex); liveFolderInfo.container = container; liveFolderInfo.screen = c.getInt(screenIndex); liveFolderInfo.cellX = c.getInt(cellXIndex); liveFolderInfo.cellY = c.getInt(cellYIndex); liveFolderInfo.uri = Uri.parse(c.getString(uriIndex)); liveFolderInfo.baseIntent = intent; liveFolderInfo.displayMode = c.getInt(displayModeIndex); loadLiveFolderIcon(launcher, c, iconTypeIndex, iconPackageIndex, iconResourceIndex, liveFolderInfo); switch (container) { case LauncherSettings.Favorites.CONTAINER_DESKTOP: desktopItems.add(liveFolderInfo); break; } break; case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH: widgetInfo = Widget.makeSearch(); container = c.getInt(containerIndex); if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) { Log.e(Launcher.LOG_TAG, "Widget found where container " + "!= CONTAINER_DESKTOP ignoring!"); continue; } widgetInfo.id = c.getLong(idIndex); widgetInfo.screen = c.getInt(screenIndex); widgetInfo.container = container; widgetInfo.cellX = c.getInt(cellXIndex); widgetInfo.cellY = c.getInt(cellYIndex); desktopItems.add(widgetInfo); break; case LauncherSettings.Favorites.ITEM_TYPE_GADGET: // Read all Launcher-specific gadget details int gadgetId = c.getInt(gadgetIdIndex); gadgetInfo = new LauncherGadgetInfo(gadgetId); gadgetInfo.id = c.getLong(idIndex); gadgetInfo.screen = c.getInt(screenIndex); gadgetInfo.cellX = c.getInt(cellXIndex); gadgetInfo.cellY = c.getInt(cellYIndex); gadgetInfo.spanX = c.getInt(spanXIndex); gadgetInfo.spanY = c.getInt(spanYIndex); container = c.getInt(containerIndex); if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) { Log.e(Launcher.LOG_TAG, "Gadget found where container " + "!= CONTAINER_DESKTOP -- ignoring!"); continue; } gadgetInfo.container = c.getInt(containerIndex); desktopItems.add(gadgetInfo); break; } } catch (Exception e) { Log.w(Launcher.LOG_TAG, "Desktop items loading interrupted:", e); } } } finally { c.close(); } if (!mStopped) { launcher.runOnUiThread(new Runnable() { public void run() { launcher.onDesktopItemsLoaded(); } }); if (mLoadApplications) startApplicationsLoader(launcher); } if (!mStopped) { mDesktopItemsLoaded = true; } mRunning = false; } } private static void loadLiveFolderIcon(Launcher launcher, 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); } } /** * 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. */ FolderInfo findFolderById(long id) { return mFolders.get(id); } void addFolder(FolderInfo info) { mFolders.put(info.id, info); } /** * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a * new one. */ private UserFolderInfo findOrMakeUserFolder(HashMap folders, long id) { // 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; } /** * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a * new one. */ private LiveFolderInfo findOrMakeLiveFolder(HashMap folders, long id) { // 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; } /** * Remove the callback for the cached drawables or we leak the previous * Home screen on orientation change. */ void unbind() { mApplicationsAdapter = null; unbindAppDrawables(mApplications); unbindDrawables(mDesktopItems); } /** * Remove the callback for the cached drawables or we leak the previous * Home screen on orientation change. */ private void unbindDrawables(ArrayList desktopItems) { 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); } } } } /** * Remove the callback for the cached drawables or we leak the previous * Home screen on orientation change. */ private void unbindAppDrawables(ArrayList applications) { if (applications != null) { final int count = applications.size(); for (int i = 0; i < count; i++) { applications.get(i).icon.setCallback(null); } } } /** * @return The current list of applications */ public ArrayList getApplications() { return mApplications; } /** * @return The current list of applications */ public ApplicationsAdapter getApplicationsAdapter() { return mApplicationsAdapter; } /** * @return The current list of desktop items */ public ArrayList getDesktopItems() { return mDesktopItems; } /** * Add an item to the desktop * @param info */ public void addDesktopItem(ItemInfo info) { // TODO: write to DB; also check that folder has been added to folders list mDesktopItems.add(info); } /** * Remove an item from the desktop * @param info */ public void removeDesktopItem(ItemInfo info) { // TODO: write to DB; figure out if we should remove folder from folders list mDesktopItems.remove(info); } /** * Make an ApplicationInfo object for an application */ private static ApplicationInfo getApplicationInfo(PackageManager manager, Intent intent) { 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; } /** * Make an ApplicationInfo object for a sortcut */ private ApplicationInfo getApplicationInfoShortcut(Cursor c, Launcher launcher, int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex) { 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; } /** * Remove an item from the in-memory represention of a user folder. Does not change the DB. */ void removeUserFolderItem(UserFolderInfo folder, ItemInfo info) { //noinspection SuspiciousMethodCalls folder.contents.remove(info); } /** * Removes a UserFolder from the in-memory list of folders. Does not change the DB. * @param userFolderInfo */ void removeUserFolder(UserFolderInfo userFolderInfo) { mFolders.remove(userFolderInfo.id); } /** * Adds an item to the DB if it was not created previously, or move it to a new * */ static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container, int screen, int cellX, int cellY) { 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); } } /** * Move an item in the DB to a new */ static void moveItemInDatabase(Context context, ItemInfo item, long container, int screen, int cellX, int cellY) { 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); } /** * Returns true if the shortcuts already exists in the database. * we identify a shortcut by its title and intent. */ static boolean shortcutExists(Context context, String title, Intent 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; } FolderInfo getFolderById(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; } /** * 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. */ static void addItemToDatabase(Context context, ItemInfo item, long container, int screen, int cellX, int cellY, boolean notify) { 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)); } } /** * Update an item to the database in a specified container. */ static void updateItemInDatabase(Context context, ItemInfo item) { final ContentValues values = new ContentValues(); final ContentResolver cr = context.getContentResolver(); item.onAddToDatabase(values); cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null); } /** * Removes the specified item from the database * @param context * @param item */ static void deleteItemFromDatabase(Context context, ItemInfo item) { final ContentResolver cr = context.getContentResolver(); cr.delete(LauncherSettings.Favorites.getContentUri(item.id, false), null, null); } /** * Remove the contents of the specified folder from the database */ static void deleteUserFolderContentsFromDatabase(Context context, UserFolderInfo info) { 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); } }