Add logging for long presses. Reset elapsed timer when changing containers.

This is the first CL in a series of logging-related CLs. Upcoming CLs will
include using Commands (HOME_INTENT, BACK) and "tapping outside" of a container
logic.

Change-Id: I62f0a08c7a9d9fce0baa5c12c67e21f63ab16a7c
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 30d5b17..164dc51 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1358,53 +1358,36 @@
     private void setupOverviewPanel() {
         mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);
 
-        // Long-clicking buttons in the overview panel does the same thing as clicking them.
-        OnLongClickListener performClickOnLongClick = new OnLongClickListener() {
-            @Override
-            public boolean onLongClick(View v) {
-                return v.performClick();
-            }
-        };
-
         // Bind wallpaper button actions
         View wallpaperButton = findViewById(R.id.wallpaper_button);
-        wallpaperButton.setOnClickListener(new OnClickListener() {
+        new OverviewButtonClickListener(LauncherLogProto.WALLPAPER_BUTTON) {
             @Override
-            public void onClick(View view) {
-                if (!mWorkspace.isSwitchingState()) {
-                    onClickWallpaperPicker(view);
-                }
+            public void handleViewClick(View view) {
+                onClickWallpaperPicker(view);
             }
-        });
-        wallpaperButton.setOnLongClickListener(performClickOnLongClick);
+        }.attachTo(wallpaperButton);
         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());
 
         // Bind widget button actions
         mWidgetsButton = findViewById(R.id.widget_button);
-        mWidgetsButton.setOnClickListener(new OnClickListener() {
+        new OverviewButtonClickListener(LauncherLogProto.WIDGETS_BUTTON) {
             @Override
-            public void onClick(View view) {
-                if (!mWorkspace.isSwitchingState()) {
-                    onClickAddWidgetButton(view);
-                }
+            public void handleViewClick(View view) {
+                onClickAddWidgetButton(view);
             }
-        });
-        mWidgetsButton.setOnLongClickListener(performClickOnLongClick);
+        }.attachTo(mWidgetsButton);
         mWidgetsButton.setOnTouchListener(getHapticFeedbackTouchListener());
 
         // Bind settings actions
         View settingsButton = findViewById(R.id.settings_button);
         boolean hasSettings = hasSettings();
         if (hasSettings) {
-            settingsButton.setOnClickListener(new OnClickListener() {
+            new OverviewButtonClickListener(LauncherLogProto.SETTINGS_BUTTON) {
                 @Override
-                public void onClick(View view) {
-                    if (!mWorkspace.isSwitchingState()) {
-                        onClickSettingsButton(view);
-                    }
+                public void handleViewClick(View view) {
+                    onClickSettingsButton(view);
                 }
-            });
-            settingsButton.setOnLongClickListener(performClickOnLongClick);
+            }.attachTo(settingsButton);
             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
         } else {
             settingsButton.setVisibility(View.GONE);
@@ -2896,6 +2879,8 @@
         // the workspace items
         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+
+        getUserEventDispatcher().resetElapsedContainerMillis();
     }
 
     public void closeFolder() {
@@ -2934,6 +2919,8 @@
         // Notify the accessibility manager that this folder "window" has disappeared and no
         // longer occludes the workspace items
         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+
+        getUserEventDispatcher().resetElapsedContainerMillis();
     }
 
     public void closeShortcutsContainer() {
@@ -2999,6 +2986,9 @@
         if (v instanceof Workspace) {
             if (!mWorkspace.isInOverviewMode()) {
                 if (!mWorkspace.isTouchActive() && !fromEdgeOfScreen) {
+                    getUserEventDispatcher().logActionOnContainer(LauncherLogProto.Action.LONGPRESS,
+                            LauncherLogProto.Action.NONE, LauncherLogProto.WORKSPACE,
+                            mWorkspace.getCurrentPage());
                     showOverviewMode(true);
                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
@@ -3027,10 +3017,15 @@
                 // User long pressed on empty space
                 if (mWorkspace.isInOverviewMode()) {
                     mWorkspace.startReordering(v);
+                    getUserEventDispatcher().logActionOnContainer(LauncherLogProto.Action.LONGPRESS,
+                            LauncherLogProto.Action.NONE, LauncherLogProto.OVERVIEW);
                 } else {
                     if (fromEdgeOfScreen) {
                         return false;
                     }
+                    getUserEventDispatcher().logActionOnContainer(LauncherLogProto.Action.LONGPRESS,
+                            LauncherLogProto.Action.NONE, LauncherLogProto.WORKSPACE,
+                            mWorkspace.getCurrentPage());
                     showOverviewMode(true);
                 }
                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
index eb70650..6d5f951 100644
--- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java
+++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
@@ -607,6 +607,8 @@
         playCommonTransitionAnimations(toWorkspaceState, fromWorkspace, null,
                 animated, animated, animation, layerViews);
 
+        mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
+
         if (animated) {
             dispatchOnLauncherTransitionPrepare(fromWorkspace, animated, multiplePagesVisible);
 
diff --git a/src/com/android/launcher3/OverviewButtonClickListener.java b/src/com/android/launcher3/OverviewButtonClickListener.java
new file mode 100644
index 0000000..c98f1d7
--- /dev/null
+++ b/src/com/android/launcher3/OverviewButtonClickListener.java
@@ -0,0 +1,51 @@
+package com.android.launcher3;
+
+import android.view.View;
+
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+
+/**
+ * A specialized listener for Overview buttons where both clicks and long clicks are logged
+ * handled the same via {@link #handleViewClick(View)}.
+ */
+public abstract class OverviewButtonClickListener implements View.OnClickListener,
+        View.OnLongClickListener {
+
+    private int mControlType; /** ControlType enum as defined in {@link LauncherLogProto} */
+
+    public OverviewButtonClickListener(int controlType) {
+        mControlType = controlType;
+    }
+
+    public void attachTo(View v) {
+        v.setOnClickListener(this);
+        v.setOnLongClickListener(this);
+    }
+
+    @Override
+    public void onClick(View view) {
+        if (shouldPerformClick(view)) {
+            handleViewClick(view, LauncherLogProto.Action.TAP);
+        }
+    }
+
+    @Override
+    public boolean onLongClick(View view) {
+        if (shouldPerformClick(view)) {
+            handleViewClick(view, LauncherLogProto.Action.LONGPRESS);
+        }
+        return true;
+    }
+
+    private boolean shouldPerformClick(View view) {
+        return !Launcher.getLauncher(view.getContext()).getWorkspace().isSwitchingState();
+    }
+
+    private void handleViewClick(View view, int action) {
+        handleViewClick(view);
+        Launcher.getLauncher(view.getContext()).getUserEventDispatcher()
+                .logActionOnControl(action, mControlType);
+    }
+
+    public abstract void handleViewClick(View view);
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 315e23a..0bf8241 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2344,6 +2344,8 @@
             DeepShortcutsContainer dsc = DeepShortcutsContainer.showForIcon((BubbleTextView) child);
             if (dsc != null) {
                 dragOptions.preDragCondition = dsc.createPreDragCondition();
+
+                mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
             }
         }
 
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index 56fdce8..2ad8847 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -166,10 +166,15 @@
     }
 
     public void logActionOnContainer(int action, int dir, int containerType) {
+        logActionOnContainer(action, dir, containerType, 0);
+    }
+
+    public void logActionOnContainer(int action, int dir, int containerType, int pageIndex) {
         LauncherEvent event = LoggerUtils.initLauncherEvent(Action.TOUCH, Target.CONTAINER);
         event.action.touch = action;
         event.action.dir = dir;
         event.srcTarget[0].containerType = containerType;
+        event.srcTarget[0].pageIndex = pageIndex;
         dispatchUserEvent(event, null);
     }
 
@@ -184,6 +189,8 @@
         provider.fillInLaunchSourceData(icon, info, event.srcTarget[0], event.srcTarget[1]);
         event.action.touch = Action.LONGPRESS;
         dispatchUserEvent(event, null);
+
+        resetElapsedContainerMillis();
     }
 
     public void setPredictedApps(List<ComponentKey> predictedApps) {