Improve Task user event logging
Bug: 79539824
Bug: 79541772

(1) Added page index of the TASK that is being launched
(2) Covers all three cases of task launch (tap, swipe down, quick scrub)
UserEvent: action:FLING direction=DOWN
UserEvent:  Source child:TASK, packageHash=-1598699687, componentHash=1952702153, pageIdx=0

UserEvent: action:DRAGDROP
UserEvent:  Source child:TASK, packageHash=-744307622, componentHash=-515832044, pageIdx=4

(3) Avoid double logging (When onStop is called, it is not logged if
the cause of onStop is APP or TASK launch)

Change-Id: Ic5db7d6a640d43bfb5cd667b49e37dd0ed127d5c
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index 8398c48..5ddd904 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -26,9 +26,8 @@
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.OnAlarmListener;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
 
@@ -124,9 +123,9 @@
                 mOnFinishedTransitionToQuickScrubRunnable = launchTaskRunnable;
             }
         }
-        mActivity.getUserEventDispatcher().logActionOnControl(Touch.DRAGDROP,
-                ControlType.QUICK_SCRUB_BUTTON, null, mStartedFromHome ?
-                        ContainerType.WORKSPACE : ContainerType.APP);
+        mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(Touch.DRAGDROP,
+                LauncherLogProto.Action.Direction.NONE, page,
+                TaskUtils.getComponentKeyForTask(mRecentsView.getPageAt(page).getTask().key));
     }
 
     /**
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 5c7118f..68432ab 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -418,6 +418,7 @@
         final int requiredChildCount = tasks.size();
         for (int i = getChildCount(); i < requiredChildCount; i++) {
             final TaskView taskView = (TaskView) inflater.inflate(R.layout.task, this, false);
+            taskView.setOnClickListener(this::onTaskClicked);
             addView(taskView);
         }
         while (getChildCount() > requiredChildCount) {
@@ -443,6 +444,17 @@
         onTaskStackUpdated();
     }
 
+    private void onTaskClicked(View v) {
+        TaskView taskView = (TaskView) v;
+        if (taskView.getTask() == null) {
+            return;
+        }
+        taskView.launchTask(true /* animate */);
+        mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
+                Touch.TAP, Direction.NONE, indexOfChild(taskView),
+                TaskUtils.getComponentKeyForTask(taskView.getTask().key));
+    }
+
     protected void onTaskStackUpdated() { }
 
     public void resetTaskVisuals() {
@@ -745,13 +757,13 @@
                 duration, LINEAR, anim);
     }
 
-    private void removeTask(Task task, PendingAnimation.OnEndListener onEndListener,
-            boolean shouldLog) {
+    private void removeTask(Task task, int index, PendingAnimation.OnEndListener onEndListener,
+                            boolean shouldLog) {
         if (task != null) {
             ActivityManagerWrapper.getInstance().removeTask(task.key.id);
             if (shouldLog) {
                 mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
-                        onEndListener.logAction, Direction.UP,
+                        onEndListener.logAction, Direction.UP, index,
                         TaskUtils.getComponentKeyForTask(task.key));
             }
         }
@@ -836,7 +848,7 @@
         mPendingAnimation.addEndListener((onEndListener) -> {
            if (onEndListener.isSuccess) {
                if (shouldRemoveTask) {
-                   removeTask(taskView.getTask(), onEndListener, true);
+                   removeTask(taskView.getTask(), draggedIndex, onEndListener, true);
                }
                int pageToSnapTo = mCurrentPage;
                if (draggedIndex < pageToSnapTo) {
@@ -872,7 +884,7 @@
             if (onEndListener.isSuccess) {
                 while (getChildCount() != 0) {
                     TaskView taskView = getPageAt(getChildCount() - 1);
-                    removeTask(taskView.getTask(), onEndListener, false);
+                    removeTask(taskView.getTask(), -1, onEndListener, false);
                     removeView(taskView);
                 }
                 onAllTasksRemoved();
@@ -1204,7 +1216,7 @@
                 Task task = tv.getTask();
                 if (task != null) {
                     mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
-                            onEndListener.logAction, Direction.DOWN,
+                            onEndListener.logAction, Direction.DOWN, indexOfChild(tv),
                             TaskUtils.getComponentKeyForTask(task.key));
                 }
             } else {
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 4b2ca45..0ddeae7 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -110,13 +110,6 @@
 
     public TaskView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        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/Launcher.java b/src/com/android/launcher3/Launcher.java
index bf73149..e851499 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -240,7 +240,6 @@
     private PendingRequestArgs mPendingRequestArgs;
 
     public ViewGroupFocusHelper mFocusHandler;
-    private boolean mAppLaunchSuccess;
 
     private RotationHelper mRotationHelper;
 
@@ -730,10 +729,8 @@
         }
         mAppWidgetHost.setListenIfResumed(false);
 
-        if (!mAppLaunchSuccess) {
-            getUserEventDispatcher().logActionCommand(Action.Command.STOP,
-                    mStateManager.getState().containerType, -1);
-        }
+        getUserEventDispatcher().logActionCommand(Action.Command.STOP,
+                mStateManager.getState().containerType, -1);
         NotificationListener.removeNotificationsChangedListener();
         getStateManager().moveToRestState();
 
@@ -760,7 +757,6 @@
         super.onResume();
         TraceHelper.partitionSection("ON_RESUME", "superCall");
 
-        mAppLaunchSuccess = false;
         getUserEventDispatcher().resetElapsedSessionMillis();
         setOnResumeCallback(null);
         // Process any items that were added while Launcher was away.
@@ -1634,8 +1630,8 @@
     }
 
     public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
-        mAppLaunchSuccess = super.startActivitySafely(v, intent, item);
-        if (mAppLaunchSuccess && v instanceof BubbleTextView) {
+        boolean success = super.startActivitySafely(v, intent, item);
+        if (success && v instanceof BubbleTextView) {
             // This is set to the view that launched the activity that navigated the user away
             // from launcher. Since there is no callback for when the activity has finished
             // launching, enable the press state and keep this reference to reset the press
@@ -1644,7 +1640,7 @@
             btv.setStayPressed(true);
             setOnResumeCallback(btv);
         }
-        return mAppLaunchSuccess;
+        return success;
     }
 
     boolean isHotseatLayout(View layout) {
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index 442691f..83593aa 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -131,6 +131,9 @@
                     + "), pageIdx=" + t.pageIndex;
 
         }
+        if (t.itemType == ItemType.TASK) {
+            typeStr += ", pageIdx=" + t.pageIndex;
+        }
         return typeStr;
     }
 
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index 07e1315..850c948 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -132,6 +132,7 @@
     private boolean mIsInLandscapeMode;
     private String mUuidStr;
     protected InstantAppResolver mInstantAppResolver;
+    private boolean mAppOrTaskLaunch;
 
     //                      APP_ICON    SHORTCUT    WIDGET
     // --------------------------------------------------------------
@@ -163,11 +164,13 @@
             fillIntentInfo(event.srcTarget[0], intent);
         }
         dispatchUserEvent(event, intent);
+        mAppOrTaskLaunch = true;
     }
 
     public void logActionTip(int actionType, int viewType) { }
 
-    public void logTaskLaunchOrDismiss(int action, int direction, ComponentKey componentKey) {
+    public void logTaskLaunchOrDismiss(int action, int direction, int taskIndex,
+            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) {
@@ -175,8 +178,10 @@
             event.action.dir = direction;
         }
         event.srcTarget[0].itemType = LauncherLogProto.ItemType.TASK;
+        event.srcTarget[0].pageIndex = taskIndex;
         fillComponentInfo(event.srcTarget[0], componentKey.componentName);
         dispatchUserEvent(event, null);
+        mAppOrTaskLaunch = true;
     }
 
     protected void fillIntentInfo(Target target, Intent intent) {
@@ -211,6 +216,11 @@
 
     public void logActionCommand(int command, Target srcTarget, Target dstTarget) {
         LauncherEvent event = newLauncherEvent(newCommandAction(command), srcTarget);
+        if (command == Action.Command.STOP && mAppOrTaskLaunch) {
+            // Prevent double logging by skipping STOP when app or task has been launched.
+            return;
+        }
+
         if (dstTarget != null) {
             event.destTarget = new Target[1];
             event.destTarget[0] = dstTarget;
@@ -405,6 +415,7 @@
     }
 
     public void dispatchUserEvent(LauncherEvent ev, Intent intent) {
+        mAppOrTaskLaunch = false;
         ev.isInLandscapeMode = mIsInLandscapeMode;
         ev.isInMultiWindowMode = mIsInMultiWindowMode;
         ev.elapsedContainerMillis = SystemClock.uptimeMillis() - mElapsedContainerMillis;
@@ -413,7 +424,8 @@
         if (!IS_VERBOSE) {
             return;
         }
-        String log = "\n\naction:" + LoggerUtils.getActionStr(ev.action);
+        String log = "\n-----------------------------------------------------"
+                + "\naction:" + LoggerUtils.getActionStr(ev.action);
         if (ev.srcTarget != null && ev.srcTarget.length > 0) {
             log += "\n Source " + getTargetsStr(ev.srcTarget);
         }