Handle OutOfMemory when decoding images
Decoding images and videos in the messaging app appears to be a
vulnerable point for running out of memory. Catch those exceptions,
log an error, and continue on without loading the image. Most of these
"catches" are around situations where there's been a problem decoding
the original image in the first place, and now we're simply trying
to decode a small missing stand-in image. However, since BitmapFactory.decodeResource
seems to be in an inordinate number of bug reports, I want to log every
use in the code in case of failure.
Handles the 2nd part of bug 2994057.
Change-Id: Iaa8035f6ef28385b353d31507b9753934881d3e8
diff --git a/src/com/android/mms/ui/BasicSlideEditorView.java b/src/com/android/mms/ui/BasicSlideEditorView.java
index df31be6..c5676c7 100644
--- a/src/com/android/mms/ui/BasicSlideEditorView.java
+++ b/src/com/android/mms/ui/BasicSlideEditorView.java
@@ -98,11 +98,15 @@
}
public void setImage(String name, Bitmap bitmap) {
- if (null == bitmap) {
- bitmap = BitmapFactory.decodeResource(getResources(),
- R.drawable.ic_missing_thumbnail_picture);
+ try {
+ if (null == bitmap) {
+ bitmap = BitmapFactory.decodeResource(getResources(),
+ R.drawable.ic_missing_thumbnail_picture);
+ }
+ mImageView.setImageBitmap(bitmap);
+ } catch (java.lang.OutOfMemoryError e) {
+ Log.e(TAG, "setImage: out of memory: ", e);
}
- mImageView.setImageBitmap(bitmap);
}
public void setImageRegionFit(String fit) {
@@ -127,12 +131,16 @@
}
public void setVideo(String name, Uri video) {
- Bitmap bitmap = VideoAttachmentView.createVideoThumbnail(mContext, video);
- if (null == bitmap) {
- bitmap = BitmapFactory.decodeResource(getResources(),
- R.drawable.ic_missing_thumbnail_video);
+ try {
+ Bitmap bitmap = VideoAttachmentView.createVideoThumbnail(mContext, video);
+ if (null == bitmap) {
+ bitmap = BitmapFactory.decodeResource(getResources(),
+ R.drawable.ic_missing_thumbnail_video);
+ }
+ mImageView.setImageBitmap(bitmap);
+ } catch (java.lang.OutOfMemoryError e) {
+ Log.e(TAG, "setVideo: out of memory: ", e);
}
- mImageView.setImageBitmap(bitmap);
}
public void setVideoVisibility(boolean visible) {
diff --git a/src/com/android/mms/ui/ImageAttachmentView.java b/src/com/android/mms/ui/ImageAttachmentView.java
index 90f52ef..c6f59b9 100644
--- a/src/com/android/mms/ui/ImageAttachmentView.java
+++ b/src/com/android/mms/ui/ImageAttachmentView.java
@@ -24,6 +24,7 @@
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -35,6 +36,7 @@
*/
public class ImageAttachmentView extends LinearLayout implements SlideViewInterface {
private ImageView mImageView;
+ private static final String TAG = "ImageAttachmentView";
public ImageAttachmentView(Context context) {
super(context);
@@ -65,11 +67,15 @@
}
public void setImage(String name, Bitmap bitmap) {
- if (null == bitmap) {
- bitmap = BitmapFactory.decodeResource(getResources(),
- R.drawable.ic_missing_thumbnail_picture);
+ try {
+ if (null == bitmap) {
+ bitmap = BitmapFactory.decodeResource(getResources(),
+ R.drawable.ic_missing_thumbnail_picture);
+ }
+ mImageView.setImageBitmap(bitmap);
+ } catch (java.lang.OutOfMemoryError e) {
+ Log.e(TAG, "setImage: out of memory: ", e);
}
- mImageView.setImageBitmap(bitmap);
}
public void setImageRegionFit(String fit) {
diff --git a/src/com/android/mms/ui/MessageListAdapter.java b/src/com/android/mms/ui/MessageListAdapter.java
index 2f4e00d..222df63 100644
--- a/src/com/android/mms/ui/MessageListAdapter.java
+++ b/src/com/android/mms/ui/MessageListAdapter.java
@@ -590,12 +590,16 @@
* doing that here.
*/
private void loadDefaultAvatar() {
- if (mDefaultAvatarDrawable == null) {
- Bitmap b = BitmapFactory.decodeResource(mContext.getResources(),
- R.drawable.ic_contact_picture);
- mDefaultAvatarDrawable = new BitmapDrawable(mContext.getResources(), b);
+ try {
+ if (mDefaultAvatarDrawable == null) {
+ Bitmap b = BitmapFactory.decodeResource(mContext.getResources(),
+ R.drawable.ic_contact_picture);
+ mDefaultAvatarDrawable = new BitmapDrawable(mContext.getResources(), b);
+ }
+ mPhoto = mDefaultAvatarDrawable;
+ } catch (java.lang.OutOfMemoryError e) {
+ Log.e(TAG, "loadDefaultAvatar: out of memory: ", e);
}
- mPhoto = mDefaultAvatarDrawable;
}
};
diff --git a/src/com/android/mms/ui/MessageListItem.java b/src/com/android/mms/ui/MessageListItem.java
index 79db2e4..352772b 100644
--- a/src/com/android/mms/ui/MessageListItem.java
+++ b/src/com/android/mms/ui/MessageListItem.java
@@ -54,6 +54,7 @@
import android.text.style.TextAppearanceSpan;
import android.text.style.URLSpan;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
@@ -311,12 +312,16 @@
public void setImage(String name, Bitmap bitmap) {
inflateMmsView();
- if (null == bitmap) {
- bitmap = BitmapFactory.decodeResource(getResources(),
- R.drawable.ic_missing_thumbnail_picture);
+ try {
+ if (null == bitmap) {
+ bitmap = BitmapFactory.decodeResource(getResources(),
+ R.drawable.ic_missing_thumbnail_picture);
+ }
+ mImageView.setImageBitmap(bitmap);
+ mImageView.setVisibility(VISIBLE);
+ } catch (java.lang.OutOfMemoryError e) {
+ Log.e(TAG, "setImage: out of memory: ", e);
}
- mImageView.setImageBitmap(bitmap);
- mImageView.setVisibility(VISIBLE);
}
private void inflateMmsView() {
@@ -629,13 +634,18 @@
public void setVideo(String name, Uri video) {
inflateMmsView();
- Bitmap bitmap = VideoAttachmentView.createVideoThumbnail(mContext, video);
- if (null == bitmap) {
- bitmap = BitmapFactory.decodeResource(getResources(),
- R.drawable.ic_missing_thumbnail_video);
+
+ try {
+ Bitmap bitmap = VideoAttachmentView.createVideoThumbnail(mContext, video);
+ if (null == bitmap) {
+ bitmap = BitmapFactory.decodeResource(getResources(),
+ R.drawable.ic_missing_thumbnail_video);
+ }
+ mImageView.setImageBitmap(bitmap);
+ mImageView.setVisibility(VISIBLE);
+ } catch (java.lang.OutOfMemoryError e) {
+ Log.e(TAG, "setVideo: out of memory: ", e);
}
- mImageView.setImageBitmap(bitmap);
- mImageView.setVisibility(VISIBLE);
}
public void setVideoVisibility(boolean visible) {
diff --git a/src/com/android/mms/ui/MmsThumbnailPresenter.java b/src/com/android/mms/ui/MmsThumbnailPresenter.java
index 2b62774..00e679c 100644
--- a/src/com/android/mms/ui/MmsThumbnailPresenter.java
+++ b/src/com/android/mms/ui/MmsThumbnailPresenter.java
@@ -28,8 +28,10 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.util.Log;
public class MmsThumbnailPresenter extends Presenter {
+ private static final String TAG = "MmsThumbnailPresenter";
public MmsThumbnailPresenter(Context context, ViewInterface view, Model model) {
super(context, view, model);
@@ -81,9 +83,13 @@
// Show an icon instead of real content in the thumbnail.
private void showDrmIcon(SlideViewInterface view, String name) {
- Bitmap bitmap = BitmapFactory.decodeResource(
- mContext.getResources(), R.drawable.ic_mms_drm_protected);
- view.setImage(name, bitmap);
+ try {
+ Bitmap bitmap = BitmapFactory.decodeResource(
+ mContext.getResources(), R.drawable.ic_mms_drm_protected);
+ view.setImage(name, bitmap);
+ } catch (java.lang.OutOfMemoryError e) {
+ Log.e(TAG, "showDrmIcon: out of memory: ", e);
+ }
}
public void onModelChanged(Model model, boolean dataChanged) {
diff --git a/src/com/android/mms/ui/SlideListItemView.java b/src/com/android/mms/ui/SlideListItemView.java
index 87a0f9e..c35694b 100644
--- a/src/com/android/mms/ui/SlideListItemView.java
+++ b/src/com/android/mms/ui/SlideListItemView.java
@@ -83,11 +83,15 @@
}
public void setImage(String name, Bitmap bitmap) {
- if (null == bitmap) {
- bitmap = BitmapFactory.decodeResource(getResources(),
- R.drawable.ic_missing_thumbnail_picture);
+ try {
+ if (null == bitmap) {
+ bitmap = BitmapFactory.decodeResource(getResources(),
+ R.drawable.ic_missing_thumbnail_picture);
+ }
+ mImagePreview.setImageBitmap(bitmap);
+ } catch (java.lang.OutOfMemoryError e) {
+ Log.e(TAG, "setImage: out of memory: ", e);
}
- mImagePreview.setImageBitmap(bitmap);
}
public void setImageRegionFit(String fit) {
diff --git a/src/com/android/mms/ui/SlideView.java b/src/com/android/mms/ui/SlideView.java
index 9925744..ada1f7f 100644
--- a/src/com/android/mms/ui/SlideView.java
+++ b/src/com/android/mms/ui/SlideView.java
@@ -114,12 +114,16 @@
mImageView.setBackgroundColor(0xFFFF0000);
}
}
- if (null == bitmap) {
- bitmap = BitmapFactory.decodeResource(getResources(),
- R.drawable.ic_missing_thumbnail_picture);
+ try {
+ if (null == bitmap) {
+ bitmap = BitmapFactory.decodeResource(getResources(),
+ R.drawable.ic_missing_thumbnail_picture);
+ }
+ mImageView.setVisibility(View.VISIBLE);
+ mImageView.setImageBitmap(bitmap);
+ } catch (java.lang.OutOfMemoryError e) {
+ Log.e(TAG, "setImage: out of memory: ", e);
}
- mImageView.setVisibility(View.VISIBLE);
- mImageView.setImageBitmap(bitmap);
}
public void setImageRegion(int left, int top, int width, int height) {
@@ -434,7 +438,7 @@
*
* 2. The TextView is fixed in the small area of screen, and other part of screen
* is empty once there is no image in the current slide.
- *
+ *
* 3. The TextView is scrollable in a small area of screen and the font size is
* small which make the user experience bad.
*
diff --git a/src/com/android/mms/ui/UriImage.java b/src/com/android/mms/ui/UriImage.java
index f22ff96..fae3acf 100644
--- a/src/com/android/mms/ui/UriImage.java
+++ b/src/com/android/mms/ui/UriImage.java
@@ -270,7 +270,8 @@
}
}
} catch (java.lang.OutOfMemoryError e) {
- Log.e(TAG, e.getMessage(), e);
+ Log.w(TAG, "getResizedImageData - image too big (OutOfMemoryError), will try "
+ + " with smaller scale factor, cur scale factor: " + scaleFactor);
// fall through and keep trying with a smaller scale factor.
}
if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
diff --git a/src/com/android/mms/ui/VideoAttachmentView.java b/src/com/android/mms/ui/VideoAttachmentView.java
index a9ee971..b394983 100644
--- a/src/com/android/mms/ui/VideoAttachmentView.java
+++ b/src/com/android/mms/ui/VideoAttachmentView.java
@@ -26,6 +26,7 @@
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -86,12 +87,16 @@
}
public void setVideo(String name, Uri video) {
- Bitmap bitmap = createVideoThumbnail(mContext, video);
- if (null == bitmap) {
- bitmap = BitmapFactory.decodeResource(getResources(),
- R.drawable.ic_missing_thumbnail_video);
+ try {
+ Bitmap bitmap = createVideoThumbnail(mContext, video);
+ if (null == bitmap) {
+ bitmap = BitmapFactory.decodeResource(getResources(),
+ R.drawable.ic_missing_thumbnail_video);
+ }
+ mThumbnailView.setImageBitmap(bitmap);
+ } catch (java.lang.OutOfMemoryError e) {
+ Log.e(TAG, "setVideo: out of memory: ", e);
}
- mThumbnailView.setImageBitmap(bitmap);
}
public static Bitmap createVideoThumbnail(Context context, Uri uri) {