Log dismissing or launching recent tasks
We now pass the log action (e.g. SWIPE or FLING) to the pending
animation, so that the end listener can log appropriately. This
is used when swiping down or up on a task, for example.
Bug: 73783784
Change-Id: I5c2eee24e8b23cf4af68d503d3435a6d8088dd8a
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
index 1b65ca0..5971576 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
@@ -37,6 +37,7 @@
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SwipeDetector;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.quickstep.TouchInteractionService;
import com.android.quickstep.util.SysuiEventLogger;
@@ -182,7 +183,7 @@
}
if (mPendingAnimation != null) {
- mPendingAnimation.finish(false);
+ mPendingAnimation.finish(false, Touch.SWIPE);
mPendingAnimation = null;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
index e73b219..84a60bd 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
@@ -30,11 +30,10 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.touch.SwipeDetector;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.launcher3.util.PendingAnimation;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
-import com.android.launcher3.util.PendingAnimation;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -152,7 +151,7 @@
mCurrentAnimation.setPlayFraction(0);
}
if (mPendingAnimation != null) {
- mPendingAnimation.finish(false);
+ mPendingAnimation.finish(false, Touch.SWIPE);
mPendingAnimation = null;
}
@@ -249,15 +248,9 @@
private void onCurrentAnimationEnd(boolean wasSuccess, int logAction) {
if (mPendingAnimation != null) {
- mPendingAnimation.finish(wasSuccess);
+ mPendingAnimation.finish(wasSuccess, logAction);
mPendingAnimation = null;
}
- if (wasSuccess) {
- if (!mCurrentAnimationIsGoingUp) {
- mActivity.getUserEventDispatcher().logTaskLaunch(logAction,
- Direction.DOWN, mTaskBeingDragged.getTask().getTopComponent());
- }
- }
mDetector.finishedScrolling();
mTaskBeingDragged = null;
mCurrentAnimation = null;
diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java
index 2df951b..5bf1d07 100644
--- a/quickstep/src/com/android/quickstep/TaskUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskUtils.java
@@ -24,6 +24,7 @@
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.util.ComponentKey;
import com.android.systemui.shared.recents.model.Task;
/**
@@ -48,4 +49,8 @@
return userManagerCompat.getBadgedLabelForUser(
applicationInfo.loadLabel(packageManager), user);
}
+
+ public static ComponentKey getComponentKeyForTask(Task.TaskKey taskKey) {
+ return new ComponentKey(taskKey.getComponent(), UserHandle.of(taskKey.userId));
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index d95619c..b22e2b6 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -59,12 +59,15 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PropertyListBuilder;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.PendingAnimation;
import com.android.launcher3.util.Themes;
import com.android.quickstep.QuickScrubController;
import com.android.quickstep.RecentsAnimationInterpolator;
import com.android.quickstep.RecentsAnimationInterpolator.TaskWindowBounds;
import com.android.quickstep.RecentsModel;
+import com.android.quickstep.TaskUtils;
import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan;
import com.android.systemui.shared.recents.model.RecentsTaskLoader;
import com.android.systemui.shared.recents.model.Task;
@@ -324,7 +327,7 @@
private void applyLoadPlan(RecentsTaskLoadPlan loadPlan) {
if (mPendingAnimation != null) {
- mPendingAnimation.addEndListener((b) -> applyLoadPlan(loadPlan));
+ mPendingAnimation.addEndListener((onEndListener) -> applyLoadPlan(loadPlan));
return;
}
TaskStack stack = loadPlan != null ? loadPlan.getTaskStack() : null;
@@ -748,10 +751,16 @@
}
mPendingAnimation = pendingAnimation;
- mPendingAnimation.addEndListener((isSuccess) -> {
- if (isSuccess) {
+ mPendingAnimation.addEndListener((onEndListener) -> {
+ if (onEndListener.isSuccess) {
if (removeTask) {
- ActivityManagerWrapper.getInstance().removeTask(taskView.getTask().key.id);
+ Task task = taskView.getTask();
+ if (task != null) {
+ ActivityManagerWrapper.getInstance().removeTask(task.key.id);
+ mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
+ onEndListener.logAction, Direction.UP,
+ TaskUtils.getComponentKeyForTask(task.key));
+ }
}
removeView(taskView);
if (getChildCount() == 0) {
@@ -793,7 +802,7 @@
AnimatorPlaybackController controller = AnimatorPlaybackController.wrap(
pendingAnim.anim, DISMISS_TASK_DURATION);
controller.dispatchOnStart();
- controller.setEndAction(() -> pendingAnim.finish(true));
+ controller.setEndAction(() -> pendingAnim.finish(true, Touch.SWIPE));
controller.getAnimationPlayer().setInterpolator(FAST_OUT_SLOW_IN);
controller.start();
}
@@ -1050,9 +1059,15 @@
anim.setDuration(duration);
mPendingAnimation = new PendingAnimation(anim);
- mPendingAnimation.addEndListener((isSuccess) -> {
- if (isSuccess) {
+ mPendingAnimation.addEndListener((onEndListener) -> {
+ if (onEndListener.isSuccess) {
tv.launchTask(false);
+ Task task = tv.getTask();
+ if (task != null) {
+ mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
+ onEndListener.logAction, Direction.DOWN,
+ TaskUtils.getComponentKeyForTask(task.key));
+ }
} else {
resetTaskVisuals();
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 42da472..c04f825 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -31,11 +31,15 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
+import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.quickstep.RecentsAnimationInterpolator;
import com.android.quickstep.TaskSystemShortcut;
+import com.android.quickstep.TaskUtils;
import com.android.quickstep.views.RecentsView.PageCallbacks;
import com.android.quickstep.views.RecentsView.ScrollState;
import com.android.systemui.shared.recents.model.Task;
@@ -82,7 +86,13 @@
public TaskView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- setOnClickListener((view) -> launchTask(true /* animate */));
+ setOnClickListener((view) -> {
+ if (mTask != null) {
+ launchTask(true /* animate */);
+ BaseActivity.fromContext(context).getUserEventDispatcher().logTaskLaunchOrDismiss(
+ Touch.TAP, Direction.NONE, TaskUtils.getComponentKeyForTask(mTask.key));
+ }
+ });
setOutlineProvider(new TaskOutlineProvider(getResources()));
}
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index 90355bd..bf870cc 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -16,6 +16,14 @@
package com.android.launcher3.logging;
+import static com.android.launcher3.logging.LoggerUtils.newCommandAction;
+import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.logging.LoggerUtils.newDropTarget;
+import static com.android.launcher3.logging.LoggerUtils.newItemTarget;
+import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
+import static com.android.launcher3.logging.LoggerUtils.newTarget;
+import static com.android.launcher3.logging.LoggerUtils.newTouchAction;
+
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -38,20 +46,13 @@
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
+import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.LogConfig;
import java.util.Locale;
import java.util.UUID;
-import static com.android.launcher3.logging.LoggerUtils.newCommandAction;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-import static com.android.launcher3.logging.LoggerUtils.newDropTarget;
-import static com.android.launcher3.logging.LoggerUtils.newItemTarget;
-import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
-import static com.android.launcher3.logging.LoggerUtils.newTarget;
-import static com.android.launcher3.logging.LoggerUtils.newTouchAction;
-
/**
* Manages the creation of {@link LauncherEvent}.
* To debug this class, execute following command before side loading a new apk.
@@ -162,14 +163,15 @@
dispatchUserEvent(event, intent);
}
- public void logTaskLaunch(int action, int direction, ComponentName componentName){
- LauncherEvent event = newLauncherEvent(newTouchAction(action), // TAP or SWIPE
+ public void logTaskLaunchOrDismiss(int action, int direction, ComponentKey componentKey) {
+ LauncherEvent event = newLauncherEvent(newTouchAction(action), // TAP or SWIPE or FLING
newTarget(Target.Type.ITEM));
if (action == Action.Touch.SWIPE || action == Action.Touch.FLING) {
+ // Direction DOWN means the task was launched, UP means it was dismissed.
event.action.dir = direction;
}
event.srcTarget[0].itemType = LauncherLogProto.ItemType.TASK;
- fillComponentInfo(event.srcTarget[0], componentName);
+ fillComponentInfo(event.srcTarget[0], componentKey.componentName);
dispatchUserEvent(event, null);
}
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 9726704..c875cf9 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -246,24 +246,24 @@
}
protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
- if (targetState != mFromState) {
- // Transition complete. log the action
- mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
- getDirectionForLog(),
- mStartContainerType,
- mFromState.containerType,
- mToState.containerType,
- mLauncher.getWorkspace().getCurrentPage());
- }
clearState();
boolean shouldGoToTargetState = true;
if (mPendingAnimation != null) {
boolean reachedTarget = mToState == targetState;
- mPendingAnimation.finish(reachedTarget);
+ mPendingAnimation.finish(reachedTarget, logAction);
mPendingAnimation = null;
shouldGoToTargetState = !reachedTarget;
}
if (shouldGoToTargetState) {
+ if (targetState != mFromState) {
+ // Transition complete. log the action
+ mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
+ getDirectionForLog(),
+ mStartContainerType,
+ mFromState.containerType,
+ mToState.containerType,
+ mLauncher.getWorkspace().getCurrentPage());
+ }
mLauncher.getStateManager().goToState(targetState, false /* animated */);
}
}
diff --git a/src/com/android/launcher3/util/PendingAnimation.java b/src/com/android/launcher3/util/PendingAnimation.java
index 4116d56..617a38b 100644
--- a/src/com/android/launcher3/util/PendingAnimation.java
+++ b/src/com/android/launcher3/util/PendingAnimation.java
@@ -32,7 +32,7 @@
@TargetApi(Build.VERSION_CODES.O)
public class PendingAnimation {
- private final ArrayList<Consumer<Boolean>> mEndListeners = new ArrayList<>();
+ private final ArrayList<Consumer<OnEndListener>> mEndListeners = new ArrayList<>();
public final AnimatorSet anim;
@@ -40,14 +40,24 @@
this.anim = anim;
}
- public void finish(boolean isSuccess) {
- for (Consumer<Boolean> listeners : mEndListeners) {
- listeners.accept(isSuccess);
+ public void finish(boolean isSuccess, int logAction) {
+ for (Consumer<OnEndListener> listeners : mEndListeners) {
+ listeners.accept(new OnEndListener(isSuccess, logAction));
}
mEndListeners.clear();
}
- public void addEndListener(Consumer<Boolean> listener) {
+ public void addEndListener(Consumer<OnEndListener> listener) {
mEndListeners.add(listener);
}
+
+ public static class OnEndListener {
+ public boolean isSuccess;
+ public int logAction;
+
+ public OnEndListener(boolean isSuccess, int logAction) {
+ this.isSuccess = isSuccess;
+ this.logAction = logAction;
+ }
+ }
}