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
This commit is contained in:
thiruram 2020-05-04 17:49:37 -07:00
parent d13dd3bc44
commit 5a01f0ec51
9 changed files with 96 additions and 35 deletions

View File

@ -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

View File

@ -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();

View File

@ -416,8 +416,12 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
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<WorkspacePageIndicator>
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<WorkspacePageIndicator>
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<WorkspacePageIndicator>
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<WorkspacePageIndicator>
resetTransitionTransform();
}
}
mStatsLogManager.log(
LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
d.logInstanceId,
d.dragInfo.buildProto(null));
}
public Bitmap createWidgetBitmap(ItemInfo widgetInfo, View layout) {

View File

@ -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));

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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<ComponentName> 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;
}
}