• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.users;
18 
19 import android.app.Activity;
20 import android.app.Dialog;
21 import android.content.DialogInterface;
22 import android.content.Intent;
23 import android.content.pm.UserInfo;
24 import android.graphics.Bitmap;
25 import android.graphics.drawable.Drawable;
26 import android.os.AsyncTask;
27 import android.os.Bundle;
28 import android.os.UserHandle;
29 import android.os.UserManager;
30 import android.text.TextUtils;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.view.WindowManager;
34 import android.widget.EditText;
35 import android.widget.ImageView;
36 
37 import androidx.annotation.VisibleForTesting;
38 import androidx.appcompat.app.AlertDialog;
39 import androidx.fragment.app.Fragment;
40 
41 import com.android.settings.R;
42 import com.android.settingslib.Utils;
43 import com.android.settingslib.drawable.CircleFramedDrawable;
44 
45 import java.io.File;
46 
47 /**
48  * This class encapsulates a Dialog for editing the user nickname and photo.
49  */
50 public class EditUserInfoController {
51 
52     private static final String KEY_AWAITING_RESULT = "awaiting_result";
53     private static final String KEY_SAVED_PHOTO = "pending_photo";
54 
55     private Dialog mEditUserInfoDialog;
56     private Bitmap mSavedPhoto;
57     private EditUserPhotoController mEditUserPhotoController;
58     private UserHandle mUser;
59     private UserManager mUserManager;
60     private boolean mWaitingForActivityResult = false;
61 
62     public interface OnContentChangedCallback {
onPhotoChanged(Drawable photo)63         public void onPhotoChanged(Drawable photo);
onLabelChanged(CharSequence label)64         public void onLabelChanged(CharSequence label);
65     }
66 
clear()67     public void clear() {
68         mEditUserPhotoController.removeNewUserPhotoBitmapFile();
69         mEditUserInfoDialog = null;
70         mSavedPhoto = null;
71     }
72 
getDialog()73     public Dialog getDialog() {
74         return mEditUserInfoDialog;
75     }
76 
onRestoreInstanceState(Bundle icicle)77     public void onRestoreInstanceState(Bundle icicle) {
78         String pendingPhoto = icicle.getString(KEY_SAVED_PHOTO);
79         if (pendingPhoto != null) {
80             mSavedPhoto = EditUserPhotoController.loadNewUserPhotoBitmap(new File(pendingPhoto));
81         }
82         mWaitingForActivityResult = icicle.getBoolean(KEY_AWAITING_RESULT, false);
83     }
84 
onSaveInstanceState(Bundle outState)85     public void onSaveInstanceState(Bundle outState) {
86         if (mEditUserInfoDialog != null && mEditUserInfoDialog.isShowing()
87                 && mEditUserPhotoController != null) {
88             // Bitmap cannot be stored into bundle because it may exceed parcel limit
89             // Store it in a temporary file instead
90             File file = mEditUserPhotoController.saveNewUserPhotoBitmap();
91             if (file != null) {
92                 outState.putString(KEY_SAVED_PHOTO, file.getPath());
93             }
94         }
95         if (mWaitingForActivityResult) {
96             outState.putBoolean(KEY_AWAITING_RESULT, mWaitingForActivityResult);
97         }
98     }
99 
startingActivityForResult()100     public void startingActivityForResult() {
101         mWaitingForActivityResult = true;
102     }
103 
onActivityResult(int requestCode, int resultCode, Intent data)104     public void onActivityResult(int requestCode, int resultCode, Intent data) {
105         mWaitingForActivityResult = false;
106 
107         if (mEditUserInfoDialog != null) {
108             mEditUserPhotoController.onActivityResult(requestCode, resultCode, data);
109         }
110     }
111 
createDialog(final Fragment fragment, final Drawable currentUserIcon, final CharSequence currentUserName, int titleResId, final OnContentChangedCallback callback, UserHandle user)112     public Dialog createDialog(final Fragment fragment, final Drawable currentUserIcon,
113             final CharSequence currentUserName,
114             int titleResId, final OnContentChangedCallback callback, UserHandle user) {
115         Activity activity = fragment.getActivity();
116         mUser = user;
117         if (mUserManager == null) {
118             mUserManager = activity.getSystemService(UserManager.class);
119         }
120         LayoutInflater inflater = activity.getLayoutInflater();
121         View content = inflater.inflate(R.layout.edit_user_info_dialog_content, null);
122 
123         UserInfo info = mUserManager.getUserInfo(mUser.getIdentifier());
124 
125         final EditText userNameView = (EditText) content.findViewById(R.id.user_name);
126         userNameView.setText(info.name);
127 
128         final ImageView userPhotoView = (ImageView) content.findViewById(R.id.user_photo);
129         Drawable drawable = null;
130         if (mSavedPhoto != null) {
131             drawable = CircleFramedDrawable.getInstance(activity, mSavedPhoto);
132         } else {
133             drawable = currentUserIcon;
134             if (drawable == null) {
135                 drawable = Utils.getUserIcon(activity, mUserManager, info);
136             }
137         }
138         userPhotoView.setImageDrawable(drawable);
139         mEditUserPhotoController = createEditUserPhotoController(fragment, userPhotoView, drawable);
140         mEditUserInfoDialog = new AlertDialog.Builder(activity)
141                 .setTitle(R.string.profile_info_settings_title)
142                 .setView(content)
143                 .setCancelable(true)
144                 .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
145                     @Override
146                     public void onClick(DialogInterface dialog, int which) {
147                         if (which == DialogInterface.BUTTON_POSITIVE) {
148                             // Update the name if changed.
149                             CharSequence userName = userNameView.getText();
150                             if (!TextUtils.isEmpty(userName)) {
151                                 if (currentUserName == null
152                                         || !userName.toString().equals(currentUserName.toString())) {
153                                     if (callback != null) {
154                                         callback.onLabelChanged(userName.toString());
155                                     }
156                                     mUserManager.setUserName(mUser.getIdentifier(),
157                                             userName.toString());
158                                 }
159                             }
160                             // Update the photo if changed.
161                             Drawable drawable = mEditUserPhotoController.getNewUserPhotoDrawable();
162                             Bitmap bitmap = mEditUserPhotoController.getNewUserPhotoBitmap();
163                             if (drawable != null && bitmap != null
164                                     && !drawable.equals(currentUserIcon)) {
165                                 if (callback != null) {
166                                     callback.onPhotoChanged(drawable);
167                                 }
168                                 new AsyncTask<Void, Void, Void>() {
169                                     @Override
170                                     protected Void doInBackground(Void... params) {
171                                         mUserManager.setUserIcon(mUser.getIdentifier(),
172                                                 mEditUserPhotoController.getNewUserPhotoBitmap());
173                                         return null;
174                                     }
175                                 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
176                             }
177                             fragment.getActivity().removeDialog(
178                                     RestrictedProfileSettings.DIALOG_ID_EDIT_USER_INFO);
179                         }
180                         clear();
181                     }
182                 })
183                 .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
184                     @Override
185                     public void onClick(DialogInterface dialog, int which) {
186                         clear();
187                     }
188                 })
189                 .create();
190 
191         // Make sure the IME is up.
192         mEditUserInfoDialog.getWindow().setSoftInputMode(
193                 WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
194 
195         return mEditUserInfoDialog;
196     }
197 
198     @VisibleForTesting
createEditUserPhotoController(Fragment fragment, ImageView userPhotoView, Drawable drawable)199     EditUserPhotoController createEditUserPhotoController(Fragment fragment,
200             ImageView userPhotoView, Drawable drawable) {
201         return new EditUserPhotoController(fragment, userPhotoView,
202                 mSavedPhoto, drawable, mWaitingForActivityResult);
203     }
204 }
205