Hookup statsd for workspace layout logging

Bug: 144953948

Change-Id: I81bd42929b2d65a63c610e95e5e01179a3971493
diff --git a/Android.mk b/Android.mk
index 9cfcf17..fcd4a94 100644
--- a/Android.mk
+++ b/Android.mk
@@ -129,6 +129,7 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
+    SystemUI-statsd \
     SystemUISharedLib \
     launcherprotosnano \
     launcher_log_protos_lite
@@ -201,6 +202,7 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
+    SystemUI-statsd \
     SystemUISharedLib \
     launcherprotosnano \
     launcher_log_protos_lite
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 49aca30..4306631 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -30,8 +30,8 @@
 import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_DISMISS_SWIPE_UP;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_LAUNCH_SWIPE_DOWN;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
 import static com.android.launcher3.statehandlers.DepthController.DEPTH;
 import static com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS;
 import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
@@ -1314,7 +1314,8 @@
             ComponentKey compKey = TaskUtils.getLaunchComponentKeyForTask(taskView.getTask().key);
             mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
                     endState.logAction, Direction.UP, index, compKey);
-            mActivity.getStatsLogManager().log(TASK_DISMISS_SWIPE_UP, taskView.buildProto());
+            mActivity.getStatsLogManager().log(
+                    LAUNCHER_TASK_DISMISS_SWIPE_UP, taskView.buildProto());
         }
     }
 
@@ -1892,8 +1893,8 @@
                     mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
                             endState.logAction, Direction.DOWN, indexOfChild(tv),
                             TaskUtils.getLaunchComponentKeyForTask(task.key));
-                    mActivity.getStatsLogManager().log(TASK_LAUNCH_SWIPE_DOWN, tv.buildProto()
-                    );
+                    mActivity.getStatsLogManager().log(
+                            LAUNCHER_TASK_LAUNCH_SWIPE_DOWN, tv.buildProto());
                 }
             } else {
                 onTaskLaunched(false);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index 97652aa..da9468e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -30,7 +30,7 @@
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_LAUNCH_TAP;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -212,7 +212,7 @@
             mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
                     Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this),
                     TaskUtils.getLaunchComponentKeyForTask(getTask().key));
-            mActivity.getStatsLogManager().log(TASK_LAUNCH_TAP, buildProto());
+            mActivity.getStatsLogManager().log(LAUNCHER_TASK_LAUNCH_TAP, buildProto());
         });
 
         mCurrentFullscreenParams = new FullscreenDrawParams(context);
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 2d51732..a98aad1 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -16,17 +16,17 @@
 
 package com.android.quickstep.logging;
 
-import static android.stats.launcher.nano.Launcher.ALLAPPS;
-import static android.stats.launcher.nano.Launcher.BACKGROUND;
-import static android.stats.launcher.nano.Launcher.HOME;
-import static android.stats.launcher.nano.Launcher.OVERVIEW;
+import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.FOLDER;
+import static com.android.launcher3.logger.LauncherAtom.ItemInfo.ItemCase.WIDGET;
 
 import android.content.Context;
+import android.util.Log;
 
 import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.logger.LauncherAtom;
+import com.android.launcher3.logging.InstanceId;
 import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.logging.StatsLogUtils;
 import com.android.launcher3.model.AllAppsList;
 import com.android.launcher3.model.BaseModelUpdateTask;
 import com.android.launcher3.model.BgDataModel;
@@ -34,11 +34,13 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
 import com.android.launcher3.util.IntSparseArrayMap;
+import com.android.launcher3.util.LogConfig;
+import com.android.systemui.shared.system.SysUiStatsLog;
 
 import java.util.ArrayList;
 
 /**
- * This method calls the StatsLog hidden method until they are made available public.
+ * This class calls StatsLog compile time generated methods.
  *
  * To see if the logs are properly sent to statsd, execute following command.
  * $ adb root && adb shell statsd
@@ -47,29 +49,69 @@
  */
 public class StatsLogCompatManager extends StatsLogManager {
 
-    private static final int SUPPORTED_TARGET_DEPTH = 2;
     private static final String TAG = "StatsLog";
-    private static final boolean DEBUG = false;
+    private static final boolean IS_VERBOSE = Utilities.isPropertyEnabled(LogConfig.STATSLOG);
+
     private static Context sContext;
 
+    private static final int DEFAULT_WIDGET_SPAN_XY = 1;
+    private static final int DEFAULT_WORKSPACE_GRID_XY = -1;
+    private static final int DEFAULT_PAGE_INDEX = -2;
+    private static final InstanceId DEFAULT_INSTANCE_ID = InstanceId.fakeInstanceId(0);
+
     public StatsLogCompatManager(Context context) {
         sContext = context;
     }
 
+    /**
+     * Logs an event and accompanying {@link ItemInfo}
+     */
+    public void log(LauncherEvent event, LauncherAtom.ItemInfo itemInfo) {
+        log(event, DEFAULT_INSTANCE_ID, itemInfo);
+    }
+
+    /**
+     * Logs an event and accompanying {@link LauncherAtom.ItemInfo}
+     */
     @Override
-    public void verify() {
-        if (!(StatsLogUtils.LAUNCHER_STATE_ALLAPPS == ALLAPPS
-                && StatsLogUtils.LAUNCHER_STATE_BACKGROUND == BACKGROUND
-                && StatsLogUtils.LAUNCHER_STATE_OVERVIEW == OVERVIEW
-                && StatsLogUtils.LAUNCHER_STATE_HOME == HOME)) {
-            throw new IllegalStateException(
-                    "StatsLogUtil constants doesn't match enums in launcher.proto");
+    public void log(LauncherEvent event, InstanceId instanceId, LauncherAtom.ItemInfo itemInfo) {
+        if (IS_VERBOSE) {
+            Log.d(TAG, String.format("\n%s\n%s", event.name(), itemInfo));
         }
+        if (!Utilities.ATLEAST_R) {
+            return;
+        }
+        SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_EVENT,
+                SysUiStatsLog.LAUNCHER_UICHANGED__ACTION__DEFAULT_ACTION /* deprecated */,
+                SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__HOME /* TODO */,
+                SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__BACKGROUND /* TODO */,
+                null /* launcher extensions, deprecated */,
+                false /* quickstep_enabled, deprecated */,
+                event.getId() /* event_id */,
+                itemInfo.getItemCase().getNumber() /* target_id */,
+                instanceId.getId() /* instance_id TODO */,
+                0 /* uid TODO */,
+                getPackageName(itemInfo) /* package_name */,
+                getComponentName(itemInfo) /* component_name */,
+                getGridX(itemInfo, false) /* grid_x */,
+                getGridY(itemInfo, false) /* grid_y */,
+                getPageId(itemInfo, false) /* page_id */,
+                getGridX(itemInfo, true) /* grid_x_parent */,
+                getGridY(itemInfo, true) /* grid_y_parent */,
+                getPageId(itemInfo, true) /* page_id_parent */,
+                getHierarchy(itemInfo) /* hierarchy */,
+                itemInfo.getIsWork() /* is_work_profile */,
+                itemInfo.getRank() /* rank */,
+                0 /* fromState */,
+                0 /* toState */,
+                null /* edittext */,
+                0 /* cardinality */);
     }
 
     /**
      * Logs the workspace layout information on the model thread.
      */
+    @Override
     public void logSnapshot() {
         LauncherAppState.getInstance(sContext).getModel().enqueueModelUpdateTask(
                 new SnapshotWorker());
@@ -84,18 +126,160 @@
 
             for (ItemInfo info : workspaceItems) {
                 LauncherAtom.ItemInfo atomInfo = info.buildProto(null);
-                // call StatsLog method
+                writeSnapshot(atomInfo);
             }
             for (FolderInfo fInfo : folders) {
                 for (ItemInfo info : fInfo.contents) {
                     LauncherAtom.ItemInfo atomInfo = info.buildProto(fInfo);
-                    // call StatsLog method
+                    writeSnapshot(atomInfo);
                 }
             }
             for (ItemInfo info : appWidgets) {
                 LauncherAtom.ItemInfo atomInfo = info.buildProto(null);
-                // call StatsLog method
+                writeSnapshot(atomInfo);
             }
         }
     }
+    private static void writeSnapshot(LauncherAtom.ItemInfo itemInfo) {
+        if (IS_VERBOSE) {
+            Log.d(TAG, "\nwriteSnapshot:" + itemInfo);
+        }
+        if (!Utilities.ATLEAST_R) {
+            return;
+        }
+        SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_SNAPSHOT,
+                0 /* event_id */,
+                itemInfo.getItemCase().getNumber() /* target_id */,
+                0 /* instance_id */,
+                0 /* uid */,
+                getPackageName(itemInfo) /* package_name */,
+                getComponentName(itemInfo) /* component_name */,
+                getGridX(itemInfo, false) /* grid_x */,
+                getGridY(itemInfo, false) /* grid_y */,
+                getPageId(itemInfo, false) /* page_id */,
+                getGridX(itemInfo, true) /* grid_x_parent */,
+                getGridY(itemInfo, true) /* grid_y_parent */,
+                getPageId(itemInfo, true) /* page_id_parent */,
+                getHierarchy(itemInfo) /* hierarchy */,
+                itemInfo.getIsWork() /* is_work_profile */,
+                0 /* origin TODO */,
+                0 /* cardinality */,
+                getSpanX(itemInfo),
+                getSpanY(itemInfo));
+    }
+
+    private static int getSpanX(LauncherAtom.ItemInfo atomInfo) {
+        if (atomInfo.getItemCase() != WIDGET) {
+            return DEFAULT_WIDGET_SPAN_XY;
+        }
+        return atomInfo.getWidget().getSpanX();
+    }
+
+    private static int getSpanY(LauncherAtom.ItemInfo atomInfo) {
+        if (atomInfo.getItemCase() != WIDGET) {
+            return DEFAULT_WIDGET_SPAN_XY;
+        }
+        return atomInfo.getWidget().getSpanY();
+    }
+
+    private static String getPackageName(LauncherAtom.ItemInfo atomInfo) {
+        switch (atomInfo.getItemCase()) {
+            case APPLICATION:
+                return atomInfo.getApplication().getPackageName();
+            case SHORTCUT:
+                return atomInfo.getShortcut().getShortcutName();
+            case WIDGET:
+                return atomInfo.getWidget().getPackageName();
+            case TASK:
+                return atomInfo.getTask().getPackageName();
+            default:
+                return null;
+        }
+    }
+
+    private static String getComponentName(LauncherAtom.ItemInfo atomInfo) {
+        switch (atomInfo.getItemCase()) {
+            case APPLICATION:
+                return atomInfo.getApplication().getComponentName();
+            case SHORTCUT:
+                return atomInfo.getShortcut().getShortcutName();
+            case WIDGET:
+                return atomInfo.getWidget().getComponentName();
+            case TASK:
+                return atomInfo.getTask().getComponentName();
+            default:
+                return null;
+        }
+    }
+
+    private static int getGridX(LauncherAtom.ItemInfo info, boolean parent) {
+        switch (info.getContainerInfo().getContainerCase()) {
+            case WORKSPACE:
+                if (parent) {
+                    return DEFAULT_WORKSPACE_GRID_XY;
+                } else {
+                    return info.getContainerInfo().getWorkspace().getGridX();
+                }
+            case FOLDER:
+                if (parent) {
+                    switch (info.getContainerInfo().getFolder().getParentContainerCase()) {
+                        case WORKSPACE:
+                            return info.getContainerInfo().getFolder().getWorkspace().getGridX();
+                        default:
+                            return DEFAULT_WORKSPACE_GRID_XY;
+                    }
+                } else {
+                    return info.getContainerInfo().getFolder().getGridX();
+                }
+            default:
+                return DEFAULT_WORKSPACE_GRID_XY;
+        }
+    }
+
+    private static int getGridY(LauncherAtom.ItemInfo info, boolean parent) {
+        switch (info.getContainerInfo().getContainerCase()) {
+            case WORKSPACE:
+                if (parent) {
+                    return DEFAULT_WORKSPACE_GRID_XY;
+                } else {
+                    return info.getContainerInfo().getWorkspace().getGridY();
+                }
+            case FOLDER:
+                if (parent) {
+                    switch (info.getContainerInfo().getFolder().getParentContainerCase()) {
+                        case WORKSPACE:
+                            return info.getContainerInfo().getFolder().getWorkspace().getGridY();
+                        default:
+                            return DEFAULT_WORKSPACE_GRID_XY;
+                    }
+                } else {
+                    return info.getContainerInfo().getFolder().getGridY();
+                }
+            default:
+                return DEFAULT_WORKSPACE_GRID_XY;
+        }
+    }
+
+    private static int getPageId(LauncherAtom.ItemInfo info, boolean parent) {
+        switch (info.getContainerInfo().getContainerCase()) {
+            case HOTSEAT:
+                return info.getContainerInfo().getHotseat().getIndex();
+            case WORKSPACE:
+                return info.getContainerInfo().getWorkspace().getPageIndex();
+            default:
+                return DEFAULT_PAGE_INDEX;
+        }
+    }
+
+    /**
+     *
+     */
+    private static int getHierarchy(LauncherAtom.ItemInfo info) {
+        // TODO
+        if (info.getContainerInfo().getContainerCase() == FOLDER) {
+            return info.getContainerInfo().getFolder().getParentContainerCase().getNumber() + 100;
+        } else {
+            return info.getContainerInfo().getContainerCase().getNumber();
+        }
+    }
 }
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 09fe64a..239d8a3 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -16,7 +16,7 @@
 
 package com.android.launcher3;
 
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.APP_LAUNCH_TAP;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
 import static com.android.launcher3.util.DefaultDisplay.CHANGE_ROTATION;
 
 import android.app.ActivityOptions;
@@ -183,8 +183,7 @@
                         sourceContainer);
             }
             getUserEventDispatcher().logAppLaunch(v, intent, user);
-
-            getStatsLogManager().log(APP_LAUNCH_TAP, item == null ? null
+            getStatsLogManager().log(LAUNCHER_APP_LAUNCH_TAP, item == null ? null
                     : item.buildProto(null));
             return true;
         } catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index abf027d..fdd32b8 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -16,34 +16,33 @@
 package com.android.launcher3.logging;
 
 import android.content.Context;
-import android.util.Log;
 
 import com.android.launcher3.R;
 import com.android.launcher3.logger.LauncherAtom;
-import com.android.launcher3.logger.LauncherAtom.ItemInfo;
 import com.android.launcher3.logging.StatsLogUtils.LogStateProvider;
 import com.android.launcher3.util.ResourceBasedOverride;
 
 /**
  * Handles the user event logging in R+.
+ * All of the event id is defined here.
+ * Most of the methods are dummy methods for Launcher3
+ * Actual call happens only for Launcher variant that implements QuickStep.
  */
 public class StatsLogManager implements ResourceBasedOverride {
 
-    private static final String TAG = "StatsLogManager";
-
     interface EventEnum {
         int getId();
     }
 
     public enum LauncherEvent implements EventEnum {
         @LauncherUiEvent(doc = "App launched from workspace, hotseat or folder in launcher")
-        APP_LAUNCH_TAP(1),
+        LAUNCHER_APP_LAUNCH_TAP(338),
         @LauncherUiEvent(doc = "Task launched from overview using TAP")
-        TASK_LAUNCH_TAP(2),
+        LAUNCHER_TASK_LAUNCH_TAP(339),
         @LauncherUiEvent(doc = "Task launched from overview using SWIPE DOWN")
-        TASK_LAUNCH_SWIPE_DOWN(2),
+        LAUNCHER_TASK_LAUNCH_SWIPE_DOWN(340),
         @LauncherUiEvent(doc = "TASK dismissed from overview using SWIPE UP")
-        TASK_DISMISS_SWIPE_UP(3),
+        LAUNCHER_TASK_DISMISS_SWIPE_UP(341),
         @LauncherUiEvent(doc = "User dragged a launcher item")
         LAUNCHER_ITEM_DRAG_STARTED(383),
         @LauncherUiEvent(doc = "A dragged launcher item is successfully dropped")
@@ -75,30 +74,18 @@
         StatsLogManager mgr = Overrides.getObject(StatsLogManager.class,
                 context.getApplicationContext(), R.string.stats_log_manager_class);
         mgr.mStateProvider = stateProvider;
-        mgr.verify();
         return mgr;
     }
 
     /**
-     * Logs an event and accompanying {@link ItemInfo}
+     * Logs an event and accompanying {@link LauncherAtom.ItemInfo}
      */
-    public void log(LauncherEvent event, LauncherAtom.ItemInfo itemInfo) {
-        Log.d(TAG, String.format("%s\n%s", event.name(), itemInfo));
-        // Call StatsLog method
-    }
+    public void log(LauncherEvent event, InstanceId instanceId, LauncherAtom.ItemInfo itemInfo) { }
+    public void log(LauncherEvent event, LauncherAtom.ItemInfo itemInfo) { }
 
-    /**
-     * Logs an event and accompanying {@link ItemInfo}
-     */
-    public void log(LauncherEvent event, InstanceId instanceId, LauncherAtom.ItemInfo itemInfo) {
-        Log.d(TAG, String.format("%s(InstanceId:%s)\n%s", event.name(), instanceId, itemInfo));
-        // Call StatsLog method
-    }
 
     /**
      * Logs snapshot, or impression of the current workspace.
      */
     public void logSnapshot() { }
-
-    public void verify() {}     // TODO: should move into robo tests
 }
diff --git a/src/com/android/launcher3/logging/StatsLogUtils.java b/src/com/android/launcher3/logging/StatsLogUtils.java
index 97aaf84..10d88e5 100644
--- a/src/com/android/launcher3/logging/StatsLogUtils.java
+++ b/src/com/android/launcher3/logging/StatsLogUtils.java
@@ -1,7 +1,5 @@
 package com.android.launcher3.logging;
 
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.DEFAULT_CONTAINERTYPE;
-
 import android.view.View;
 import android.view.ViewParent;
 
@@ -13,6 +11,7 @@
 
 import java.util.ArrayList;
 
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.DEFAULT_CONTAINERTYPE;
 
 public class StatsLogUtils {
 
@@ -31,8 +30,6 @@
 
     /**
      * Implemented by containers to provide a container source for a given child.
-     *
-     * Currently,
      */
     public interface LogContainerProvider {
 
diff --git a/src/com/android/launcher3/util/LogConfig.java b/src/com/android/launcher3/util/LogConfig.java
index b54074e..528a6e9 100644
--- a/src/com/android/launcher3/util/LogConfig.java
+++ b/src/com/android/launcher3/util/LogConfig.java
@@ -12,6 +12,8 @@
 public class LogConfig {
     // These are list of strings that can be used to replace TAGNAME.
 
+    public static final String STATSLOG = "StatsLog";
+
     /**
      * After this tag is turned on, whenever there is n user event, debug information is
      * printed out to logcat.