Merge "Adding support for easily extending Launcher DragAndDrop support" into tm-dev am: d7281d097d am: 3416df65a9

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/18287509

Change-Id: I5f0a45c44108ad3da26daa61825eafbb0d616de3
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Sunny Goyal
2022-05-12 18:04:34 +00:00
committed by Automerger Merge Worker
18 changed files with 133 additions and 106 deletions
@@ -19,6 +19,7 @@ package com.android.launcher3.appprediction;
import static com.android.quickstep.InstantAppResolverImpl.COMPONENT_CLASS_MARKER; import static com.android.quickstep.InstantAppResolverImpl.COMPONENT_CLASS_MARKER;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings;
@@ -38,8 +39,8 @@ public class InstantAppItemInfo extends AppInfo {
} }
@Override @Override
public WorkspaceItemInfo makeWorkspaceItem() { public WorkspaceItemInfo makeWorkspaceItem(Context context) {
WorkspaceItemInfo workspaceItemInfo = super.makeWorkspaceItem(); WorkspaceItemInfo workspaceItemInfo = super.makeWorkspaceItem(context);
workspaceItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; workspaceItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
workspaceItemInfo.status = WorkspaceItemInfo.FLAG_AUTOINSTALL_ICON workspaceItemInfo.status = WorkspaceItemInfo.FLAG_AUTOINSTALL_ICON
| WorkspaceItemInfo.FLAG_RESTORE_STARTED | WorkspaceItemInfo.FLAG_RESTORE_STARTED
@@ -85,7 +85,7 @@ public class PredictionUpdateTask extends BaseModelUpdateTask {
.filter(info -> user.equals(info.user) && cn.equals(info.componentName)) .filter(info -> user.equals(info.user) && cn.equals(info.componentName))
.map(ai -> { .map(ai -> {
app.getIconCache().getTitleAndIcon(ai, false); app.getIconCache().getTitleAndIcon(ai, false);
return ai.makeWorkspaceItem(); return ai.makeWorkspaceItem(context);
}) })
.findAny() .findAny()
.orElseGet(() -> { .orElseGet(() -> {
@@ -96,7 +96,7 @@ public class PredictionUpdateTask extends BaseModelUpdateTask {
} }
AppInfo ai = new AppInfo(context, lai, user); AppInfo ai = new AppInfo(context, lai, user);
app.getIconCache().getTitleAndIcon(ai, lai, false); app.getIconCache().getTitleAndIcon(ai, lai, false);
return ai.makeWorkspaceItem(); return ai.makeWorkspaceItem(context);
}); });
if (itemInfo == null) { if (itemInfo == null) {
@@ -460,7 +460,7 @@ public class QuickstepModelDelegate extends ModelDelegate {
AppInfo info = new AppInfo(lai, user, mUMS.isUserQuiet(user)); AppInfo info = new AppInfo(lai, user, mUMS.isUserQuiet(user));
mAppState.getIconCache().getTitleAndIcon(info, lai, false); mAppState.getIconCache().getTitleAndIcon(info, lai, false);
mReadCount++; mReadCount++;
return info.makeWorkspaceItem(); return info.makeWorkspaceItem(mAppState.getContext());
} }
case ITEM_TYPE_DEEP_SHORTCUT: { case ITEM_TYPE_DEEP_SHORTCUT: {
ShortcutKey key = ShortcutKey.fromIntent(intent, user); ShortcutKey key = ShortcutKey.fromIntent(intent, user);
@@ -43,6 +43,7 @@ import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.LauncherBindableItemsContainer; import com.android.launcher3.util.LauncherBindableItemsContainer;
import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.ActivityContext;
import com.android.quickstep.SystemUiProxy; import com.android.quickstep.SystemUiProxy;
@@ -136,7 +137,7 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
return null; return null;
} }
ItemInfo item = (ItemInfo) icon.getTag(); ItemInfo item = (ItemInfo) icon.getTag();
if (!PopupContainerWithArrow.canShow(icon, item)) { if (!ShortcutUtil.supportsShortcuts(item)) {
return null; return null;
} }
+21 -16
View File
@@ -53,6 +53,7 @@ import androidx.annotation.UiThread;
import com.android.launcher3.accessibility.BaseAccessibilityDelegate; import com.android.launcher3.accessibility.BaseAccessibilityDelegate;
import com.android.launcher3.dot.DotInfo; import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.dragndrop.DragOptions.PreDragCondition;
import com.android.launcher3.dragndrop.DraggableView; import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.graphics.IconShape; import com.android.launcher3.graphics.IconShape;
@@ -65,12 +66,11 @@ import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.model.data.SearchActionItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.util.SafeCloseable; import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BubbleTextHolder;
import com.android.launcher3.views.IconLabelDotView; import com.android.launcher3.views.IconLabelDotView;
import java.text.NumberFormat; import java.text.NumberFormat;
@@ -174,7 +174,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
private HandlerRunnable mIconLoadRequest; private HandlerRunnable mIconLoadRequest;
private boolean mEnableIconUpdateAnimation = false; private boolean mEnableIconUpdateAnimation = false;
private BubbleTextHolder mBubbleTextHolder;
public BubbleTextView(Context context) { public BubbleTextView(Context context) {
this(context, null, 0); this(context, null, 0);
@@ -362,15 +361,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
setDownloadStateContentDescription(info, info.getProgressLevel()); setDownloadStateContentDescription(info, info.getProgressLevel());
} }
private void setItemInfo(ItemInfoWithIcon itemInfo) { protected void setItemInfo(ItemInfoWithIcon itemInfo) {
setTag(itemInfo); setTag(itemInfo);
if (mBubbleTextHolder != null) {
mBubbleTextHolder.onItemInfoUpdated(itemInfo);
}
}
public void setBubbleTextHolder(BubbleTextHolder bubbleTextHolder) {
mBubbleTextHolder = bubbleTextHolder;
} }
@UiThread @UiThread
@@ -920,10 +912,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
} else if (info instanceof WorkspaceItemInfo) { } else if (info instanceof WorkspaceItemInfo) {
applyFromWorkspaceItem((WorkspaceItemInfo) info); applyFromWorkspaceItem((WorkspaceItemInfo) info);
mActivity.invalidateParent(info); mActivity.invalidateParent(info);
} else if (info instanceof PackageItemInfo) { } else if (info != null) {
applyFromItemInfoWithIcon((PackageItemInfo) info); applyFromItemInfoWithIcon(info);
} else if (info instanceof SearchActionItemInfo) {
applyFromItemInfoWithIcon((SearchActionItemInfo) info);
} }
mDisableRelayout = false; mDisableRelayout = false;
@@ -1061,4 +1051,19 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
args.put("count", notificationCount); args.put("count", notificationCount);
return icuCountFormat.format(args); return icuCountFormat.format(args);
} }
/**
* Starts a long press action and returns the corresponding pre-drag condition
*/
public PreDragCondition startLongPressAction() {
PopupContainerWithArrow popup = PopupContainerWithArrow.showForIcon(this);
return popup != null ? popup.createPreDragCondition(true) : null;
}
/**
* Returns true if the view can show long-press popup
*/
public boolean canShowLongPressPopup() {
return getTag() instanceof ItemInfo && ShortcutUtil.supportsShortcuts((ItemInfo) getTag());
}
} }
+4 -15
View File
@@ -85,14 +85,12 @@ import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.InstanceId; import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.LauncherEvent; import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.SearchActionItemInfo; import com.android.launcher3.model.data.WorkspaceItemFactory;
import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pageindicators.PageIndicator; import com.android.launcher3.pageindicators.PageIndicator;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.states.StateAnimationConfig;
@@ -1680,11 +1678,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
} }
if (child instanceof BubbleTextView && !dragOptions.isAccessibleDrag) { if (child instanceof BubbleTextView && !dragOptions.isAccessibleDrag) {
PopupContainerWithArrow<Launcher> popupContainer = PopupContainerWithArrow dragOptions.preDragCondition = ((BubbleTextView) child).startLongPressAction();
.showForIcon((BubbleTextView) child);
if (popupContainer != null) {
dragOptions.preDragCondition = popupContainer.createPreDragCondition(true);
}
} }
final DragView dv; final DragView dv;
@@ -2777,9 +2771,9 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION: case LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION:
if (info instanceof AppInfo) { if (info instanceof WorkspaceItemFactory) {
// Came from all apps -- make a copy // Came from all apps -- make a copy
info = ((AppInfo) info).makeWorkspaceItem(); info = ((WorkspaceItemFactory) info).makeWorkspaceItem(mLauncher);
d.dragInfo = info; d.dragInfo = info;
} }
if (info instanceof WorkspaceItemInfo if (info instanceof WorkspaceItemInfo
@@ -2788,11 +2782,6 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
info = new WorkspaceItemInfo((WorkspaceItemInfo) info); info = new WorkspaceItemInfo((WorkspaceItemInfo) info);
d.dragInfo = info; d.dragInfo = info;
} }
if (info instanceof SearchActionItemInfo) {
info = ((SearchActionItemInfo) info).createWorkspaceItem(
mLauncher.getModel());
d.dragInfo = info;
}
view = mLauncher.createShortcut(cellLayout, (WorkspaceItemInfo) info); view = mLauncher.createShortcut(cellLayout, (WorkspaceItemInfo) info);
break; break;
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
@@ -23,6 +23,7 @@ import android.util.SparseArray;
import android.view.View; import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DropTarget; import com.android.launcher3.DropTarget;
import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings;
import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragController;
@@ -31,9 +32,9 @@ import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.util.Thunk; import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BubbleTextHolder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -72,7 +73,7 @@ public abstract class BaseAccessibilityDelegate<T extends Context & ActivityCont
getSupportedActions(host, item, actions); getSupportedActions(host, item, actions);
actions.forEach(la -> info.addAction(la.accessibilityAction)); actions.forEach(la -> info.addAction(la.accessibilityAction));
if (!itemSupportsLongClick(host, item)) { if (!itemSupportsLongClick(host)) {
info.setLongClickable(false); info.setLongClickable(false);
info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK); info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
} }
@@ -84,8 +85,15 @@ public abstract class BaseAccessibilityDelegate<T extends Context & ActivityCont
*/ */
protected abstract void getSupportedActions(View host, ItemInfo item, List<LauncherAction> out); protected abstract void getSupportedActions(View host, ItemInfo item, List<LauncherAction> out);
private boolean itemSupportsLongClick(View host, ItemInfo info) { private boolean itemSupportsLongClick(View host) {
return PopupContainerWithArrow.canShow(host, info); if (host instanceof BubbleTextView) {
return ((BubbleTextView) host).canShowLongPressPopup();
} else if (host instanceof BubbleTextHolder) {
BubbleTextHolder holder = (BubbleTextHolder) host;
return holder.getBubbleText() != null && holder.getBubbleText().canShowLongPressPopup();
} else {
return false;
}
} }
protected boolean itemSupportsAccessibleDrag(ItemInfo item) { protected boolean itemSupportsAccessibleDrag(ItemInfo item) {
@@ -113,7 +121,6 @@ public abstract class BaseAccessibilityDelegate<T extends Context & ActivityCont
@Thunk @Thunk
protected void announceConfirmation(String confirmation) { protected void announceConfirmation(String confirmation) {
mContext.getDragLayer().announceForAccessibility(confirmation); mContext.getDragLayer().announceForAccessibility(confirmation);
} }
public boolean isInAccessibleDrag() { public boolean isInAccessibleDrag() {
@@ -24,13 +24,14 @@ import com.android.launcher3.PendingAddItemInfo;
import com.android.launcher3.R; import com.android.launcher3.R;
import com.android.launcher3.Workspace; import com.android.launcher3.Workspace;
import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragOptions.PreDragCondition;
import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.Folder;
import com.android.launcher3.keyboard.KeyboardDragAndDropView; import com.android.launcher3.keyboard.KeyboardDragAndDropView;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemFactory;
import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.notification.NotificationListener; import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.popup.ArrowPopup; import com.android.launcher3.popup.ArrowPopup;
@@ -40,6 +41,7 @@ import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet; import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ShortcutUtil; import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.util.Thunk; import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.BubbleTextHolder;
import com.android.launcher3.views.OptionsPopupView; import com.android.launcher3.views.OptionsPopupView;
import com.android.launcher3.views.OptionsPopupView.OptionItem; import com.android.launcher3.views.OptionsPopupView.OptionItem;
import com.android.launcher3.widget.LauncherAppWidgetHostView; import com.android.launcher3.widget.LauncherAppWidgetHostView;
@@ -118,7 +120,7 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
} }
} }
if ((item instanceof AppInfo) || (item instanceof WorkspaceItemInfo) if ((item instanceof WorkspaceItemFactory) || (item instanceof WorkspaceItemInfo)
|| (item instanceof PendingAddItemInfo)) { || (item instanceof PendingAddItemInfo)) {
out.add(mActions.get(ADD_TO_WORKSPACE)); out.add(mActions.get(ADD_TO_WORKSPACE));
} }
@@ -143,13 +145,18 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
protected boolean performAction(final View host, final ItemInfo item, int action, protected boolean performAction(final View host, final ItemInfo item, int action,
boolean fromKeyboard) { boolean fromKeyboard) {
if (action == ACTION_LONG_CLICK) { if (action == ACTION_LONG_CLICK) {
if (PopupContainerWithArrow.canShow(host, item)) { PreDragCondition dragCondition = null;
// Long press should be consumed for workspace items, and it should invoke the // Long press should be consumed for workspace items, and it should invoke the
// Shortcuts / Notifications / Actions pop-up menu, and not start a drag as the // Shortcuts / Notifications / Actions pop-up menu, and not start a drag as the
// standard long press path does. // standard long press path does.
PopupContainerWithArrow.showForIcon((BubbleTextView) host); if (host instanceof BubbleTextView) {
return true; dragCondition = ((BubbleTextView) host).startLongPressAction();
} else if (host instanceof BubbleTextHolder) {
BubbleTextHolder holder = (BubbleTextHolder) host;
dragCondition = holder.getBubbleText() == null ? null
: holder.getBubbleText().startLongPressAction();
} }
return dragCondition != null;
} else if (action == MOVE) { } else if (action == MOVE) {
return beginAccessibleDrag(host, item, fromKeyboard); return beginAccessibleDrag(host, item, fromKeyboard);
} else if (action == ADD_TO_WORKSPACE) { } else if (action == ADD_TO_WORKSPACE) {
@@ -166,7 +173,10 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
popup.setOnCloseCallback(host::requestFocus); popup.setOnCloseCallback(host::requestFocus);
return true; return true;
} else if (action == DEEP_SHORTCUTS || action == SHORTCUTS_AND_NOTIFICATIONS) { } else if (action == DEEP_SHORTCUTS || action == SHORTCUTS_AND_NOTIFICATIONS) {
return PopupContainerWithArrow.showForIcon((BubbleTextView) host) != null; BubbleTextView btv = host instanceof BubbleTextView ? (BubbleTextView) host
: (host instanceof BubbleTextHolder
? ((BubbleTextHolder) host).getBubbleText() : null);
return btv != null && PopupContainerWithArrow.showForIcon(btv) != null;
} else { } else {
for (ButtonDropTarget dropTarget : mContext.getDropTargetBar().getDropTargets()) { for (ButtonDropTarget dropTarget : mContext.getDropTargetBar().getDropTargets()) {
if (dropTarget.supportsAccessibilityDrop(item, host) if (dropTarget.supportsAccessibilityDrop(item, host)
@@ -367,8 +377,8 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
return false; return false;
} }
mContext.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> { mContext.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> {
if (item instanceof AppInfo) { if (item instanceof WorkspaceItemFactory) {
WorkspaceItemInfo info = ((AppInfo) item).makeWorkspaceItem(); WorkspaceItemInfo info = ((WorkspaceItemFactory) item).makeWorkspaceItem(mContext);
mContext.getModelWriter().addItemToDatabase(info, mContext.getModelWriter().addItemToDatabase(info,
LauncherSettings.Favorites.CONTAINER_DESKTOP, LauncherSettings.Favorites.CONTAINER_DESKTOP,
screenId, coordinates[0], coordinates[1]); screenId, coordinates[0], coordinates[1]);
+3 -3
View File
@@ -88,10 +88,10 @@ import com.android.launcher3.logger.LauncherAtom.FromState;
import com.android.launcher3.logger.LauncherAtom.ToState; import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger; import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.FolderInfo.FolderListener; import com.android.launcher3.model.data.FolderInfo.FolderListener;
import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemFactory;
import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pageindicators.PageIndicatorDots; import com.android.launcher3.pageindicators.PageIndicatorDots;
import com.android.launcher3.util.Executors; import com.android.launcher3.util.Executors;
@@ -1283,9 +1283,9 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
final WorkspaceItemInfo si; final WorkspaceItemInfo si;
if (pasiSi != null) { if (pasiSi != null) {
si = pasiSi; si = pasiSi;
} else if (d.dragInfo instanceof AppInfo) { } else if (d.dragInfo instanceof WorkspaceItemFactory) {
// Came from all apps -- make a copy. // Came from all apps -- make a copy.
si = ((AppInfo) d.dragInfo).makeWorkspaceItem(); si = ((WorkspaceItemFactory) d.dragInfo).makeWorkspaceItem(launcher);
} else { } else {
// WorkspaceItemInfo // WorkspaceItemInfo
si = (WorkspaceItemInfo) d.dragInfo; si = (WorkspaceItemInfo) d.dragInfo;
@@ -68,11 +68,11 @@ import com.android.launcher3.logger.LauncherAtom.FromState;
import com.android.launcher3.logger.LauncherAtom.ToState; import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.logging.InstanceId; import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.FolderInfo.FolderListener; import com.android.launcher3.model.data.FolderInfo.FolderListener;
import com.android.launcher3.model.data.FolderInfo.LabelState; import com.android.launcher3.model.data.FolderInfo.LabelState;
import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemFactory;
import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.util.Executors; import com.android.launcher3.util.Executors;
@@ -284,7 +284,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
mBackground.animateToAccept(cl, lp.cellX, lp.cellY); mBackground.animateToAccept(cl, lp.cellX, lp.cellY);
mOpenAlarm.setOnAlarmListener(mOnOpenListener); mOpenAlarm.setOnAlarmListener(mOnOpenListener);
if (SPRING_LOADING_ENABLED && if (SPRING_LOADING_ENABLED &&
((dragInfo instanceof AppInfo) ((dragInfo instanceof WorkspaceItemFactory)
|| (dragInfo instanceof WorkspaceItemInfo) || (dragInfo instanceof WorkspaceItemInfo)
|| (dragInfo instanceof PendingAddShortcutInfo))) { || (dragInfo instanceof PendingAddShortcutInfo))) {
mOpenAlarm.setAlarm(ON_OPEN_DELAY); mOpenAlarm.setAlarm(ON_OPEN_DELAY);
@@ -486,9 +486,9 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
public void onDrop(DragObject d, boolean itemReturnedOnFailedDrop) { public void onDrop(DragObject d, boolean itemReturnedOnFailedDrop) {
WorkspaceItemInfo item; WorkspaceItemInfo item;
if (d.dragInfo instanceof AppInfo) { if (d.dragInfo instanceof WorkspaceItemFactory) {
// Came from all apps -- make a copy // Came from all apps -- make a copy
item = ((AppInfo) d.dragInfo).makeWorkspaceItem(); item = ((WorkspaceItemFactory) d.dragInfo).makeWorkspaceItem(getContext());
} else if (d.dragSource instanceof BaseItemDragListener){ } else if (d.dragSource instanceof BaseItemDragListener){
// Came from a different window -- make a copy // Came from a different window -- make a copy
item = new WorkspaceItemInfo((WorkspaceItemInfo) d.dragInfo); item = new WorkspaceItemInfo((WorkspaceItemInfo) d.dragInfo);
@@ -32,6 +32,7 @@ import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemFactory;
import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper; import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.pm.PackageInstallInfo; import com.android.launcher3.pm.PackageInstallInfo;
@@ -107,8 +108,8 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
} }
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
if (item instanceof AppInfo) { if (item instanceof WorkspaceItemFactory) {
item = ((AppInfo) item).makeWorkspaceItem(); item = ((WorkspaceItemFactory) item).makeWorkspaceItem(app.getContext());
} }
} }
if (item != null) { if (item != null) {
@@ -130,8 +131,8 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
if (item instanceof WorkspaceItemInfo || item instanceof FolderInfo || if (item instanceof WorkspaceItemInfo || item instanceof FolderInfo ||
item instanceof LauncherAppWidgetInfo) { item instanceof LauncherAppWidgetInfo) {
itemInfo = item; itemInfo = item;
} else if (item instanceof AppInfo) { } else if (item instanceof WorkspaceItemFactory) {
itemInfo = ((AppInfo) item).makeWorkspaceItem(); itemInfo = ((WorkspaceItemFactory) item).makeWorkspaceItem(app.getContext());
} else { } else {
throw new RuntimeException("Unexpected info type"); throw new RuntimeException("Unexpected info type");
} }
@@ -180,7 +181,7 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
// App was installed while launcher was in the background, // App was installed while launcher was in the background,
// or app was already installed for another user. // or app was already installed for another user.
itemInfo = new AppInfo(app.getContext(), activities.get(0), item.user) itemInfo = new AppInfo(app.getContext(), activities.get(0), item.user)
.makeWorkspaceItem(); .makeWorkspaceItem(app.getContext());
if (shortcutExists(dataModel, itemInfo.getIntent(), itemInfo.user)) { if (shortcutExists(dataModel, itemInfo.getIntent(), itemInfo.user)) {
// We need this additional check here since we treat all auto added // We need this additional check here since we treat all auto added
@@ -35,7 +35,6 @@ import androidx.annotation.VisibleForTesting;
import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings;
import com.android.launcher3.Utilities; import com.android.launcher3.Utilities;
import com.android.launcher3.pm.PackageInstallInfo; import com.android.launcher3.pm.PackageInstallInfo;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.PackageManagerHelper;
import java.util.Comparator; import java.util.Comparator;
@@ -43,7 +42,7 @@ import java.util.Comparator;
/** /**
* Represents an app in AllAppsView. * Represents an app in AllAppsView.
*/ */
public class AppInfo extends ItemInfoWithIcon { public class AppInfo extends ItemInfoWithIcon implements WorkspaceItemFactory {
public static final AppInfo[] EMPTY_ARRAY = new AppInfo[0]; public static final AppInfo[] EMPTY_ARRAY = new AppInfo[0];
public static final Comparator<AppInfo> COMPONENT_KEY_COMPARATOR = (a, b) -> { public static final Comparator<AppInfo> COMPONENT_KEY_COMPARATOR = (a, b) -> {
@@ -121,7 +120,8 @@ public class AppInfo extends ItemInfoWithIcon {
return super.dumpProperties() + " componentName=" + componentName; return super.dumpProperties() + " componentName=" + componentName;
} }
public WorkspaceItemInfo makeWorkspaceItem() { @Override
public WorkspaceItemInfo makeWorkspaceItem(Context context) {
WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(this); WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(this);
if ((runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0) { if ((runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0) {
@@ -139,10 +139,6 @@ public class AppInfo extends ItemInfoWithIcon {
return workspaceItemInfo; return workspaceItemInfo;
} }
public ComponentKey toComponentKey() {
return new ComponentKey(componentName, user);
}
public static Intent makeLaunchIntent(LauncherActivityInfo info) { public static Intent makeLaunchIntent(LauncherActivityInfo info) {
return makeLaunchIntent(info.getComponentName()); return makeLaunchIntent(info.getComponentName());
} }
@@ -18,6 +18,7 @@ package com.android.launcher3.model.data;
import static com.android.launcher3.LauncherSettings.Favorites.EXTENDED_CONTAINERS; import static com.android.launcher3.LauncherSettings.Favorites.EXTENDED_CONTAINERS;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Icon; import android.graphics.drawable.Icon;
import android.os.Process; import android.os.Process;
@@ -26,18 +27,14 @@ import android.os.UserHandle;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings;
import com.android.launcher3.logger.LauncherAtom.ItemInfo; import com.android.launcher3.logger.LauncherAtom.ItemInfo;
import com.android.launcher3.logger.LauncherAtom.SearchActionItem; import com.android.launcher3.logger.LauncherAtom.SearchActionItem;
import com.android.launcher3.model.AllAppsList;
import com.android.launcher3.model.BaseModelUpdateTask;
import com.android.launcher3.model.BgDataModel;
/** /**
* Represents a SearchAction with in launcher * Represents a SearchAction with in launcher
*/ */
public class SearchActionItemInfo extends ItemInfoWithIcon { public class SearchActionItemInfo extends ItemInfoWithIcon implements WorkspaceItemFactory {
public static final int FLAG_SHOULD_START = 1 << 1; public static final int FLAG_SHOULD_START = 1 << 1;
public static final int FLAG_SHOULD_START_FOR_RESULT = FLAG_SHOULD_START | 1 << 2; public static final int FLAG_SHOULD_START_FOR_RESULT = FLAG_SHOULD_START | 1 << 2;
@@ -158,7 +155,8 @@ public class SearchActionItemInfo extends ItemInfoWithIcon {
/** /**
* Creates a {@link WorkspaceItemInfo} coorsponding to search action to be stored in launcher db * Creates a {@link WorkspaceItemInfo} coorsponding to search action to be stored in launcher db
*/ */
public WorkspaceItemInfo createWorkspaceItem(LauncherModel model) { @Override
public WorkspaceItemInfo makeWorkspaceItem(Context context) {
WorkspaceItemInfo info = new WorkspaceItemInfo(); WorkspaceItemInfo info = new WorkspaceItemInfo();
info.title = title; info.title = title;
info.bitmap = bitmap; info.bitmap = bitmap;
@@ -167,18 +165,12 @@ public class SearchActionItemInfo extends ItemInfoWithIcon {
if (hasFlags(FLAG_SHOULD_START_FOR_RESULT)) { if (hasFlags(FLAG_SHOULD_START_FOR_RESULT)) {
info.options |= WorkspaceItemInfo.FLAG_START_FOR_RESULT; info.options |= WorkspaceItemInfo.FLAG_START_FOR_RESULT;
} }
LauncherAppState app = LauncherAppState.getInstance(context);
model.enqueueModelUpdateTask(new BaseModelUpdateTask() { app.getModel().updateAndBindWorkspaceItem(() -> {
@Override PackageItemInfo pkgInfo = new PackageItemInfo(getIntentPackageName(), user);
public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) { app.getIconCache().getTitleAndIconForApp(pkgInfo, false);
info.bitmap = info.bitmap.withBadgeInfo(pkgInfo.bitmap);
model.updateAndBindWorkspaceItem(() -> { return info;
PackageItemInfo pkgInfo = new PackageItemInfo(getIntentPackageName(), user);
app.getIconCache().getTitleAndIconForApp(pkgInfo, false);
info.bitmap = info.bitmap.withBadgeInfo(pkgInfo.bitmap);
return info;
});
}
}); });
return info; return info;
} }
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2022 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.launcher3.model.data;
import android.content.Context;
/**
* Interface to objects capable of generating workspace item
*/
public interface WorkspaceItemFactory {
/**
* Called to create a pinnable item info
*/
WorkspaceItemInfo makeWorkspaceItem(Context context);
}
@@ -187,7 +187,10 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
/** /**
* Returns true if we can show the container. * Returns true if we can show the container.
*
* @deprecated Left here since some dependent projects are using this method
*/ */
@Deprecated
public static boolean canShow(View icon, ItemInfo item) { public static boolean canShow(View icon, ItemInfo item) {
return icon instanceof BubbleTextView && ShortcutUtil.supportsShortcuts(item); return icon instanceof BubbleTextView && ShortcutUtil.supportsShortcuts(item);
} }
@@ -204,7 +207,7 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
return null; return null;
} }
ItemInfo item = (ItemInfo) icon.getTag(); ItemInfo item = (ItemInfo) icon.getTag();
if (!canShow(icon, item)) { if (!ShortcutUtil.supportsShortcuts(item)) {
return null; return null;
} }
@@ -538,7 +541,7 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
public static void dismissInvalidPopup(BaseDraggingActivity activity) { public static void dismissInvalidPopup(BaseDraggingActivity activity) {
PopupContainerWithArrow popup = getOpen(activity); PopupContainerWithArrow popup = getOpen(activity);
if (popup != null && (!popup.mOriginalIcon.isAttachedToWindow() if (popup != null && (!popup.mOriginalIcon.isAttachedToWindow()
|| !canShow(popup.mOriginalIcon, (ItemInfo) popup.mOriginalIcon.getTag()))) { || !ShortcutUtil.supportsShortcuts((ItemInfo) popup.mOriginalIcon.getTag()))) {
popup.animateClose(); popup.animateClose();
} }
} }
@@ -100,8 +100,7 @@ public class ItemClickHandler {
onClickFolderIcon(v); onClickFolderIcon(v);
} }
} else if (tag instanceof AppInfo) { } else if (tag instanceof AppInfo) {
startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher);
);
} else if (tag instanceof LauncherAppWidgetInfo) { } else if (tag instanceof LauncherAppWidgetInfo) {
if (v instanceof PendingAppWidgetHostView) { if (v instanceof PendingAppWidgetHostView) {
onClickPendingWidget((PendingAppWidgetHostView) v, launcher); onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
@@ -37,6 +37,7 @@ import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.views.BubbleTextHolder;
/** /**
* Class to handle long-clicks on workspace items and start drag as a result. * Class to handle long-clicks on workspace items and start drag as a result.
@@ -79,9 +80,12 @@ public class ItemLongClickListener {
launcher.getWorkspace().startDrag(longClickCellInfo, dragOptions); launcher.getWorkspace().startDrag(longClickCellInfo, dragOptions);
} }
private static boolean onAllAppsItemLongClick(View v) { private static boolean onAllAppsItemLongClick(View view) {
TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onAllAppsItemLongClick"); TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onAllAppsItemLongClick");
v.cancelLongPress(); view.cancelLongPress();
View v = (view instanceof BubbleTextHolder)
? ((BubbleTextHolder) view).getBubbleText()
: view;
Launcher launcher = Launcher.getLauncher(v.getContext()); Launcher launcher = Launcher.getLauncher(v.getContext());
if (!canStartDrag(launcher)) return false; if (!canStartDrag(launcher)) return false;
// When we have exited all apps or are in transition, disregard long clicks // When we have exited all apps or are in transition, disregard long clicks
@@ -16,8 +16,6 @@
package com.android.launcher3.views; package com.android.launcher3.views;
import com.android.launcher3.BubbleTextView; import com.android.launcher3.BubbleTextView;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
/** /**
* Views that contain {@link BubbleTextView} should implement this interface. * Views that contain {@link BubbleTextView} should implement this interface.
@@ -25,14 +23,6 @@ import com.android.launcher3.model.data.ItemInfoWithIcon;
public interface BubbleTextHolder extends IconLabelDotView { public interface BubbleTextHolder extends IconLabelDotView {
BubbleTextView getBubbleText(); BubbleTextView getBubbleText();
/**
* Called when new {@link ItemInfo} is set to {@link BubbleTextView}
*
* @param itemInfo the new itemInfo
*/
default void onItemInfoUpdated(ItemInfoWithIcon itemInfo) {
}
@Override @Override
default void setIconVisible(boolean visible) { default void setIconVisible(boolean visible) {
getBubbleText().setIconVisible(visible); getBubbleText().setIconVisible(visible);