Refactor TaskView to allow no TaskContainers

Flag: EXEMPT refactor
Bug: 391918297
Test: m
Change-Id: I3343da2b6d73a0b0283334a37be5ae288d94f776
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index 2b296c8..f582324 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -149,9 +149,9 @@
         mOverviewPanel.setFullscreenProgress(progress);
         if (progress > UPDATE_SYSUI_FLAGS_THRESHOLD) {
             int sysuiFlags = 0;
-            TaskView tv = mOverviewPanel.getFirstTaskView();
-            if (tv != null) {
-                sysuiFlags = tv.getSysUiStatusNavFlags();
+            TaskView firstTaskView = mOverviewPanel.getFirstTaskView();
+            if (firstTaskView != null) {
+                sysuiFlags = firstTaskView.getSysUiStatusNavFlags();
             }
             mLauncher.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, sysuiFlags);
         } else {
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 78e543c..5f8b89a 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -120,6 +120,7 @@
 import com.android.launcher3.dragndrop.DragView;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.logging.StatsLogManager.StatsLogger;
+import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.statemanager.BaseState;
 import com.android.launcher3.statemanager.StatefulContainer;
 import com.android.launcher3.taskbar.TaskbarThresholdUtils;
@@ -1527,8 +1528,9 @@
                 .withInputType(mGestureState.isTrackpadGesture()
                         ? SysUiStatsLog.LAUNCHER_UICHANGED__INPUT_TYPE__TRACKPAD
                         : SysUiStatsLog.LAUNCHER_UICHANGED__INPUT_TYPE__TOUCH);
-        if (targetTask != null) {
-            logger.withItemInfo(targetTask.getFirstItemInfo());
+        ItemInfo itemInfo;
+        if (targetTask != null && (itemInfo = targetTask.getFirstItemInfo()) != null) {
+            logger.withItemInfo(itemInfo);
         }
 
         int pageIndex = endTarget == LAST_TASK || mRecentsView == null
@@ -2369,9 +2371,6 @@
                 ActiveGestureLog.CompoundString nextTaskLog =
                         ActiveGestureLog.CompoundString.newEmptyString();
                 for (TaskContainer container : nextTask.getTaskContainers()) {
-                    if (container == null) {
-                        continue;
-                    }
                     nextTaskLog.append("[id: %d, pkg: %s] | ",
                             container.getTask().key.id,
                             container.getTask().key.getPackageName());
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index c60d3e8..e1e9c99 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -56,6 +56,7 @@
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.animation.TransitionAnimator;
+import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.system.InputConsumerController;
 
 import java.util.Collections;
@@ -300,7 +301,9 @@
             // Disable if swiping to PIP
             return null;
         }
-        if (sourceTaskView == null || sourceTaskView.getFirstTask().key.getComponent() == null) {
+        Task firstTask;
+        if (sourceTaskView == null || ((firstTask = sourceTaskView.getFirstTask()) == null)
+                || firstTask.key.getComponent() == null) {
             // Disable if it's an invalid task
             return null;
         }
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index ff9c9f6..0772159 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -233,7 +233,7 @@
             RecentsView overviewPanel = mTaskContainer.getTaskView().getRecentsView();
             // Task has already been dismissed
             if (overviewPanel == null) return;
-            overviewPanel.initiateSplitSelect(mTaskContainer.getTaskView());
+            overviewPanel.initiateSplitSelect(mTaskContainer);
         }
 
         protected void saveAppPair() {
@@ -369,7 +369,7 @@
 
             @Override
             public void onClick(View view) {
-                saveScreenshot(mTaskContainer.getTaskView().getFirstTask());
+                saveScreenshot(mTaskContainer.getTask());
                 dismissTaskMenuView();
             }
         }
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index ab5e830..ee1d8a6 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -48,6 +48,7 @@
 import com.android.launcher3.popup.SystemShortcut;
 import com.android.launcher3.popup.SystemShortcut.AppInfo;
 import com.android.launcher3.util.InstantAppResolver;
+import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
 import com.android.launcher3.views.ActivityContext;
 import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
@@ -128,20 +129,28 @@
     };
 
     class SplitSelectSystemShortcut extends SystemShortcut {
-        private final TaskView mTaskView;
+        private final TaskContainer mTaskContainer;
         private final SplitPositionOption mSplitPositionOption;
 
-        public SplitSelectSystemShortcut(RecentsViewContainer container, TaskView taskView,
+        public SplitSelectSystemShortcut(RecentsViewContainer container,
+                TaskContainer taskContainer, TaskView taskView,
                 SplitPositionOption option) {
             super(option.iconResId, option.textResId, container, taskView.getFirstItemInfo(),
                     taskView);
-            mTaskView = taskView;
+            mTaskContainer = taskContainer;
             mSplitPositionOption = option;
         }
 
         @Override
         public void onClick(View view) {
-            mTaskView.initiateSplitSelect(mSplitPositionOption);
+            RecentsView recentsView = mTaskContainer.getTaskView().getRecentsView();
+            if (recentsView != null) {
+                recentsView.initiateSplitSelect(
+                        mTaskContainer,
+                        mSplitPositionOption.stagePosition,
+                        SplitConfigurationOptions.getLogEventForPosition(
+                                mSplitPositionOption.stagePosition));
+            }
         }
     }
 
@@ -152,7 +161,6 @@
     class SaveAppPairSystemShortcut extends SystemShortcut<RecentsViewContainer> {
         private final GroupedTaskView mTaskView;
 
-
         public SaveAppPairSystemShortcut(RecentsViewContainer container, GroupedTaskView taskView,
             int iconResId) {
             super(iconResId, R.string.save_app_pair, container, taskView.getFirstItemInfo(),
@@ -202,14 +210,14 @@
         }
 
         private void startActivity() {
-            final Task.TaskKey taskKey = mTaskView.getFirstTask().key;
-            final int taskId = taskKey.id;
             final ActivityOptions options = makeLaunchOptions(mTarget);
-            if (options != null) {
-                options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
+            if (options == null) {
+                return;
             }
-            if (options != null
-                    && ActivityManagerWrapper.getInstance().startActivityFromRecents(taskId,
+            final Task.TaskKey taskKey = mTaskContainer.getTask().key;
+            final int taskId = taskKey.id;
+            options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
+            if (ActivityManagerWrapper.getInstance().startActivityFromRecents(taskId,
                     options)) {
                 final Runnable animStartedListener = () -> {
                     // Hide the task view and wait for the window to be resized
@@ -252,8 +260,8 @@
                 overridePendingAppTransitionMultiThumbFuture(
                         future, animStartedListener, mHandler, true /* scaleUp */,
                         taskKey.displayId);
-                mTarget.getStatsLogManager().logger().withItemInfo(mTaskView.getFirstItemInfo())
-                        .log(mLauncherEvent);
+                mTarget.getStatsLogManager().logger().withItemInfo(mTaskContainer.getItemInfo())
+                            .log(mLauncherEvent);
             }
         }
 
@@ -327,7 +335,8 @@
             return orientationHandler.getSplitPositionOptions(deviceProfile)
                     .stream()
                     .map((Function<SplitPositionOption, SystemShortcut>) option ->
-                            new SplitSelectSystemShortcut(container, taskView, option))
+                            new SplitSelectSystemShortcut(container, taskContainer, taskView,
+                                    option))
                     .collect(Collectors.toList());
         }
     };
@@ -420,24 +429,24 @@
 
         private static final String TAG = "PinSystemShortcut";
 
-        private final TaskView mTaskView;
+        private final TaskContainer mTaskContainer;
 
         public PinSystemShortcut(RecentsViewContainer target,
                 TaskContainer taskContainer) {
             super(R.drawable.ic_pin, R.string.recent_task_option_pin, target,
                     taskContainer.getItemInfo(), taskContainer.getTaskView());
-            mTaskView = taskContainer.getTaskView();
+            mTaskContainer = taskContainer;
         }
 
         @Override
         public void onClick(View view) {
-            if (mTaskView.launchAsStaticTile() != null) {
+            if (mTaskContainer.getTaskView().launchAsStaticTile() != null) {
                 SystemUiProxy.INSTANCE.get(mTarget.asContext()).startScreenPinning(
-                        mTaskView.getFirstTask().key.id);
+                        mTaskContainer.getTask().key.id);
             }
             dismissTaskMenuView();
-            mTarget.getStatsLogManager().logger().withItemInfo(mTaskView.getFirstItemInfo())
-                    .log(LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_PIN_TAP);
+            mTarget.getStatsLogManager().logger().withItemInfo(mTaskContainer.getItemInfo())
+                        .log(LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_PIN_TAP);
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 3133907..e47223b 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -123,8 +123,9 @@
             int userId = itemInfo.user.getIdentifier();
             if (componentName != null) {
                 for (TaskView taskView : recentsView.getTaskViews()) {
-                    if (recentsView.isTaskViewVisible(taskView)) {
-                        Task.TaskKey key = taskView.getFirstTask().key;
+                    Task firstTask = taskView.getFirstTask();
+                    if (firstTask != null && recentsView.isTaskViewVisible(taskView)) {
+                        Task.TaskKey key = firstTask.key;
                         if (componentName.equals(key.getComponent()) && userId == key.userId) {
                             return taskView;
                         }
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index fff7e9b..8d010e2 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -52,6 +52,7 @@
 import com.android.quickstep.views.OverviewActionsView;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.RecentsViewContainer;
+import com.android.quickstep.views.TaskContainer;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.recents.model.Task;
 
@@ -239,10 +240,10 @@
     }
 
     @Override
-    public void initiateSplitSelect(TaskView taskView,
+    public void initiateSplitSelect(TaskContainer taskContainer,
             @SplitConfigurationOptions.StagePosition int stagePosition,
             StatsLogManager.EventEnum splitEvent) {
-        super.initiateSplitSelect(taskView, stagePosition, splitEvent);
+        super.initiateSplitSelect(taskContainer, stagePosition, splitEvent);
         mContainer.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
     }
 
diff --git a/quickstep/src/com/android/quickstep/util/AppPairsController.java b/quickstep/src/com/android/quickstep/util/AppPairsController.java
index 6b8650f..54ff0c4 100644
--- a/quickstep/src/com/android/quickstep/util/AppPairsController.java
+++ b/quickstep/src/com/android/quickstep/util/AppPairsController.java
@@ -134,6 +134,8 @@
 
         GroupedTaskView gtv = (GroupedTaskView) taskView;
         List<TaskContainer> containers = gtv.getTaskContainers();
+        // TODO(b/391918297): Replace `taskContainers[x]` with `leftTopTaskContainer` and
+        //  `rightBottomTaskContainer`.
         ComponentKey taskKey1 = TaskUtils.getLaunchComponentKeyForTask(
                 containers.get(0).getTask().key);
         ComponentKey taskKey2 = TaskUtils.getLaunchComponentKeyForTask(
@@ -183,9 +185,8 @@
             return;
         }
 
-        List<TaskContainer> containers = gtv.getTaskContainers();
         List<TaskViewItemInfo> recentsInfos =
-                containers.stream().map(TaskContainer::getItemInfo).toList();
+                gtv.getTaskContainers().stream().map(TaskContainer::getItemInfo).toList();
         List<WorkspaceItemInfo> apps =
                 recentsInfos.stream().map(this::resolveAppPairWorkspaceInfo).toList();
 
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
index 38ffe50..0187b58 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
@@ -191,9 +191,7 @@
             val bottomRightTaskPercent = 1 - topLeftTaskPercent
             taskContainers[0]
                 .iconView
-                .setFlexSplitAlpha(
-                    if (topLeftTaskPercent < MINIMUM_RATIO_TO_SHOW_ICON) 0f else 1f
-                )
+                .setFlexSplitAlpha(if (topLeftTaskPercent < MINIMUM_RATIO_TO_SHOW_ICON) 0f else 1f)
             taskContainers[1]
                 .iconView
                 .setFlexSplitAlpha(
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 9be462c..c6bd677 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -36,7 +36,6 @@
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.desktop.DesktopRecentsTransitionController;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.statehandlers.DepthController;
@@ -127,9 +126,11 @@
         // If Launcher needs to return to split select state, do it now, after the icon has updated.
         if (mContainer.hasPendingSplitSelectInfo()) {
             PendingSplitSelectInfo recoveryData = mContainer.getPendingSplitSelectInfo();
-            if (recoveryData.getStagedTaskId() == taskId) {
+            TaskContainer taskContainer;
+            if (recoveryData != null && recoveryData.getStagedTaskId() == taskId && (taskContainer =
+                    mUtils.getTaskContainerById(taskId)) != null) {
                 initiateSplitSelect(
-                        getTaskViewByTaskId(recoveryData.getStagedTaskId()),
+                        taskContainer,
                         recoveryData.getStagePosition(), recoveryData.getSource()
                 );
                 mContainer.finishSplitSelectRecovery();
@@ -240,10 +241,10 @@
     }
 
     @Override
-    public void initiateSplitSelect(TaskView taskView,
+    public void initiateSplitSelect(TaskContainer taskContainer,
             @SplitConfigurationOptions.StagePosition int stagePosition,
             StatsLogManager.EventEnum splitEvent) {
-        super.initiateSplitSelect(taskView, stagePosition, splitEvent);
+        super.initiateSplitSelect(taskContainer, stagePosition, splitEvent);
         getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 1c8299d..5ee8bcd 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -652,13 +652,13 @@
                 return;
             }
 
-            TaskView taskView = getTaskViewByTaskId(taskId);
-            if (taskView == null) {
-                Log.d(TAG, "onTaskRemoved: " + taskId + ", no associated TaskView");
+            TaskContainer taskContainer = mUtils.getTaskContainerById(taskId);
+            if (taskContainer == null) {
+                Log.d(TAG, "onTaskRemoved: " + taskId + ", no associated Task");
                 return;
             }
             Log.d(TAG, "onTaskRemoved: " + taskId);
-            Task.TaskKey taskKey = taskView.getFirstTask().key;
+            Task.TaskKey taskKey = taskContainer.getTask().key;
             UI_HELPER_EXECUTOR.execute(new CancellableTask<>(
                     () -> PackageManagerWrapper.getInstance()
                             .getActivityInfo(taskKey.getComponent(), taskKey.userId) == null,
@@ -847,7 +847,7 @@
 
     private final RecentsViewModel mRecentsViewModel;
     private final RecentsViewModelHelper mHelper;
-    private final RecentsViewUtils mUtils = new RecentsViewUtils(this);
+    protected final RecentsViewUtils mUtils = new RecentsViewUtils(this);
 
     private final Matrix mTmpMatrix = new Matrix();
 
@@ -1117,7 +1117,7 @@
                 TaskView taskView = getTaskViewByTaskId(taskId);
                 if (taskView != null) {
                     for (TaskContainer container : taskView.getTaskContainers()) {
-                        if (container == null || taskId != container.getTask().key.id) {
+                        if (taskId != container.getTask().key.id) {
                             continue;
                         }
                         container.getThumbnailViewDeprecated().setThumbnail(container.getTask(),
@@ -1132,9 +1132,10 @@
     @Override
     public void onTaskIconChanged(@NonNull String pkg, @NonNull UserHandle user) {
         for (TaskView taskView : getTaskViews()) {
-            Task task = taskView.getFirstTask();
-            if (pkg.equals(task.key.getPackageName()) && task.key.userId == user.getIdentifier()) {
-                task.icon = null;
+            Task firstTask = taskView.getFirstTask();
+            if (firstTask != null && pkg.equals(firstTask.key.getPackageName())
+                    && firstTask.key.userId == user.getIdentifier()) {
+                firstTask.icon = null;
                 if (taskView.getTaskContainers().stream().anyMatch(
                         container -> container.getIconView().getDrawable() != null)) {
                     taskView.onTaskListVisibilityChanged(true /* visible */);
@@ -4084,6 +4085,7 @@
                         } else {
                             removeTaskInternal(dismissedTaskView);
                         }
+                        // TODO(b/391918297): Logging when the TaskView does not have tasks as well.
                         mContainer.getStatsLogManager().logger()
                                 .withItemInfo(dismissedTaskView.getFirstItemInfo())
                                 .log(LAUNCHER_TASK_DISMISS_SWIPE_UP);
@@ -5171,18 +5173,20 @@
      * Primarily used by overview actions to initiate split from focused task, logs the source
      * of split invocation as such.
      */
-    public void initiateSplitSelect(TaskView taskView) {
+    public void initiateSplitSelect(TaskContainer taskContainer) {
         int defaultSplitPosition = getPagedOrientationHandler()
                 .getDefaultSplitPosition(mContainer.getDeviceProfile());
-        initiateSplitSelect(taskView, defaultSplitPosition, LAUNCHER_OVERVIEW_ACTIONS_SPLIT);
+        initiateSplitSelect(taskContainer, defaultSplitPosition, LAUNCHER_OVERVIEW_ACTIONS_SPLIT);
     }
 
     /** TODO(b/266477929): Consolidate this call w/ the one below */
-    public void initiateSplitSelect(TaskView taskView, @StagePosition int stagePosition,
+    public void initiateSplitSelect(TaskContainer taskContainer,
+            @StagePosition int stagePosition,
             StatsLogManager.EventEnum splitEvent) {
+        TaskView taskView = taskContainer.getTaskView();
         mSplitHiddenTaskView = taskView;
         mSplitSelectStateController.setInitialTaskSelect(null /*intent*/, stagePosition,
-                taskView.getFirstItemInfo(), splitEvent, taskView.getFirstTask().key.id);
+                taskContainer.getItemInfo(), splitEvent, taskContainer.getTask().key.id);
         mSplitSelectStateController.setAnimateCurrentTaskDismissal(
                 true /*animateCurrentTaskDismissal*/);
         mSplitHiddenTaskViewIndex = indexOfChild(taskView);
@@ -5278,6 +5282,8 @@
             createInitialSplitSelectAnimation(builder);
 
             // Animate pair thumbnail into full thumbnail
+            // TODO(b/391918297): Use `leftTopTaskContainer` that will be introduced inside
+            //  `appPairsController`.
             boolean primaryTaskSelected = mSplitHiddenTaskView.getTaskIds()[0]
                     == mSplitSelectStateController.getInitialTaskId();
             TaskContainer taskContainer = mSplitHiddenTaskView
@@ -5767,8 +5773,12 @@
                 } else {
                     taskView.launchWithoutAnimation(this::onTaskLaunchAnimationEnd);
                 }
-                mContainer.getStatsLogManager().logger().withItemInfo(taskView.getFirstItemInfo())
-                        .log(LAUNCHER_TASK_LAUNCH_SWIPE_DOWN);
+                // TODO(b/391918297): Logging when there is no associated task.
+                ItemInfo firstItemInfo = taskView.getFirstItemInfo();
+                if (firstItemInfo != null) {
+                    mContainer.getStatsLogManager().logger().withItemInfo(firstItemInfo)
+                            .log(LAUNCHER_TASK_LAUNCH_SWIPE_DOWN);
+                }
             } else {
                 onTaskLaunchAnimationEnd(false);
             }
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt
index bce5a5e..94e8c03 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt
@@ -224,6 +224,9 @@
     /** Returns true if there are at least one TaskView has been added to the RecentsView. */
     fun hasTaskViews() = taskViews.any()
 
+    fun getTaskContainerById(taskId: Int) =
+        taskViews.firstNotNullOfOrNull { it.getTaskContainerById(taskId) }
+
     private fun getRowRect(firstView: View?, lastView: View?, outRowRect: Rect) {
         outRowRect.setEmpty()
         firstView?.let {
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt
index 20a385f..9807b0d 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskView.kt
@@ -33,7 +33,6 @@
 import android.view.Display
 import android.view.MotionEvent
 import android.view.View
-import android.view.View.OnClickListener
 import android.view.ViewGroup
 import android.view.ViewStub
 import android.view.accessibility.AccessibilityNodeInfo
@@ -64,9 +63,7 @@
 import com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE
 import com.android.launcher3.util.MultiValueAlpha
 import com.android.launcher3.util.RunnableList
-import com.android.launcher3.util.SplitConfigurationOptions
 import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
-import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption
 import com.android.launcher3.util.SplitConfigurationOptions.StagePosition
 import com.android.launcher3.util.TraceHelper
 import com.android.launcher3.util.TransformingTouchDelegate
@@ -163,14 +160,15 @@
     val pagedOrientationHandler: RecentsPagedOrientationHandler
         get() = orientedState.orientationHandler
 
-    @get:Deprecated("Use [taskContainers] instead.")
-    val firstTask: Task
-        /** Returns the first task bound to this TaskView. */
-        get() = taskContainers[0].task
+    val firstTaskContainer: TaskContainer?
+        get() = taskContainers.firstOrNull()
 
-    @get:Deprecated("Use [taskContainers] instead.")
-    val firstItemInfo: ItemInfo
-        get() = taskContainers[0].itemInfo
+    val firstTask: Task?
+        /** Returns the first task bound to this TaskView. */
+        get() = firstTaskContainer?.task
+
+    val firstItemInfo: ItemInfo?
+        get() = firstTaskContainer?.itemInfo
 
     protected val container: RecentsViewContainer =
         RecentsViewContainer.containerFromContext(context)
@@ -942,7 +940,7 @@
     protected open fun updateThumbnailSize() {
         // TODO(b/271468547), we should default to setting translations only on the snapshot instead
         //  of a hybrid of both margins and translations
-        taskContainers[0].snapshotView.updateLayoutParams<LayoutParams> {
+        firstTaskContainer?.snapshotView?.updateLayoutParams<LayoutParams> {
             topMargin = container.deviceProfile.overviewTaskThumbnailTopMarginPx
         }
         taskContainers.forEach { it.digitalWellBeingToast?.setupLayout() }
@@ -1106,10 +1104,13 @@
                 }
             }
         Log.d("b/310064698", "${taskIds.contentToString()} - onClick - callbackList: $callbackList")
-        container.statsLogManager
-            .logger()
-            .withItemInfo(firstItemInfo)
-            .log(LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP)
+        // TODO(b/391918297): Logging when there is no associated task.
+        firstItemInfo?.let {
+            container.statsLogManager
+                .logger()
+                .withItemInfo(it)
+                .log(LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP)
+        }
     }
 
     /** Launch of the current task (both live and inactive tasks) with an animation. */
@@ -1212,6 +1213,7 @@
      * @return CompletionStage to indicate the animation completion or null if the launch failed.
      */
     open fun launchAsStaticTile(): RunnableList? {
+        val firstTaskContainer = firstTaskContainer ?: return null
         TestLogging.recordEvent(
             TestProtocol.SEQUENCE_MAIN,
             "startActivityFromRecentsAsync",
@@ -1223,7 +1225,7 @@
             }
         if (
             ActivityManagerWrapper.getInstance()
-                .startActivityFromRecents(taskContainers[0].task.key, opts.options)
+                .startActivityFromRecents(firstTaskContainer.task.key, opts.options)
         ) {
             Log.d(
                 TAG,
@@ -1262,18 +1264,18 @@
         isQuickSwitch: Boolean = false,
         callback: (launched: Boolean) -> Unit,
     ) {
+        val firstTaskContainer = firstTaskContainer ?: return
         TestLogging.recordEvent(
             TestProtocol.SEQUENCE_MAIN,
             "startActivityFromRecentsAsync",
             taskIds.contentToString(),
         )
-        val firstContainer = taskContainers[0]
         val failureListener = TaskRemovedDuringLaunchListener(context.applicationContext)
         if (isQuickSwitch) {
             // We only listen for failures to launch in quickswitch because the during this
             // gesture launcher is in the background state, vs other launches which are in
             // the actual overview state
-            failureListener.register(container, firstContainer.task.key.id) {
+            failureListener.register(container, firstTaskContainer.task.key.id) {
                 notifyTaskLaunchFailed("launchWithoutAnimation")
                 recentsView?.let {
                     // Disable animations for now, as it is an edge case and the app usually
@@ -1305,12 +1307,12 @@
                     if (isQuickSwitch) {
                         setFreezeRecentTasksReordering()
                     }
-                    disableStartingWindow = firstContainer.shouldShowSplashView
+                    disableStartingWindow = firstTaskContainer.shouldShowSplashView
                 }
         Executors.UI_HELPER_EXECUTOR.execute {
             if (
                 !ActivityManagerWrapper.getInstance()
-                    .startActivityFromRecents(firstContainer.task.key, opts)
+                    .startActivityFromRecents(firstTaskContainer.task.key, opts)
             ) {
                 // If the call to start activity failed, then post the result immediately,
                 // otherwise, wait for the animation start callback from the activity options
@@ -1337,14 +1339,6 @@
         Toast.makeText(context, R.string.activity_not_available, Toast.LENGTH_SHORT).show()
     }
 
-    fun initiateSplitSelect(splitPositionOption: SplitPositionOption) {
-        recentsView?.initiateSplitSelect(
-            this,
-            splitPositionOption.stagePosition,
-            SplitConfigurationOptions.getLogEventForPosition(splitPositionOption.stagePosition),
-        )
-    }
-
     /**
      * Returns `true` if user is already in split select mode and this tap was to choose the second
      * app. `false` otherwise
diff --git a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
index f923142..c78fe1c 100644
--- a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
+++ b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
@@ -21,6 +21,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import android.app.PendingIntent;
@@ -93,7 +94,8 @@
         final TaskView task = getOnceNotNull("No latest task", launcher -> getLatestTask(launcher));
 
         return getFromLauncher(launcher -> {
-            TaskContainer taskContainer = task.getTaskContainers().get(0);
+            TaskContainer taskContainer = task.getFirstTaskContainer();
+            assertNotNull(taskContainer);
             assertTrue("Latest task is not Calculator", calculatorPackage.equals(
                     taskContainer.getTask().getTopComponent().getPackageName()));
             return taskContainer.getDigitalWellBeingToast();