Restore user picture in add user dialog on rotation
Picture was being cached in OnSaveInstanceState method in background thread. It finished saving after the restoration was happening in OnRestoreInstanceState and therefore the picture could not be retrieved. Picture is now saved straight after choosing and retrieved when dialog gets created.
Bug: 293435121
Test: atest CreateUserDialogControllerTest
Change-Id: Ic3aa22d19732c5480075cea613070e0de19ad73e
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/CreateUserDialogController.java b/packages/SettingsLib/src/com/android/settingslib/users/CreateUserDialogController.java
index 3011d31..8d03f70 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/CreateUserDialogController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/CreateUserDialogController.java
@@ -80,6 +80,7 @@
private Bitmap mSavedPhoto;
private String mSavedName;
private Drawable mSavedDrawable;
+ private String mCachedDrawablePath;
private String mUserName;
private Drawable mNewUserIcon;
private Boolean mIsAdmin;
@@ -117,6 +118,7 @@
mUserNameView = null;
mSuccessCallback = null;
mCancelCallback = null;
+ mCachedDrawablePath = null;
mCurrentState = INITIAL_DIALOG;
}
@@ -124,13 +126,7 @@
* Notifies that the containing activity or fragment was reinitialized.
*/
public void onRestoreInstanceState(Bundle savedInstanceState) {
- String pendingPhoto = savedInstanceState.getString(KEY_SAVED_PHOTO);
- if (pendingPhoto != null) {
- ThreadUtils.postOnBackgroundThread(() -> {
- mSavedPhoto = EditUserPhotoController.loadNewUserPhotoBitmap(
- new File(pendingPhoto));
- });
- }
+ mCachedDrawablePath = savedInstanceState.getString(KEY_SAVED_PHOTO);
mCurrentState = savedInstanceState.getInt(KEY_CURRENT_STATE);
if (savedInstanceState.containsKey(KEY_IS_ADMIN)) {
mIsAdmin = savedInstanceState.getBoolean(KEY_IS_ADMIN);
@@ -143,15 +139,12 @@
* Notifies that the containing activity or fragment is saving its state for later use.
*/
public void onSaveInstanceState(Bundle savedInstanceState) {
- if (mUserCreationDialog != null && mEditUserPhotoController != null) {
- // Bitmap cannot be stored into bundle because it may exceed parcel limit
- // Store it in a temporary file instead
- ThreadUtils.postOnBackgroundThread(() -> {
- File file = mEditUserPhotoController.saveNewUserPhotoBitmap();
- if (file != null) {
- savedInstanceState.putString(KEY_SAVED_PHOTO, file.getPath());
- }
- });
+ if (mUserCreationDialog != null && mEditUserPhotoController != null
+ && mCachedDrawablePath == null) {
+ mCachedDrawablePath = mEditUserPhotoController.getCachedDrawablePath();
+ }
+ if (mCachedDrawablePath != null) {
+ savedInstanceState.putString(KEY_SAVED_PHOTO, mCachedDrawablePath);
}
if (mIsAdmin != null) {
savedInstanceState.putBoolean(KEY_IS_ADMIN, Boolean.TRUE.equals(mIsAdmin));
@@ -271,9 +264,10 @@
mGrantAdminView.setVisibility(View.GONE);
break;
case CREATE_USER_AND_CLOSE:
- mNewUserIcon = mEditUserPhotoController != null
+ mNewUserIcon = (mEditUserPhotoController != null
+ && mEditUserPhotoController.getNewUserPhotoDrawable() != null)
? mEditUserPhotoController.getNewUserPhotoDrawable()
- : null;
+ : mSavedDrawable;
String newName = mUserNameView.getText().toString().trim();
String defaultName = mActivity.getString(R.string.user_new_user_name);
@@ -295,12 +289,17 @@
}
}
- private Drawable getUserIcon(Drawable defaultUserIcon) {
- if (mSavedPhoto != null) {
- mSavedDrawable = CircleFramedDrawable.getInstance(mActivity, mSavedPhoto);
- return mSavedDrawable;
+ private void setUserIcon(Drawable defaultUserIcon, ImageView userPhotoView) {
+ if (mCachedDrawablePath != null) {
+ ThreadUtils.postOnBackgroundThread(() -> {
+ mSavedPhoto = EditUserPhotoController.loadNewUserPhotoBitmap(
+ new File(mCachedDrawablePath));
+ mSavedDrawable = CircleFramedDrawable.getInstance(mActivity, mSavedPhoto);
+ ThreadUtils.postOnMainThread(() -> userPhotoView.setImageDrawable(mSavedDrawable));
+ });
+ } else {
+ userPhotoView.setImageDrawable(defaultUserIcon);
}
- return defaultUserIcon;
}
private void addUserInfoEditView() {
@@ -312,10 +311,7 @@
// if oldUserIcon param is null then we use a default gray user icon
Drawable defaultUserIcon = UserIcons.getDefaultUserIcon(
mActivity.getResources(), UserHandle.USER_NULL, false);
- // in case a new photo was selected and the activity got recreated we have to load the image
- Drawable userIcon = getUserIcon(defaultUserIcon);
- userPhotoView.setImageDrawable(userIcon);
-
+ setUserIcon(defaultUserIcon, userPhotoView);
if (isChangePhotoRestrictedByBase(mActivity)) {
// some users can't change their photos so we need to remove the suggestive icon
mEditUserInfoView.findViewById(R.id.add_a_photo_icon).setVisibility(View.GONE);
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java b/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
index 38cf383..3fb2f60 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
@@ -60,6 +60,7 @@
private final File mImagesDir;
private Bitmap mNewUserPhotoBitmap;
private Drawable mNewUserPhotoDrawable;
+ private String mCachedDrawablePath;
public EditUserPhotoController(Activity activity, ActivityStarter activityStarter,
ImageView view, Bitmap savedBitmap, Drawable savedDrawable, String fileAuthority) {
@@ -156,6 +157,9 @@
private void onPhotoProcessed(Bitmap bitmap) {
if (bitmap != null) {
mNewUserPhotoBitmap = bitmap;
+ ThreadUtils.postOnBackgroundThread(() -> {
+ mCachedDrawablePath = saveNewUserPhotoBitmap().getPath();
+ });
mNewUserPhotoDrawable = CircleFramedDrawable
.getInstance(mImageView.getContext(), mNewUserPhotoBitmap);
mImageView.setImageDrawable(mNewUserPhotoDrawable);
@@ -186,4 +190,8 @@
void removeNewUserPhotoBitmapFile() {
new File(mImagesDir, NEW_USER_PHOTO_FILE_NAME).delete();
}
+
+ String getCachedDrawablePath() {
+ return mCachedDrawablePath;
+ }
}