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
17package com.android.settings.users;
18
19import android.app.Activity;
20import android.app.AlertDialog;
21import android.app.Dialog;
22import android.app.Fragment;
23import android.content.DialogInterface;
24import android.content.Intent;
25import android.content.pm.UserInfo;
26import android.graphics.Bitmap;
27import android.graphics.drawable.Drawable;
28import android.os.AsyncTask;
29import android.os.Bundle;
30import android.os.UserHandle;
31import android.os.UserManager;
32import android.text.TextUtils;
33import android.view.LayoutInflater;
34import android.view.View;
35import android.view.WindowManager;
36import android.widget.EditText;
37import android.widget.ImageView;
38
39import com.android.settings.R;
40import com.android.settingslib.Utils;
41import com.android.settingslib.drawable.CircleFramedDrawable;
42
43import java.io.File;
44
45/**
46 * This class encapsulates a Dialog for editing the user nickname and photo.
47 */
48public 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 {
61        public void onPhotoChanged(Drawable photo);
62        public void onLabelChanged(CharSequence label);
63    }
64
65    public void clear() {
66        mEditUserPhotoController.removeNewUserPhotoBitmapFile();
67        mEditUserInfoDialog = null;
68        mSavedPhoto = null;
69    }
70
71    public Dialog getDialog() {
72        return mEditUserInfoDialog;
73    }
74
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
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
98    public void startingActivityForResult() {
99        mWaitingForActivityResult = true;
100    }
101
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
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