Loading src/com/android/launcher3/IconCache.java +1 −1 Original line number Diff line number Diff line Loading @@ -301,7 +301,7 @@ public class IconCache { c.close(); if (!itemsToRemove.isEmpty()) { mIconDb.getWritableDatabase().delete(IconDB.TABLE_NAME, IconDB.COLUMN_ROWID + " IN ( " + TextUtils.join(", ", itemsToRemove) +" )", Utilities.createDbSelectionQuery(IconDB.COLUMN_ROWID, itemsToRemove), null); } Loading src/com/android/launcher3/LauncherModel.java +21 −56 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.app.SearchManager; import android.appwidget.AppWidgetProviderInfo; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentProviderClient; import android.content.ContentProviderOperation; import android.content.ContentResolver; import android.content.ContentValues; Loading @@ -43,7 +42,6 @@ import android.os.HandlerThread; import android.os.Looper; import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.TransactionTooLargeException; import android.provider.BaseColumns; Loading Loading @@ -1866,6 +1864,7 @@ public class LauncherModel extends BroadcastReceiver int itemType = c.getInt(itemTypeIndex); boolean restored = 0 != c.getInt(restoredIndex); boolean allowMissingTarget = false; container = c.getInt(containerIndex); switch (itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: Loading Loading @@ -2004,7 +2003,6 @@ public class LauncherModel extends BroadcastReceiver continue; } container = c.getInt(containerIndex); boolean useLowResIcon = container >= 0 && c.getInt(rankIndex) >= FolderIcon.NUM_ITEMS_IN_PREVIEW; Loading Loading @@ -2111,7 +2109,6 @@ public class LauncherModel extends BroadcastReceiver // Do not trim the folder label, as is was set by the user. folderInfo.title = c.getString(titleIndex); folderInfo.id = id; container = c.getInt(containerIndex); folderInfo.container = container; folderInfo.screenId = c.getInt(screenIndex); folderInfo.cellX = c.getInt(cellXIndex); Loading Loading @@ -2233,7 +2230,6 @@ public class LauncherModel extends BroadcastReceiver appWidgetInfo.spanX = c.getInt(spanXIndex); appWidgetInfo.spanY = c.getInt(spanYIndex); container = c.getInt(containerIndex); if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP && container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) { Log.e(TAG, "Widget found where container != " + Loading @@ -2241,7 +2237,7 @@ public class LauncherModel extends BroadcastReceiver continue; } appWidgetInfo.container = c.getInt(containerIndex); appWidgetInfo.container = container; // check & update map of what's occupied if (!checkItemPlacement(occupied, appWidgetInfo)) { itemsToRemove.add(id); Loading Loading @@ -2283,56 +2279,32 @@ public class LauncherModel extends BroadcastReceiver return; } // Remove any empty folder LongArrayMap<FolderInfo> emptyFolders = sBgFolders.clone(); for (ItemInfo item: sBgItemsIdMap) { long container = item.container; if (emptyFolders.containsKey(container)) { emptyFolders.remove(container); } } for (FolderInfo folder : emptyFolders) { long folderId = folder.id; sBgFolders.remove(folderId); sBgItemsIdMap.remove(folderId); sBgWorkspaceItems.remove(folder); itemsToRemove.add(folderId); } if (itemsToRemove.size() > 0) { ContentProviderClient client = contentResolver.acquireContentProviderClient( contentUri); // Remove dead items for (long id : itemsToRemove) { contentResolver.delete(LauncherSettings.Favorites.CONTENT_URI, Utilities.createDbSelectionQuery( LauncherSettings.Favorites._ID, itemsToRemove), null); if (DEBUG_LOADERS) { Log.d(TAG, "Removed id = " + id); } // Don't notify content observers try { client.delete(LauncherSettings.Favorites.getContentUri(id), null, null); } catch (RemoteException e) { Log.w(TAG, "Could not remove id = " + id); Log.d(TAG, "Removed = " + Utilities.createDbSelectionQuery( LauncherSettings.Favorites._ID, itemsToRemove)); } // Remove any empty folder for (long folderId : LauncherAppState.getLauncherProvider() .deleteEmptyFolders()) { sBgWorkspaceItems.remove(sBgFolders.get(folderId)); sBgFolders.remove(folderId); sBgItemsIdMap.remove(folderId); } } if (restoredRows.size() > 0) { ContentProviderClient updater = contentResolver.acquireContentProviderClient( contentUri); // Update restored items that no longer require special handling try { StringBuilder selectionBuilder = new StringBuilder(); selectionBuilder.append(LauncherSettings.Favorites._ID); selectionBuilder.append(" IN ("); selectionBuilder.append(TextUtils.join(", ", restoredRows)); selectionBuilder.append(")"); ContentValues values = new ContentValues(); values.put(LauncherSettings.Favorites.RESTORED, 0); updater.update(LauncherSettings.Favorites.CONTENT_URI, values, selectionBuilder.toString(), null); } catch (RemoteException e) { Log.w(TAG, "Could not update restored rows"); } contentResolver.update(LauncherSettings.Favorites.CONTENT_URI, values, Utilities.createDbSelectionQuery( LauncherSettings.Favorites._ID, restoredRows), null); } if (!isSdCardReady && !sPendingPackages.isEmpty()) { Loading @@ -2342,9 +2314,6 @@ public class LauncherModel extends BroadcastReceiver } sBgWorkspaceScreens.addAll(loadWorkspaceScreensDb(mContext)); // Log to disk Launcher.addDumpLog(TAG, "11683562 - sBgWorkspaceScreens: " + TextUtils.join(", ", sBgWorkspaceScreens), true); // Remove any empty screens ArrayList<Long> unusedScreens = new ArrayList<Long>(sBgWorkspaceScreens); Loading @@ -2358,10 +2327,6 @@ public class LauncherModel extends BroadcastReceiver // If there are any empty screens remove them, and update. if (unusedScreens.size() != 0) { // Log to disk Launcher.addDumpLog(TAG, "11683562 - unusedScreens (to be removed): " + TextUtils.join(", ", unusedScreens), true); sBgWorkspaceScreens.removeAll(unusedScreens); updateWorkspaceScreenOrder(context, sBgWorkspaceScreens); } Loading src/com/android/launcher3/LauncherProvider.java +37 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; public class LauncherProvider extends ContentProvider { private static final String TAG = "Launcher.LauncherProvider"; Loading Loading @@ -263,6 +264,42 @@ public class LauncherProvider extends ContentProvider { return null; } /** * Deletes any empty folder from the DB. * @return Ids of deleted folders. */ public List<Long> deleteEmptyFolders() { ArrayList<Long> folderIds = new ArrayList<Long>(); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); db.beginTransaction(); try { // Select folders whose id do not match any container value. String selection = LauncherSettings.Favorites.ITEM_TYPE + " = " + LauncherSettings.Favorites.ITEM_TYPE_FOLDER + " AND " + LauncherSettings.Favorites._ID + " NOT IN (SELECT " + LauncherSettings.Favorites.CONTAINER + " FROM " + TABLE_FAVORITES + ")"; Cursor c = db.query(TABLE_FAVORITES, new String[] {LauncherSettings.Favorites._ID}, selection, null, null, null, null); while (c.moveToNext()) { folderIds.add(c.getLong(0)); } c.close(); if (folderIds.size() > 0) { db.delete(TABLE_FAVORITES, Utilities.createDbSelectionQuery( LauncherSettings.Favorites._ID, folderIds), null); } db.setTransactionSuccessful(); } catch (SQLException ex) { Log.e(TAG, ex.getMessage(), ex); folderIds.clear(); } finally { db.endTransaction(); } return folderIds; } private void notifyListeners() { // always notify the backup agent LauncherBackupAgentHelper.dataChanged(getContext()); Loading src/com/android/launcher3/Utilities.java +6 −0 Original line number Diff line number Diff line Loading @@ -54,12 +54,14 @@ import android.util.SparseArray; import android.util.TypedValue; import android.view.View; import android.widget.Toast; import junit.framework.Assert; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Comparator; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; Loading Loading @@ -677,4 +679,8 @@ public final class Utilities { return (int) Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, size, metrics)); } public static String createDbSelectionQuery(String columnName, Iterable<?> values) { return String.format(Locale.ENGLISH, "%s IN (%s)", columnName, TextUtils.join(", ", values)); } } src/com/android/launcher3/compat/LauncherAppsCompatVL.java +1 −1 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ public class LauncherAppsCompatVL extends LauncherAppsCompat { List<LauncherActivityInfo> list = mLauncherApps.getActivityList(packageName, user.getUser()); if (list.size() == 0) { return Collections.EMPTY_LIST; return Collections.emptyList(); } ArrayList<LauncherActivityInfoCompat> compatList = new ArrayList<LauncherActivityInfoCompat>(list.size()); Loading Loading
src/com/android/launcher3/IconCache.java +1 −1 Original line number Diff line number Diff line Loading @@ -301,7 +301,7 @@ public class IconCache { c.close(); if (!itemsToRemove.isEmpty()) { mIconDb.getWritableDatabase().delete(IconDB.TABLE_NAME, IconDB.COLUMN_ROWID + " IN ( " + TextUtils.join(", ", itemsToRemove) +" )", Utilities.createDbSelectionQuery(IconDB.COLUMN_ROWID, itemsToRemove), null); } Loading
src/com/android/launcher3/LauncherModel.java +21 −56 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.app.SearchManager; import android.appwidget.AppWidgetProviderInfo; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentProviderClient; import android.content.ContentProviderOperation; import android.content.ContentResolver; import android.content.ContentValues; Loading @@ -43,7 +42,6 @@ import android.os.HandlerThread; import android.os.Looper; import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.TransactionTooLargeException; import android.provider.BaseColumns; Loading Loading @@ -1866,6 +1864,7 @@ public class LauncherModel extends BroadcastReceiver int itemType = c.getInt(itemTypeIndex); boolean restored = 0 != c.getInt(restoredIndex); boolean allowMissingTarget = false; container = c.getInt(containerIndex); switch (itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: Loading Loading @@ -2004,7 +2003,6 @@ public class LauncherModel extends BroadcastReceiver continue; } container = c.getInt(containerIndex); boolean useLowResIcon = container >= 0 && c.getInt(rankIndex) >= FolderIcon.NUM_ITEMS_IN_PREVIEW; Loading Loading @@ -2111,7 +2109,6 @@ public class LauncherModel extends BroadcastReceiver // Do not trim the folder label, as is was set by the user. folderInfo.title = c.getString(titleIndex); folderInfo.id = id; container = c.getInt(containerIndex); folderInfo.container = container; folderInfo.screenId = c.getInt(screenIndex); folderInfo.cellX = c.getInt(cellXIndex); Loading Loading @@ -2233,7 +2230,6 @@ public class LauncherModel extends BroadcastReceiver appWidgetInfo.spanX = c.getInt(spanXIndex); appWidgetInfo.spanY = c.getInt(spanYIndex); container = c.getInt(containerIndex); if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP && container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) { Log.e(TAG, "Widget found where container != " + Loading @@ -2241,7 +2237,7 @@ public class LauncherModel extends BroadcastReceiver continue; } appWidgetInfo.container = c.getInt(containerIndex); appWidgetInfo.container = container; // check & update map of what's occupied if (!checkItemPlacement(occupied, appWidgetInfo)) { itemsToRemove.add(id); Loading Loading @@ -2283,56 +2279,32 @@ public class LauncherModel extends BroadcastReceiver return; } // Remove any empty folder LongArrayMap<FolderInfo> emptyFolders = sBgFolders.clone(); for (ItemInfo item: sBgItemsIdMap) { long container = item.container; if (emptyFolders.containsKey(container)) { emptyFolders.remove(container); } } for (FolderInfo folder : emptyFolders) { long folderId = folder.id; sBgFolders.remove(folderId); sBgItemsIdMap.remove(folderId); sBgWorkspaceItems.remove(folder); itemsToRemove.add(folderId); } if (itemsToRemove.size() > 0) { ContentProviderClient client = contentResolver.acquireContentProviderClient( contentUri); // Remove dead items for (long id : itemsToRemove) { contentResolver.delete(LauncherSettings.Favorites.CONTENT_URI, Utilities.createDbSelectionQuery( LauncherSettings.Favorites._ID, itemsToRemove), null); if (DEBUG_LOADERS) { Log.d(TAG, "Removed id = " + id); } // Don't notify content observers try { client.delete(LauncherSettings.Favorites.getContentUri(id), null, null); } catch (RemoteException e) { Log.w(TAG, "Could not remove id = " + id); Log.d(TAG, "Removed = " + Utilities.createDbSelectionQuery( LauncherSettings.Favorites._ID, itemsToRemove)); } // Remove any empty folder for (long folderId : LauncherAppState.getLauncherProvider() .deleteEmptyFolders()) { sBgWorkspaceItems.remove(sBgFolders.get(folderId)); sBgFolders.remove(folderId); sBgItemsIdMap.remove(folderId); } } if (restoredRows.size() > 0) { ContentProviderClient updater = contentResolver.acquireContentProviderClient( contentUri); // Update restored items that no longer require special handling try { StringBuilder selectionBuilder = new StringBuilder(); selectionBuilder.append(LauncherSettings.Favorites._ID); selectionBuilder.append(" IN ("); selectionBuilder.append(TextUtils.join(", ", restoredRows)); selectionBuilder.append(")"); ContentValues values = new ContentValues(); values.put(LauncherSettings.Favorites.RESTORED, 0); updater.update(LauncherSettings.Favorites.CONTENT_URI, values, selectionBuilder.toString(), null); } catch (RemoteException e) { Log.w(TAG, "Could not update restored rows"); } contentResolver.update(LauncherSettings.Favorites.CONTENT_URI, values, Utilities.createDbSelectionQuery( LauncherSettings.Favorites._ID, restoredRows), null); } if (!isSdCardReady && !sPendingPackages.isEmpty()) { Loading @@ -2342,9 +2314,6 @@ public class LauncherModel extends BroadcastReceiver } sBgWorkspaceScreens.addAll(loadWorkspaceScreensDb(mContext)); // Log to disk Launcher.addDumpLog(TAG, "11683562 - sBgWorkspaceScreens: " + TextUtils.join(", ", sBgWorkspaceScreens), true); // Remove any empty screens ArrayList<Long> unusedScreens = new ArrayList<Long>(sBgWorkspaceScreens); Loading @@ -2358,10 +2327,6 @@ public class LauncherModel extends BroadcastReceiver // If there are any empty screens remove them, and update. if (unusedScreens.size() != 0) { // Log to disk Launcher.addDumpLog(TAG, "11683562 - unusedScreens (to be removed): " + TextUtils.join(", ", unusedScreens), true); sBgWorkspaceScreens.removeAll(unusedScreens); updateWorkspaceScreenOrder(context, sBgWorkspaceScreens); } Loading
src/com/android/launcher3/LauncherProvider.java +37 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; public class LauncherProvider extends ContentProvider { private static final String TAG = "Launcher.LauncherProvider"; Loading Loading @@ -263,6 +264,42 @@ public class LauncherProvider extends ContentProvider { return null; } /** * Deletes any empty folder from the DB. * @return Ids of deleted folders. */ public List<Long> deleteEmptyFolders() { ArrayList<Long> folderIds = new ArrayList<Long>(); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); db.beginTransaction(); try { // Select folders whose id do not match any container value. String selection = LauncherSettings.Favorites.ITEM_TYPE + " = " + LauncherSettings.Favorites.ITEM_TYPE_FOLDER + " AND " + LauncherSettings.Favorites._ID + " NOT IN (SELECT " + LauncherSettings.Favorites.CONTAINER + " FROM " + TABLE_FAVORITES + ")"; Cursor c = db.query(TABLE_FAVORITES, new String[] {LauncherSettings.Favorites._ID}, selection, null, null, null, null); while (c.moveToNext()) { folderIds.add(c.getLong(0)); } c.close(); if (folderIds.size() > 0) { db.delete(TABLE_FAVORITES, Utilities.createDbSelectionQuery( LauncherSettings.Favorites._ID, folderIds), null); } db.setTransactionSuccessful(); } catch (SQLException ex) { Log.e(TAG, ex.getMessage(), ex); folderIds.clear(); } finally { db.endTransaction(); } return folderIds; } private void notifyListeners() { // always notify the backup agent LauncherBackupAgentHelper.dataChanged(getContext()); Loading
src/com/android/launcher3/Utilities.java +6 −0 Original line number Diff line number Diff line Loading @@ -54,12 +54,14 @@ import android.util.SparseArray; import android.util.TypedValue; import android.view.View; import android.widget.Toast; import junit.framework.Assert; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Comparator; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; Loading Loading @@ -677,4 +679,8 @@ public final class Utilities { return (int) Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, size, metrics)); } public static String createDbSelectionQuery(String columnName, Iterable<?> values) { return String.format(Locale.ENGLISH, "%s IN (%s)", columnName, TextUtils.join(", ", values)); } }
src/com/android/launcher3/compat/LauncherAppsCompatVL.java +1 −1 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ public class LauncherAppsCompatVL extends LauncherAppsCompat { List<LauncherActivityInfo> list = mLauncherApps.getActivityList(packageName, user.getUser()); if (list.size() == 0) { return Collections.EMPTY_LIST; return Collections.emptyList(); } ArrayList<LauncherActivityInfoCompat> compatList = new ArrayList<LauncherActivityInfoCompat>(list.size()); Loading