Merge "Move cancellation of CoroutineScopes to bg thread as it can be slow." into main
diff --git a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
index 3aae760..8c26d8f 100644
--- a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
+++ b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
@@ -96,7 +96,7 @@
         taskRequests[taskId] =
             Pair(
                 task.key,
-                recentsCoroutineScope.launch {
+                recentsCoroutineScope.launch(dispatcherProvider.main) {
                     Log.i(TAG, "requestTaskData: $taskId")
                     fetchIcon(task)
                     fetchThumbnail(task)
@@ -134,7 +134,7 @@
             task.key,
             object : TaskIconChangedCallback {
                 override fun onTaskIconChanged() {
-                    recentsCoroutineScope.launch {
+                    recentsCoroutineScope.launch(dispatcherProvider.main) {
                         updateIcon(task.key.id, getIconFromDataSource(task))
                     }
                 }
@@ -152,7 +152,7 @@
                 }
 
                 override fun onHighResLoadingStateChanged() {
-                    recentsCoroutineScope.launch {
+                    recentsCoroutineScope.launch(dispatcherProvider.main) {
                         updateThumbnail(task.key.id, getThumbnailFromDataSource(task))
                     }
                 }
diff --git a/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt b/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
index b78e214..95ecbe9 100644
--- a/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
+++ b/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
@@ -39,7 +39,6 @@
 import com.android.systemui.shared.recents.model.Task
 import kotlinx.coroutines.CoroutineName
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.SupervisorJob
 
 internal typealias RecentsScopeId = String
@@ -58,10 +57,13 @@
     private fun startDefaultScope(appContext: Context) {
         createScope(DEFAULT_SCOPE_ID).apply {
             set(RecentsViewData::class.java.simpleName, RecentsViewData())
+            val dispatcherProvider: DispatcherProvider = ProductionDispatchers
             val recentsCoroutineScope =
-                CoroutineScope(SupervisorJob() + Dispatchers.Main + CoroutineName("RecentsView"))
+                CoroutineScope(
+                    SupervisorJob() + dispatcherProvider.unconfined + CoroutineName("RecentsView")
+                )
             set(CoroutineScope::class.java.simpleName, recentsCoroutineScope)
-            set(DispatcherProvider::class.java.simpleName, ProductionDispatchers)
+            set(DispatcherProvider::class.java.simpleName, dispatcherProvider)
             val recentsModel = RecentsModel.INSTANCE.get(appContext)
             val taskVisualsChangedDelegate =
                 TaskVisualsChangedDelegateImpl(
@@ -170,18 +172,6 @@
         log("linked scopes: ${getScope(scopeId).scopeIdsLinked}")
         val instance: Any =
             when (modelClass) {
-                RecentTasksRepository::class.java -> {
-                    with(RecentsModel.INSTANCE.get(appContext)) {
-                        TasksRepository(
-                            this,
-                            thumbnailCache,
-                            iconCache,
-                            get(),
-                            get(),
-                            ProductionDispatchers,
-                        )
-                    }
-                }
                 RecentsViewData::class.java -> RecentsViewData()
                 TaskContainerData::class.java -> TaskContainerData()
                 TaskThumbnailViewData::class.java -> TaskThumbnailViewData()
diff --git a/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt b/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt
index ea4602d..e334695 100644
--- a/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt
+++ b/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt
@@ -29,6 +29,7 @@
 import androidx.core.view.isInvisible
 import com.android.launcher3.R
 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
@@ -45,8 +46,12 @@
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.launch
 
 class TaskThumbnailView : FrameLayout, ViewPool.Reusable {
+    private val recentsCoroutineScope: CoroutineScope = RecentsDependencies.get()
+    private val dispatcherProvider: DispatcherProvider = RecentsDependencies.get()
+
     private lateinit var viewData: TaskThumbnailViewData
     private lateinit var viewModel: TaskThumbnailViewModel
 
@@ -119,7 +124,9 @@
 
     override fun onDetachedFromWindow() {
         super.onDetachedFromWindow()
-        viewAttachedScope.cancel("TaskThumbnailView detaching from window")
+        recentsCoroutineScope.launch(dispatcherProvider.background) {
+            viewAttachedScope.cancel("TaskThumbnailView detaching from window")
+        }
     }
 
     override fun onRecycle() {
diff --git a/quickstep/src/com/android/quickstep/task/util/TaskOverlayHelper.kt b/quickstep/src/com/android/quickstep/task/util/TaskOverlayHelper.kt
index 203177a..e6c8d27 100644
--- a/quickstep/src/com/android/quickstep/task/util/TaskOverlayHelper.kt
+++ b/quickstep/src/com/android/quickstep/task/util/TaskOverlayHelper.kt
@@ -18,6 +18,7 @@
 
 import android.util.Log
 import android.view.View.OnLayoutChangeListener
+import com.android.launcher3.util.coroutines.DispatcherProvider
 import com.android.quickstep.TaskOverlayFactory
 import com.android.quickstep.recents.di.RecentsDependencies
 import com.android.quickstep.recents.di.get
@@ -33,12 +34,15 @@
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.launch
 
 /**
  * Helper for [TaskOverlayFactory.TaskOverlay] to interact with [TaskOverlayViewModel], this helper
  * should merge with [TaskOverlayFactory.TaskOverlay] when it's migrated to MVVM.
  */
 class TaskOverlayHelper(val task: Task, val overlay: TaskOverlayFactory.TaskOverlay<*>) {
+    private val recentsCoroutineScope: CoroutineScope = RecentsDependencies.get()
+    private val dispatcherProvider: DispatcherProvider = RecentsDependencies.get()
     private lateinit var overlayInitializedScope: CoroutineScope
     private var uiState: TaskOverlayUiState = Disabled
 
@@ -101,7 +105,9 @@
     }
 
     fun destroy() {
-        overlayInitializedScope.cancel()
+        recentsCoroutineScope.launch(dispatcherProvider.background) {
+            overlayInitializedScope.cancel("TaskOverlay being destroyed")
+        }
         uiState = Disabled
         overlay.snapshotView.removeOnLayoutChangeListener(snapshotLayoutChangeListener)
         reset()
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 499f50e..fca115e 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -25,11 +25,11 @@
 import static com.android.app.animation.Interpolators.ACCELERATE_0_75;
 import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE;
 import static com.android.app.animation.Interpolators.DECELERATE_2;
+import static com.android.app.animation.Interpolators.EMPHASIZED;
 import static com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE;
 import static com.android.app.animation.Interpolators.FAST_OUT_SLOW_IN;
 import static com.android.app.animation.Interpolators.FINAL_FRAME;
 import static com.android.app.animation.Interpolators.LINEAR;
-import static com.android.app.animation.Interpolators.EMPHASIZED;
 import static com.android.app.animation.Interpolators.clampToProgress;
 import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
 import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU;
@@ -179,6 +179,7 @@
 import com.android.launcher3.util.TranslateEdgeEffect;
 import com.android.launcher3.util.VibratorWrapper;
 import com.android.launcher3.util.ViewPool;
+import com.android.launcher3.util.coroutines.DispatcherProvider;
 import com.android.quickstep.BaseContainerInterface;
 import com.android.quickstep.GestureState;
 import com.android.quickstep.OverviewCommandHelper;
@@ -238,6 +239,8 @@
 import kotlin.Unit;
 import kotlin.collections.CollectionsKt;
 
+import kotlinx.coroutines.CoroutineScope;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -927,7 +930,11 @@
                     recentsDependencies.inject(RecentTasksRepository.class),
                     recentsDependencies.inject(RecentsViewData.class)
             );
-            mHelper = new RecentsViewModelHelper(mRecentsViewModel);
+            mHelper = new RecentsViewModelHelper(
+                    mRecentsViewModel,
+                    recentsDependencies.inject(CoroutineScope.class),
+                    recentsDependencies.inject(DispatcherProvider.class)
+            );
 
             recentsDependencies.provide(RecentsRotationStateRepository.class,
                     () -> new RecentsRotationStateRepositoryImpl(mOrientationState));
@@ -1264,9 +1271,6 @@
         if (FeatureFlags.enableSplitContextually()) {
             mSplitSelectStateController.registerSplitListener(mSplitSelectionListener);
         }
-        if (enableRefactorTaskThumbnail()) {
-            mHelper.onAttachedToWindow();
-        }
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt b/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt
index 3616fbb..87771c6 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt
@@ -16,28 +16,24 @@
 
 package com.android.quickstep.views
 
+import com.android.launcher3.util.coroutines.DispatcherProvider
 import com.android.quickstep.ViewUtils
 import com.android.quickstep.recents.viewmodel.RecentsViewModel
 import com.android.systemui.shared.recents.model.ThumbnailData
-import kotlinx.coroutines.CoroutineName
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.SupervisorJob
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 
 /** Helper for [RecentsView] to interact with the [RecentsViewModel]. */
-class RecentsViewModelHelper(private val recentsViewModel: RecentsViewModel) {
-    private lateinit var viewAttachedScope: CoroutineScope
-
-    fun onAttachedToWindow() {
-        viewAttachedScope =
-            CoroutineScope(SupervisorJob() + Dispatchers.Default + CoroutineName("RecentsView"))
-    }
-
+class RecentsViewModelHelper(
+    private val recentsViewModel: RecentsViewModel,
+    private val recentsCoroutineScope: CoroutineScope,
+    private val dispatcherProvider: DispatcherProvider,
+) {
     fun onDetachedFromWindow() {
-        viewAttachedScope.cancel("RecentsView detaching from window")
+        recentsCoroutineScope.cancel("RecentsView detaching from window")
     }
 
     fun switchToScreenshot(
@@ -48,7 +44,7 @@
         // Update recentsViewModel and apply the thumbnailOverride ASAP, before waiting inside
         // viewAttachedScope.
         recentsViewModel.setRunningTaskShowScreenshot(true)
-        viewAttachedScope.launch {
+        recentsCoroutineScope.launch(dispatcherProvider.main) {
             recentsViewModel.waitForRunningTaskShowScreenshotToUpdate()
             recentsViewModel.waitForThumbnailsToUpdate(updatedThumbnails)
             withContext(Dispatchers.Main) { ViewUtils.postFrameDrawn(taskView, onFinishRunnable) }