Merge "Refactor: Extract GetThumbnailPositionUseCase from TTVM" into main
diff --git a/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt b/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
index d2f10b6..4b3bef3 100644
--- a/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
+++ b/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
@@ -28,15 +28,14 @@
 import com.android.quickstep.recents.data.TasksRepository
 import com.android.quickstep.recents.domain.usecase.GetSysUiStatusNavFlagsUseCase
 import com.android.quickstep.recents.domain.usecase.GetTaskUseCase
+import com.android.quickstep.recents.domain.usecase.GetThumbnailPositionUseCase
 import com.android.quickstep.recents.domain.usecase.IsThumbnailValidUseCase
 import com.android.quickstep.recents.domain.usecase.OrganizeDesktopTasksUseCase
-import com.android.quickstep.recents.usecase.GetThumbnailPositionUseCase
 import com.android.quickstep.recents.usecase.GetThumbnailUseCase
 import com.android.quickstep.recents.viewmodel.RecentsViewData
 import com.android.quickstep.task.viewmodel.TaskOverlayViewModel
-import com.android.quickstep.task.viewmodel.TaskThumbnailViewModel
-import com.android.quickstep.task.viewmodel.TaskThumbnailViewModelImpl
 import com.android.systemui.shared.recents.model.Task
+import com.android.systemui.shared.recents.utilities.PreviewPositionHelper
 import kotlinx.coroutines.CoroutineName
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.SupervisorJob
@@ -173,8 +172,6 @@
         val instance: Any =
             when (modelClass) {
                 RecentsViewData::class.java -> RecentsViewData()
-                TaskThumbnailViewModel::class.java ->
-                    TaskThumbnailViewModelImpl(getThumbnailPositionUseCase = inject())
                 TaskOverlayViewModel::class.java -> {
                     val task = extras["Task"] as Task
                     TaskOverlayViewModel(
@@ -194,7 +191,7 @@
                     GetThumbnailPositionUseCase(
                         deviceProfileRepository = inject(),
                         rotationStateRepository = inject(),
-                        tasksRepository = inject(),
+                        previewPositionHelper = PreviewPositionHelper(),
                     )
                 OrganizeDesktopTasksUseCase::class.java -> OrganizeDesktopTasksUseCase()
                 else -> {
diff --git a/quickstep/src/com/android/quickstep/recents/usecase/GetThumbnailPositionUseCase.kt b/quickstep/src/com/android/quickstep/recents/domain/usecase/GetThumbnailPositionUseCase.kt
similarity index 62%
rename from quickstep/src/com/android/quickstep/recents/usecase/GetThumbnailPositionUseCase.kt
rename to quickstep/src/com/android/quickstep/recents/domain/usecase/GetThumbnailPositionUseCase.kt
index bea1d07..8501382 100644
--- a/quickstep/src/com/android/quickstep/recents/usecase/GetThumbnailPositionUseCase.kt
+++ b/quickstep/src/com/android/quickstep/recents/domain/usecase/GetThumbnailPositionUseCase.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,28 +14,30 @@
  * limitations under the License.
  */
 
-package com.android.quickstep.recents.usecase
+package com.android.quickstep.recents.domain.usecase
 
 import android.graphics.Matrix
 import android.graphics.Rect
-import com.android.quickstep.recents.data.RecentTasksRepository
 import com.android.quickstep.recents.data.RecentsDeviceProfileRepository
 import com.android.quickstep.recents.data.RecentsRotationStateRepository
-import com.android.quickstep.recents.usecase.ThumbnailPositionState.MatrixScaling
-import com.android.quickstep.recents.usecase.ThumbnailPositionState.MissingThumbnail
+import com.android.systemui.shared.recents.model.ThumbnailData
 import com.android.systemui.shared.recents.utilities.PreviewPositionHelper
 
 /** Use case for retrieving [Matrix] for positioning Thumbnail in a View */
 class GetThumbnailPositionUseCase(
     private val deviceProfileRepository: RecentsDeviceProfileRepository,
     private val rotationStateRepository: RecentsRotationStateRepository,
-    private val tasksRepository: RecentTasksRepository,
-    private val previewPositionHelper: PreviewPositionHelper = PreviewPositionHelper(),
+    private val previewPositionHelper: PreviewPositionHelper,
 ) {
-    fun run(taskId: Int, width: Int, height: Int, isRtl: Boolean): ThumbnailPositionState {
-        val thumbnailData =
-            tasksRepository.getCurrentThumbnailById(taskId) ?: return MissingThumbnail
-        val thumbnail = thumbnailData.thumbnail ?: return MissingThumbnail
+    operator fun invoke(
+        thumbnailData: ThumbnailData?,
+        width: Int,
+        height: Int,
+        isRtl: Boolean,
+    ): ThumbnailPosition {
+        val thumbnail =
+            thumbnailData?.thumbnail ?: return ThumbnailPosition(Matrix.IDENTITY_MATRIX, false)
+
         previewPositionHelper.updateThumbnailMatrix(
             Rect(0, 0, thumbnail.width, thumbnail.height),
             thumbnailData,
@@ -45,9 +47,11 @@
             rotationStateRepository.getRecentsRotationState().activityRotation,
             isRtl,
         )
-        return MatrixScaling(
-            previewPositionHelper.matrix,
-            previewPositionHelper.isOrientationChanged,
+        return ThumbnailPosition(
+            matrix = previewPositionHelper.matrix,
+            isRotated = previewPositionHelper.isOrientationChanged,
         )
     }
 }
+
+data class ThumbnailPosition(val matrix: Matrix, val isRotated: Boolean)
diff --git a/quickstep/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModel.kt b/quickstep/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModel.kt
index 0b299ee..3c4a384 100644
--- a/quickstep/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModel.kt
+++ b/quickstep/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModel.kt
@@ -24,7 +24,9 @@
 import com.android.quickstep.recents.domain.model.TaskModel
 import com.android.quickstep.recents.domain.usecase.GetSysUiStatusNavFlagsUseCase
 import com.android.quickstep.recents.domain.usecase.GetTaskUseCase
+import com.android.quickstep.recents.domain.usecase.GetThumbnailPositionUseCase
 import com.android.quickstep.recents.domain.usecase.IsThumbnailValidUseCase
+import com.android.quickstep.recents.domain.usecase.ThumbnailPosition
 import com.android.quickstep.recents.viewmodel.RecentsViewData
 import com.android.quickstep.views.TaskViewType
 import com.android.systemui.shared.recents.model.ThumbnailData
@@ -48,6 +50,7 @@
     private val getTaskUseCase: GetTaskUseCase,
     private val getSysUiStatusNavFlagsUseCase: GetSysUiStatusNavFlagsUseCase,
     private val isThumbnailValidUseCase: IsThumbnailValidUseCase,
+    private val getThumbnailPositionUseCase: GetThumbnailPositionUseCase,
     dispatcherProvider: DispatcherProvider,
 ) {
     private var taskIds = MutableStateFlow(emptySet<Int>())
@@ -83,6 +86,19 @@
     fun isThumbnailValid(thumbnail: ThumbnailData?, width: Int, height: Int): Boolean =
         isThumbnailValidUseCase(thumbnail, width, height)
 
+    fun getThumbnailPosition(
+        thumbnail: ThumbnailData?,
+        width: Int,
+        height: Int,
+        isRtl: Boolean,
+    ): ThumbnailPosition =
+        getThumbnailPositionUseCase(
+            thumbnailData = thumbnail,
+            width = width,
+            height = height,
+            isRtl = isRtl,
+        )
+
     private fun mapToTaskTile(tasks: List<TaskData>, isLiveTile: Boolean): TaskTileUiState {
         val firstThumbnailData = (tasks.firstOrNull() as? TaskData.Data)?.thumbnailData
         return TaskTileUiState(
diff --git a/quickstep/src/com/android/quickstep/recents/usecase/ThumbnailPositionState.kt b/quickstep/src/com/android/quickstep/recents/usecase/ThumbnailPositionState.kt
deleted file mode 100644
index 1a1bef7..0000000
--- a/quickstep/src/com/android/quickstep/recents/usecase/ThumbnailPositionState.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.quickstep.recents.usecase
-
-import android.graphics.Matrix
-
-/** State on how a task Thumbnail can fit on given canvas */
-sealed class ThumbnailPositionState {
-    data object MissingThumbnail : ThumbnailPositionState()
-
-    data class MatrixScaling(val matrix: Matrix, val isRotated: Boolean) : ThumbnailPositionState()
-}
diff --git a/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt b/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt
index 87aace8..e672ec4 100644
--- a/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt
+++ b/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt
@@ -18,6 +18,7 @@
 
 import android.content.Context
 import android.graphics.Color
+import android.graphics.Matrix
 import android.graphics.Outline
 import android.graphics.Rect
 import android.graphics.drawable.ShapeDrawable
@@ -34,34 +35,15 @@
 import com.android.launcher3.R
 import com.android.launcher3.util.MultiPropertyFactory
 import com.android.launcher3.util.ViewPool
-import com.android.launcher3.util.coroutines.DispatcherProvider
-import com.android.quickstep.recents.di.RecentsDependencies
-import com.android.quickstep.recents.di.get
 import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.BackgroundOnly
 import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.LiveTile
 import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Snapshot
 import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.SnapshotSplash
 import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Uninitialized
-import com.android.quickstep.task.viewmodel.TaskThumbnailViewModel
 import com.android.quickstep.views.FixedSizeImageView
 import com.android.quickstep.views.TaskThumbnailViewHeader
-import kotlinx.coroutines.CoroutineName
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.SupervisorJob
-import kotlinx.coroutines.cancel
-import kotlinx.coroutines.launch
 
 class TaskThumbnailView : FrameLayout, ViewPool.Reusable {
-    private val recentsCoroutineScope: CoroutineScope = RecentsDependencies.get()
-    private val dispatcherProvider: DispatcherProvider = RecentsDependencies.get()
-
-    // This is initialised here and set in onAttachedToWindow because onLayout can be called before
-    // onAttachedToWindow so this property needs to be initialised as it is used below.
-    private lateinit var viewModel: TaskThumbnailViewModel
-
-    private lateinit var viewAttachedScope: CoroutineScope
-
     private val scrimView: View by lazy { findViewById(R.id.task_thumbnail_scrim) }
     private val liveTileView: LiveTileView by lazy { findViewById(R.id.task_thumbnail_live_tile) }
     private val thumbnailView: FixedSizeImageView by lazy { findViewById(R.id.task_thumbnail) }
@@ -70,6 +52,7 @@
     private val dimAlpha: MultiPropertyFactory<View> by lazy {
         MultiPropertyFactory(scrimView, VIEW_ALPHA, ScrimViewAlpha.entries.size, ::maxOf)
     }
+    private var onSizeChanged: ((width: Int, height: Int) -> Unit)? = null
 
     private var taskThumbnailViewHeader: TaskThumbnailViewHeader? = null
 
@@ -104,17 +87,11 @@
 
     override fun onFinishInflate() {
         super.onFinishInflate()
-
         maybeCreateHeader()
     }
 
     override fun onAttachedToWindow() {
         super.onAttachedToWindow()
-        viewAttachedScope =
-            CoroutineScope(
-                SupervisorJob() + Dispatchers.Main.immediate + CoroutineName("TaskThumbnailView")
-            )
-        viewModel = RecentsDependencies.get(this)
         clipToOutline = true
         outlineProvider =
             object : ViewOutlineProvider() {
@@ -124,16 +101,9 @@
             }
     }
 
-    // TODO(b/391842220): Cancel scope in onDetach instead of having a specific method for this.
-    fun destroyScopes() {
-        val scopeToCancel = viewAttachedScope
-        recentsCoroutineScope.launch(dispatcherProvider.background) {
-            scopeToCancel.cancel("TaskThumbnailView detaching from window")
-        }
-    }
-
     override fun onRecycle() {
         uiState = Uninitialized
+        onSizeChanged = null
         outlineBounds = null
         resetViews()
     }
@@ -170,11 +140,13 @@
         splashIcon.alpha = value
     }
 
+    fun doOnSizeChange(action: (width: Int, height: Int) -> Unit) {
+        onSizeChanged = action
+    }
+
     override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
         super.onSizeChanged(w, h, oldw, oldh)
-        if (uiState is SnapshotSplash) {
-            setImageMatrix()
-        }
+        onSizeChanged?.invoke(width, height)
         bounds.set(0, 0, w, h)
         invalidateOutline()
     }
@@ -231,11 +203,12 @@
         drawBackground(snapshot.backgroundColor)
         thumbnailView.setImageBitmap(snapshot.bitmap)
         thumbnailView.isInvisible = false
-        setImageMatrix()
     }
 
-    private fun setImageMatrix() {
-        thumbnailView.imageMatrix = viewModel.getThumbnailPositionState(width, height, isLayoutRtl)
+    fun setImageMatrix(matrix: Matrix) {
+        if (uiState is SnapshotSplash) {
+            thumbnailView.imageMatrix = matrix
+        }
     }
 
     private fun logDebug(message: String) {
diff --git a/quickstep/src/com/android/quickstep/task/viewmodel/TaskOverlayViewModel.kt b/quickstep/src/com/android/quickstep/task/viewmodel/TaskOverlayViewModel.kt
index 81a904b..9bff3ac 100644
--- a/quickstep/src/com/android/quickstep/task/viewmodel/TaskOverlayViewModel.kt
+++ b/quickstep/src/com/android/quickstep/task/viewmodel/TaskOverlayViewModel.kt
@@ -19,9 +19,7 @@
 import android.graphics.Matrix
 import com.android.launcher3.util.coroutines.DispatcherProvider
 import com.android.quickstep.recents.data.RecentTasksRepository
-import com.android.quickstep.recents.usecase.GetThumbnailPositionUseCase
-import com.android.quickstep.recents.usecase.ThumbnailPositionState.MatrixScaling
-import com.android.quickstep.recents.usecase.ThumbnailPositionState.MissingThumbnail
+import com.android.quickstep.recents.domain.usecase.GetThumbnailPositionUseCase
 import com.android.quickstep.recents.viewmodel.RecentsViewData
 import com.android.quickstep.task.thumbnail.TaskOverlayUiState.Disabled
 import com.android.quickstep.task.thumbnail.TaskOverlayUiState.Enabled
@@ -36,7 +34,7 @@
     private val task: Task,
     recentsViewData: RecentsViewData,
     private val getThumbnailPositionUseCase: GetThumbnailPositionUseCase,
-    recentTasksRepository: RecentTasksRepository,
+    private val recentTasksRepository: RecentTasksRepository,
     dispatcherProvider: DispatcherProvider,
 ) {
     val overlayState =
@@ -60,22 +58,17 @@
             .flowOn(dispatcherProvider.background)
 
     fun getThumbnailPositionState(width: Int, height: Int, isRtl: Boolean): ThumbnailPositionState {
-        val matrix: Matrix
-        val isRotated: Boolean
-        when (
-            val thumbnailPositionState =
-                getThumbnailPositionUseCase.run(task.key.id, width, height, isRtl)
-        ) {
-            is MatrixScaling -> {
-                matrix = thumbnailPositionState.matrix
-                isRotated = thumbnailPositionState.isRotated
-            }
-            is MissingThumbnail -> {
-                matrix = Matrix.IDENTITY_MATRIX
-                isRotated = false
-            }
-        }
-        return ThumbnailPositionState(matrix, isRotated)
+        val thumbnailPositionState =
+            getThumbnailPositionUseCase(
+                thumbnailData = recentTasksRepository.getCurrentThumbnailById(task.key.id),
+                width = width,
+                height = height,
+                isRtl = isRtl,
+            )
+        return ThumbnailPositionState(
+            thumbnailPositionState.matrix,
+            thumbnailPositionState.isRotated,
+        )
     }
 
     data class ThumbnailPositionState(val matrix: Matrix, val isRotated: Boolean)
diff --git a/quickstep/src/com/android/quickstep/task/viewmodel/TaskThumbnailViewModel.kt b/quickstep/src/com/android/quickstep/task/viewmodel/TaskThumbnailViewModel.kt
deleted file mode 100644
index e641737..0000000
--- a/quickstep/src/com/android/quickstep/task/viewmodel/TaskThumbnailViewModel.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.quickstep.task.viewmodel
-
-import android.graphics.Matrix
-
-/** ViewModel for representing TaskThumbnails */
-interface TaskThumbnailViewModel {
-    /** Attaches this ViewModel to a specific task id for it to provide data from. */
-    fun bind(taskId: Int)
-
-    /** Returns a Matrix which can be applied to the snapshot */
-    fun getThumbnailPositionState(width: Int, height: Int, isRtl: Boolean): Matrix
-}
diff --git a/quickstep/src/com/android/quickstep/task/viewmodel/TaskThumbnailViewModelImpl.kt b/quickstep/src/com/android/quickstep/task/viewmodel/TaskThumbnailViewModelImpl.kt
deleted file mode 100644
index 94c40d1..0000000
--- a/quickstep/src/com/android/quickstep/task/viewmodel/TaskThumbnailViewModelImpl.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language goveryning permissions and
- * limitations under the License.
- */
-
-package com.android.quickstep.task.viewmodel
-
-import android.app.ActivityTaskManager.INVALID_TASK_ID
-import android.graphics.Matrix
-import android.util.Log
-import com.android.quickstep.recents.usecase.GetThumbnailPositionUseCase
-import com.android.quickstep.recents.usecase.ThumbnailPositionState
-
-class TaskThumbnailViewModelImpl(
-    private val getThumbnailPositionUseCase: GetThumbnailPositionUseCase
-) : TaskThumbnailViewModel {
-    private var taskId: Int = INVALID_TASK_ID
-
-    override fun bind(taskId: Int) {
-        Log.d(TAG, "bind taskId: $taskId")
-        this.taskId = taskId
-    }
-
-    override fun getThumbnailPositionState(width: Int, height: Int, isRtl: Boolean): Matrix =
-        when (
-            val thumbnailPositionState =
-                getThumbnailPositionUseCase.run(taskId, width, height, isRtl)
-        ) {
-            is ThumbnailPositionState.MatrixScaling -> thumbnailPositionState.matrix
-            is ThumbnailPositionState.MissingThumbnail -> Matrix.IDENTITY_MATRIX
-        }
-
-    private companion object {
-        const val TAG = "TaskThumbnailViewModel"
-    }
-}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index e4633e4..5bfcf43 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -2691,8 +2691,6 @@
         }
         if (enableRefactorTaskThumbnail()) {
             mRecentsViewModel.onReset();
-            // TODO(b/391842220) Remove TaskViews rather than calling specific logic to cancel scope
-            getTaskViews().forEach(TaskView::destroyScopes);
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/TaskContainer.kt b/quickstep/src/com/android/quickstep/views/TaskContainer.kt
index ef85aa1..ce20bf9 100644
--- a/quickstep/src/com/android/quickstep/views/TaskContainer.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskContainer.kt
@@ -17,6 +17,7 @@
 package com.android.quickstep.views
 
 import android.graphics.Bitmap
+import android.graphics.Matrix
 import android.view.View
 import com.android.launcher3.Flags.enableRefactorTaskThumbnail
 import com.android.launcher3.model.data.TaskViewItemInfo
@@ -26,11 +27,9 @@
 import com.android.quickstep.ViewUtils.addAccessibleChildToList
 import com.android.quickstep.recents.di.RecentsDependencies
 import com.android.quickstep.recents.di.getScope
-import com.android.quickstep.recents.di.inject
 import com.android.quickstep.recents.ui.mapper.TaskUiStateMapper
 import com.android.quickstep.recents.ui.viewmodel.TaskData
 import com.android.quickstep.task.thumbnail.TaskThumbnailView
-import com.android.quickstep.task.viewmodel.TaskThumbnailViewModel
 import com.android.systemui.shared.recents.model.Task
 import com.android.systemui.shared.recents.model.ThumbnailData
 
@@ -55,10 +54,6 @@
 ) {
     val overlay: TaskOverlayFactory.TaskOverlay<*> = taskOverlayFactory.createOverlay(this)
 
-    // TODO(b/390581380): Remove this after this bug is fixed
-    private val taskThumbnailViewModel: TaskThumbnailViewModel by
-        RecentsDependencies.inject(snapshotView)
-
     init {
         if (enableRefactorTaskThumbnail()) {
             require(snapshotView is TaskThumbnailView)
@@ -75,6 +70,7 @@
     }
 
     internal var thumbnailData: ThumbnailData? = null
+        private set
 
     val thumbnail: Bitmap?
         /** If possible don't use this. It should be replaced as part of b/331753115. */
@@ -108,9 +104,7 @@
 
     fun bind() {
         digitalWellBeingToast?.bind(task, taskView, snapshotView, stagePosition)
-        if (enableRefactorTaskThumbnail()) {
-            taskThumbnailViewModel.bind(task.key.id)
-        } else {
+        if (!enableRefactorTaskThumbnail()) {
             thumbnailViewDeprecated.bind(task, overlay, taskView)
         }
         overlay.init()
@@ -130,11 +124,6 @@
         }
     }
 
-    // TODO(b/391842220): Cancel scope in onDetach instead of having a specific method for this.
-    fun destroyScopes() {
-        thumbnailView.destroyScopes()
-    }
-
     fun setOverlayEnabled(enabled: Boolean) {
         if (!enableRefactorTaskThumbnail()) {
             thumbnailViewDeprecated.setOverlayEnabled(enabled)
@@ -191,4 +180,8 @@
             thumbnailViewDeprecated.setSplashAlpha(progress)
         }
     }
+
+    fun updateThumbnailMatrix(matrix: Matrix) {
+        thumbnailView.setImageMatrix(matrix)
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt
index 39c15b1..49ec31d 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskView.kt
@@ -41,7 +41,6 @@
 import android.widget.Toast
 import androidx.annotation.IntDef
 import androidx.annotation.VisibleForTesting
-import androidx.core.view.doOnLayout
 import androidx.core.view.updateLayoutParams
 import com.android.app.animation.Interpolators
 import com.android.launcher3.Flags.enableCursorHoverStates
@@ -671,11 +670,6 @@
         taskContainers.forEach { it.destroy() }
     }
 
-    fun destroyScopes() {
-        // TODO(b/391842220): Cancel scope in onDetach instead of having a specific method for this.
-        taskContainers.forEach { it.destroyScopes() }
-    }
-
     // TODO: Clip-out the icon region from the thumbnail, since they are overlapping.
     override fun hasOverlappingRendering() = false
 
@@ -778,9 +772,14 @@
             container.setState(
                 state = containerState,
                 liveTile = state.isLiveTile,
-                hasHeader = type == TaskViewType.DESKTOP,
+                hasHeader = state.hasHeader,
             )
             updateThumbnailValidity(container)
+            updateThumbnailMatrix(
+                container = container,
+                width = container.thumbnailView.width,
+                height = container.thumbnailView.height,
+            )
 
             if (enableOverviewIconMenu()) {
                 setIconState(container, containerState)
@@ -798,6 +797,23 @@
         applyThumbnailSplashAlpha()
     }
 
+    /**
+     * Updates the thumbnail's transformation matrix and rotation state within a TaskContainer.
+     *
+     * This function is called to reposition the thumbnail in the following scenarios:
+     * - When the TTV's size changes (onSizeChanged), and it's displaying a SnapshotSplash.
+     * - When drawing a snapshot (drawSnapshot).
+     *
+     * @param container The TaskContainer holding the thumbnail to be updated.
+     * @param width The desired width of the thumbnail's container.
+     * @param height The desired height of the thumbnail's container.
+     */
+    private fun updateThumbnailMatrix(container: TaskContainer, width: Int, height: Int) {
+        val thumbnailPosition =
+            viewModel!!.getThumbnailPosition(container.thumbnailData, width, height, isLayoutRtl)
+        container.updateThumbnailMatrix(thumbnailPosition.matrix)
+    }
+
     override fun onDetachedFromWindow() {
         super.onDetachedFromWindow()
         if (enableRefactorTaskThumbnail()) {
@@ -843,6 +859,7 @@
                         getTaskUseCase = RecentsDependencies.get(),
                         getSysUiStatusNavFlagsUseCase = RecentsDependencies.get(),
                         isThumbnailValidUseCase = RecentsDependencies.get(),
+                        getThumbnailPositionUseCase = RecentsDependencies.get(),
                         dispatcherProvider = RecentsDependencies.get(),
                     )
                     .apply { bind(*taskIds) }
@@ -852,7 +869,10 @@
             container.bind()
             if (enableRefactorTaskThumbnail()) {
                 container.thumbnailView.cornerRadius = thumbnailFullscreenParams.currentCornerRadius
-                container.thumbnailView.doOnLayout { updateThumbnailValidity(container) }
+                container.thumbnailView.doOnSizeChange { width, height ->
+                    updateThumbnailValidity(container)
+                    updateThumbnailMatrix(container, width, height)
+                }
             }
         }
         setOrientationState(orientedState)
diff --git a/quickstep/tests/multivalentScreenshotTests/src/com/android/quickstep/task/thumbnail/FakeTaskThumbnailViewModel.kt b/quickstep/tests/multivalentScreenshotTests/src/com/android/quickstep/task/thumbnail/FakeTaskThumbnailViewModel.kt
deleted file mode 100644
index 1a2b1c3..0000000
--- a/quickstep/tests/multivalentScreenshotTests/src/com/android/quickstep/task/thumbnail/FakeTaskThumbnailViewModel.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.quickstep.task.thumbnail
-
-import android.graphics.Matrix
-import com.android.quickstep.task.viewmodel.TaskThumbnailViewModel
-
-class FakeTaskThumbnailViewModel : TaskThumbnailViewModel {
-    override fun bind(taskId: Int) {
-        // no-op
-    }
-
-    override fun getThumbnailPositionState(width: Int, height: Int, isRtl: Boolean) =
-        Matrix.IDENTITY_MATRIX
-}
diff --git a/quickstep/tests/multivalentScreenshotTests/src/com/android/quickstep/task/thumbnail/TaskThumbnailViewScreenshotTest.kt b/quickstep/tests/multivalentScreenshotTests/src/com/android/quickstep/task/thumbnail/TaskThumbnailViewScreenshotTest.kt
index c3b4d15..b9d2fed 100644
--- a/quickstep/tests/multivalentScreenshotTests/src/com/android/quickstep/task/thumbnail/TaskThumbnailViewScreenshotTest.kt
+++ b/quickstep/tests/multivalentScreenshotTests/src/com/android/quickstep/task/thumbnail/TaskThumbnailViewScreenshotTest.kt
@@ -19,12 +19,9 @@
 import android.graphics.Color
 import android.view.LayoutInflater
 import com.android.launcher3.R
-import com.android.quickstep.recents.di.RecentsDependencies
 import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.BackgroundOnly
 import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Uninitialized
-import com.android.quickstep.task.viewmodel.TaskThumbnailViewModel
 import com.google.android.apps.nexuslauncher.imagecomparison.goldenpathmanager.ViewScreenshotGoldenPathManager
-import org.junit.After
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -46,13 +43,6 @@
             ViewScreenshotGoldenPathManager(getEmulatedDevicePathConfig(emulationSpec)),
         )
 
-    private val taskThumbnailViewModel = FakeTaskThumbnailViewModel()
-
-    @After
-    fun tearDown() {
-        RecentsDependencies.destroy()
-    }
-
     @Test
     fun taskThumbnailView_uninitializedByDefault() {
         screenshotRule.screenshotTest("taskThumbnailView_uninitialized") { activity ->
@@ -125,14 +115,10 @@
     }
 
     private fun createTaskThumbnailView(context: Context): TaskThumbnailView {
-        val di = RecentsDependencies.initialize(context)
         val taskThumbnailView =
             LayoutInflater.from(context).inflate(R.layout.task_thumbnail, null, false)
                 as TaskThumbnailView
         taskThumbnailView.cornerRadius = CORNER_RADIUS
-        val ttvDiScopeId = di.getScope(taskThumbnailView).scopeId
-        di.provide(TaskThumbnailViewModel::class.java, ttvDiScopeId) { taskThumbnailViewModel }
-
         return taskThumbnailView
     }
 
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailPositionUseCaseTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/domain/usecase/GetThumbnailPositionUseCaseTest.kt
similarity index 61%
rename from quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailPositionUseCaseTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/recents/domain/usecase/GetThumbnailPositionUseCaseTest.kt
index bd7d970..a253280 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailPositionUseCaseTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/domain/usecase/GetThumbnailPositionUseCaseTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,22 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.quickstep.recents.usecase
+package com.android.quickstep.recents.domain.usecase
 
-import android.content.ComponentName
-import android.content.Intent
 import android.graphics.Bitmap
-import android.graphics.Color
 import android.graphics.Matrix
 import android.graphics.Rect
 import android.view.Surface.ROTATION_90
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.quickstep.recents.data.FakeRecentsDeviceProfileRepository
 import com.android.quickstep.recents.data.FakeRecentsRotationStateRepository
-import com.android.quickstep.recents.data.FakeTasksRepository
-import com.android.quickstep.recents.usecase.ThumbnailPositionState.MatrixScaling
-import com.android.quickstep.recents.usecase.ThumbnailPositionState.MissingThumbnail
-import com.android.systemui.shared.recents.model.Task
 import com.android.systemui.shared.recents.model.ThumbnailData
 import com.android.systemui.shared.recents.utilities.PreviewPositionHelper
 import com.google.common.truth.Truth.assertThat
@@ -43,55 +36,34 @@
 /** Test for [GetThumbnailPositionUseCase] */
 @RunWith(AndroidJUnit4::class)
 class GetThumbnailPositionUseCaseTest {
-    private val task =
-        Task(Task.TaskKey(TASK_ID, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
-            colorBackground = Color.BLACK
-        }
-    private val thumbnailData =
-        ThumbnailData(
-            thumbnail =
-                mock<Bitmap>().apply {
-                    whenever(width).thenReturn(THUMBNAIL_WIDTH)
-                    whenever(height).thenReturn(THUMBNAIL_HEIGHT)
-                }
-        )
-
     private val deviceProfileRepository = FakeRecentsDeviceProfileRepository()
     private val rotationStateRepository = FakeRecentsRotationStateRepository()
-    private val tasksRepository = FakeTasksRepository()
     private val previewPositionHelper = mock<PreviewPositionHelper>()
 
     private val systemUnderTest =
         GetThumbnailPositionUseCase(
             deviceProfileRepository,
             rotationStateRepository,
-            tasksRepository,
             previewPositionHelper,
         )
 
     @Test
-    fun invisibleTask_returnsIdentityMatrix() = runTest {
-        tasksRepository.seedTasks(listOf(task))
-
-        assertThat(systemUnderTest.run(TASK_ID, CANVAS_WIDTH, CANVAS_HEIGHT, isRtl = true))
-            .isInstanceOf(MissingThumbnail::class.java)
+    fun nullThumbnailData_returnsIdentityMatrix() = runTest {
+        val expectedResult = ThumbnailPosition(Matrix.IDENTITY_MATRIX, false)
+        val result = systemUnderTest.invoke(null, CANVAS_WIDTH, CANVAS_HEIGHT, isRtl = true)
+        assertThat(result).isEqualTo(expectedResult)
     }
 
     @Test
-    fun visibleTaskWithoutThumbnailData_returnsIdentityMatrix() = runTest {
-        tasksRepository.seedTasks(listOf(task))
-        tasksRepository.setVisibleTasks(setOf(TASK_ID))
-
-        assertThat(systemUnderTest.run(TASK_ID, CANVAS_WIDTH, CANVAS_HEIGHT, isRtl = true))
-            .isInstanceOf(MissingThumbnail::class.java)
+    fun withoutThumbnail_returnsIdentityMatrix() = runTest {
+        val expectedResult = ThumbnailPosition(Matrix.IDENTITY_MATRIX, false)
+        val result =
+            systemUnderTest.invoke(ThumbnailData(), CANVAS_WIDTH, CANVAS_HEIGHT, isRtl = true)
+        assertThat(result).isEqualTo(expectedResult)
     }
 
     @Test
     fun visibleTaskWithThumbnailData_returnsTransformedMatrix() = runTest {
-        tasksRepository.seedThumbnailData(mapOf(TASK_ID to thumbnailData))
-        tasksRepository.seedTasks(listOf(task))
-        tasksRepository.setVisibleTasks(setOf(TASK_ID))
-
         val isLargeScreen = true
         deviceProfileRepository.setRecentsDeviceProfile(
             deviceProfileRepository.getRecentsDeviceProfile().copy(isLargeScreen = isLargeScreen)
@@ -108,13 +80,14 @@
         whenever(previewPositionHelper.matrix).thenReturn(MATRIX)
         whenever(previewPositionHelper.isOrientationChanged).thenReturn(isRotated)
 
-        assertThat(systemUnderTest.run(TASK_ID, CANVAS_WIDTH, CANVAS_HEIGHT, isRtl))
-            .isEqualTo(MatrixScaling(MATRIX, isRotated))
+        val result = systemUnderTest.invoke(THUMBNAIL_DATA, CANVAS_WIDTH, CANVAS_HEIGHT, isRtl)
+        val expectedResult = ThumbnailPosition(MATRIX, isRotated)
+        assertThat(result).isEqualTo(expectedResult)
 
         verify(previewPositionHelper)
             .updateThumbnailMatrix(
                 Rect(0, 0, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT),
-                thumbnailData,
+                THUMBNAIL_DATA,
                 CANVAS_WIDTH,
                 CANVAS_HEIGHT,
                 isLargeScreen,
@@ -123,8 +96,7 @@
             )
     }
 
-    companion object {
-        const val TASK_ID = 2
+    private companion object {
         const val THUMBNAIL_WIDTH = 100
         const val THUMBNAIL_HEIGHT = 200
         const val CANVAS_WIDTH = 300
@@ -133,5 +105,14 @@
             Matrix().apply {
                 setValues(floatArrayOf(2.3f, 4.5f, 2.6f, 7.4f, 3.4f, 2.3f, 2.5f, 6.0f, 3.4f))
             }
+
+        val THUMBNAIL_DATA =
+            ThumbnailData(
+                thumbnail =
+                    mock<Bitmap>().apply {
+                        whenever(width).thenReturn(THUMBNAIL_WIDTH)
+                        whenever(height).thenReturn(THUMBNAIL_HEIGHT)
+                    }
+            )
     }
 }
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModelTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModelTest.kt
index 08e459b..a97ef0c 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModelTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModelTest.kt
@@ -29,6 +29,7 @@
 import com.android.quickstep.recents.domain.model.TaskModel
 import com.android.quickstep.recents.domain.usecase.GetSysUiStatusNavFlagsUseCase
 import com.android.quickstep.recents.domain.usecase.GetTaskUseCase
+import com.android.quickstep.recents.domain.usecase.GetThumbnailPositionUseCase
 import com.android.quickstep.recents.domain.usecase.IsThumbnailValidUseCase
 import com.android.quickstep.recents.viewmodel.RecentsViewData
 import com.android.quickstep.views.TaskViewType
@@ -58,6 +59,7 @@
 
     private val recentsViewData = RecentsViewData()
     private val getTaskUseCase = mock<GetTaskUseCase>()
+    private val getThumbnailPositionUseCase = mock<GetThumbnailPositionUseCase>()
     private val isThumbnailValidUseCase =
         spy(IsThumbnailValidUseCase(FakeRecentsRotationStateRepository()))
     private lateinit var sut: TaskViewModel
@@ -71,6 +73,7 @@
                 getTaskUseCase = getTaskUseCase,
                 getSysUiStatusNavFlagsUseCase = GetSysUiStatusNavFlagsUseCase(),
                 isThumbnailValidUseCase = isThumbnailValidUseCase,
+                getThumbnailPositionUseCase = getThumbnailPositionUseCase,
                 dispatcherProvider = TestDispatcherProvider(unconfinedTestDispatcher),
             )
         whenever(getTaskUseCase.invoke(TASK_MODEL_1.id)).thenReturn(flow { emit(TASK_MODEL_1) })
@@ -112,6 +115,7 @@
                         getTaskUseCase = getTaskUseCase,
                         getSysUiStatusNavFlagsUseCase = GetSysUiStatusNavFlagsUseCase(),
                         isThumbnailValidUseCase = isThumbnailValidUseCase,
+                        getThumbnailPositionUseCase = getThumbnailPositionUseCase,
                         dispatcherProvider = TestDispatcherProvider(unconfinedTestDispatcher),
                     )
                 sut.bind(TASK_MODEL_1.id)
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailUseCaseTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailUseCaseTest.kt
index 0044631..90ef61d 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailUseCaseTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailUseCaseTest.kt
@@ -21,7 +21,6 @@
 import android.graphics.Bitmap
 import android.graphics.Color
 import com.android.quickstep.recents.data.FakeTasksRepository
-import com.android.quickstep.task.viewmodel.TaskOverlayViewModelTest
 import com.android.systemui.shared.recents.model.Task
 import com.android.systemui.shared.recents.model.ThumbnailData
 import com.google.common.truth.Truth.assertThat
@@ -62,7 +61,7 @@
     @Test
     fun taskNotVisible_returnsNull() {
         tasksRepository.seedTasks(listOf(task))
-        tasksRepository.seedThumbnailData(mapOf(TaskOverlayViewModelTest.TASK_ID to thumbnailData))
+        tasksRepository.seedThumbnailData(mapOf(TASK_ID to thumbnailData))
 
         assertThat(systemUnderTest.run(TASK_ID)).isNull()
     }
@@ -70,8 +69,8 @@
     @Test
     fun taskVisible_returnsThumbnail() {
         tasksRepository.seedTasks(listOf(task))
-        tasksRepository.seedThumbnailData(mapOf(TaskOverlayViewModelTest.TASK_ID to thumbnailData))
-        tasksRepository.setVisibleTasks(setOf(TaskOverlayViewModelTest.TASK_ID))
+        tasksRepository.seedThumbnailData(mapOf(TASK_ID to thumbnailData))
+        tasksRepository.setVisibleTasks(setOf(TASK_ID))
 
         assertThat(systemUnderTest.run(TASK_ID)).isEqualTo(thumbnailData.thumbnail)
     }
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/task/thumbnail/TaskThumbnailViewModelImplTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/task/thumbnail/TaskThumbnailViewModelImplTest.kt
deleted file mode 100644
index 4b4e2eb..0000000
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/task/thumbnail/TaskThumbnailViewModelImplTest.kt
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.quickstep.task.thumbnail
-
-import android.graphics.Matrix
-import android.platform.test.flag.junit.SetFlagsRule
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.android.quickstep.recents.usecase.GetThumbnailPositionUseCase
-import com.android.quickstep.recents.usecase.ThumbnailPositionState.MatrixScaling
-import com.android.quickstep.recents.usecase.ThumbnailPositionState.MissingThumbnail
-import com.android.quickstep.task.viewmodel.TaskThumbnailViewModelImpl
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.runTest
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.whenever
-
-/** Test for [TaskThumbnailView] */
-@RunWith(AndroidJUnit4::class)
-class TaskThumbnailViewModelImplTest {
-    @get:Rule val setFlagsRule = SetFlagsRule()
-
-    private val dispatcher = StandardTestDispatcher()
-    private val testScope = TestScope(dispatcher)
-
-    private val mGetThumbnailPositionUseCase = mock<GetThumbnailPositionUseCase>()
-
-    private val systemUnderTest by lazy { TaskThumbnailViewModelImpl(mGetThumbnailPositionUseCase) }
-
-    @Test
-    fun getSnapshotMatrix_MissingThumbnail() =
-        testScope.runTest {
-            val taskId = 2
-            val isRtl = true
-
-            whenever(mGetThumbnailPositionUseCase.run(taskId, CANVAS_WIDTH, CANVAS_HEIGHT, isRtl))
-                .thenReturn(MissingThumbnail)
-
-            systemUnderTest.bind(taskId)
-            assertThat(
-                    systemUnderTest.getThumbnailPositionState(CANVAS_WIDTH, CANVAS_HEIGHT, isRtl)
-                )
-                .isEqualTo(Matrix.IDENTITY_MATRIX)
-        }
-
-    @Test
-    fun getSnapshotMatrix_MatrixScaling() =
-        testScope.runTest {
-            val taskId = 2
-            val isRtl = true
-
-            whenever(mGetThumbnailPositionUseCase.run(taskId, CANVAS_WIDTH, CANVAS_HEIGHT, isRtl))
-                .thenReturn(MatrixScaling(MATRIX, isRotated = false))
-
-            systemUnderTest.bind(taskId)
-            assertThat(
-                    systemUnderTest.getThumbnailPositionState(CANVAS_WIDTH, CANVAS_HEIGHT, isRtl)
-                )
-                .isEqualTo(MATRIX)
-        }
-
-    private companion object {
-        const val CANVAS_WIDTH = 300
-        const val CANVAS_HEIGHT = 600
-        val MATRIX =
-            Matrix().apply {
-                setValues(floatArrayOf(2.3f, 4.5f, 2.6f, 7.4f, 3.4f, 2.3f, 2.5f, 6.0f, 3.4f))
-            }
-    }
-}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/task/viewmodel/TaskOverlayViewModelTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/task/viewmodel/TaskOverlayViewModelTest.kt
deleted file mode 100644
index 95504af..0000000
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/task/viewmodel/TaskOverlayViewModelTest.kt
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.quickstep.task.viewmodel
-
-import android.content.ComponentName
-import android.content.Intent
-import android.graphics.Bitmap
-import android.graphics.Color
-import android.graphics.Matrix
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.android.launcher3.util.TestDispatcherProvider
-import com.android.quickstep.recents.data.FakeTasksRepository
-import com.android.quickstep.recents.usecase.GetThumbnailPositionUseCase
-import com.android.quickstep.recents.usecase.ThumbnailPositionState.MatrixScaling
-import com.android.quickstep.recents.usecase.ThumbnailPositionState.MissingThumbnail
-import com.android.quickstep.recents.viewmodel.RecentsViewData
-import com.android.quickstep.task.thumbnail.TaskOverlayUiState.Disabled
-import com.android.quickstep.task.thumbnail.TaskOverlayUiState.Enabled
-import com.android.quickstep.task.viewmodel.TaskOverlayViewModel.ThumbnailPositionState
-import com.android.systemui.shared.recents.model.Task
-import com.android.systemui.shared.recents.model.ThumbnailData
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.whenever
-
-/** Test for [TaskOverlayViewModel] */
-@OptIn(ExperimentalCoroutinesApi::class)
-@RunWith(AndroidJUnit4::class)
-class TaskOverlayViewModelTest {
-    private val task =
-        Task(Task.TaskKey(TASK_ID, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
-            colorBackground = Color.BLACK
-        }
-    private val thumbnailData =
-        ThumbnailData(
-            thumbnail =
-                mock<Bitmap>().apply {
-                    whenever(width).thenReturn(THUMBNAIL_WIDTH)
-                    whenever(height).thenReturn(THUMBNAIL_HEIGHT)
-                }
-        )
-    private val recentsViewData = RecentsViewData()
-    private val tasksRepository = FakeTasksRepository()
-    private val mGetThumbnailPositionUseCase = mock<GetThumbnailPositionUseCase>()
-    private val dispatcher = UnconfinedTestDispatcher()
-    private val testScope = TestScope(dispatcher)
-    private val systemUnderTest =
-        TaskOverlayViewModel(
-            task,
-            recentsViewData,
-            mGetThumbnailPositionUseCase,
-            tasksRepository,
-            TestDispatcherProvider(dispatcher),
-        )
-
-    @Test
-    fun initialStateIsDisabled() =
-        testScope.runTest { assertThat(systemUnderTest.overlayState.first()).isEqualTo(Disabled) }
-
-    @Test
-    fun recentsViewOverlayDisabled_Disabled() =
-        testScope.runTest {
-            recentsViewData.overlayEnabled.value = false
-            recentsViewData.settledFullyVisibleTaskIds.value = setOf(TASK_ID)
-
-            assertThat(systemUnderTest.overlayState.first()).isEqualTo(Disabled)
-        }
-
-    @Test
-    fun taskNotFullyVisible_Disabled() =
-        testScope.runTest {
-            recentsViewData.overlayEnabled.value = true
-            recentsViewData.settledFullyVisibleTaskIds.value = setOf()
-
-            assertThat(systemUnderTest.overlayState.first()).isEqualTo(Disabled)
-        }
-
-    @Test
-    fun noThumbnail_Enabled() =
-        testScope.runTest {
-            recentsViewData.overlayEnabled.value = true
-            recentsViewData.settledFullyVisibleTaskIds.value = setOf(TASK_ID)
-            task.isLocked = false
-
-            assertThat(systemUnderTest.overlayState.first())
-                .isEqualTo(Enabled(isRealSnapshot = false, thumbnail = null))
-        }
-
-    @Test
-    fun withThumbnail_RealSnapshot_NotLocked_Enabled() =
-        testScope.runTest {
-            recentsViewData.overlayEnabled.value = true
-            recentsViewData.settledFullyVisibleTaskIds.value = setOf(TASK_ID)
-            tasksRepository.seedTasks(listOf(task))
-            tasksRepository.seedThumbnailData(mapOf(TASK_ID to thumbnailData))
-            tasksRepository.setVisibleTasks(setOf(TASK_ID))
-            thumbnailData.isRealSnapshot = true
-            task.isLocked = false
-
-            assertThat(systemUnderTest.overlayState.first())
-                .isEqualTo(Enabled(isRealSnapshot = true, thumbnail = thumbnailData.thumbnail))
-        }
-
-    @Test
-    fun withThumbnail_RealSnapshot_Locked_Enabled() =
-        testScope.runTest {
-            recentsViewData.overlayEnabled.value = true
-            recentsViewData.settledFullyVisibleTaskIds.value = setOf(TASK_ID)
-            tasksRepository.seedTasks(listOf(task))
-            tasksRepository.seedThumbnailData(mapOf(TASK_ID to thumbnailData))
-            tasksRepository.setVisibleTasks(setOf(TASK_ID))
-            thumbnailData.isRealSnapshot = true
-            task.isLocked = true
-
-            assertThat(systemUnderTest.overlayState.first())
-                .isEqualTo(Enabled(isRealSnapshot = false, thumbnail = thumbnailData.thumbnail))
-        }
-
-    @Test
-    fun withThumbnail_FakeSnapshot_Enabled() =
-        testScope.runTest {
-            recentsViewData.overlayEnabled.value = true
-            recentsViewData.settledFullyVisibleTaskIds.value = setOf(TASK_ID)
-            tasksRepository.seedTasks(listOf(task))
-            tasksRepository.seedThumbnailData(mapOf(TASK_ID to thumbnailData))
-            tasksRepository.setVisibleTasks(setOf(TASK_ID))
-            thumbnailData.isRealSnapshot = false
-            task.isLocked = false
-
-            assertThat(systemUnderTest.overlayState.first())
-                .isEqualTo(Enabled(isRealSnapshot = false, thumbnail = thumbnailData.thumbnail))
-        }
-
-    @Test
-    fun getThumbnailMatrix_MissingThumbnail() =
-        testScope.runTest {
-            val isRtl = true
-
-            whenever(mGetThumbnailPositionUseCase.run(TASK_ID, CANVAS_WIDTH, CANVAS_HEIGHT, isRtl))
-                .thenReturn(MissingThumbnail)
-
-            assertThat(
-                    systemUnderTest.getThumbnailPositionState(CANVAS_WIDTH, CANVAS_HEIGHT, isRtl)
-                )
-                .isEqualTo(ThumbnailPositionState(Matrix.IDENTITY_MATRIX, isRotated = false))
-        }
-
-    @Test
-    fun getThumbnailMatrix_MatrixScaling() =
-        testScope.runTest {
-            val isRtl = true
-            val isRotated = true
-
-            whenever(mGetThumbnailPositionUseCase.run(TASK_ID, CANVAS_WIDTH, CANVAS_HEIGHT, isRtl))
-                .thenReturn(MatrixScaling(MATRIX, isRotated))
-
-            assertThat(
-                    systemUnderTest.getThumbnailPositionState(CANVAS_WIDTH, CANVAS_HEIGHT, isRtl)
-                )
-                .isEqualTo(ThumbnailPositionState(MATRIX, isRotated))
-        }
-
-    companion object {
-        const val TASK_ID = 0
-        const val THUMBNAIL_WIDTH = 100
-        const val THUMBNAIL_HEIGHT = 200
-        const val CANVAS_WIDTH = 300
-        const val CANVAS_HEIGHT = 600
-        val MATRIX =
-            Matrix().apply {
-                setValues(floatArrayOf(2.3f, 4.5f, 2.6f, 7.4f, 3.4f, 2.3f, 2.5f, 6.0f, 3.4f))
-            }
-    }
-}