From 3214ca39114d6ee6f7365600697d02e0a28558d9 Mon Sep 17 00:00:00 2001 From: Steve Elliott Date: Mon, 21 Mar 2022 12:31:43 -0400 Subject: [PATCH] Guard against ContentResolver exceptions There is a code path deep in the ContentResolver stack that will read and then throw an exception that was written to the underlying DB by the remote application. We don't want this to crash SystemUI, so guard against it. Fixes: 225359390 Test: 1. Mark Signal notification as Priority 2. Observe no crash Change-Id: Ie84e29bb0b9d9f19da267f2aa3ed9d8e028bbac3 --- .../row/NotificationInlineImageCache.java | 11 +----- .../row/NotificationInlineImageResolver.java | 37 +++++++++---------- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java index 4b0e2ffd5d7f7..41eeada0fcda4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java @@ -21,7 +21,6 @@ import android.net.Uri; import android.os.AsyncTask; import android.util.Log; -import java.io.IOException; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; @@ -82,16 +81,8 @@ public class NotificationInlineImageCache implements NotificationInlineImageReso @Override protected Drawable doInBackground(Uri... uris) { - Drawable drawable = null; Uri target = uris[0]; - - try { - drawable = mResolver.resolveImage(target); - } catch (IOException | SecurityException ex) { - Log.d(TAG, "PreloadImageTask: Resolve failed from " + target, ex); - } - - return drawable; + return mResolver.resolveImage(target); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java index 44ccb68cce4a2..b05e64ab19916 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java @@ -31,7 +31,6 @@ import com.android.internal.widget.ImageResolver; import com.android.internal.widget.LocalImageResolver; import com.android.internal.widget.MessagingMessage; -import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -111,30 +110,30 @@ public class NotificationInlineImageResolver implements ImageResolver { * To resolve image from specified uri directly. If the resulting image is larger than the * maximum allowed size, scale it down. * @param uri Uri of the image. - * @return Drawable of the image. - * @throws IOException Throws if failed at resolving the image. + * @return Drawable of the image, or null if unable to load. */ - Drawable resolveImage(Uri uri) throws IOException { - return LocalImageResolver.resolveImage(uri, mContext, mMaxImageWidth, mMaxImageHeight); + Drawable resolveImage(Uri uri) { + try { + return LocalImageResolver.resolveImage(uri, mContext, mMaxImageWidth, mMaxImageHeight); + } catch (Exception ex) { + // Catch general Exception because ContentResolver can re-throw arbitrary Exception + // from remote process as a RuntimeException. See: Parcel#readException + Log.d(TAG, "resolveImage: Can't load image from " + uri, ex); + } + return null; } @Override public Drawable loadImage(Uri uri) { - Drawable result = null; - try { - if (hasCache()) { - // if the uri isn't currently cached, try caching it first - if (!mImageCache.hasEntry(uri)) { - mImageCache.preload((uri)); - } - result = mImageCache.get(uri); - } else { - result = resolveImage(uri); - } - } catch (IOException | SecurityException ex) { - Log.d(TAG, "loadImage: Can't load image from " + uri, ex); + return hasCache() ? loadImageFromCache(uri) : resolveImage(uri); + } + + private Drawable loadImageFromCache(Uri uri) { + // if the uri isn't currently cached, try caching it first + if (!mImageCache.hasEntry(uri)) { + mImageCache.preload((uri)); } - return result; + return mImageCache.get(uri); } /**