Do not store bitmap into Bundle in onSaveInstanceState
It may cause TransactionTooLargeException because of the parcel size limit
Bug: 27990767
Change-Id: Ie1a702810a5c26e25fc485ebae09dc65e2b48e41
diff --git a/src/com/android/settings/users/EditUserInfoController.java b/src/com/android/settings/users/EditUserInfoController.java
index a4c07bd..315ebcb 100644
--- a/src/com/android/settings/users/EditUserInfoController.java
+++ b/src/com/android/settings/users/EditUserInfoController.java
@@ -40,6 +40,8 @@
import com.android.settingslib.Utils;
import com.android.settingslib.drawable.CircleFramedDrawable;
+import java.io.File;
+
/**
* This class encapsulates a Dialog for editing the user nickname and photo.
*/
@@ -61,6 +63,7 @@
}
public void clear() {
+ mEditUserPhotoController.removeNewUserPhotoBitmapFile();
mEditUserInfoDialog = null;
mSavedPhoto = null;
}
@@ -70,19 +73,25 @@
}
public void onRestoreInstanceState(Bundle icicle) {
- mSavedPhoto = (Bitmap) icicle.getParcelable(KEY_SAVED_PHOTO);
+ String pendingPhoto = icicle.getString(KEY_SAVED_PHOTO);
+ if (pendingPhoto != null) {
+ mSavedPhoto = EditUserPhotoController.loadNewUserPhotoBitmap(new File(pendingPhoto));
+ }
mWaitingForActivityResult = icicle.getBoolean(KEY_AWAITING_RESULT, false);
}
public void onSaveInstanceState(Bundle outState) {
if (mEditUserInfoDialog != null && mEditUserInfoDialog.isShowing()
&& mEditUserPhotoController != null) {
- outState.putParcelable(KEY_SAVED_PHOTO,
- mEditUserPhotoController.getNewUserPhotoBitmap());
+ // Bitmap cannot be stored into bundle because it may exceed parcel limit
+ // Store it in a temporary file instead
+ File file = mEditUserPhotoController.saveNewUserPhotoBitmap();
+ if (file != null) {
+ outState.putString(KEY_SAVED_PHOTO, file.getPath());
+ }
}
if (mWaitingForActivityResult) {
- outState.putBoolean(KEY_AWAITING_RESULT,
- mWaitingForActivityResult);
+ outState.putBoolean(KEY_AWAITING_RESULT, mWaitingForActivityResult);
}
}
diff --git a/src/com/android/settings/users/EditUserPhotoController.java b/src/com/android/settings/users/EditUserPhotoController.java
index 0d327a0..01b553c 100644
--- a/src/com/android/settings/users/EditUserPhotoController.java
+++ b/src/com/android/settings/users/EditUserPhotoController.java
@@ -50,8 +50,10 @@
import java.io.File;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
@@ -69,6 +71,7 @@
private static final String CROP_PICTURE_FILE_NAME = "CropEditUserPhoto.jpg";
private static final String TAKE_PICTURE_FILE_NAME = "TakeEditUserPhoto2.jpg";
+ private static final String NEW_USER_PHOTO_FILE_NAME = "NewUserPhoto.png";
private final int mPhotoSize;
@@ -329,9 +332,33 @@
if (purge) {
fullPath.delete();
}
- final Uri fileUri =
- FileProvider.getUriForFile(context, RestrictedProfileSettings.FILE_PROVIDER_AUTHORITY, fullPath);
- return fileUri;
+ return FileProvider.getUriForFile(context,
+ RestrictedProfileSettings.FILE_PROVIDER_AUTHORITY, fullPath);
+ }
+
+ File saveNewUserPhotoBitmap() {
+ if (mNewUserPhotoBitmap == null) {
+ return null;
+ }
+ try {
+ File file = new File(mContext.getCacheDir(), NEW_USER_PHOTO_FILE_NAME);
+ OutputStream os = new FileOutputStream(file);
+ mNewUserPhotoBitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
+ os.flush();
+ os.close();
+ return file;
+ } catch (IOException e) {
+ Log.e(TAG, "Cannot create temp file", e);
+ }
+ return null;
+ }
+
+ static Bitmap loadNewUserPhotoBitmap(File file) {
+ return BitmapFactory.decodeFile(file.getAbsolutePath());
+ }
+
+ void removeNewUserPhotoBitmapFile() {
+ new File(mContext.getCacheDir(), NEW_USER_PHOTO_FILE_NAME).delete();
}
private static final class AdapterItem {