Add kill switch for ViewPool.initPool.
This fixes an issue where, in fast E2E tests, the test can complete before initPool is completed. This results in the ViewPool continuing to create TaskViews and therefore TaskThumbnailViews after RecentsDeps is destroyed. Doing this causes a crash.
Stopping the ViewPool.initPool thread before destroying RecentsDeps fixes this.
Bug: 390156722
Flag: com.android.launcher3.enable_refactor_task_thumbnail
Test: fast E2E tests in presubmit e.g. AllAppsImageTest
Change-Id: I0f8801ca75cda383df8ed96077cf1b7178771cb6
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index e037045..b764e42 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1255,6 +1255,13 @@
public void destroy() {
Log.d(TAG, "destroy");
if (enableRefactorTaskThumbnail()) {
+ try {
+ mTaskViewPool.killOngoingInitializations();
+ mGroupedTaskViewPool.killOngoingInitializations();
+ mDesktopTaskViewPool.killOngoingInitializations();
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Ongoing initializations could not be killed", e);
+ }
mHelper.onDestroy();
RecentsDependencies.destroy();
}
diff --git a/src/com/android/launcher3/util/ViewPool.java b/src/com/android/launcher3/util/ViewPool.java
index d1cd30f..1627057 100644
--- a/src/com/android/launcher3/util/ViewPool.java
+++ b/src/com/android/launcher3/util/ViewPool.java
@@ -44,6 +44,9 @@
private int mCurrentSize = 0;
+ @Nullable
+ private Thread mViewPoolInitThread;
+
public ViewPool(Context context, @Nullable ViewGroup parent,
int layoutId, int maxSize, int initialSize) {
this(LayoutInflater.from(context).cloneInContext(context),
@@ -74,13 +77,15 @@
// Inflate views on a non looper thread. This allows us to catch errors like calling
// "new Handler()" in constructor easily.
- new Thread(() -> {
+ mViewPoolInitThread = new Thread(() -> {
for (int i = 0; i < initialSize; i++) {
T view = inflateNewView(inflater);
handler.post(() -> addToPool(view));
}
Log.d(TAG, "initPool complete");
- }, "ViewPool-init").start();
+ mViewPoolInitThread = null;
+ }, "ViewPool-init");
+ mViewPoolInitThread.start();
}
@UiThread
@@ -117,6 +122,12 @@
return (T) inflater.inflate(mLayoutId, mParent, false);
}
+ public void killOngoingInitializations() throws InterruptedException {
+ if (mViewPoolInitThread != null) {
+ mViewPoolInitThread.join();
+ }
+ }
+
/**
* Interface to indicate that a view is reusable
*/