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.AlertDialog;
21 import android.app.Dialog;
22 import android.app.Fragment;
23 import android.content.DialogInterface;
24 import android.content.Intent;
25 import android.content.pm.UserInfo;
26 import android.graphics.Bitmap;
27 import android.graphics.drawable.Drawable;
28 import android.os.AsyncTask;
29 import android.os.Bundle;
30 import android.os.UserHandle;
31 import android.os.UserManager;
32 import android.text.TextUtils;
33 import android.view.LayoutInflater;
34 import android.view.View;
35 import android.view.WindowManager;
36 import android.widget.EditText;
37 import android.widget.ImageView;
38 
39 import com.android.settings.R;
40 import com.android.settingslib.Utils;
41 import com.android.settingslib.drawable.CircleFramedDrawable;
42 
43 import java.io.File;
44 
45 /**
46  * This class encapsulates a Dialog for editing the user nickname and photo.
47  */
48 public class EditUserInfoController {
49 
50     private static final String KEY_AWAITING_RESULT = "awaiting_result";
51     private static final String KEY_SAVED_PHOTO = "pending_photo";
52 
53     private Dialog mEditUserInfoDialog;
54     private Bitmap mSavedPhoto;
55     private EditUserPhotoController mEditUserPhotoController;
56     private UserHandle mUser;
57     private UserManager mUserManager;
58     private boolean mWaitingForActivityResult = false;
59 
60     public interface OnContentChangedCallback {
onPhotoChanged(Drawable photo)61         public void onPhotoChanged(Drawable photo);
onLabelChanged(CharSequence label)62         public void onLabelChanged(CharSequence label);
63     }
64 
clear()65     public void clear() {
66         mEditUserPhotoController.removeNewUserPhotoBitmapFile();
67         mEditUserInfoDialog = null;
68         mSavedPhoto = null;
69     }
70 
getDialog()71     public Dialog getDialog() {
72         return mEditUserInfoDialog;
73     }
74 
onRestoreInstanceState(Bundle icicle)75     public void onRestoreInstanceState(Bundle icicle) {
76         String pendingPhoto = icicle.getString(KEY_SAVED_PHOTO);
77         if (pendingPhoto != null) {
78             mSavedPhoto = EditUserPhotoController.loadNewUserPhotoBitmap(new File(pendingPhoto));
79         }
80         mWaitingForActivityResult = icicle.getBoolean(KEY_AWAITING_RESULT, false);
81     }
82 
onSaveInstanceState(Bundle outState)83     public void onSaveInstanceState(Bundle outState) {
84         if (mEditUserInfoDialog != null && mEditUserInfoDialog.isShowing()
85                 && mEditUserPhotoController != null) {
86             // Bitmap cannot be stored into bundle because it may exceed parcel limit
87             // Store it in a temporary file instead
88             File file = mEditUserPhotoController.saveNewUserPhotoBitmap();
89             if (file != null) {
90                 outState.putString(KEY_SAVED_PHOTO, file.getPath());
91             }
92         }
93         if (mWaitingForActivityResult) {
94             outState.putBoolean(KEY_AWAITING_RESULT, mWaitingForActivityResult);
95         }
96     }
97 
startingActivityForResult()98     public void startingActivityForResult() {
99         mWaitingForActivityResult = true;
100     }
101 
onActivityResult(int requestCode, int resultCode, Intent data)102     public void onActivityResult(int requestCode, int resultCode, Intent data) {
103         mWaitingForActivityResult = false;
104 
105         if (mEditUserInfoDialog != null && mEditUserInfoDialog.isShowing()
106                 && mEditUserPhotoController.onActivityResult(requestCode, resultCode, data)) {
107             return;
108         }
109     }
110 
createDialog(final Fragment fragment, final Drawable currentUserIcon, final CharSequence currentUserName, int titleResId, final OnContentChangedCallback callback, UserHandle user)111     public Dialog createDialog(final Fragment fragment, final Drawable currentUserIcon,
112             final CharSequence currentUserName,
113             int titleResId, final OnContentChangedCallback callback, UserHandle user) {
114         Activity activity = fragment.getActivity();
115         mUser = user;
116         if (mUserManager == null) {
117             mUserManager = UserManager.get(activity);
118         }
119         LayoutInflater inflater = activity.getLayoutInflater();
120         View content = inflater.inflate(R.layout.edit_user_info_dialog_content, null);
121 
122         UserInfo info = mUserManager.getUserInfo(mUser.getIdentifier());
123 
124         final EditText userNameView = (EditText) content.findViewById(R.id.user_name);
125         userNameView.setText(info.name);
126 
127         final ImageView userPhotoView = (ImageView) content.findViewById(R.id.user_photo);
128         Drawable drawable = null;
129         if (mSavedPhoto != null) {
130             drawable = CircleFramedDrawable.getInstance(activity, mSavedPhoto);
131         } else {
132             drawable = currentUserIcon;
133             if (drawable == null) {
134                 drawable = Utils.getUserIcon(activity, mUserManager, info);
135             }
136         }
137         userPhotoView.setImageDrawable(drawable);
138         mEditUserPhotoController = new EditUserPhotoController(fragment, userPhotoView,
139                 mSavedPhoto, drawable, mWaitingForActivityResult);
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