Fix NPE of AllAppsRecyclerViewPool.kt

Skip preinflating all apps icons if RecyclerView doesn't have layout manager yet. Also force crash in studio build to help find a repro case

Fix: 355192472
Flag: NONE - npe fix
Test: presubmit
Change-Id: I1e3e271eb6d5b732a7a71eb466bff402c172be0a
This commit is contained in:
Fengjiang Li
2024-08-01 14:37:08 -07:00
parent 6f699d23ea
commit 696a6c58d8
@@ -17,6 +17,7 @@
package com.android.launcher3.recyclerview
import android.content.Context
import android.util.Log
import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting.Companion.PROTECTED
@@ -24,6 +25,7 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.RecycledViewPool
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.android.launcher3.BubbleTextView
import com.android.launcher3.BuildConfig
import com.android.launcher3.allapps.BaseAllAppsAdapter
import com.android.launcher3.config.FeatureFlags
import com.android.launcher3.util.CancellableTask
@@ -32,6 +34,7 @@ import com.android.launcher3.util.Executors.VIEW_PREINFLATION_EXECUTOR
import com.android.launcher3.util.Themes
import com.android.launcher3.views.ActivityContext
import com.android.launcher3.views.ActivityContext.ActivityContextDelegate
import java.lang.IllegalStateException
const val PREINFLATE_ICONS_ROW_COUNT = 4
const val EXTRA_ICONS_COUNT = 2
@@ -47,6 +50,12 @@ class AllAppsRecyclerViewPool<T> : RecycledViewPool() where T : Context, T : Act
@VisibleForTesting(otherwise = PROTECTED)
var mCancellableTask: CancellableTask<List<ViewHolder>>? = null
companion object {
private const val TAG = "AllAppsRecyclerViewPool"
private const val NULL_LAYOUT_MANAGER_ERROR_STRING =
"activeRv's layoutManager should not be null"
}
/**
* Preinflate app icons. If all apps RV cannot be scrolled down, we don't need to preinflate.
*/
@@ -54,6 +63,15 @@ class AllAppsRecyclerViewPool<T> : RecycledViewPool() where T : Context, T : Act
val appsView = context.appsView ?: return
val activeRv: RecyclerView = appsView.activeRecyclerView ?: return
if (activeRv.layoutManager == null) {
if (BuildConfig.IS_STUDIO_BUILD) {
throw IllegalStateException(NULL_LAYOUT_MANAGER_ERROR_STRING)
} else {
Log.e(TAG, NULL_LAYOUT_MANAGER_ERROR_STRING)
}
return
}
// Create a separate context dedicated for all apps preinflation thread. The goal is to
// create a separate AssetManager obj internally to avoid lock contention with
// AssetManager obj that is associated with the launcher context on the main thread.