From 5a01f0ec51577582ed2433fbeafb1caa517e3440 Mon Sep 17 00:00:00 2001 From: thiruram Date: Mon, 4 May 2020 17:49:37 -0700 Subject: [PATCH] Implements LAUNCHER_ITEM_DROP_FOLDER_CREATED event. When item is dropped on a existing item resulting in new folder creation, triggers LAUNCHER_ITEM_DROP_FOLDER_CREATED event with details of the destination package. This change also introduces new FolderIcon item to launcher_atom.proto to represent folder icon. Screencast and sample logs: https://docs.google.com/document/d/1CBP2yTcXdFhPdNG5ZmWFKSgd8mDbMevY-akVlUXPLDo/edit#bookmark=id.tmbucd1f44qp Bug: 152978018 Change-Id: Ib4d343ba9075aa8853652f128457c4638541ec59 --- protos/launcher_atom.proto | 6 ++ src/com/android/launcher3/DropTarget.java | 2 +- src/com/android/launcher3/Workspace.java | 29 ++++++--- .../launcher3/dragndrop/DragController.java | 3 +- src/com/android/launcher3/folder/Folder.java | 5 ++ .../android/launcher3/folder/FolderIcon.java | 2 +- .../launcher3/logging/StatsLogManager.java | 5 +- .../launcher3/model/data/FolderInfo.java | 17 +++++ .../launcher3/model/data/ItemInfo.java | 62 ++++++++++++------- 9 files changed, 96 insertions(+), 35 deletions(-) diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto index 036fb02243..cac2d8f5a7 100644 --- a/protos/launcher_atom.proto +++ b/protos/launcher_atom.proto @@ -26,6 +26,7 @@ message ItemInfo { Task task = 2; Shortcut shortcut = 3; Widget widget = 4; + FolderIcon folder_icon = 9; } // When used for launch event, stores the global predictive rank optional int32 rank = 5; @@ -92,6 +93,11 @@ message Task { optional int32 index = 3; } +// Represents folder in a closed state. +message FolderIcon { + optional int32 cardinality = 1; +} + ////////////////////////////////////////////// // Containers diff --git a/src/com/android/launcher3/DropTarget.java b/src/com/android/launcher3/DropTarget.java index 6cb803a12c..0b0983cbee 100644 --- a/src/com/android/launcher3/DropTarget.java +++ b/src/com/android/launcher3/DropTarget.java @@ -78,7 +78,7 @@ public interface DropTarget { public DraggableView originalView = null; /** Used for matching DROP event with its corresponding DRAG event on the server side. */ - final InstanceId mLogInstanceId = + public final InstanceId logInstanceId = new InstanceIdSequence(1 << 20 /*InstanceId.INSTANCE_ID_MAX*/) .newInstanceId(); diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index dd00bd302d..412eef104d 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -416,8 +416,12 @@ public class Workspace extends PagedView mLauncher.getStateManager().goToState(SPRING_LOADED); mStatsLogManager.log( LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED, - dragObject.mLogInstanceId, - dragObject.originalDragInfo.buildProto(null)); + dragObject.logInstanceId, + dragObject.originalDragInfo.buildProto( + dragObject.dragSource instanceof Folder + ? ((Folder) dragObject.dragSource).mInfo + : null) + ); } public void deferRemoveExtraEmptyScreen() { @@ -1645,7 +1649,10 @@ public class Workspace extends PagedView Rect folderLocation = new Rect(); float scale = mLauncher.getDragLayer().getDescendantRectRelativeToSelf(v, folderLocation); target.removeView(v); - + mStatsLogManager.log( + LauncherEvent.LAUNCHER_ITEM_DROP_FOLDER_CREATED, + d.logInstanceId, + destInfo.buildProto(null)); FolderIcon fi = mLauncher.addFolder(target, container, screenId, targetCell[0], targetCell[1]); destInfo.cellX = -1; @@ -1683,6 +1690,10 @@ public class Workspace extends PagedView if (dropOverView instanceof FolderIcon) { FolderIcon fi = (FolderIcon) dropOverView; if (fi.acceptDrop(d.dragInfo)) { + mStatsLogManager.log( + LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED, + d.logInstanceId, + fi.mInfo.buildProto(null)); fi.onDrop(d, false /* itemReturnedOnFailedDrop */); // if the drag started here, we need to remove it from the workspace @@ -1885,15 +1896,15 @@ public class Workspace extends PagedView mLauncher.getStateManager().goToState( NORMAL, SPRING_LOADED_EXIT_DELAY, onCompleteRunnable); + mStatsLogManager.log( + LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED, + d.logInstanceId, + d.dragInfo.buildProto(null)); } if (d.stateAnnouncer != null && !droppedOnOriginalCell) { d.stateAnnouncer.completeAction(R.string.item_moved); } - mStatsLogManager.log( - LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED, - d.mLogInstanceId, - d.dragInfo.buildProto(null)); } public void onNoCellFound(View dropTargetLayout) { @@ -2515,6 +2526,10 @@ public class Workspace extends PagedView resetTransitionTransform(); } } + mStatsLogManager.log( + LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED, + d.logInstanceId, + d.dragInfo.buildProto(null)); } public Bitmap createWidgetBitmap(ItemInfo widgetInfo, View layout) { diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index d93fb1a6cd..03028d3a86 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -186,8 +186,7 @@ public class DragController implements DragDriver.EventListener, TouchController mDragObject.dragSource = source; mDragObject.dragInfo = dragInfo; - mDragObject.originalDragInfo = new ItemInfo(); - mDragObject.originalDragInfo.copyFrom(dragInfo); + mDragObject.originalDragInfo = mDragObject.dragInfo.makeShallowCopy(); if (dragOffset != null) { dragView.setDragVisualizeOffset(new Point(dragOffset)); diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index c2871906e1..9a36b3ed7c 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -87,6 +87,7 @@ import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragController.DragListener; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.dragndrop.DragOptions; +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.FolderListener; @@ -1346,6 +1347,10 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo if (d.stateAnnouncer != null) { d.stateAnnouncer.completeAction(R.string.item_moved); } + StatsLogManager.newInstance(getContext()) + .log(StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED, + d.logInstanceId, + d.dragInfo.buildProto(mInfo)); } // This is used so the item doesn't immediately appear in the folder when added. In one case diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index b875a0b4cc..e2963d7cd9 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -85,7 +85,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel @Thunk ActivityContext mActivity; @Thunk Folder mFolder; - private FolderInfo mInfo; + public FolderInfo mInfo; private CheckLongPressHelper mLongPressHelper; diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java index 62a3829d04..abf027dc08 100644 --- a/src/com/android/launcher3/logging/StatsLogManager.java +++ b/src/com/android/launcher3/logging/StatsLogManager.java @@ -47,7 +47,10 @@ public class StatsLogManager implements ResourceBasedOverride { @LauncherUiEvent(doc = "User dragged a launcher item") LAUNCHER_ITEM_DRAG_STARTED(383), @LauncherUiEvent(doc = "A dragged launcher item is successfully dropped") - LAUNCHER_ITEM_DROP_COMPLETED(385); + LAUNCHER_ITEM_DROP_COMPLETED(385), + @LauncherUiEvent(doc = "A dragged launcher item is successfully dropped on another item " + + "resulting in new folder creation") + LAUNCHER_ITEM_DROP_FOLDER_CREATED(386); // ADD MORE private final int mId; diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java index cfe34c1fc0..3ac6a2213b 100644 --- a/src/com/android/launcher3/model/data/FolderInfo.java +++ b/src/com/android/launcher3/model/data/FolderInfo.java @@ -21,6 +21,7 @@ import android.os.Process; import com.android.launcher3.LauncherSettings; import com.android.launcher3.Utilities; +import com.android.launcher3.logger.LauncherAtom; import com.android.launcher3.model.ModelWriter; import com.android.launcher3.util.ContentWriter; @@ -155,4 +156,20 @@ public class FolderInfo extends ItemInfo { return super.dumpProperties() + " manuallyTypedTitle=" + hasOption(FLAG_MANUAL_FOLDER_NAME); } + + @Override + public LauncherAtom.ItemInfo buildProto(FolderInfo fInfo) { + return getDefaultItemInfoBuilder() + .setFolderIcon(LauncherAtom.FolderIcon.newBuilder().setCardinality(contents.size())) + .setContainerInfo(getContainerInfo()) + .build(); + } + + @Override + public ItemInfo makeShallowCopy() { + FolderInfo folderInfo = new FolderInfo(); + folderInfo.copyFrom(this); + folderInfo.contents = this.contents; + return folderInfo; + } } diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java index 12ea888c4f..4359f251cc 100644 --- a/src/com/android/launcher3/model/data/ItemInfo.java +++ b/src/com/android/launcher3/model/data/ItemInfo.java @@ -253,8 +253,7 @@ public class ItemInfo { * Creates {@link LauncherAtom.ItemInfo} with important fields and parent container info. */ public LauncherAtom.ItemInfo buildProto(FolderInfo fInfo) { - LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder(); - itemBuilder.setIsWork(user != Process.myUserHandle()); + LauncherAtom.ItemInfo.Builder itemBuilder = getDefaultItemInfoBuilder(); Optional nullableComponent = Optional.ofNullable(getTargetComponent()); switch (itemType) { case ITEM_TYPE_APPLICATION: @@ -305,28 +304,45 @@ public class ItemInfo { } itemBuilder.setContainerInfo(ContainerInfo.newBuilder().setFolder(folderBuilder)); } else { - switch (container) { - case CONTAINER_HOTSEAT: - case CONTAINER_HOTSEAT_PREDICTION: - itemBuilder.setContainerInfo( - ContainerInfo.newBuilder().setHotseat( - LauncherAtom.HotseatContainer.newBuilder().setIndex(screenId))); - break; - case CONTAINER_DESKTOP: - itemBuilder.setContainerInfo( - ContainerInfo.newBuilder().setWorkspace( - LauncherAtom.WorkspaceContainer.newBuilder() - .setGridX(cellX) - .setGridY(cellY) - .setPageIndex(screenId))); - break; - case CONTAINER_ALL_APPS: - itemBuilder.setContainerInfo( - ContainerInfo.newBuilder().setAllAppsContainer( - AllAppsContainer.getDefaultInstance())); - break; - } + itemBuilder.setContainerInfo(getContainerInfo()); } return itemBuilder.build(); } + + LauncherAtom.ItemInfo.Builder getDefaultItemInfoBuilder() { + LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder(); + itemBuilder.setIsWork(user != Process.myUserHandle()); + return itemBuilder; + } + + ContainerInfo getContainerInfo() { + switch (container) { + case CONTAINER_HOTSEAT: + case CONTAINER_HOTSEAT_PREDICTION: + return ContainerInfo.newBuilder() + .setHotseat(LauncherAtom.HotseatContainer.newBuilder().setIndex(screenId)) + .build(); + case CONTAINER_DESKTOP: + return ContainerInfo.newBuilder() + .setWorkspace( + LauncherAtom.WorkspaceContainer.newBuilder() + .setGridX(cellX) + .setGridY(cellY) + .setPageIndex(screenId)) + .build(); + case CONTAINER_ALL_APPS: + return ContainerInfo.newBuilder() + .setAllAppsContainer( + AllAppsContainer.getDefaultInstance()) + .build(); + } + return ContainerInfo.getDefaultInstance(); + } + + /** Returns shallow copy of the object. */ + public ItemInfo makeShallowCopy() { + ItemInfo itemInfo = new ItemInfo(); + itemInfo.copyFrom(this); + return itemInfo; + } }