Merge "Reparent folders and app pairs" into main

This commit is contained in:
Jeremy Sim
2024-03-30 03:06:44 +00:00
committed by Android (Google) Code Review
50 changed files with 517 additions and 341 deletions

View File

@@ -20,7 +20,6 @@ import static com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN;
import static com.android.launcher3.Flags.enableLauncherBrMetricsFixed;
import static com.android.launcher3.LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE;
import static com.android.launcher3.LauncherPrefs.SHOULD_SHOW_SMARTSPACE;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR;
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
import static com.android.launcher3.config.FeatureFlags.ENABLE_SMARTSPACE_REMOVAL;
import static com.android.launcher3.config.FeatureFlags.SMARTSPACE_AS_A_WIDGET;
@@ -77,9 +76,12 @@ import com.android.launcher3.icons.ShortcutCachingLogic;
import com.android.launcher3.icons.cache.IconCacheUpdateHandler;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.AppPairInfo;
import com.android.launcher3.model.data.CollectionInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.IconRequestInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
@@ -99,7 +101,6 @@ import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.widget.WidgetInflater;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -234,6 +235,7 @@ public class LoaderTask implements Runnable {
if (Objects.equals(mApp.getInvariantDeviceProfile().dbFile, mDbName)) {
verifyNotStopped();
sanitizeFolders(mItemsDeleted);
sanitizeAppPairs();
sanitizeWidgetsShortcutsAndPackages();
logASplit("sanitizeData");
}
@@ -482,14 +484,20 @@ public class LoaderTask implements Runnable {
}
/**
* After all items have been processed and added to the BgDataModel, this method requests
* high-res icons for the items that are part of an app pair
* After all items have been processed and added to the BgDataModel, this method sorts and
* requests high-res icons for the items that are part of an app pair.
*/
private void processAppPairItems() {
mBgDataModel.workspaceItems.stream()
.filter((itemInfo -> itemInfo.itemType == ITEM_TYPE_APP_PAIR))
.forEach(fi -> ((FolderInfo) fi).contents.forEach(item ->
mIconCache.getTitleAndIcon(item, false /*useLowResIcon*/)));
for (CollectionInfo collection : mBgDataModel.collections) {
if (!(collection instanceof AppPairInfo appPair)) {
continue;
}
appPair.getContents().sort(Folder.ITEM_POS_COMPARATOR);
// Fetch hi-res icons if needed.
appPair.getContents().stream().filter(ItemInfoWithIcon::usingLowResIcon)
.forEach(member -> mIconCache.getTitleAndIcon(member, false));
}
}
/**
@@ -545,20 +553,21 @@ public class LoaderTask implements Runnable {
// Sort the folder items, update ranks, and make sure all preview items are high res.
List<FolderGridOrganizer> verifiers = mApp.getInvariantDeviceProfile().supportedProfiles
.stream().map(FolderGridOrganizer::new).toList();
for (FolderInfo folder : mBgDataModel.folders) {
Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR);
for (CollectionInfo collection : mBgDataModel.collections) {
if (!(collection instanceof FolderInfo folder)) {
continue;
}
folder.getContents().sort(Folder.ITEM_POS_COMPARATOR);
verifiers.forEach(verifier -> verifier.setFolderInfo(folder));
int size = folder.contents.size();
int size = folder.getContents().size();
// Update ranks here to ensure there are no gaps caused by removed folder items.
// Ranks are the source of truth for folder items, so cellX and cellY can be
// ignored for now. Database will be updated once user manually modifies folder.
for (int rank = 0; rank < size; ++rank) {
WorkspaceItemInfo info = folder.contents.get(rank);
// rank is used differently in app pairs, so don't reset
if (folder.itemType != ITEM_TYPE_APP_PAIR) {
info.rank = rank;
}
WorkspaceItemInfo info = folder.getContents().get(rank);
info.rank = rank;
if (info.usingLowResIcon() && info.itemType == Favorites.ITEM_TYPE_APPLICATION
&& verifiers.stream().anyMatch(it -> it.isItemInPreview(info.rank))) {
@@ -611,14 +620,32 @@ public class LoaderTask implements Runnable {
IntArray deletedFolderIds = mApp.getModel().getModelDbController().deleteEmptyFolders();
synchronized (mBgDataModel) {
for (int folderId : deletedFolderIds) {
mBgDataModel.workspaceItems.remove(mBgDataModel.folders.get(folderId));
mBgDataModel.folders.remove(folderId);
mBgDataModel.workspaceItems.remove(mBgDataModel.collections.get(folderId));
mBgDataModel.collections.remove(folderId);
mBgDataModel.itemsIdMap.remove(folderId);
}
}
}
}
/** Cleans up app pairs if they don't have the right number of member apps (2). */
private void sanitizeAppPairs() {
IntArray deletedAppPairIds = mApp.getModel().getModelDbController().deleteBadAppPairs();
IntArray deletedAppIds = mApp.getModel().getModelDbController().deleteUnparentedApps();
IntArray deleted = new IntArray();
deleted.addAll(deletedAppPairIds);
deleted.addAll(deletedAppIds);
synchronized (mBgDataModel) {
for (int id : deleted) {
mBgDataModel.workspaceItems.remove(mBgDataModel.collections.get(id));
mBgDataModel.collections.remove(id);
mBgDataModel.itemsIdMap.remove(id);
}
}
}
private void sanitizeWidgetsShortcutsAndPackages() {
Context context = mApp.getContext();
@@ -754,16 +781,16 @@ public class LoaderTask implements Runnable {
private void loadFolderNames() {
FolderNameProvider provider = FolderNameProvider.newInstance(mApp.getContext(),
mBgAllAppsList.data, mBgDataModel.folders);
mBgAllAppsList.data, mBgDataModel.collections);
synchronized (mBgDataModel) {
for (int i = 0; i < mBgDataModel.folders.size(); i++) {
for (int i = 0; i < mBgDataModel.collections.size(); i++) {
FolderNameInfos suggestionInfos = new FolderNameInfos();
FolderInfo info = mBgDataModel.folders.valueAt(i);
if (info.suggestedFolderNames == null) {
provider.getSuggestedFolderName(mApp.getContext(), info.contents,
CollectionInfo info = mBgDataModel.collections.valueAt(i);
if (info instanceof FolderInfo fi && fi.suggestedFolderNames == null) {
provider.getSuggestedFolderName(mApp.getContext(), fi.getContents(),
suggestionInfos);
info.suggestedFolderNames = suggestionInfos;
fi.suggestedFolderNames = suggestionInfos;
}
}
}