Introduce non-null `itemInfo` inside TaskView
Let `TaskView` have a non-null `itemInfo` even it has no
tasks (no corresponding TaskContainer). Thus, we can still
go forward to log the necessary info of the `TaskView`
without any tasks.
Flag: EXEMPT refactor
Fix: 391918297
Test: TaskViewItemInfoTest
Change-Id: Idd08eb9846b1cd2043dd0087bc3e0078bb0b8247
diff --git a/quickstep/src/com/android/launcher3/model/data/TaskViewItemInfo.kt b/quickstep/src/com/android/launcher3/model/data/TaskViewItemInfo.kt
index ee28d7a..c201ab1 100644
--- a/quickstep/src/com/android/launcher3/model/data/TaskViewItemInfo.kt
+++ b/quickstep/src/com/android/launcher3/model/data/TaskViewItemInfo.kt
@@ -18,6 +18,7 @@
import android.content.Context
import android.content.Intent
+import android.os.Process
import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting.Companion.PRIVATE
import com.android.launcher3.Flags.privateSpaceRestrictAccessibilityDrag
@@ -26,34 +27,40 @@
import com.android.launcher3.pm.UserCache
import com.android.quickstep.TaskUtils
import com.android.quickstep.views.TaskContainer
+import com.android.quickstep.views.TaskView
-class TaskViewItemInfo(taskContainer: TaskContainer) : WorkspaceItemInfo() {
+class TaskViewItemInfo(taskView: TaskView, taskContainer: TaskContainer?) : WorkspaceItemInfo() {
@VisibleForTesting(otherwise = PRIVATE) val taskViewAtom: LauncherAtom.TaskView
init {
itemType = LauncherSettings.Favorites.ITEM_TYPE_TASK
container = LauncherSettings.Favorites.CONTAINER_TASKSWITCHER
- val componentKey = TaskUtils.getLaunchComponentKeyForTask(taskContainer.task.key)
- user = componentKey.user
- intent = Intent().setComponent(componentKey.componentName)
- title = taskContainer.task.title
- if (privateSpaceRestrictAccessibilityDrag()) {
- if (
- UserCache.getInstance(taskContainer.taskView.context)
- .getUserInfo(componentKey.user)
- .isPrivate
- ) {
- runtimeStatusFlags = runtimeStatusFlags or ItemInfoWithIcon.FLAG_NOT_PINNABLE
+ val componentName: String
+ if (taskContainer != null) {
+ val componentKey = TaskUtils.getLaunchComponentKeyForTask(taskContainer.task.key)
+ user = componentKey.user
+ intent = Intent().setComponent(componentKey.componentName)
+ title = taskContainer.task.title
+ if (privateSpaceRestrictAccessibilityDrag()) {
+ if (
+ UserCache.getInstance(taskView.context).getUserInfo(componentKey.user).isPrivate
+ ) {
+ runtimeStatusFlags = runtimeStatusFlags or ItemInfoWithIcon.FLAG_NOT_PINNABLE
+ }
}
+ componentName = componentKey.componentName.flattenToShortString()
+ } else {
+ user = Process.myUserHandle()
+ intent = Intent()
+ componentName = ""
}
taskViewAtom =
createTaskViewAtom(
- type = taskContainer.taskView.type.ordinal,
- index =
- taskContainer.taskView.recentsView?.indexOfChild(taskContainer.taskView) ?: -1,
- componentName = componentKey.componentName.flattenToShortString(),
- cardinality = taskContainer.taskView.taskContainers.size,
+ type = taskView.type.ordinal,
+ index = taskView.recentsView?.indexOfChild(taskView) ?: -1,
+ componentName,
+ cardinality = taskView.taskContainers.size,
)
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 5f8b89a..f4400fa 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -120,7 +120,6 @@
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;
@@ -1491,7 +1490,7 @@
startShift, endShift, duration, interpolator, endTarget, velocityPxPerMs);
}
- private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTask) {
+ private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTaskView) {
if (mDp == null || !mDp.isGestureMode) {
// We probably never received an animation controller, skip logging.
return;
@@ -1509,9 +1508,9 @@
case NEW_TASK:
events.add(mLogDirectionUpOrLeft ? LAUNCHER_QUICKSWITCH_LEFT
: LAUNCHER_QUICKSWITCH_RIGHT);
- if (targetTask != null && DesktopModeStatus.canEnterDesktopMode(mContext)
+ if (targetTaskView != null && DesktopModeStatus.canEnterDesktopMode(mContext)
&& DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_QUICK_SWITCH.isTrue()) {
- if (targetTask.getType() == TaskViewType.DESKTOP) {
+ if (targetTaskView.getType() == TaskViewType.DESKTOP) {
events.add(LAUNCHER_QUICKSWITCH_ENTER_DESKTOP_MODE);
} else if (mPreviousTaskViewType == TaskViewType.DESKTOP) {
events.add(LAUNCHER_QUICKSWITCH_EXIT_DESKTOP_MODE);
@@ -1528,9 +1527,8 @@
.withInputType(mGestureState.isTrackpadGesture()
? SysUiStatsLog.LAUNCHER_UICHANGED__INPUT_TYPE__TRACKPAD
: SysUiStatsLog.LAUNCHER_UICHANGED__INPUT_TYPE__TOUCH);
- ItemInfo itemInfo;
- if (targetTask != null && (itemInfo = targetTask.getFirstItemInfo()) != null) {
- logger.withItemInfo(itemInfo);
+ if (targetTaskView != null) {
+ logger.withItemInfo(targetTaskView.getItemInfo());
}
int pageIndex = endTarget == LAST_TASK || mRecentsView == null
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index ee1d8a6..deeaacc 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -135,7 +135,7 @@
public SplitSelectSystemShortcut(RecentsViewContainer container,
TaskContainer taskContainer, TaskView taskView,
SplitPositionOption option) {
- super(option.iconResId, option.textResId, container, taskView.getFirstItemInfo(),
+ super(option.iconResId, option.textResId, container, taskContainer.getItemInfo(),
taskView);
mTaskContainer = taskContainer;
mSplitPositionOption = option;
@@ -163,8 +163,7 @@
public SaveAppPairSystemShortcut(RecentsViewContainer container, GroupedTaskView taskView,
int iconResId) {
- super(iconResId, R.string.save_app_pair, container, taskView.getFirstItemInfo(),
- taskView);
+ super(iconResId, R.string.save_app_pair, container, taskView.getItemInfo(), taskView);
mTaskView = taskView;
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 1b59f5b..79685ac 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -4085,9 +4085,8 @@
} else {
removeTaskInternal(dismissedTaskView);
}
- // TODO(b/391918297): Logging when the TaskView does not have tasks as well.
mContainer.getStatsLogManager().logger()
- .withItemInfo(dismissedTaskView.getFirstItemInfo())
+ .withItemInfo(dismissedTaskView.getItemInfo())
.log(LAUNCHER_TASK_DISMISS_SWIPE_UP);
}
@@ -5772,12 +5771,8 @@
} else {
taskView.launchWithoutAnimation(this::onTaskLaunchAnimationEnd);
}
- // 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);
- }
+ mContainer.getStatsLogManager().logger().withItemInfo(taskView.getItemInfo())
+ .log(LAUNCHER_TASK_LAUNCH_SWIPE_DOWN);
} else {
onTaskLaunchAnimationEnd(false);
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskContainer.kt b/quickstep/src/com/android/quickstep/views/TaskContainer.kt
index a9e84ef..2c6ecb1 100644
--- a/quickstep/src/com/android/quickstep/views/TaskContainer.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskContainer.kt
@@ -106,7 +106,7 @@
/** Builds proto for logging */
val itemInfo: TaskViewItemInfo
- get() = TaskViewItemInfo(this)
+ get() = TaskViewItemInfo(taskView, this)
fun bind() {
digitalWellBeingToast?.bind(task, taskView, snapshotView, stagePosition)
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt
index 9807b0d..15982ad 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskView.kt
@@ -55,6 +55,7 @@
import com.android.launcher3.anim.AnimatedFloat
import com.android.launcher3.logging.StatsLogManager.LauncherEvent
import com.android.launcher3.model.data.ItemInfo
+import com.android.launcher3.model.data.TaskViewItemInfo
import com.android.launcher3.testing.TestLogging
import com.android.launcher3.testing.shared.TestProtocol
import com.android.launcher3.util.CancellableTask
@@ -170,6 +171,15 @@
val firstItemInfo: ItemInfo?
get() = firstTaskContainer?.itemInfo
+ /**
+ * A [TaskViewItemInfo] of this TaskView. The [firstTaskContainer] will be used to get some
+ * specific information like user, title etc of the Task. However, these task specific
+ * information will be skipped if the TaskView has no [taskContainers]. Note, please use
+ * [TaskContainer.itemInfo] for [TaskViewItemInfo] on a specific [TaskContainer].
+ */
+ val itemInfo: TaskViewItemInfo
+ get() = TaskViewItemInfo(this, firstTaskContainer)
+
protected val container: RecentsViewContainer =
RecentsViewContainer.containerFromContext(context)
protected val lastTouchDownPosition = PointF()
@@ -1104,13 +1114,10 @@
}
}
Log.d("b/310064698", "${taskIds.contentToString()} - onClick - callbackList: $callbackList")
- // TODO(b/391918297): Logging when there is no associated task.
- firstItemInfo?.let {
- container.statsLogManager
- .logger()
- .withItemInfo(it)
- .log(LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP)
- }
+ container.statsLogManager
+ .logger()
+ .withItemInfo(itemInfo)
+ .log(LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP)
}
/** Launch of the current task (both live and inactive tasks) with an animation. */
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/model/data/TaskViewItemInfoTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/model/data/TaskViewItemInfoTest.kt
index be71640..de0da64 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/model/data/TaskViewItemInfoTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/model/data/TaskViewItemInfoTest.kt
@@ -18,6 +18,7 @@
import android.content.ComponentName
import android.content.Intent
+import android.os.Process
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import com.android.launcher3.Flags.enableRefactorTaskThumbnail
@@ -33,7 +34,6 @@
import com.android.launcher3.util.UserIconInfo
import com.android.quickstep.TaskOverlayFactory
import com.android.quickstep.TaskOverlayFactory.TaskOverlay
-import com.android.quickstep.TestComponent
import com.android.quickstep.recents.di.RecentsDependencies
import com.android.quickstep.task.thumbnail.TaskThumbnailView
import com.android.quickstep.views.RecentsView
@@ -84,7 +84,7 @@
whenever(taskView.type).thenReturn(TaskViewType.SINGLE)
whenever(taskView.taskContainers).thenReturn(taskContainers)
- val taskViewItemInfo = TaskViewItemInfo(taskContainers[0])
+ val taskViewItemInfo = TaskViewItemInfo(taskContainers[0].taskView, taskContainers[0])
assertThat(taskViewItemInfo.taskViewAtom)
.isEqualTo(
@@ -105,7 +105,7 @@
whenever(taskView.type).thenReturn(TaskViewType.GROUPED)
whenever(taskView.taskContainers).thenReturn(taskContainers)
- val taskViewItemInfo = TaskViewItemInfo(taskContainers[0])
+ val taskViewItemInfo = TaskViewItemInfo(taskContainers[0].taskView, taskContainers[0])
assertThat(taskViewItemInfo.taskViewAtom)
.isEqualTo(
@@ -130,7 +130,7 @@
whenever(taskView.type).thenReturn(TaskViewType.DESKTOP)
whenever(taskView.taskContainers).thenReturn(taskContainers)
- val taskViewItemInfo = TaskViewItemInfo(taskContainers[0])
+ val taskViewItemInfo = TaskViewItemInfo(taskContainers[0].taskView, taskContainers[0])
assertThat(taskViewItemInfo.taskViewAtom)
.isEqualTo(
@@ -151,7 +151,7 @@
whenever(taskView.taskContainers).thenReturn(taskContainers)
whenever(userInfo.isPrivate).thenReturn(true)
- val taskViewItemInfo = TaskViewItemInfo(taskContainers[0])
+ val taskViewItemInfo = TaskViewItemInfo(taskContainers[0].taskView, taskContainers[0])
assertThat(taskViewItemInfo.taskViewAtom)
.isEqualTo(
@@ -166,6 +166,25 @@
.isEqualTo(FLAG_NOT_PINNABLE)
}
+ @Test
+ fun emptyDesktopTask() {
+ whenever(taskView.type).thenReturn(TaskViewType.DESKTOP)
+
+ val taskViewItemInfo = TaskViewItemInfo(taskView = taskView, taskContainer = null)
+
+ assertThat(taskViewItemInfo.taskViewAtom)
+ .isEqualTo(
+ createTaskViewAtom(
+ type = 2,
+ index = TASK_VIEW_INDEX,
+ componentName = "",
+ cardinality = 0,
+ )
+ )
+ assertThat(taskViewItemInfo.user).isEqualTo(Process.myUserHandle())
+ assertThat(taskViewItemInfo.intent).isNotNull()
+ }
+
private fun createTask(id: Int) =
Task(TaskKey(id, 0, Intent(), ComponentName(PACKAGE, CLASS), 0, 2000))