Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 696a6c58 authored by Fengjiang Li's avatar Fengjiang Li
Browse files

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
parent 6f699d23
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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.