Allow app pairs in folders

This CL substantially refactors folders to be able to take contents of type AppPairInfo. App pairs can now be moved in and out of folders, and launch from folders.

This CL contains only logic and model changes; animation and style changes (for dropping items into folders, color changes to app pair surfaces, etc.) will be in a following CL. Another CL (hopefully) will contain tests. I'm planning to submit them together, but this patch should also be able to stand alone with no issues (except janky transitions).

Bug: 315731527
Flag: ACONFIG com.android.wm.shell.enable_app_pairs TRUNKFOOD
Test: Manual, more to follow in another CL.
Change-Id: I73732fcaefbdc61bf6e02a5be365962b8bbc3e41
This commit is contained in:
Jeremy Sim
2024-04-02 01:21:31 -07:00
parent da4ba9336e
commit a596f589c4
28 changed files with 454 additions and 233 deletions
@@ -71,6 +71,7 @@ import com.android.launcher3.logger.LauncherAtom.FromState;
import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.AppPairInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.FolderInfo.FolderListener;
import com.android.launcher3.model.data.FolderInfo.LabelState;
@@ -118,7 +119,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
ClippedFolderIconLayoutRule mPreviewLayoutRule;
private PreviewItemManager mPreviewItemManager;
private PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0);
private List<WorkspaceItemInfo> mCurrentPreviewItems = new ArrayList<>();
private List<ItemInfo> mCurrentPreviewItems = new ArrayList<>();
boolean mAnimating = false;
@@ -215,7 +216,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
// Keep the notification dot up to date with the sum of all the content's dots.
FolderDotInfo folderDotInfo = new FolderDotInfo();
for (WorkspaceItemInfo si : folderInfo.getContents()) {
for (ItemInfo si : folderInfo.getContents()) {
folderDotInfo.addDotInfo(activity.getDotInfoForItem(si));
}
icon.setDotInfo(folderDotInfo);
@@ -261,20 +262,18 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
private boolean willAcceptItem(ItemInfo item) {
final int itemType = item.itemType;
return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) &&
item != mInfo && !mFolder.isOpen());
return (Folder.willAcceptItemType(itemType) && item != mInfo && !mFolder.isOpen());
}
public boolean acceptDrop(ItemInfo dragInfo) {
return !mFolder.isDestroyed() && willAcceptItem(dragInfo);
}
public void addItem(WorkspaceItemInfo item) {
public void addItem(ItemInfo item) {
mInfo.add(item, true);
}
public void removeItem(WorkspaceItemInfo item, boolean animate) {
public void removeItem(ItemInfo item, boolean animate) {
mInfo.remove(item, animate);
}
@@ -287,8 +286,8 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
mOpenAlarm.setOnAlarmListener(mOnOpenListener);
if (SPRING_LOADING_ENABLED &&
((dragInfo instanceof WorkspaceItemFactory)
|| (dragInfo instanceof WorkspaceItemInfo)
|| (dragInfo instanceof PendingAddShortcutInfo))) {
|| (dragInfo instanceof PendingAddShortcutInfo)
|| Folder.willAccept(dragInfo))) {
mOpenAlarm.setAlarm(ON_OPEN_DELAY);
}
}
@@ -303,8 +302,8 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
return mPreviewItemManager.prepareCreateAnimation(destView);
}
public void performCreateAnimation(final WorkspaceItemInfo destInfo, final View destView,
final WorkspaceItemInfo srcInfo, final DragObject d, Rect dstRect,
public void performCreateAnimation(final ItemInfo destInfo, final View destView,
final ItemInfo srcInfo, final DragObject d, Rect dstRect,
float scaleRelativeToDragLayer) {
final DragView srcView = d.dragView;
prepareCreateAnimation(destView);
@@ -330,7 +329,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
mOpenAlarm.cancelAlarm();
}
private void onDrop(final WorkspaceItemInfo item, DragObject d, Rect finalRect,
private void onDrop(final ItemInfo item, DragObject d, Rect finalRect,
float scaleRelativeToDragLayer, int index, boolean itemReturnedOnFailedDrop) {
item.cellX = -1;
item.cellY = -1;
@@ -361,7 +360,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
int numItemsInPreview = Math.min(MAX_NUM_ITEMS_IN_PREVIEW, index + 1);
boolean itemAdded = false;
if (itemReturnedOnFailedDrop || index >= MAX_NUM_ITEMS_IN_PREVIEW) {
List<WorkspaceItemInfo> oldPreviewItems = new ArrayList<>(mCurrentPreviewItems);
List<ItemInfo> oldPreviewItems = new ArrayList<>(mCurrentPreviewItems);
mInfo.add(item, index, false);
mCurrentPreviewItems.clear();
mCurrentPreviewItems.addAll(getPreviewItemsOnPage(0));
@@ -422,7 +421,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
FolderNameInfos nameInfos = new FolderNameInfos();
Executors.MODEL_EXECUTOR.post(() -> {
d.folderNameProvider.getSuggestedFolderName(
getContext(), mInfo.getContents(), nameInfos);
getContext(), mInfo.getAppContents(), nameInfos);
postDelayed(() -> {
setLabelSuggestion(nameInfos, d.logInstanceId);
invalidate();
@@ -475,15 +474,21 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
public void onDrop(DragObject d, boolean itemReturnedOnFailedDrop) {
WorkspaceItemInfo item;
ItemInfo item;
if (d.dragInfo instanceof WorkspaceItemFactory) {
// Came from all apps -- make a copy
item = ((WorkspaceItemFactory) d.dragInfo).makeWorkspaceItem(getContext());
} else if (d.dragSource instanceof BaseItemDragListener){
// Came from a different window -- make a copy
item = new WorkspaceItemInfo((WorkspaceItemInfo) d.dragInfo);
if (d.dragInfo instanceof AppPairInfo) {
// dragged item is app pair
item = new AppPairInfo((AppPairInfo) d.dragInfo);
} else {
// dragged item is WorkspaceItemInfo
item = new WorkspaceItemInfo((WorkspaceItemInfo) d.dragInfo);
}
} else {
item = (WorkspaceItemInfo) d.dragInfo;
item = d.dragInfo;
}
mFolder.notifyDrop();
onDrop(item, d, null, 1.0f,
@@ -665,7 +670,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
/**
* Returns the list of items which should be visible in the preview
*/
public List<WorkspaceItemInfo> getPreviewItemsOnPage(int page) {
public List<ItemInfo> getPreviewItemsOnPage(int page) {
return mPreviewVerifier.setFolderInfo(mInfo).previewItemsForPage(page, mInfo.getContents());
}
@@ -690,12 +695,12 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
/**
* Updates the preview items which match the provided condition
*/
public void updatePreviewItems(Predicate<WorkspaceItemInfo> itemCheck) {
public void updatePreviewItems(Predicate<ItemInfo> itemCheck) {
mPreviewItemManager.updatePreviewItems(itemCheck);
}
@Override
public void onAdd(WorkspaceItemInfo item, int rank) {
public void onAdd(ItemInfo item, int rank) {
updatePreviewItems(false);
boolean wasDotted = mDotInfo.hasDot();
mDotInfo.addDotInfo(mActivity.getDotInfoForItem(item));
@@ -707,7 +712,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
}
@Override
public void onRemove(List<WorkspaceItemInfo> items) {
public void onRemove(List<ItemInfo> items) {
updatePreviewItems(false);
boolean wasDotted = mDotInfo.hasDot();
items.stream().map(mActivity::getDotInfoForItem).forEach(mDotInfo::subtractDotInfo);