LAUNCHER_APP_LAUNCH_TAP should log correctly for icons inside folder
Bug: 137777105

Change-Id: I5c1552481fc1b788ba41c57bfe97f126f55e5b16
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index 7e8e51e..d1185bd 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -54,6 +54,7 @@
     ShortcutsContainer shortcuts_container = 8;
     SettingsContainer settings_container = 9;
     PredictedHotseatContainer predicted_hotseat_container = 10;
+    TaskSwitcherContainer task_switcher_container = 11;
   }
 }
 
@@ -82,6 +83,9 @@
 message SettingsContainer {
 }
 
+message TaskSwitcherContainer {
+}
+
 enum Attribute {
   UNKNOWN = 0;
   DEFAULT_LAYOUT = 1;       // icon automatically placed in workspace, folder, hotseat
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskShortcutFactory.java
index ea1795c..4eae437 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskShortcutFactory.java
@@ -26,23 +26,18 @@
 
 import android.app.Activity;
 import android.app.ActivityOptions;
-import android.content.ComponentName;
-import android.content.Intent;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.UserHandle;
 import android.view.View;
 
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
-import com.android.launcher3.logger.LauncherAtom;
 import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
 import com.android.launcher3.model.WellbeingModel;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.popup.SystemShortcut;
 import com.android.launcher3.popup.SystemShortcut.AppInfo;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
@@ -71,28 +66,7 @@
 
     SystemShortcut getShortcut(BaseDraggingActivity activity, TaskView view);
 
-    static WorkspaceItemInfo dummyInfo(TaskView view) {
-        Task task = view.getTask();
-
-        WorkspaceItemInfo dummyInfo = new WorkspaceItemInfo(){
-            /**
-             * Helps to log events as {@link LauncherAtom.Task}
-             * instead of {@link LauncherAtom.ItemInfo}.
-             */
-            @Override
-            public LauncherAtom.ItemInfo buildProto() {
-                return view.buildProto();
-            }
-        };
-        dummyInfo.intent = new Intent();
-        ComponentName component = task.getTopComponent();
-        dummyInfo.getIntent().setComponent(component);
-        dummyInfo.user = UserHandle.of(task.key.userId);
-        dummyInfo.title = TaskUtils.getTitle(view.getContext(), task);
-        return dummyInfo;
-    }
-
-    TaskShortcutFactory APP_INFO = (activity, view) -> new AppInfo(activity, dummyInfo(view));
+    TaskShortcutFactory APP_INFO = (activity, view) -> new AppInfo(activity, view.getItemInfo());
 
     abstract class MultiWindowFactory implements TaskShortcutFactory {
 
@@ -136,7 +110,7 @@
 
         public MultiWindowSystemShortcut(int iconRes, int textRes, BaseDraggingActivity activity,
                 TaskView taskView, MultiWindowFactory factory, LauncherEvent launcherEvent) {
-            super(iconRes, textRes, activity, dummyInfo(taskView));
+            super(iconRes, textRes, activity, taskView.getItemInfo());
             mLauncherEvent = launcherEvent;
             mHandler = new Handler(Looper.getMainLooper());
             mTaskView = taskView;
@@ -222,7 +196,7 @@
                 WindowManagerWrapper.getInstance().overridePendingAppTransitionMultiThumbFuture(
                         future, animStartedListener, mHandler, true /* scaleUp */,
                         taskKey.displayId);
-                mTarget.getStatsLogManager().log(mLauncherEvent, mTaskView.buildProto());
+                mTarget.getStatsLogManager().log(mLauncherEvent, mTaskView.getItemInfo());
             }
         }
     }
@@ -306,7 +280,7 @@
         private final TaskView mTaskView;
 
         public PinSystemShortcut(BaseDraggingActivity target, TaskView tv) {
-            super(R.drawable.ic_pin, R.string.recent_task_option_pin, target, dummyInfo(tv));
+            super(R.drawable.ic_pin, R.string.recent_task_option_pin, target, tv.getItemInfo());
             mTaskView = tv;
         }
 
@@ -323,29 +297,29 @@
             mTaskView.launchTask(true, resultCallback, Executors.MAIN_EXECUTOR.getHandler());
             dismissTaskMenuView(mTarget);
             mTarget.getStatsLogManager().log(LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_PIN_TAP,
-                    mTaskView.buildProto());
+                    mTaskView.getItemInfo());
         }
     }
 
     TaskShortcutFactory INSTALL = (activity, view) ->
             InstantAppResolver.newInstance(activity).isInstantApp(activity,
                  view.getTask().getTopComponent().getPackageName())
-                    ? new SystemShortcut.Install(activity, dummyInfo(view)) : null;
+                    ? new SystemShortcut.Install(activity, view.getItemInfo()) : null;
 
     TaskShortcutFactory WELLBEING = (activity, view) ->
-            WellbeingModel.SHORTCUT_FACTORY.getShortcut(activity, dummyInfo(view));
+            WellbeingModel.SHORTCUT_FACTORY.getShortcut(activity, view.getItemInfo());
 
     TaskShortcutFactory SCREENSHOT = (activity, tv) -> {
         if (ENABLE_OVERVIEW_ACTIONS.get()) {
             return tv.getThumbnail().getTaskOverlay()
-                .getScreenshotShortcut(activity, dummyInfo(tv));
+                .getScreenshotShortcut(activity, tv.getItemInfo());
         }
         return null;
     };
 
     TaskShortcutFactory MODAL = (activity, tv) -> {
         if (ENABLE_OVERVIEW_ACTIONS.get() && ENABLE_OVERVIEW_SELECTIONS.get()) {
-            return tv.getThumbnail().getTaskOverlay().getModalStateSystemShortcut(dummyInfo(tv));
+            return tv.getThumbnail().getTaskOverlay().getModalStateSystemShortcut(tv.getItemInfo());
         }
         return null;
     };
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 05f4e91..534ef7b 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
@@ -1347,7 +1347,7 @@
             mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
                     endState.logAction, Direction.UP, index, compKey);
             mActivity.getStatsLogManager().log(
-                    LAUNCHER_TASK_DISMISS_SWIPE_UP, taskView.buildProto());
+                    LAUNCHER_TASK_DISMISS_SWIPE_UP, taskView.getItemInfo());
         }
     }
 
@@ -1930,7 +1930,7 @@
                             endState.logAction, Direction.DOWN, indexOfChild(tv),
                             TaskUtils.getLaunchComponentKeyForTask(task.key));
                     mActivity.getStatsLogManager().log(
-                            LAUNCHER_TASK_LAUNCH_SWIPE_DOWN, tv.buildProto());
+                            LAUNCHER_TASK_LAUNCH_SWIPE_DOWN, tv.getItemInfo());
                 }
             } 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 e25c85b..3b1210e 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
@@ -40,6 +40,7 @@
 import android.animation.ValueAnimator;
 import android.app.ActivityOptions;
 import android.content.Context;
+import android.content.Intent;
 import android.graphics.Outline;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -48,7 +49,6 @@
 import android.graphics.drawable.InsetDrawable;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.Process;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.Log;
@@ -61,13 +61,14 @@
 
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.logger.LauncherAtom;
 import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.popup.SystemShortcut;
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.TestProtocol;
@@ -213,7 +214,7 @@
             mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
                     Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this),
                     TaskUtils.getLaunchComponentKeyForTask(getTask().key));
-            mActivity.getStatsLogManager().log(LAUNCHER_TASK_LAUNCH_TAP, buildProto());
+            mActivity.getStatsLogManager().log(LAUNCHER_TASK_LAUNCH_TAP, getItemInfo());
         });
 
         mCurrentFullscreenParams = new FullscreenDrawParams(context);
@@ -226,14 +227,16 @@
     /**
      * Builds proto for logging
      */
-    public LauncherAtom.ItemInfo buildProto() {
+    public WorkspaceItemInfo getItemInfo() {
         ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(getTask().key);
-        LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder();
-        itemBuilder.setIsWork(componentKey.user != Process.myUserHandle());
-        itemBuilder.setTask(LauncherAtom.Task.newBuilder()
-                .setComponentName(componentKey.componentName.flattenToShortString())
-                .setIndex(getRecentsView().indexOfChild(this)));
-        return itemBuilder.build();
+        WorkspaceItemInfo dummyInfo = new WorkspaceItemInfo();
+        dummyInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_TASK;
+        dummyInfo.container = LauncherSettings.Favorites.CONTAINER_TASKSWITCHER;
+        dummyInfo.user = componentKey.user;
+        dummyInfo.intent = new Intent().setComponent(componentKey.componentName);
+        dummyInfo.title = TaskUtils.getTitle(getContext(), getTask());
+        dummyInfo.screenId = getRecentsView().indexOfChild(this);
+        return dummyInfo;
     }
 
     @Override
@@ -429,7 +432,7 @@
             getRecentsView().snapToPage(getRecentsView().indexOfChild(this));
         } else {
             mMenuView = TaskMenuView.showForTask(this);
-            mActivity.getStatsLogManager().log(LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS, buildProto());
+            mActivity.getStatsLogManager().log(LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS, getItemInfo());
             UserEventDispatcher.newInstance(getContext()).logActionOnItem(action, Direction.NONE,
                     LauncherLogProto.ItemType.TASK_ICON);
             if (mMenuView != null) {
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 390330f..a88ba3c 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -64,6 +64,9 @@
     private static Context sContext;
 
     private static final InstanceId DEFAULT_INSTANCE_ID = InstanceId.fakeInstanceId(0);
+    // LauncherAtom.ItemInfo.getDefaultInstance() should be used but until launcher proto migrates
+    // from nano to lite, bake constant to prevent robo test failure.
+    private static final int DEFAULT_PAGE_INDEX = -2;
     private static final int FOLDER_HIERARCHY_OFFSET = 100;
 
     public StatsLogCompatManager(Context context) {
@@ -75,7 +78,7 @@
      */
     @Override
     public void log(EventEnum event) {
-        log(event, DEFAULT_INSTANCE_ID, LauncherAtom.ItemInfo.getDefaultInstance());
+        log(event, DEFAULT_INSTANCE_ID, null);
     }
 
     /**
@@ -83,31 +86,27 @@
      */
     @Override
     public void log(EventEnum event, InstanceId instanceId) {
-        log(event, instanceId, LauncherAtom.ItemInfo.getDefaultInstance());
+        log(event, instanceId, null);
     }
 
     /**
      * Logs an event and accompanying {@link ItemInfo}.
      */
     @Override
-    public void log(EventEnum event, @Nullable LauncherAtom.ItemInfo info) {
+    public void log(EventEnum event, @Nullable ItemInfo info) {
         log(event, DEFAULT_INSTANCE_ID, info);
     }
 
-    @Override
-    public void log(EventEnum event, ItemInfo itemInfo) {
-        logInternal(event, DEFAULT_INSTANCE_ID, itemInfo);
-    }
-
     /**
      * Logs an event and accompanying {@link InstanceId} and {@link LauncherAtom.ItemInfo}.
      */
     @Override
     public void log(EventEnum event, InstanceId instanceId,
-            @Nullable LauncherAtom.ItemInfo info) {
+            @Nullable ItemInfo info) {
         logInternal(event, instanceId, info,
                 LAUNCHER_UICHANGED__DST_STATE__HOME,
-                LAUNCHER_UICHANGED__DST_STATE__BACKGROUND);
+                LAUNCHER_UICHANGED__DST_STATE__BACKGROUND,
+                DEFAULT_PAGE_INDEX);
     }
 
     /**
@@ -129,58 +128,60 @@
      */
     @Override
     public void log(EventEnum event, int srcState, int dstState, int pageIndex) {
-        LauncherAtom.ItemInfo info = LauncherAtom.ItemInfo.getDefaultInstance();
-        if (srcState == LAUNCHER_UICHANGED__DST_STATE__HOME
-                || dstState == LAUNCHER_UICHANGED__SRC_STATE__HOME) {
-            info = LauncherAtom.ItemInfo.newBuilder().setContainerInfo(
-                    LauncherAtom.ContainerInfo.newBuilder().setWorkspace(
-                            LauncherAtom.WorkspaceContainer.newBuilder().setPageIndex(pageIndex)
-                    )).build();
-        }
-        logInternal(event, DEFAULT_INSTANCE_ID, info, srcState, dstState);
+        logInternal(event, DEFAULT_INSTANCE_ID, null, srcState, dstState, pageIndex);
     }
 
-    private void logInternal(EventEnum event, InstanceId instanceId, @Nullable ItemInfo info) {
+    /**
+     * Logs an event and accompanying {@link InstanceId} and {@link ItemInfo}.
+     */
+    private void logInternal(EventEnum event, InstanceId instanceId,
+            @Nullable ItemInfo info, int srcState, int dstState, int pageIndex) {
+
         LauncherAppState.getInstance(sContext).getModel().enqueueModelUpdateTask(
                 new BaseModelUpdateTask() {
                     @Override
                     public void execute(LauncherAppState app, BgDataModel dataModel,
                             AllAppsList apps) {
-                        LauncherAtom.ItemInfo atomInfo = LauncherAtom.ItemInfo.getDefaultInstance();
-                        if (info != null) {
-                            if (info.container >= 0) {
-                                atomInfo = info.buildProto(dataModel.folders.get(info.container));
-                            } else {
-                                atomInfo = info.buildProto();
-                            }
-                        }
-                        logInternal(event, instanceId, atomInfo,
-                                LAUNCHER_UICHANGED__DST_STATE__HOME,
-                                LAUNCHER_UICHANGED__DST_STATE__BACKGROUND);
+                        writeEvent(event, instanceId, info, srcState, dstState, pageIndex,
+                                dataModel.folders);
                     }
                 });
     }
 
-    /**
-     * Logs an event and accompanying {@link InstanceId} and {@link LauncherAtom.ItemInfo}.
-     */
-    private void logInternal(EventEnum event, InstanceId instanceId,
-            @Nullable LauncherAtom.ItemInfo info, int srcState, int dstState) {
-        info = info == null ? LauncherAtom.ItemInfo.getDefaultInstance() : info;
+    private static void writeEvent(EventEnum event, InstanceId instanceId,
+            @Nullable ItemInfo info, int srcState, int dstState, int pageIndex,
+            IntSparseArrayMap<FolderInfo> folders) {
+
+        if (!Utilities.ATLEAST_R) {
+            return;
+        }
+        LauncherAtom.ItemInfo atomInfo = LauncherAtom.ItemInfo.getDefaultInstance();
+        if (info != null) {
+            if (info.container >= 0) {
+                atomInfo = info.buildProto(folders.get(info.container));
+            } else {
+                atomInfo = info.buildProto();
+            }
+        } else {
+            if (srcState == LAUNCHER_UICHANGED__DST_STATE__HOME
+                    || dstState == LAUNCHER_UICHANGED__SRC_STATE__HOME) {
+                atomInfo = LauncherAtom.ItemInfo.newBuilder().setContainerInfo(
+                        LauncherAtom.ContainerInfo.newBuilder().setWorkspace(
+                                LauncherAtom.WorkspaceContainer.newBuilder().setPageIndex(pageIndex)
+                        )).build();
+            }
+        }
 
         if (IS_VERBOSE) {
             String name = (event instanceof Enum) ? ((Enum) event).name() :
                     event.getId() + "";
 
             Log.d(TAG, instanceId == DEFAULT_INSTANCE_ID
-                    ? String.format("\n%s (State:%s->%s) \n%s", name, getStateString(srcState),
-                    getStateString(dstState), info)
-                    : String.format("\n%s (State:%s->%s) (InstanceId:%s)\n%s", name,
-                            getStateString(srcState), getStateString(dstState), instanceId, info));
-        }
-
-        if (!Utilities.ATLEAST_R) {
-            return;
+                    ? String.format("\n%s (State:%s->%s) \n%s\n%s", name, getStateString(srcState),
+                            getStateString(dstState), info, atomInfo)
+                    : String.format("\n%s (State:%s->%s) (InstanceId:%s)\n%s\n%s", name,
+                            getStateString(srcState), getStateString(dstState), instanceId, info,
+                            atomInfo));
         }
 
         SysUiStatsLog.write(
@@ -191,24 +192,24 @@
                 null /* launcher extensions, deprecated */,
                 false /* quickstep_enabled, deprecated */,
                 event.getId() /* event_id */,
-                info.getItemCase().getNumber() /* target_id */,
+                atomInfo.getItemCase().getNumber() /* target_id */,
                 instanceId.getId() /* instance_id TODO */,
                 0 /* uid TODO */,
-                getPackageName(info) /* package_name */,
-                getComponentName(info) /* component_name */,
-                getGridX(info, false) /* grid_x */,
-                getGridY(info, false) /* grid_y */,
-                getPageId(info, false) /* page_id */,
-                getGridX(info, true) /* grid_x_parent */,
-                getGridY(info, true) /* grid_y_parent */,
-                getPageId(info, true) /* page_id_parent */,
-                getHierarchy(info) /* hierarchy */,
-                info.getIsWork() /* is_work_profile */,
-                info.getRank() /* rank */,
-                info.getFolderIcon().getFromLabelState().getNumber() /* fromState */,
-                info.getFolderIcon().getToLabelState().getNumber() /* toState */,
-                info.getFolderIcon().getLabelInfo() /* edittext */,
-                getCardinality(info) /* cardinality */);
+                getPackageName(atomInfo) /* package_name */,
+                getComponentName(atomInfo) /* component_name */,
+                getGridX(atomInfo, false) /* grid_x */,
+                getGridY(atomInfo, false) /* grid_y */,
+                getPageId(atomInfo, false) /* page_id */,
+                getGridX(atomInfo, true) /* grid_x_parent */,
+                getGridY(atomInfo, true) /* grid_y_parent */,
+                getPageId(atomInfo, true) /* page_id_parent */,
+                getHierarchy(atomInfo) /* hierarchy */,
+                atomInfo.getIsWork() /* is_work_profile */,
+                atomInfo.getRank() /* rank */,
+                atomInfo.getFolderIcon().getFromLabelState().getNumber() /* fromState */,
+                atomInfo.getFolderIcon().getToLabelState().getNumber() /* toState */,
+                atomInfo.getFolderIcon().getLabelInfo() /* edittext */,
+                getCardinality(atomInfo) /* cardinality */);
     }
 
     /**
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 268b910..88dbfd6 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -188,7 +188,7 @@
             }
             getUserEventDispatcher().logAppLaunch(v, intent, user);
             if (item != null) {
-                getStatsLogManager().log(LAUNCHER_APP_LAUNCH_TAP, item.buildProto());
+                getStatsLogManager().log(LAUNCHER_APP_LAUNCH_TAP, item);
             }
             return true;
         } catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 208d565..5512654 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -163,6 +163,7 @@
         public static final int CONTAINER_SEARCH_RESULTS = -106;
         public static final int CONTAINER_SHORTCUTS = -107;
         public static final int CONTAINER_SETTINGS = -108;
+        public static final int CONTAINER_TASKSWITCHER = -109;
 
         public static final String containerToString(int container) {
             switch (container) {
@@ -250,6 +251,12 @@
         public static final int ITEM_TYPE_DEEP_SHORTCUT = 6;
 
         /**
+         * Type of the item is recents task.
+         * TODO(hyunyoungs): move constants not related to Favorites DB to a better location.
+         */
+        public static final int ITEM_TYPE_TASK = 7;
+
+        /**
          * The appWidgetId of the widget
          *
          * <P>Type: INTEGER</P>
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index f6c392b..4198e9f 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -418,10 +418,7 @@
         mStatsLogManager.log(
                 LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED,
                 dragObject.logInstanceId,
-                dragObject.dragSource instanceof Folder
-                        ? dragObject.originalDragInfo
-                                .buildProto(((Folder) dragObject.dragSource).mInfo)
-                        : dragObject.originalDragInfo.buildProto()
+                dragObject.originalDragInfo
         );
     }
 
@@ -1652,7 +1649,7 @@
             mStatsLogManager.log(
                     LauncherEvent.LAUNCHER_ITEM_DROP_FOLDER_CREATED,
                     d.logInstanceId,
-                    destInfo.buildProto(null));
+                    destInfo);
             FolderIcon fi = mLauncher.addFolder(target, container, screenId, targetCell[0],
                     targetCell[1]);
             destInfo.cellX = -1;
@@ -1693,7 +1690,7 @@
                 mStatsLogManager.log(
                         LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
                         d.logInstanceId,
-                        fi.mInfo.buildProto(null));
+                        fi.mInfo);
                 fi.onDrop(d, false /* itemReturnedOnFailedDrop */);
 
                 // if the drag started here, we need to remove it from the workspace
@@ -1899,7 +1896,7 @@
             mStatsLogManager.log(
                     LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
                     d.logInstanceId,
-                    d.dragInfo.buildProto(null));
+                    d.dragInfo);
         }
 
         if (d.stateAnnouncer != null && !droppedOnOriginalCell) {
@@ -2440,7 +2437,7 @@
                     mStatsLogManager.log(
                             LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
                             d.logInstanceId,
-                            d.dragInfo.buildProto(null));
+                            d.dragInfo);
                 }
             };
             boolean isWidget = pendingInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET
@@ -2532,7 +2529,7 @@
             mStatsLogManager.log(
                     LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
                     d.logInstanceId,
-                    d.dragInfo.buildProto(null));
+                    d.dragInfo);
         }
 
     }
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index c7487cb..530010e 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -1338,7 +1338,7 @@
             d.stateAnnouncer.completeAction(R.string.item_moved);
         }
         mStatsLogManager
-                .log(LAUNCHER_ITEM_DROP_COMPLETED, d.logInstanceId, d.dragInfo.buildProto(mInfo));
+                .log(LAUNCHER_ITEM_DROP_COMPLETED, d.logInstanceId, d.dragInfo);
     }
 
     // This is used so the item doesn't immediately appear in the folder when added. In one case
@@ -1443,7 +1443,7 @@
             if (hasFocus) {
                 startEditingFolderName();
             } else {
-                mStatsLogManager.log(LAUNCHER_FOLDER_LABEL_UPDATED, mInfo.buildProto());
+                mStatsLogManager.log(LAUNCHER_FOLDER_LABEL_UPDATED, mInfo);
                 logFolderLabelState();
                 mFolderName.dispatchBackKey();
             }
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 153d6bc..098ce50 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -450,7 +450,7 @@
         }
         mInfo.setTitle(nameInfos[0].getLabel());
         StatsLogManager.newInstance(getContext())
-                .log(LAUNCHER_FOLDER_LABEL_UPDATED, instanceId, mInfo.buildProto());
+                .log(LAUNCHER_FOLDER_LABEL_UPDATED, instanceId, mInfo);
         onTitleChanged(mInfo.title);
         mFolder.mFolderName.setText(mInfo.title);
         mFolder.mLauncher.getModelWriter().updateItemInDatabase(mInfo);
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index ce70a32..e95c062 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -21,8 +21,8 @@
 
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.R;
-import com.android.launcher3.logger.LauncherAtom.ItemInfo;
 import com.android.launcher3.logging.StatsLogUtils.LogStateProvider;
+import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.util.ResourceBasedOverride;
 
 /**
@@ -191,32 +191,37 @@
     }
 
     /**
-     * Logs a {@link EventEnum}.
+     * Logs an event.
+     *
+     * @param event an enum implementing EventEnum interface.
      */
     public void log(EventEnum event) {
     }
 
     /**
-     * Logs an event and accompanying {@link InstanceId}.
+     * Logs an event.
+     *
+     * @param event an enum implementing EventEnum interface.
+     * @param instanceId an identifier obtained from an InstanceIdSequence.
      */
     public void log(EventEnum event, InstanceId instanceId) {
     }
 
     /**
-     * Logs an event and accompanying {@link ItemInfo}.
+     * Logs an event.
+     *
+     * @param event an enum implementing EventEnum interface.
+     * @param itemInfo item typically containing app or task launch related information.
      */
     public void log(EventEnum event, @Nullable ItemInfo itemInfo) {
     }
 
     /**
-     * Logs an event and accompanying {@link com.android.launcher3.model.data.ItemInfo}.
-     */
-    public void log(EventEnum event,
-            com.android.launcher3.model.data.ItemInfo itemInfo) {
-    }
-
-    /**
-     * Logs an event and accompanying {@link InstanceId} and {@link ItemInfo}.
+     * Logs an event.
+     *
+     * @param event an enum implementing EventEnum interface.
+     * @param instanceId an identifier obtained from an InstanceIdSequence.
+     * @param itemInfo item typically containing app or task launch related information.
      */
     public void log(EventEnum event, InstanceId instanceId, @Nullable ItemInfo itemInfo) {
     }
@@ -225,7 +230,7 @@
      * Log an event with ranked-choice information along with package. Does nothing if event.getId()
      * <= 0.
      *
-     * @param rankingEvent an enum implementing UiEventEnum interface.
+     * @param rankingEvent an enum implementing EventEnum interface.
      * @param instanceId An identifier obtained from an InstanceIdSequence.
      * @param packageName the package name of the relevant app, if known (null otherwise).
      * @param position the position picked.
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index d52b7eb..66c3cbb 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -24,11 +24,13 @@
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SEARCH_RESULTS;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SETTINGS;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SHORTCUTS;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_TASKSWITCHER;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_TRAY;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_TASK;
 import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.CONTAINER_NOT_SET;
 
 import android.content.ComponentName;
@@ -49,6 +51,7 @@
 import com.android.launcher3.logger.LauncherAtom.SearchResultContainer;
 import com.android.launcher3.logger.LauncherAtom.SettingsContainer;
 import com.android.launcher3.logger.LauncherAtom.ShortcutsContainer;
+import com.android.launcher3.logger.LauncherAtom.TaskSwitcherContainer;
 import com.android.launcher3.util.ContentWriter;
 
 import java.util.Optional;
@@ -298,6 +301,12 @@
                                 .setSpanX(spanX)
                                 .setSpanY(spanY));
                 break;
+            case ITEM_TYPE_TASK:
+                itemBuilder
+                        .setTask(LauncherAtom.Task.newBuilder()
+                                .setComponentName(getTargetComponent().flattenToShortString())
+                                .setIndex(screenId));
+                break;
             default:
                 break;
         }
@@ -378,6 +387,11 @@
                 return ContainerInfo.newBuilder()
                         .setSettingsContainer(SettingsContainer.getDefaultInstance())
                         .build();
+            case CONTAINER_TASKSWITCHER:
+                return ContainerInfo.newBuilder()
+                        .setTaskSwitcherContainer(TaskSwitcherContainer.getDefaultInstance())
+                        .build();
+
         }
         return ContainerInfo.getDefaultInstance();
     }
diff --git a/src/com/android/launcher3/notification/NotificationInfo.java b/src/com/android/launcher3/notification/NotificationInfo.java
index fa1bdfb..f1b63f2 100644
--- a/src/com/android/launcher3/notification/NotificationInfo.java
+++ b/src/com/android/launcher3/notification/NotificationInfo.java
@@ -108,7 +108,7 @@
             intent.send(null, 0, null, null, null, null, activityOptions);
             launcher.getUserEventDispatcher().logNotificationLaunch(view, intent);
             launcher.getStatsLogManager()
-                    .log(LAUNCHER_NOTIFICATION_LAUNCH_TAP, mItemInfo.buildProto());
+                    .log(LAUNCHER_NOTIFICATION_LAUNCH_TAP, mItemInfo);
         } catch (PendingIntent.CanceledException e) {
             e.printStackTrace();
         }
diff --git a/src/com/android/launcher3/popup/RemoteActionShortcut.java b/src/com/android/launcher3/popup/RemoteActionShortcut.java
index 58251e8..8e60c27 100644
--- a/src/com/android/launcher3/popup/RemoteActionShortcut.java
+++ b/src/com/android/launcher3/popup/RemoteActionShortcut.java
@@ -78,7 +78,7 @@
     public void onClick(View view) {
         AbstractFloatingView.closeAllOpenViews(mTarget);
         mTarget.getStatsLogManager()
-                .log(LAUNCHER_SYSTEM_SHORTCUT_PAUSE_TAP, mItemInfo.buildProto());
+                .log(LAUNCHER_SYSTEM_SHORTCUT_PAUSE_TAP, mItemInfo);
 
         final String actionIdentity = mAction.getTitle() + ", "
                 + mItemInfo.getTargetComponent().getPackageName();
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index ea8caf5..59d24de 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -119,9 +119,7 @@
             widgetsBottomSheet.populateAndShow(mItemInfo);
             mTarget.getUserEventDispatcher().logActionOnControl(Action.Touch.TAP,
                     ControlType.WIDGETS_BUTTON, view);
-            // TODO(thiruram): Fix missing container info when item is inside folder.
-            mTarget.getStatsLogManager().log(LAUNCHER_SYSTEM_SHORTCUT_WIDGETS_TAP,
-                    mItemInfo.buildProto());
+            mTarget.getStatsLogManager().log(LAUNCHER_SYSTEM_SHORTCUT_WIDGETS_TAP, mItemInfo);
         }
     }
 
@@ -142,9 +140,8 @@
                     mItemInfo, sourceBounds, ActivityOptions.makeBasic().toBundle());
             mTarget.getUserEventDispatcher().logActionOnControl(Action.Touch.TAP,
                     ControlType.APPINFO_TARGET, view);
-            // TODO(thiruram): Fix missing container info when item is inside folder.
             mTarget.getStatsLogManager()
-                    .log(LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP, mItemInfo.buildProto());
+                    .log(LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP, mItemInfo);
         }
     }