Load app icons defensively

Use a placeholder when an app icon or a direct share icon loading failed
with an exception.

Bug: 260924828
Test: functionality smoke test
Test: manual test with simulate exceptions
Test: atest IntentResolverUnitTests
Change-Id: Id3e4311c6bcc23a78043622b018c410985c8b701
diff --git a/java/src/com/android/intentresolver/ChooserListAdapter.java b/java/src/com/android/intentresolver/ChooserListAdapter.java
index 59d1a6e..b9a7840 100644
--- a/java/src/com/android/intentresolver/ChooserListAdapter.java
+++ b/java/src/com/android/intentresolver/ChooserListAdapter.java
@@ -259,8 +259,7 @@
         final ViewHolder holder = (ViewHolder) view.getTag();
 
         if (info == null) {
-            holder.icon.setImageDrawable(
-                    mContext.getDrawable(R.drawable.resolver_icon_placeholder));
+            holder.icon.setImageDrawable(loadIconPlaceholder());
             return;
         }
 
@@ -657,11 +656,21 @@
 
         @Override
         protected Drawable doInBackground(Void... voids) {
-            return getChooserTargetIconDrawable(
-                    mContext,
-                    mTargetInfo.getChooserTargetIcon(),
-                    mTargetInfo.getChooserTargetComponentName(),
-                    mTargetInfo.getDirectShareShortcutInfo());
+            Drawable drawable;
+            try {
+                drawable = getChooserTargetIconDrawable(
+                        mContext,
+                        mTargetInfo.getChooserTargetIcon(),
+                        mTargetInfo.getChooserTargetComponentName(),
+                        mTargetInfo.getDirectShareShortcutInfo());
+            } catch (Exception e) {
+                Log.e(TAG,
+                        "Failed to load shortcut icon for "
+                                + mTargetInfo.getChooserTargetComponentName(),
+                        e);
+                drawable = loadIconPlaceholder();
+            }
+            return drawable;
         }
 
         @Override
diff --git a/java/src/com/android/intentresolver/ResolverListAdapter.java b/java/src/com/android/intentresolver/ResolverListAdapter.java
index 9f65459..28bbfc5 100644
--- a/java/src/com/android/intentresolver/ResolverListAdapter.java
+++ b/java/src/com/android/intentresolver/ResolverListAdapter.java
@@ -677,8 +677,7 @@
     protected void onBindView(View view, TargetInfo info, int position) {
         final ViewHolder holder = (ViewHolder) view.getTag();
         if (info == null) {
-            holder.icon.setImageDrawable(
-                    mContext.getDrawable(R.drawable.resolver_icon_placeholder));
+            holder.icon.setImageDrawable(loadIconPlaceholder());
             holder.bindLabel("", "", false);
             return;
         }
@@ -704,7 +703,7 @@
     protected final void loadIcon(DisplayResolveInfo info) {
         LoadIconTask task = mIconLoaders.get(info);
         if (task == null) {
-            task = new LoadIconTask((DisplayResolveInfo) info);
+            task = new LoadIconTask(info);
             mIconLoaders.put(info, task);
             task.execute();
         }
@@ -779,13 +778,25 @@
         return makePresentationGetter(ri).getIcon(getUserHandle());
     }
 
+    protected final Drawable loadIconPlaceholder() {
+        return mContext.getDrawable(R.drawable.resolver_icon_placeholder);
+    }
+
     void loadFilteredItemIconTaskAsync(@NonNull ImageView iconView) {
         final DisplayResolveInfo iconInfo = getFilteredItem();
         if (iconView != null && iconInfo != null) {
             new AsyncTask<Void, Void, Drawable>() {
                 @Override
                 protected Drawable doInBackground(Void... params) {
-                    return loadIconForResolveInfo(iconInfo.getResolveInfo());
+                    Drawable drawable;
+                    try {
+                        drawable = loadIconForResolveInfo(iconInfo.getResolveInfo());
+                    } catch (Exception e) {
+                        ComponentName componentName = iconInfo.getResolvedComponentName();
+                        Log.e(TAG, "Failed to load app icon for " + componentName, e);
+                        drawable = loadIconPlaceholder();
+                    }
+                    return drawable;
                 }
 
                 @Override
@@ -1021,7 +1032,13 @@
 
         @Override
         protected Drawable doInBackground(Void... params) {
-            return loadIconForResolveInfo(mResolveInfo);
+            try {
+                return loadIconForResolveInfo(mResolveInfo);
+            } catch (Exception e) {
+                ComponentName componentName = mDisplayResolveInfo.getResolvedComponentName();
+                Log.e(TAG, "Failed to load app icon for " + componentName, e);
+                return loadIconPlaceholder();
+            }
         }
 
         @Override