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

Commit ec60e698 authored by Andrew Cole's avatar Andrew Cole
Browse files

NullPointer Check For ComponentName

Handling a null pointer check for component name and adding a log message so that we accuratly figure out which component is causing the issue

Bug: 357725795
Test: IconCacheUpdateHandlerTest
Flag: EXEMPT bugfix
Change-Id: I6a5fb997767530e55785f909fb41aa74fe198f23
parent f405ea09
Loading
Loading
Loading
Loading
+78 −46
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseBooleanArray;

import androidx.annotation.VisibleForTesting;

import com.android.launcher3.icons.cache.BaseIconCache.IconDB;

import java.util.ArrayDeque;
@@ -67,6 +69,15 @@ public class IconCacheUpdateHandler {
    private final SparseBooleanArray mItemsToDelete = new SparseBooleanArray();
    private boolean mFilterMode = MODE_SET_INVALID_ITEMS;

    /**
     * Constructor for testing.
     */
    @VisibleForTesting
    public IconCacheUpdateHandler(HashMap<String, PackageInfo> pkgInfoMap, BaseIconCache cache) {
        mIconCache = cache;
        mPkgInfoMap = pkgInfoMap;
    }

    IconCacheUpdateHandler(BaseIconCache cache) {
        mIconCache = cache;

@@ -152,18 +163,54 @@ public class IconCacheUpdateHandler {
                IconDB.COLUMN_USER + " = ? ",
                new String[]{Long.toString(userSerial)})) {

            while (c.moveToNext()) {
                var app = updateOrDeleteIcon(c, componentMap, ignorePackages, user, cachingLogic);
                if (app != null) {
                    appsToUpdate.add(app);
                }
            }
        } catch (SQLiteException e) {
            Log.d(TAG, "Error reading icon cache", e);
            // Continue updating whatever we have read so far
        }

        // Insert remaining apps.
        if (!componentMap.isEmpty() || !appsToUpdate.isEmpty()) {
            ArrayDeque<T> appsToAdd = new ArrayDeque<>();
            appsToAdd.addAll(componentMap.values());
            mIconCache.setIconUpdateInProgress(true);
            new SerializedIconUpdateTask(userSerial, user, appsToAdd, appsToUpdate, cachingLogic,
                    onUpdateCallback).scheduleNext();
        }
    }

    /**
     * This method retrieves the component and either adds it to the list of apps to update or
     * adds it to a list of apps to delete from cache later. Returns the individual app if it
     * should be updated, or null if nothing should be updated.
     */
    @VisibleForTesting
    public <T> T updateOrDeleteIcon(Cursor c, HashMap<ComponentName, T> componentMap,
            Set<String> ignorePackages, UserHandle user, CachingLogic<T> cachingLogic) {

        final int indexComponent = c.getColumnIndex(IconDB.COLUMN_COMPONENT);
        final int indexLastUpdate = c.getColumnIndex(IconDB.COLUMN_LAST_UPDATED);
        final int indexVersion = c.getColumnIndex(IconDB.COLUMN_VERSION);
        final int rowIndex = c.getColumnIndex(IconDB.COLUMN_ROWID);
        final int systemStateIndex = c.getColumnIndex(IconDB.COLUMN_SYSTEM_STATE);

            while (c.moveToNext()) {
        int rowId = c.getInt(rowIndex);
        String cn = c.getString(indexComponent);
        ComponentName component = ComponentName.unflattenFromString(cn);
        if (component == null) {
            // b/357725795
            Log.e(TAG, "Invalid component name while updating icon cache: " + cn);
            mItemsToDelete.put(rowId, true);
            return null;
        }

        PackageInfo info = mPkgInfoMap.get(component.getPackageName());

                int rowId = c.getInt(rowIndex);
        if (info == null) {
            if (!ignorePackages.contains(component.getPackageName())) {

@@ -172,11 +219,11 @@ public class IconCacheUpdateHandler {
                    mItemsToDelete.put(rowId, true);
                }
            }
                    continue;
            return null;
        }
        if ((info.applicationInfo.flags & ApplicationInfo.FLAG_IS_DATA_ONLY) != 0) {
            // Application is not present
                    continue;
            return null;
        }

        long updateTime = c.getLong(indexLastUpdate);
@@ -190,7 +237,7 @@ public class IconCacheUpdateHandler {
            if (mFilterMode == MODE_CLEAR_VALID_ITEMS) {
                mItemsToDelete.put(rowId, false);
            }
                    continue;
            return null;
        }

        if (app == null) {
@@ -198,23 +245,8 @@ public class IconCacheUpdateHandler {
                mIconCache.remove(component, user);
                mItemsToDelete.put(rowId, true);
            }
                } else {
                    appsToUpdate.add(app);
                }
            }
        } catch (SQLiteException e) {
            Log.d(TAG, "Error reading icon cache", e);
            // Continue updating whatever we have read so far
        }

        // Insert remaining apps.
        if (!componentMap.isEmpty() || !appsToUpdate.isEmpty()) {
            ArrayDeque<T> appsToAdd = new ArrayDeque<>();
            appsToAdd.addAll(componentMap.values());
            mIconCache.setIconUpdateInProgress(true);
            new SerializedIconUpdateTask(userSerial, user, appsToAdd, appsToUpdate, cachingLogic,
                    onUpdateCallback).scheduleNext();
        }
        return app;
    }

    /**