diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2017-01-05 21:50:27 -0800 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2017-01-10 13:53:50 -0800 |
commit | aaf86fe9a0406720cca7cfe204f28e2d2de085eb (patch) | |
tree | cc3c034548692ac963545d9eb11dc5742099ff74 /src/com/android/launcher3/LauncherModel.java | |
parent | e09bacc1ef50aa7c4fe551a7360d7f5613927ee9 (diff) | |
download | android_packages_apps_Trebuchet-aaf86fe9a0406720cca7cfe204f28e2d2de085eb.tar.gz android_packages_apps_Trebuchet-aaf86fe9a0406720cca7cfe204f28e2d2de085eb.tar.bz2 android_packages_apps_Trebuchet-aaf86fe9a0406720cca7cfe204f28e2d2de085eb.zip |
Refactoring some loadWorkspace logic in a separate class
Bug: 34112546
Change-Id: I8a43ed1646056aa1957ac3d6ea82018691df6386
Diffstat (limited to 'src/com/android/launcher3/LauncherModel.java')
-rw-r--r-- | src/com/android/launcher3/LauncherModel.java | 558 |
1 files changed, 85 insertions, 473 deletions
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index daa910fc8..616b2c7dd 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -24,21 +24,16 @@ import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; -import android.content.Intent.ShortcutIconResource; import android.content.IntentFilter; import android.content.pm.PackageManager; -import android.database.Cursor; -import android.graphics.Bitmap; import android.net.Uri; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; -import android.os.Parcelable; import android.os.Process; import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; -import android.provider.BaseColumns; import android.text.TextUtils; import android.util.Log; import android.util.LongSparseArray; @@ -50,18 +45,17 @@ import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.PackageInstallerCompat; import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo; import com.android.launcher3.compat.UserManagerCompat; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.config.ProviderConfig; import com.android.launcher3.dynamicui.ExtractionUtils; import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.FolderIcon; -import com.android.launcher3.graphics.LauncherIcons; import com.android.launcher3.logging.FileLog; import com.android.launcher3.model.AddWorkspaceItemsTask; import com.android.launcher3.model.BgDataModel; import com.android.launcher3.model.CacheDataUpdatedTask; import com.android.launcher3.model.ExtendedModelTask; import com.android.launcher3.model.GridSizeMigrationTask; +import com.android.launcher3.model.LoaderCursor; import com.android.launcher3.model.PackageInstallStateChangedTask; import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.model.PackageUpdatedTask; @@ -77,10 +71,7 @@ import com.android.launcher3.shortcuts.ShortcutInfoCompat; import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.ContentWriter; -import com.android.launcher3.util.CursorIconInfo; -import com.android.launcher3.util.GridOccupancy; import com.android.launcher3.util.ItemInfoMatcher; -import com.android.launcher3.util.LongArrayMap; import com.android.launcher3.util.ManagedProfileHeuristic; import com.android.launcher3.util.MultiHashMap; import com.android.launcher3.util.PackageManagerHelper; @@ -91,7 +82,6 @@ import com.android.launcher3.util.ViewOnDrawExecutor; import java.lang.ref.WeakReference; import java.net.URISyntaxException; -import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -1096,96 +1086,6 @@ public class LauncherModel extends BroadcastReceiver } } - // check & update map of what's occupied; used to discard overlapping/invalid items - private boolean checkItemPlacement(LongArrayMap<GridOccupancy> occupied, ItemInfo item, - ArrayList<Long> workspaceScreens) { - LauncherAppState app = LauncherAppState.getInstance(); - InvariantDeviceProfile profile = app.getInvariantDeviceProfile(); - - long containerIndex = item.screenId; - if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { - // Return early if we detect that an item is under the hotseat button - if (!FeatureFlags.NO_ALL_APPS_ICON && - profile.isAllAppsButtonRank((int) item.screenId)) { - Log.e(TAG, "Error loading shortcut into hotseat " + item - + " into position (" + item.screenId + ":" + item.cellX + "," - + item.cellY + ") occupied by all apps"); - return false; - } - - final GridOccupancy hotseatOccupancy = - occupied.get((long) LauncherSettings.Favorites.CONTAINER_HOTSEAT); - - if (item.screenId >= profile.numHotseatIcons) { - Log.e(TAG, "Error loading shortcut " + item - + " into hotseat position " + item.screenId - + ", position out of bounds: (0 to " + (profile.numHotseatIcons - 1) - + ")"); - return false; - } - - if (hotseatOccupancy != null) { - if (hotseatOccupancy.cells[(int) item.screenId][0]) { - Log.e(TAG, "Error loading shortcut into hotseat " + item - + " into position (" + item.screenId + ":" + item.cellX + "," - + item.cellY + ") already occupied"); - return false; - } else { - hotseatOccupancy.cells[(int) item.screenId][0] = true; - return true; - } - } else { - final GridOccupancy occupancy = new GridOccupancy(profile.numHotseatIcons, 1); - occupancy.cells[(int) item.screenId][0] = true; - occupied.put((long) LauncherSettings.Favorites.CONTAINER_HOTSEAT, occupancy); - return true; - } - } else if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { - if (!workspaceScreens.contains((Long) item.screenId)) { - // The item has an invalid screen id. - return false; - } - } else { - // Skip further checking if it is not the hotseat or workspace container - return true; - } - - final int countX = profile.numColumns; - final int countY = profile.numRows; - if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && - item.cellX < 0 || item.cellY < 0 || - item.cellX + item.spanX > countX || item.cellY + item.spanY > countY) { - Log.e(TAG, "Error loading shortcut " + item - + " into cell (" + containerIndex + "-" + item.screenId + ":" - + item.cellX + "," + item.cellY - + ") out of screen bounds ( " + countX + "x" + countY + ")"); - return false; - } - - if (!occupied.containsKey(item.screenId)) { - GridOccupancy screen = new GridOccupancy(countX + 1, countY + 1); - if (item.screenId == Workspace.FIRST_SCREEN_ID) { - // Mark the first row as occupied (if the feature is enabled) - // in order to account for the QSB. - screen.markCells(0, 0, countX + 1, 1, FeatureFlags.QSB_ON_FIRST_SCREEN); - } - occupied.put(item.screenId, screen); - } - final GridOccupancy occupancy = occupied.get(item.screenId); - - // Check if any workspace icons overlap with each other - if (occupancy.isRegionVacant(item.cellX, item.cellY, item.spanX, item.spanY)) { - occupancy.markCells(item, true); - return true; - } else { - Log.e(TAG, "Error loading shortcut " + item - + " into cell (" + containerIndex + "-" + item.screenId + ":" - + item.cellX + "," + item.cellX + "," + item.spanX + "," + item.spanY - + ") already occupied"); - return false; - } - } - private void loadWorkspace() { if (LauncherAppState.PROFILE_STARTUP) { Trace.beginSection("Loading Workspace"); @@ -1237,37 +1137,19 @@ public class LauncherModel extends BroadcastReceiver .getInstance(mContext).updateAndGetActiveSessionCache(); sBgDataModel.workspaceScreens.addAll(loadWorkspaceScreensDb(mContext)); - final ArrayList<Long> itemsToRemove = new ArrayList<>(); - final ArrayList<Long> restoredRows = new ArrayList<>(); Map<ShortcutKey, ShortcutInfoCompat> shortcutKeyToPinnedShortcuts = new HashMap<>(); - final Uri contentUri = LauncherSettings.Favorites.CONTENT_URI; - if (DEBUG_LOADERS) Log.d(TAG, "loading model from " + contentUri); - final Cursor c = contentResolver.query(contentUri, null, null, null, null); - - // +1 for the hotseat (it can be larger than the workspace) - // Load workspace in reverse order to ensure that latest items are loaded first (and - // before any earlier duplicates) - final LongArrayMap<GridOccupancy> occupied = new LongArrayMap<>(); + final LoaderCursor c = new LoaderCursor(contentResolver.query( + LauncherSettings.Favorites.CONTENT_URI, null, null, null, null), mApp); + HashMap<ComponentKey, AppWidgetProviderInfo> widgetProvidersMap = null; try { - final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID); final int intentIndex = c.getColumnIndexOrThrow (LauncherSettings.Favorites.INTENT); - final int containerIndex = c.getColumnIndexOrThrow( - LauncherSettings.Favorites.CONTAINER); - final int itemTypeIndex = c.getColumnIndexOrThrow( - LauncherSettings.Favorites.ITEM_TYPE); final int appWidgetIdIndex = c.getColumnIndexOrThrow( LauncherSettings.Favorites.APPWIDGET_ID); final int appWidgetProviderIndex = c.getColumnIndexOrThrow( LauncherSettings.Favorites.APPWIDGET_PROVIDER); - 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( @@ -1276,13 +1158,10 @@ public class LauncherModel extends BroadcastReceiver LauncherSettings.Favorites.RANK); final int restoredIndex = c.getColumnIndexOrThrow( LauncherSettings.Favorites.RESTORED); - final int profileIdIndex = c.getColumnIndexOrThrow( - LauncherSettings.Favorites.PROFILE_ID); final int optionsIndex = c.getColumnIndexOrThrow( LauncherSettings.Favorites.OPTIONS); - final CursorIconInfo cursorIconInfo = new CursorIconInfo(mContext, c); - final LongSparseArray<UserHandle> allUsers = new LongSparseArray<>(); + final LongSparseArray<UserHandle> allUsers = c.allUsers; final LongSparseArray<Boolean> quietMode = new LongSparseArray<>(); final LongSparseArray<Boolean> unlockedUsers = new LongSparseArray<>(); for (UserHandle user : mUserManager.getUserProfiles()) { @@ -1314,44 +1193,42 @@ public class LauncherModel extends BroadcastReceiver ShortcutInfo info; String intentDescription; LauncherAppWidgetInfo appWidgetInfo; - int container; - long id; - long serialNumber; Intent intent; - UserHandle user; String targetPackage; while (!mStopped && c.moveToNext()) { try { - int itemType = c.getInt(itemTypeIndex); + if (c.user == null) { + // User has been deleted, remove the item. + c.markDeleted("User has been deleted"); + continue; + } + boolean restored = 0 != c.getInt(restoredIndex); boolean allowMissingTarget = false; - container = c.getInt(containerIndex); - - switch (itemType) { + switch (c.itemType) { + case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: { + if (!Process.myUserHandle().equals(c.user)) { + c.markDeleted("Legacy shortcuts are only allowed for default user"); + continue; + } + // Follow through. + } case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: - case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: - id = c.getLong(idIndex); intentDescription = c.getString(intentIndex); - serialNumber = c.getInt(profileIdIndex); - user = allUsers.get(serialNumber); int promiseType = c.getInt(restoredIndex); int disabledState = 0; targetPackage = null; - if (user == null) { - // User has been deleted remove the item. - itemsToRemove.add(id); - continue; - } + try { intent = Intent.parseUri(intentDescription, 0); ComponentName cn = intent.getComponent(); if (cn != null && cn.getPackageName() != null) { boolean validPkg = launcherApps.isPackageEnabledForProfile( - cn.getPackageName(), user); + cn.getPackageName(), c.user); boolean validComponent = validPkg && - launcherApps.isActivityEnabledForProfile(cn, user); + launcherApps.isActivityEnabledForProfile(cn, c.user); if (validPkg) { targetPackage = cn.getPackageName(); } @@ -1359,10 +1236,10 @@ public class LauncherModel extends BroadcastReceiver if (validComponent) { if (restored) { // no special handling necessary for this item - restoredRows.add(id); + c.markRestored(); restored = false; } - if (quietMode.get(serialNumber)) { + if (quietMode.get(c.serialNumber)) { disabledState = ShortcutInfo.FLAG_DISABLED_QUIET_USER; } } else if (validPkg) { @@ -1373,22 +1250,20 @@ public class LauncherModel extends BroadcastReceiver intent = manager.getLaunchIntentForPackage( cn.getPackageName()); if (intent != null) { - ContentValues values = new ContentValues(); - values.put(LauncherSettings.Favorites.INTENT, - intent.toUri(0)); - updateItem(id, values); + c.updater().put( + LauncherSettings.Favorites.INTENT, + intent.toUri(0)).commit(); } } if (intent == null) { // The app is installed but the component is no // longer available. - FileLog.d(TAG, "Invalid component removed: " + cn); - itemsToRemove.add(id); + c.markDeleted("Invalid component removed: " + cn); continue; } else { // no special handling necessary for this item - restoredRows.add(id); + c.markRestored(); restored = false; } } else if (restored) { @@ -1401,13 +1276,11 @@ public class LauncherModel extends BroadcastReceiver } else if (installingPkgs.containsKey(cn.getPackageName())) { // App restore has started. Update the flag promiseType |= ShortcutInfo.FLAG_RESTORE_STARTED; - ContentValues values = new ContentValues(); - values.put(LauncherSettings.Favorites.RESTORED, - promiseType); - updateItem(id, values); + c.updater().put( + LauncherSettings.Favorites.RESTORED, + promiseType).commit(); } else { - FileLog.d(TAG, "Unrestored package removed: " + cn); - itemsToRemove.add(id); + c.markDeleted("Unrestored package removed: " + cn); continue; } } else if (PackageManagerHelper.isAppOnSdcard( @@ -1419,70 +1292,64 @@ public class LauncherModel extends BroadcastReceiver // SdCard is not ready yet. Package might get available, // once it is ready. Log.d(TAG, "Invalid package: " + cn + " (check again later)"); - pendingPackages.addToList(user, cn.getPackageName()); + pendingPackages.addToList(c.user, cn.getPackageName()); allowMissingTarget = true; // Add the icon on the workspace anyway. } else { // Do not wait for external media load anymore. // Log the invalid package, and remove it - FileLog.d(TAG, "Invalid package removed: " + cn); - itemsToRemove.add(id); + c.markDeleted("Invalid package removed: " + cn); continue; } } else if (cn == null) { // For shortcuts with no component, keep them as they are - restoredRows.add(id); + c.markRestored(); restored = false; } } catch (URISyntaxException e) { - FileLog.d(TAG, "Invalid uri: " + intentDescription); - itemsToRemove.add(id); + c.markDeleted("Invalid uri: " + intentDescription); continue; } - boolean useLowResIcon = container >= 0 && + boolean useLowResIcon = !c.isOnWorkspaceOrHotseat() && c.getInt(rankIndex) >= FolderIcon.NUM_ITEMS_IN_PREVIEW; if (restored) { - if (user.equals(Process.myUserHandle())) { - info = getRestoredItemInfo(c, intent, - promiseType, itemType, cursorIconInfo); - intent = getRestoredItemIntent(c, context, intent); + if (c.user.equals(Process.myUserHandle())) { + info = c.getRestoredItemInfo(intent, promiseType); + intent = PackageManagerHelper.getMarketIntent( + intent.getComponent().getPackageName()); } else { // Don't restore items for other profiles. - itemsToRemove.add(id); + c.markDeleted("Restore from managed profile not supported"); continue; } - } else if (itemType == + } else if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { - info = getAppShortcutInfo(intent, user, c, - cursorIconInfo, allowMissingTarget, useLowResIcon); - } else if (itemType == + info = c.getAppShortcutInfo( + intent, allowMissingTarget, useLowResIcon); + } else if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { - ShortcutKey key = ShortcutKey.fromIntent(intent, user); - if (unlockedUsers.get(serialNumber)) { + ShortcutKey key = ShortcutKey.fromIntent(intent, c.user); + if (unlockedUsers.get(c.serialNumber)) { ShortcutInfoCompat pinnedShortcut = shortcutKeyToPinnedShortcuts.get(key); if (pinnedShortcut == null) { // The shortcut is no longer valid. - itemsToRemove.add(id); + c.markDeleted("Pinned shortcut not found"); continue; } info = new ShortcutInfo(pinnedShortcut, context); intent = info.intent; } else { // Create a shortcut info in disabled mode for now. - info = new ShortcutInfo(); - info.user = user; - info.itemType = itemType; - loadInfoFromCursor(info, c, cursorIconInfo); - + info = c.loadSimpleShortcut(); info.isDisabled |= ShortcutInfo.FLAG_DISABLED_LOCKED_USER; } } else { // item type == ITEM_TYPE_SHORTCUT - info = getShortcutInfo(c, cursorIconInfo); + info = c.loadSimpleShortcut(); // Shortcuts are only available on the primary profile if (PackageManagerHelper.isAppSuspended(manager, targetPackage)) { @@ -1503,30 +1370,23 @@ public class LauncherModel extends BroadcastReceiver } if (info != null) { - info.id = id; + c.applyCommonProperties(info); + info.intent = intent; - info.container = container; - info.screenId = c.getInt(screenIndex); - info.cellX = c.getInt(cellXIndex); - info.cellY = c.getInt(cellYIndex); info.rank = c.getInt(rankIndex); info.spanX = 1; info.spanY = 1; - info.intent.putExtra(ItemInfo.EXTRA_PROFILE, serialNumber); + // TODO: Remove this extra. Instead we should be using + // itemInfo#user. + info.intent.putExtra(ItemInfo.EXTRA_PROFILE, c.serialNumber); if (info.promisedIntent != null) { - info.promisedIntent.putExtra(ItemInfo.EXTRA_PROFILE, serialNumber); + info.promisedIntent.putExtra(ItemInfo.EXTRA_PROFILE, c.serialNumber); } info.isDisabled |= disabledState; if (isSafeMode && !Utilities.isSystemApp(context, intent)) { info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE; } - // check & update map of what's occupied - if (!checkItemPlacement(occupied, info, sBgDataModel.workspaceScreens)) { - itemsToRemove.add(id); - break; - } - if (restored) { ComponentName cn = info.getTargetComponent(); if (cn != null) { @@ -1539,55 +1399,38 @@ public class LauncherModel extends BroadcastReceiver } } - sBgDataModel.addItem(info, false); + c.checkAndAddItem(info, sBgDataModel); } else { throw new RuntimeException("Unexpected null ShortcutInfo"); } break; case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: - id = c.getLong(idIndex); - FolderInfo folderInfo = sBgDataModel.findOrMakeFolder(id); + FolderInfo folderInfo = sBgDataModel.findOrMakeFolder(c.id); + c.applyCommonProperties(folderInfo); // Do not trim the folder label, as is was set by the user. - folderInfo.title = c.getString(cursorIconInfo.titleIndex); - folderInfo.id = id; - folderInfo.container = container; - folderInfo.screenId = c.getInt(screenIndex); - folderInfo.cellX = c.getInt(cellXIndex); - folderInfo.cellY = c.getInt(cellYIndex); + folderInfo.title = c.getString(c.titleIndex); folderInfo.spanX = 1; folderInfo.spanY = 1; folderInfo.options = c.getInt(optionsIndex); - // check & update map of what's occupied - if (!checkItemPlacement(occupied, folderInfo, sBgDataModel.workspaceScreens)) { - itemsToRemove.add(id); - break; - } if (restored) { // no special handling required for restored folders - restoredRows.add(id); + c.markRestored(); } - sBgDataModel.addItem(folderInfo, false); + c.checkAndAddItem(folderInfo, sBgDataModel); break; case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: // Read all Launcher-specific widget details - boolean customWidget = itemType == + boolean customWidget = c.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET; int appWidgetId = c.getInt(appWidgetIdIndex); - serialNumber = c.getLong(profileIdIndex); String savedProvider = c.getString(appWidgetProviderIndex); - id = c.getLong(idIndex); - user = allUsers.get(serialNumber); - if (user == null) { - itemsToRemove.add(id); - continue; - } final ComponentName component = ComponentName.unflattenFromString(savedProvider); @@ -1605,14 +1448,14 @@ public class LauncherModel extends BroadcastReceiver final AppWidgetProviderInfo provider = widgetProvidersMap.get( new ComponentKey( ComponentName.unflattenFromString(savedProvider), - user)); + c.user)); final boolean isProviderReady = isValidProvider(provider); if (!isSafeMode && !customWidget && wasProviderReady && !isProviderReady) { - FileLog.d(TAG, "Deleting widget that isn't installed anymore: " + c.markDeleted( + "Deleting widget that isn't installed anymore: " + provider); - itemsToRemove.add(id); } else { if (isProviderReady) { appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, @@ -1637,7 +1480,7 @@ public class LauncherModel extends BroadcastReceiver } appWidgetInfo.restoreStatus = status; } else { - Log.v(TAG, "Widget restore pending id=" + id + Log.v(TAG, "Widget restore pending id=" + c.id + " appWidgetId=" + appWidgetId + " status =" + restoreStatus); appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, @@ -1652,8 +1495,7 @@ public class LauncherModel extends BroadcastReceiver appWidgetInfo.restoreStatus |= LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; } else if (!isSafeMode) { - FileLog.d(TAG, "Unrestored widget removed: " + component); - itemsToRemove.add(id); + c.markDeleted("Unrestored widget removed: " + component); continue; } @@ -1669,44 +1511,31 @@ public class LauncherModel extends BroadcastReceiver } } - appWidgetInfo.id = id; - appWidgetInfo.screenId = c.getInt(screenIndex); - appWidgetInfo.cellX = c.getInt(cellXIndex); - appWidgetInfo.cellY = c.getInt(cellYIndex); + c.applyCommonProperties(appWidgetInfo); appWidgetInfo.spanX = c.getInt(spanXIndex); appWidgetInfo.spanY = c.getInt(spanYIndex); - appWidgetInfo.user = user; + appWidgetInfo.user = c.user; - if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP && - container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) { - Log.e(TAG, "Widget found where container != " + + if (!c.isOnWorkspaceOrHotseat()) { + c.markDeleted("Widget found where container != " + "CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!"); - itemsToRemove.add(id); continue; } - appWidgetInfo.container = container; - // check & update map of what's occupied - if (!checkItemPlacement(occupied, appWidgetInfo, sBgDataModel.workspaceScreens)) { - itemsToRemove.add(id); - break; - } - if (!customWidget) { String providerName = appWidgetInfo.providerName.flattenToString(); if (!providerName.equals(savedProvider) || (appWidgetInfo.restoreStatus != restoreStatus)) { - ContentValues values = new ContentValues(); - values.put( - LauncherSettings.Favorites.APPWIDGET_PROVIDER, - providerName); - values.put(LauncherSettings.Favorites.RESTORED, - appWidgetInfo.restoreStatus); - updateItem(id, values); + c.updater() + .put(LauncherSettings.Favorites.APPWIDGET_PROVIDER, + providerName) + .put(LauncherSettings.Favorites.RESTORED, + appWidgetInfo.restoreStatus) + .commit(); } } - sBgDataModel.addItem(appWidgetInfo, false); + c.checkAndAddItem(appWidgetInfo, sBgDataModel); } break; } @@ -1724,16 +1553,8 @@ public class LauncherModel extends BroadcastReceiver return; } - if (itemsToRemove.size() > 0) { - // Remove dead items - contentResolver.delete(LauncherSettings.Favorites.CONTENT_URI, - Utilities.createDbSelectionQuery( - LauncherSettings.Favorites._ID, itemsToRemove), null); - if (DEBUG_LOADERS) { - Log.d(TAG, "Removed = " + Utilities.createDbSelectionQuery( - LauncherSettings.Favorites._ID, itemsToRemove)); - } - + // Remove dead items + if (c.commitDeleted()) { // Remove any empty folder ArrayList<Long> deletedFolderIds = (ArrayList<Long>) LauncherSettings.Settings .call(contentResolver, @@ -1774,15 +1595,7 @@ public class LauncherModel extends BroadcastReceiver } } - if (restoredRows.size() > 0) { - // Update restored items that no longer require special handling - ContentValues values = new ContentValues(); - values.put(LauncherSettings.Favorites.RESTORED, 0); - contentResolver.update(LauncherSettings.Favorites.CONTENT_URI, values, - Utilities.createDbSelectionQuery( - LauncherSettings.Favorites._ID, restoredRows), null); - } - + c.commitRestoredItems(); if (!isSdCardReady && !pendingPackages.isEmpty()) { context.registerReceiver( new SdCardAvailableReceiver( @@ -1793,7 +1606,7 @@ public class LauncherModel extends BroadcastReceiver } // Remove any empty screens - ArrayList<Long> unusedScreens = new ArrayList<Long>(sBgDataModel.workspaceScreens); + ArrayList<Long> unusedScreens = new ArrayList<>(sBgDataModel.workspaceScreens); for (ItemInfo item: sBgDataModel.itemsIdMap) { long screenId = item.screenId; if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && @@ -1807,40 +1620,12 @@ public class LauncherModel extends BroadcastReceiver sBgDataModel.workspaceScreens.removeAll(unusedScreens); updateWorkspaceScreenOrder(context, sBgDataModel.workspaceScreens); } - - if (DEBUG_LOADERS) { - Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms"); - Log.d(TAG, "workspace layout: "); - int nScreens = occupied.size(); - for (int y = 0; y < countY; y++) { - String line = ""; - - for (int i = 0; i < nScreens; i++) { - long screenId = occupied.keyAt(i); - if (screenId > 0) { - line += " | "; - } - } - Log.d(TAG, "[ " + line + " ]"); - } - } } if (LauncherAppState.PROFILE_STARTUP) { Trace.endSection(); } } - /** - * Partially updates the item without any notification. Must be called on the worker thread. - */ - private void updateItem(long itemId, ContentValues update) { - mContext.getContentResolver().update( - LauncherSettings.Favorites.CONTENT_URI, - update, - BaseColumns._ID + "= ?", - new String[]{Long.toString(itemId)}); - } - /** Filters the set of items who are directly or indirectly (via another container) on the * specified screen. */ private void filterCurrentWorkspaceItems(long currentScreenId, @@ -2482,179 +2267,6 @@ public class LauncherModel extends BroadcastReceiver }); } - /** - * Make an ShortcutInfo object for a restored application or shortcut item that points - * to a package that is not yet installed on the system. - */ - public ShortcutInfo getRestoredItemInfo(Cursor c, Intent intent, - int promiseType, int itemType, CursorIconInfo iconInfo) { - final ShortcutInfo info = new ShortcutInfo(); - info.user = Process.myUserHandle(); - info.promisedIntent = intent; - - info.iconBitmap = iconInfo.loadIcon(c, info); - // the fallback icon - if (info.iconBitmap == null) { - mIconCache.getTitleAndIcon(info, false /* useLowResIcon */); - } - - if ((promiseType & ShortcutInfo.FLAG_RESTORED_ICON) != 0) { - String title = iconInfo.getTitle(c); - if (!TextUtils.isEmpty(title)) { - info.title = Utilities.trim(title); - } - } else if ((promiseType & ShortcutInfo.FLAG_AUTOINTALL_ICON) != 0) { - if (TextUtils.isEmpty(info.title)) { - info.title = iconInfo.getTitle(c); - } - } else { - throw new InvalidParameterException("Invalid restoreType " + promiseType); - } - - info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); - info.itemType = itemType; - info.status = promiseType; - return info; - } - - /** - * Make an Intent object for a restored application or shortcut item that points - * to the market page for the item. - */ - @Thunk Intent getRestoredItemIntent(Cursor c, Context context, Intent intent) { - ComponentName componentName = intent.getComponent(); - return getMarketIntent(componentName.getPackageName()); - } - - static Intent getMarketIntent(String packageName) { - return new Intent(Intent.ACTION_VIEW) - .setData(new Uri.Builder() - .scheme("market") - .authority("details") - .appendQueryParameter("id", packageName) - .build()); - } - - /** - * Make an ShortcutInfo object for a shortcut that is an application. - * - * If c is not null, then it will be used to fill in missing data like the title and icon. - */ - public ShortcutInfo getAppShortcutInfo(Intent intent, UserHandle user, Cursor c, - CursorIconInfo iconInfo, boolean allowMissingTarget, boolean useLowResIcon) { - if (user == null) { - Log.d(TAG, "Null user found in getShortcutInfo"); - return null; - } - - ComponentName componentName = intent.getComponent(); - if (componentName == null) { - Log.d(TAG, "Missing component found in getShortcutInfo"); - return null; - } - - Intent newIntent = new Intent(intent.getAction(), null); - newIntent.addCategory(Intent.CATEGORY_LAUNCHER); - newIntent.setComponent(componentName); - LauncherActivityInfoCompat lai = mLauncherApps.resolveActivity(newIntent, user); - if ((lai == null) && !allowMissingTarget) { - Log.d(TAG, "Missing activity found in getShortcutInfo: " + componentName); - return null; - } - - final ShortcutInfo info = new ShortcutInfo(); - info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; - info.user = user; - info.intent = newIntent; - - mIconCache.getTitleAndIcon(info, lai, useLowResIcon); - if (mIconCache.isDefaultIcon(info.iconBitmap, user) && c != null) { - Bitmap icon = iconInfo.loadIcon(c); - info.iconBitmap = icon != null ? icon : mIconCache.getDefaultIcon(user); - } - - if (lai != null && PackageManagerHelper.isAppSuspended(lai.getApplicationInfo())) { - info.isDisabled = ShortcutInfo.FLAG_DISABLED_SUSPENDED; - } - - // from the db - if (TextUtils.isEmpty(info.title) && c != null) { - info.title = iconInfo.getTitle(c); - } - - // fall back to the class name of the activity - if (info.title == null) { - info.title = componentName.getClassName(); - } - - info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); - return info; - } - - /** - * Make an ShortcutInfo object for a shortcut that isn't an application. - */ - @Thunk ShortcutInfo getShortcutInfo(Cursor c, CursorIconInfo iconInfo) { - final ShortcutInfo info = new ShortcutInfo(); - // Non-app shortcuts are only supported for current user. - info.user = Process.myUserHandle(); - info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; - - // TODO: If there's an explicit component and we can't install that, delete it. - - loadInfoFromCursor(info, c, iconInfo); - return info; - } - - /** - * Make an ShortcutInfo object for a shortcut that isn't an application. - */ - public void loadInfoFromCursor(ShortcutInfo info, Cursor c, CursorIconInfo iconInfo) { - info.title = iconInfo.getTitle(c); - info.iconBitmap = iconInfo.loadIcon(c, info); - // the fallback icon - if (info.iconBitmap == null) { - info.iconBitmap = mIconCache.getDefaultIcon(info.user); - } - } - - ShortcutInfo infoFromShortcutIntent(Context context, Intent data) { - Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); - String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); - Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON); - - if (intent == null) { - // If the intent is null, we can't construct a valid ShortcutInfo, so we return null - Log.e(TAG, "Can't construct ShorcutInfo with null intent"); - return null; - } - - final ShortcutInfo info = new ShortcutInfo(); - - // Only support intents for current user for now. Intents sent from other - // users wouldn't get here without intent forwarding anyway. - info.user = Process.myUserHandle(); - - if (bitmap instanceof Bitmap) { - info.iconBitmap = LauncherIcons.createIconBitmap((Bitmap) bitmap, context); - } else { - Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE); - if (extra instanceof ShortcutIconResource) { - info.iconResource = (ShortcutIconResource) extra; - info.iconBitmap = LauncherIcons.createIconBitmap(info.iconResource, context); - } - } - if (info.iconBitmap == null) { - info.iconBitmap = mIconCache.getDefaultIcon(info.user); - } - - info.title = Utilities.trim(name); - info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); - info.intent = intent; - - return info; - } - static boolean isValidProvider(AppWidgetProviderInfo provider) { return (provider != null) && (provider.provider != null) && (provider.provider.getPackageName() != null); |