Explicit Nullbility in IconCache (Part 1) am: 84fb31d264

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/libs/systemui/+/19671998

Change-Id: Ic151d6e59fd10dda80fb830f09d7b123ab0239f3
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
index f671171..836d3a8 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
@@ -37,6 +37,8 @@
 import com.android.launcher3.icons.BitmapInfo.Extender;
 import com.android.launcher3.util.FlagOp;
 
+import java.util.Objects;
+
 /**
  * This class will be moved to androidx library. There shouldn't be any dependency outside
  * this package.
@@ -51,12 +53,24 @@
 
     private static final float ICON_BADGE_SCALE = 0.444f;
 
+    @NonNull
     private final Rect mOldBounds = new Rect();
+
+    @NonNull
     private final SparseBooleanArray mIsUserBadged = new SparseBooleanArray();
+
+    @NonNull
     protected final Context mContext;
+
+    @NonNull
     private final Canvas mCanvas;
+
+    @NonNull
     private final PackageManager mPm;
+
+    @NonNull
     private final ColorExtractor mColorExtractor;
+
     private boolean mDisableColorExtractor;
 
     protected final int mFillResIconDpi;
@@ -64,8 +78,12 @@
 
     protected boolean mMonoIconEnabled;
 
+    @Nullable
     private IconNormalizer mNormalizer;
+
+    @Nullable
     private ShadowGenerator mShadowGenerator;
+
     private final boolean mShapeDetection;
 
     // Shadow bitmap used as background for theme icons
@@ -100,6 +118,7 @@
         mDisableColorExtractor = false;
     }
 
+    @NonNull
     public ShadowGenerator getShadowGenerator() {
         if (mShadowGenerator == null) {
             mShadowGenerator = new ShadowGenerator(mIconBitmapSize);
@@ -107,6 +126,7 @@
         return mShadowGenerator;
     }
 
+    @NonNull
     public IconNormalizer getNormalizer() {
         if (mNormalizer == null) {
             mNormalizer = new IconNormalizer(mContext, mIconBitmapSize, mShapeDetection);
@@ -155,6 +175,7 @@
     /**
      * Creates an icon from the bitmap cropped to the current device icon shape
      */
+    @NonNull
     public BitmapInfo createShapedIconBitmap(Bitmap icon, IconOptions options) {
         Drawable d = new FixedSizeBitmapDrawable(icon);
         float inset = getExtraInsetFraction();
@@ -164,6 +185,7 @@
         return createBadgedIconBitmap(d, options);
     }
 
+    @NonNull
     public BitmapInfo createBadgedIconBitmap(@NonNull Drawable icon) {
         return createBadgedIconBitmap(icon, null);
     }
@@ -176,6 +198,7 @@
      * @return a bitmap suitable for disaplaying as an icon at various system UIs.
      */
     @TargetApi(Build.VERSION_CODES.TIRAMISU)
+    @NonNull
     public BitmapInfo createBadgedIconBitmap(@NonNull Drawable icon,
             @Nullable IconOptions options) {
         boolean shrinkNonAdaptiveIcons = options == null || options.mShrinkNonAdaptiveIcons;
@@ -202,6 +225,7 @@
         return info;
     }
 
+    @NonNull
     public FlagOp getBitmapFlagOp(@Nullable IconOptions options) {
         FlagOp op = FlagOp.NO_OP;
         if (options != null) {
@@ -228,6 +252,7 @@
     }
 
     /** package private */
+    @NonNull
     Bitmap getWhiteShadowLayer() {
         if (mWhiteShadowLayer == null) {
             mWhiteShadowLayer = createScaledBitmapWithShadow(
@@ -236,15 +261,16 @@
         return mWhiteShadowLayer;
     }
 
-    /** package private */
-    public Bitmap createScaledBitmapWithShadow(Drawable d) {
+    @NonNull
+    public Bitmap createScaledBitmapWithShadow(@NonNull final Drawable d) {
         float scale = getNormalizer().getScale(d, null, null, null);
         Bitmap bitmap = createIconBitmap(d, scale);
         return BitmapRenderer.createHardwareBitmap(bitmap.getWidth(), bitmap.getHeight(),
                 canvas -> getShadowGenerator().recreateIcon(bitmap, canvas));
     }
 
-    public Bitmap createScaledBitmapWithoutShadow(Drawable icon) {
+    @NonNull
+    public Bitmap createScaledBitmapWithoutShadow(@Nullable Drawable icon) {
         RectF iconBounds = new RectF();
         float[] scale = new float[1];
         icon = normalizeAndWrapToAdaptiveIcon(icon, true, iconBounds, scale);
@@ -255,7 +281,7 @@
     /**
      * Sets the background color used for wrapped adaptive icon
      */
-    public void setWrapperBackgroundColor(int color) {
+    public void setWrapperBackgroundColor(final int color) {
         mWrapperBackgroundColor = (Color.alpha(color) < 255) ? DEFAULT_WRAPPER_BACKGROUND : color;
     }
 
@@ -266,8 +292,10 @@
         mDisableColorExtractor = true;
     }
 
-    protected Drawable normalizeAndWrapToAdaptiveIcon(@NonNull Drawable icon,
-            boolean shrinkNonAdaptiveIcons, RectF outIconBounds, float[] outScale) {
+    @Nullable
+    protected Drawable normalizeAndWrapToAdaptiveIcon(@Nullable Drawable icon,
+            final boolean shrinkNonAdaptiveIcons, @Nullable final RectF outIconBounds,
+            @NonNull final float[] outScale) {
         if (icon == null) {
             return null;
         }
@@ -298,12 +326,14 @@
         return icon;
     }
 
-    protected Bitmap createIconBitmap(Drawable icon, float scale) {
+    @NonNull
+    protected Bitmap createIconBitmap(@Nullable final Drawable icon, final float scale) {
         return createIconBitmap(icon, scale, BITMAP_GENERATION_MODE_DEFAULT);
     }
 
-    protected Bitmap createIconBitmap(@NonNull Drawable icon, float scale,
-            int bitmapGenerationMode) {
+    @NonNull
+    protected Bitmap createIconBitmap(@Nullable final Drawable icon, final float scale,
+            final int bitmapGenerationMode) {
         final int size = mIconBitmapSize;
 
         final Bitmap bitmap;
@@ -381,36 +411,42 @@
         clear();
     }
 
+    @NonNull
     public BitmapInfo makeDefaultIcon() {
         return createBadgedIconBitmap(getFullResDefaultActivityIcon(mFillResIconDpi));
     }
 
-    public static Drawable getFullResDefaultActivityIcon(int iconDpi) {
-        return Resources.getSystem().getDrawableForDensity(
-                android.R.drawable.sym_def_app_icon, iconDpi);
+    @NonNull
+    public static Drawable getFullResDefaultActivityIcon(final int iconDpi) {
+        return Objects.requireNonNull(Resources.getSystem().getDrawableForDensity(
+                android.R.drawable.sym_def_app_icon, iconDpi));
     }
 
-    private int extractColor(Bitmap bitmap) {
+    private int extractColor(@NonNull final Bitmap bitmap) {
         return mDisableColorExtractor ? 0 : mColorExtractor.findDominantColorByHue(bitmap);
     }
 
     /**
      * Returns the correct badge size given an icon size
      */
-    public static int getBadgeSizeForIconSize(int iconSize) {
+    public static int getBadgeSizeForIconSize(final int iconSize) {
         return (int) (ICON_BADGE_SCALE * iconSize);
     }
 
     public static class IconOptions {
 
         boolean mShrinkNonAdaptiveIcons = true;
+
         boolean mIsInstantApp;
+
+        @Nullable
         UserHandle mUserHandle;
 
         /**
          * Set to false if non-adaptive icons should not be treated
          */
-        public IconOptions setShrinkNonAdaptiveIcons(boolean shrink) {
+        @NonNull
+        public IconOptions setShrinkNonAdaptiveIcons(final boolean shrink) {
             mShrinkNonAdaptiveIcons = shrink;
             return this;
         }
@@ -418,7 +454,8 @@
         /**
          * User for this icon, in case of badging
          */
-        public IconOptions setUser(UserHandle user) {
+        @NonNull
+        public IconOptions setUser(@Nullable final UserHandle user) {
             mUserHandle = user;
             return this;
         }
@@ -426,7 +463,8 @@
         /**
          * If this icon represents an instant app
          */
-        public IconOptions setInstantApp(boolean instantApp) {
+        @NonNull
+        public IconOptions setInstantApp(final boolean instantApp) {
             mIsInstantApp = instantApp;
             return this;
         }
@@ -439,7 +477,7 @@
      */
     private static class FixedSizeBitmapDrawable extends BitmapDrawable {
 
-        public FixedSizeBitmapDrawable(Bitmap bitmap) {
+        public FixedSizeBitmapDrawable(@Nullable final Bitmap bitmap) {
             super(null, bitmap);
         }
 
@@ -468,9 +506,10 @@
 
     private static class ClippedMonoDrawable extends InsetDrawable {
 
+        @NonNull
         private final AdaptiveIconDrawable mCrop;
 
-        public ClippedMonoDrawable(Drawable base) {
+        public ClippedMonoDrawable(@Nullable final Drawable base) {
             super(base, -getExtraInsetFraction());
             mCrop = new AdaptiveIconDrawable(new ColorDrawable(Color.BLACK), null);
         }
@@ -487,11 +526,16 @@
 
     private static class CenterTextDrawable extends ColorDrawable {
 
+        @NonNull
         private final Rect mTextBounds = new Rect();
+
+        @NonNull
         private final Paint mTextPaint = new Paint(ANTI_ALIAS_FLAG | FILTER_BITMAP_FLAG);
+
+        @NonNull
         private final String mText;
 
-        CenterTextDrawable(String text, int color) {
+        CenterTextDrawable(@NonNull final String text, final int color) {
             mText = text;
             mTextPaint.setColor(color);
         }
diff --git a/iconloaderlib/src/com/android/launcher3/icons/ColorExtractor.java b/iconloaderlib/src/com/android/launcher3/icons/ColorExtractor.java
index 87bda82..56bb3ea 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/ColorExtractor.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/ColorExtractor.java
@@ -18,6 +18,9 @@
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.util.SparseArray;
+
+import androidx.annotation.NonNull;
+
 import java.util.Arrays;
 
 /**
@@ -26,16 +29,24 @@
 public class ColorExtractor {
 
     private final int NUM_SAMPLES = 20;
+
+    @NonNull
     private final float[] mTmpHsv = new float[3];
+
+    @NonNull
     private final float[] mTmpHueScoreHistogram = new float[360];
+
+    @NonNull
     private final int[] mTmpPixels = new int[NUM_SAMPLES];
+
+    @NonNull
     private final SparseArray<Float> mTmpRgbScores = new SparseArray<>();
 
     /**
      * This picks a dominant color, looking for high-saturation, high-value, repeated hues.
      * @param bitmap The bitmap to scan
      */
-    public int findDominantColorByHue(Bitmap bitmap) {
+    public int findDominantColorByHue(@NonNull final Bitmap bitmap) {
         return findDominantColorByHue(bitmap, NUM_SAMPLES);
     }
 
@@ -43,7 +54,7 @@
      * This picks a dominant color, looking for high-saturation, high-value, repeated hues.
      * @param bitmap The bitmap to scan
      */
-    public int findDominantColorByHue(Bitmap bitmap, int samples) {
+    public int findDominantColorByHue(@NonNull final Bitmap bitmap, final int samples) {
         final int height = bitmap.getHeight();
         final int width = bitmap.getWidth();
         int sampleStride = (int) Math.sqrt((height * width) / samples);
diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
index 057bdc2..963e807 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
@@ -54,6 +54,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
+import androidx.annotation.WorkerThread;
 
 import com.android.launcher3.icons.BaseIconFactory;
 import com.android.launcher3.icons.BaseIconFactory.IconOptions;
@@ -86,29 +87,50 @@
 
         @NonNull
         public BitmapInfo bitmap = BitmapInfo.LOW_RES_INFO;
+        @NonNull
         public CharSequence title = "";
+        @NonNull
         public CharSequence contentDescription = "";
     }
 
+    @NonNull
     protected final Context mContext;
+
+    @NonNull
     protected final PackageManager mPackageManager;
 
+    @NonNull
     private final Map<ComponentKey, CacheEntry> mCache;
+
+    @NonNull
     protected final Handler mWorkerHandler;
 
     protected int mIconDpi;
+
+    @NonNull
     protected IconDB mIconDb;
+
+    @NonNull
     protected LocaleList mLocaleList = LocaleList.getEmptyLocaleList();
+
+    @NonNull
     protected String mSystemState = "";
 
+    @Nullable
     private BitmapInfo mDefaultIcon;
+
+    @NonNull
     private final SparseArray<FlagOp> mUserFlagOpMap = new SparseArray<>();
 
+    @Nullable
     private final String mDbFileName;
+
+    @NonNull
     private final Looper mBgLooper;
 
-    public BaseIconCache(Context context, String dbFileName, Looper bgLooper,
-            int iconDpi, int iconPixelSize, boolean inMemoryCache) {
+    public BaseIconCache(@NonNull final Context context, @Nullable final String dbFileName,
+            @NonNull final Looper bgLooper, final int iconDpi, final int iconPixelSize,
+            final boolean inMemoryCache) {
         mContext = context;
         mDbFileName = dbFileName;
         mPackageManager = context.getPackageManager();
@@ -141,23 +163,24 @@
      * Returns the persistable serial number for {@param user}. Subclass should implement proper
      * caching strategy to avoid making binder call every time.
      */
-    protected abstract long getSerialNumberForUser(UserHandle user);
+    protected abstract long getSerialNumberForUser(@NonNull final UserHandle user);
 
     /**
      * Return true if the given app is an instant app and should be badged appropriately.
      */
-    protected abstract boolean isInstantApp(ApplicationInfo info);
+    protected abstract boolean isInstantApp(@NonNull final ApplicationInfo info);
 
     /**
      * Opens and returns an icon factory. The factory is recycled by the caller.
      */
+    @NonNull
     public abstract BaseIconFactory getIconFactory();
 
-    public void updateIconParams(int iconDpi, int iconPixelSize) {
+    public void updateIconParams(final int iconDpi, final int iconPixelSize) {
         mWorkerHandler.post(() -> updateIconParamsBg(iconDpi, iconPixelSize));
     }
 
-    private synchronized void updateIconParamsBg(int iconDpi, int iconPixelSize) {
+    private synchronized void updateIconParamsBg(final int iconDpi, final int iconPixelSize) {
         mIconDpi = iconDpi;
         mDefaultIcon = null;
         mUserFlagOpMap.clear();
@@ -167,7 +190,8 @@
         mCache.clear();
     }
 
-    private Drawable getFullResIcon(Resources resources, int iconId) {
+    @Nullable
+    private Drawable getFullResIcon(@Nullable final Resources resources, final int iconId) {
         if (resources != null && iconId != 0) {
             try {
                 return resources.getDrawableForDensity(iconId, mIconDpi);
@@ -176,14 +200,16 @@
         return getFullResDefaultActivityIcon(mIconDpi);
     }
 
-    public Drawable getFullResIcon(String packageName, int iconId) {
+    @Nullable
+    public Drawable getFullResIcon(@NonNull final String packageName, final int iconId) {
         try {
             return getFullResIcon(mPackageManager.getResourcesForApplication(packageName), iconId);
         } catch (PackageManager.NameNotFoundException e) { }
         return getFullResDefaultActivityIcon(mIconDpi);
     }
 
-    public Drawable getFullResIcon(ActivityInfo info) {
+    @Nullable
+    public Drawable getFullResIcon(@NonNull final ActivityInfo info) {
         try {
             return getFullResIcon(mPackageManager.getResourcesForApplication(info.applicationInfo),
                     info.getIconResource());
@@ -194,14 +220,16 @@
     /**
      * Remove any records for the supplied ComponentName.
      */
-    public synchronized void remove(ComponentName componentName, UserHandle user) {
+    public synchronized void remove(@NonNull final ComponentName componentName,
+            @NonNull final UserHandle user) {
         mCache.remove(new ComponentKey(componentName, user));
     }
 
     /**
      * Remove any records for the supplied package name from memory.
      */
-    private void removeFromMemCacheLocked(String packageName, UserHandle user) {
+    private void removeFromMemCacheLocked(@Nullable final String packageName,
+            @Nullable final UserHandle user) {
         HashSet<ComponentKey> forDeletion = new HashSet<>();
         for (ComponentKey key: mCache.keySet()) {
             if (key.componentName.getPackageName().equals(packageName)
@@ -217,7 +245,8 @@
     /**
      * Removes the entries related to the given package in memory and persistent DB.
      */
-    public synchronized void removeIconsForPkg(String packageName, UserHandle user) {
+    public synchronized void removeIconsForPkg(@NonNull final String packageName,
+            @NonNull final UserHandle user) {
         removeFromMemCacheLocked(packageName, user);
         long userSerial = getSerialNumberForUser(user);
         mIconDb.delete(
@@ -225,6 +254,7 @@
                 new String[]{packageName + "/%", Long.toString(userSerial)});
     }
 
+    @NonNull
     public IconCacheUpdateHandler getUpdateHandler() {
         updateSystemState();
         return new IconCacheUpdateHandler(this);
@@ -240,7 +270,8 @@
         mSystemState = mLocaleList.toLanguageTags() + "," + Build.VERSION.SDK_INT;
     }
 
-    protected String getIconSystemState(String packageName) {
+    @NonNull
+    protected String getIconSystemState(@Nullable final String packageName) {
         return mSystemState;
     }
 
@@ -251,8 +282,9 @@
      *                        old data.
      */
     @VisibleForTesting
-    public synchronized <T> void addIconToDBAndMemCache(T object, CachingLogic<T> cachingLogic,
-            PackageInfo info, long userSerial, boolean replaceExisting) {
+    public synchronized <T> void addIconToDBAndMemCache(@NonNull final T object,
+            @NonNull final CachingLogic<T> cachingLogic, @NonNull final PackageInfo info,
+            final long userSerial, final boolean replaceExisting) {
         UserHandle user = cachingLogic.getUser(object);
         ComponentName componentName = cachingLogic.getComponent(object);
 
@@ -276,7 +308,8 @@
 
         CharSequence entryTitle = cachingLogic.getLabel(object);
         if (entryTitle == null) {
-            Log.d(TAG, "No label returned from caching logic instance: " + cachingLogic);
+            Log.wtf(TAG, "No label returned from caching logic instance: " + cachingLogic);
+            entryTitle = "";
         }
         entry.title = entryTitle;
 
@@ -293,8 +326,8 @@
      * Updates {@param values} to contain versioning information and adds it to the DB.
      * @param values {@link ContentValues} containing icon & title
      */
-    private void addIconToDB(ContentValues values, ComponentName key,
-            PackageInfo info, long userSerial, long lastUpdateTime) {
+    private void addIconToDB(@NonNull final ContentValues values, @NonNull final ComponentName key,
+            @NonNull final PackageInfo info, final long userSerial, final long lastUpdateTime) {
         values.put(IconDB.COLUMN_COMPONENT, key.flattenToString());
         values.put(IconDB.COLUMN_USER, userSerial);
         values.put(IconDB.COLUMN_LAST_UPDATED, lastUpdateTime);
@@ -302,7 +335,8 @@
         mIconDb.insertOrReplace(values);
     }
 
-    public synchronized BitmapInfo getDefaultIcon(UserHandle user) {
+    @NonNull
+    public synchronized BitmapInfo getDefaultIcon(@NonNull final UserHandle user) {
         if (mDefaultIcon == null) {
             try (BaseIconFactory li = getIconFactory()) {
                 mDefaultIcon = li.makeDefaultIcon();
@@ -311,7 +345,8 @@
         return mDefaultIcon.withFlags(getUserFlagOpLocked(user));
     }
 
-    protected FlagOp getUserFlagOpLocked(UserHandle user) {
+    @NonNull
+    protected FlagOp getUserFlagOpLocked(@NonNull final UserHandle user) {
         int key = user.hashCode();
         int index;
         if ((index = mUserFlagOpMap.indexOfKey(key)) >= 0) {
@@ -325,7 +360,7 @@
         }
     }
 
-    public boolean isDefaultIcon(BitmapInfo icon, UserHandle user) {
+    public boolean isDefaultIcon(@NonNull final BitmapInfo icon, @NonNull final UserHandle user) {
         return getDefaultIcon(user).icon == icon.icon;
     }
 
@@ -333,10 +368,11 @@
      * Retrieves the entry from the cache. If the entry is not present, it creates a new entry.
      * This method is not thread safe, it must be called from a synchronized method.
      */
+    @NonNull
     protected <T> CacheEntry cacheLocked(
-            @NonNull ComponentName componentName, @NonNull UserHandle user,
-            @NonNull Supplier<T> infoProvider, @NonNull CachingLogic<T> cachingLogic,
-            boolean usePackageIcon, boolean useLowResIcon) {
+            @NonNull final ComponentName componentName, @NonNull final UserHandle user,
+            @NonNull final Supplier<T> infoProvider, @NonNull final CachingLogic<T> cachingLogic,
+            final boolean usePackageIcon, final boolean useLowResIcon) {
         return cacheLocked(
                 componentName,
                 user,
@@ -347,10 +383,12 @@
                 useLowResIcon);
     }
 
+    @NonNull
     protected <T> CacheEntry cacheLocked(
-            @NonNull ComponentName componentName, @NonNull UserHandle user,
-            @NonNull Supplier<T> infoProvider, @NonNull CachingLogic<T> cachingLogic,
-            @Nullable Cursor cursor, boolean usePackageIcon, boolean useLowResIcon) {
+            @NonNull final ComponentName componentName, @NonNull final UserHandle user,
+            @NonNull final Supplier<T> infoProvider, @NonNull final CachingLogic<T> cachingLogic,
+            @Nullable final Cursor cursor, final boolean usePackageIcon,
+            final boolean useLowResIcon) {
         assertWorkerThread();
         ComponentKey cacheKey = new ComponentKey(componentName, user);
         CacheEntry entry = mCache.get(cacheKey);
@@ -396,30 +434,28 @@
     /**
      * Fallback method for loading an icon bitmap.
      */
-    protected <T> void loadFallbackIcon(
-            T object, CacheEntry entry, @NonNull CachingLogic<T> cachingLogic,
-            boolean usePackageIcon, boolean usePackageTitle, @NonNull ComponentName componentName,
-            @NonNull UserHandle user) {
+    protected <T> void loadFallbackIcon(@Nullable final T object, @NonNull final CacheEntry entry,
+            @NonNull final CachingLogic<T> cachingLogic, final boolean usePackageIcon,
+            final boolean usePackageTitle, @NonNull final ComponentName componentName,
+            @NonNull final UserHandle user) {
         if (object != null) {
             entry.bitmap = cachingLogic.loadIcon(mContext, object);
         } else {
             if (usePackageIcon) {
                 CacheEntry packageEntry = getEntryForPackageLocked(
                         componentName.getPackageName(), user, false);
-                if (packageEntry != null) {
-                    if (DEBUG) Log.d(TAG, "using package default icon for " +
-                            componentName.toShortString());
-                    entry.bitmap = packageEntry.bitmap;
-                    entry.contentDescription = packageEntry.contentDescription;
+                if (DEBUG) Log.d(TAG, "using package default icon for " +
+                        componentName.toShortString());
+                entry.bitmap = packageEntry.bitmap;
+                entry.contentDescription = packageEntry.contentDescription;
 
-                    if (usePackageTitle) {
-                        entry.title = packageEntry.title;
-                    }
+                if (usePackageTitle) {
+                    entry.title = packageEntry.title;
                 }
             }
             if (entry.bitmap == null) {
-                if (DEBUG) Log.d(TAG, "using default icon for " +
-                        componentName.toShortString());
+                // TODO: entry.bitmap can never be null, so this should not happen at all.
+                Log.wtf(TAG, "using default icon for " + componentName.toShortString());
                 entry.bitmap = getDefaultIcon(user);
             }
         }
@@ -429,8 +465,8 @@
      * Fallback method for loading an app title.
      */
     protected <T> void loadFallbackTitle(
-            T object, CacheEntry entry, @NonNull CachingLogic<T> cachingLogic,
-            @NonNull UserHandle user) {
+            @NonNull final T object, @NonNull final CacheEntry entry,
+            @NonNull final CachingLogic<T> cachingLogic, @NonNull final UserHandle user) {
         entry.title = cachingLogic.getLabel(object);
         entry.contentDescription = mPackageManager.getUserBadgedLabel(
                 cachingLogic.getDescription(object, entry.title), user);
@@ -445,8 +481,9 @@
      * Adds a default package entry in the cache. This entry is not persisted and will be removed
      * when the cache is flushed.
      */
-    protected synchronized void cachePackageInstallInfo(String packageName, UserHandle user,
-            Bitmap icon, CharSequence title) {
+    protected synchronized void cachePackageInstallInfo(@NonNull final String packageName,
+            @NonNull final UserHandle user, @Nullable final Bitmap icon,
+            @Nullable final CharSequence title) {
         removeFromMemCacheLocked(packageName, user);
 
         ComponentKey cacheKey = getPackageKey(packageName, user);
@@ -469,7 +506,9 @@
         }
     }
 
-    private static ComponentKey getPackageKey(String packageName, UserHandle user) {
+    @NonNull
+    private static ComponentKey getPackageKey(@NonNull final String packageName,
+            @NonNull final UserHandle user) {
         ComponentName cn = new ComponentName(packageName, packageName + EMPTY_CLASS_NAME);
         return new ComponentKey(cn, user);
     }
@@ -478,8 +517,10 @@
      * Gets an entry for the package, which can be used as a fallback entry for various components.
      * This method is not thread safe, it must be called from a synchronized method.
      */
-    protected CacheEntry getEntryForPackageLocked(String packageName, UserHandle user,
-            boolean useLowResIcon) {
+    @WorkerThread
+    @NonNull
+    protected CacheEntry getEntryForPackageLocked(@NonNull final String packageName,
+            @NonNull final UserHandle user, final boolean useLowResIcon) {
         assertWorkerThread();
         ComponentKey cacheKey = getPackageKey(packageName, user);
         CacheEntry entry = mCache.get(cacheKey);
@@ -533,8 +574,8 @@
         return entry;
     }
 
-    protected boolean getEntryFromDBLocked(
-            ComponentKey cacheKey, CacheEntry entry, boolean lowRes) {
+    protected boolean getEntryFromDBLocked(@NonNull final ComponentKey cacheKey,
+            @NonNull final CacheEntry entry, final boolean lowRes) {
         Cursor c = null;
         Trace.beginSection("loadIconIndividually");
         try {
@@ -559,7 +600,8 @@
     }
 
     private boolean updateTitleAndIconLocked(
-            ComponentKey cacheKey, CacheEntry entry, Cursor c, boolean lowRes) {
+            @NonNull final ComponentKey cacheKey, @NonNull final CacheEntry entry,
+            @NonNull final Cursor c, final boolean lowRes) {
         // Set the alpha to be 255, so that we never have a wrong color
         entry.bitmap = BitmapInfo.of(LOW_RES_ICON,
                 setColorAlphaBound(c.getInt(IconDB.INDEX_COLOR), 255));
@@ -678,8 +720,10 @@
         }
     }
 
-    private ContentValues newContentValues(BitmapInfo bitmapInfo, String label,
-            String packageName, @Nullable String keywords) {
+    @NonNull
+    private ContentValues newContentValues(@NonNull final BitmapInfo bitmapInfo,
+            @NonNull final String label, @NonNull final String packageName,
+            @Nullable final String keywords) {
         ContentValues values = new ContentValues();
         if (bitmapInfo.canPersist()) {
             values.put(IconDB.COLUMN_ICON, flattenBitmap(bitmapInfo.icon));
diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java b/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java
index c12e9dc..8034d6e 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java
@@ -28,31 +28,36 @@
 
 public interface CachingLogic<T> {
 
-    ComponentName getComponent(T object);
+    @NonNull
+    ComponentName getComponent(@NonNull final T object);
 
-    UserHandle getUser(T object);
+    @NonNull
+    UserHandle getUser(@NonNull final T object);
 
-    CharSequence getLabel(T object);
+    @NonNull
+    CharSequence getLabel(@NonNull final T object);
 
-    default CharSequence getDescription(T object, CharSequence fallback) {
+    @NonNull
+    default CharSequence getDescription(@NonNull final T object,
+            @NonNull final CharSequence fallback) {
         return fallback;
     }
 
     @NonNull
-    BitmapInfo loadIcon(Context context, T object);
+    BitmapInfo loadIcon(@NonNull final Context context, @NonNull final T object);
 
     /**
      * Provides a option list of keywords to associate with this object
      */
     @Nullable
-    default String getKeywords(T object, LocaleList localeList) {
+    default String getKeywords(@NonNull final T object, @NonNull final LocaleList localeList) {
         return null;
     }
 
     /**
      * Returns the timestamp the entry was last updated in cache.
      */
-    default long getLastUpdatedTime(T object, PackageInfo info) {
+    default long getLastUpdatedTime(@Nullable final T object, @NonNull final PackageInfo info) {
         return info.lastUpdateTime;
     }
 
diff --git a/iconloaderlib/src_full_lib/com/android/launcher3/icons/SimpleIconCache.java b/iconloaderlib/src_full_lib/com/android/launcher3/icons/SimpleIconCache.java
index cc4ad7b..63ba887 100644
--- a/iconloaderlib/src_full_lib/com/android/launcher3/icons/SimpleIconCache.java
+++ b/iconloaderlib/src_full_lib/com/android/launcher3/icons/SimpleIconCache.java
@@ -32,6 +32,8 @@
 import android.os.UserManager;
 import android.util.SparseLongArray;
 
+import androidx.annotation.NonNull;
+
 import com.android.launcher3.icons.cache.BaseIconCache;
 
 /**
@@ -64,7 +66,7 @@
     }
 
     @Override
-    protected long getSerialNumberForUser(UserHandle user) {
+    protected long getSerialNumberForUser(@NonNull UserHandle user) {
         synchronized (mUserSerialMap) {
             int index = mUserSerialMap.indexOfKey(user.getIdentifier());
             if (index >= 0) {
@@ -83,10 +85,11 @@
     }
 
     @Override
-    protected boolean isInstantApp(ApplicationInfo info) {
+    protected boolean isInstantApp(@NonNull ApplicationInfo info) {
         return info.isInstantApp();
     }
 
+    @NonNull
     @Override
     public BaseIconFactory getIconFactory() {
         return IconFactory.obtain(mContext);