diff options
author | Ben Murdoch <benm@google.com> | 2020-01-15 13:10:35 +0000 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2020-01-23 11:11:02 +0000 |
commit | 34462c0cb060b9d89b919d85c64bcc6fc28ec821 (patch) | |
tree | 5c42e43e17cf9e846b2c576dbf44549f81a314a9 /src/com/android/settings/users | |
parent | 1a3e286d0c0ad4270d8a0071d5a0c24a7f51811f (diff) | |
download | packages_apps_Settings-34462c0cb060b9d89b919d85c64bcc6fc28ec821.tar.gz packages_apps_Settings-34462c0cb060b9d89b919d85c64bcc6fc28ec821.tar.bz2 packages_apps_Settings-34462c0cb060b9d89b919d85c64bcc6fc28ec821.zip |
Refactor Add new user / restricted profile UX flow.
Incorporate the choose user name / avatar into the
user creation flow so that we don't end up with many
"New User"s.
Bug: 147653252
Test: make -j64 RunSettingsRoboTests ROBOTEST_FILTER="com.android.settings.users.EditUserInfoControllerTest"
Change-Id: Ie19230791d8b50c8ab04df89909606179364ebab
Diffstat (limited to 'src/com/android/settings/users')
3 files changed, 200 insertions, 99 deletions
diff --git a/src/com/android/settings/users/EditUserInfoController.java b/src/com/android/settings/users/EditUserInfoController.java index 4d9244aeba..373d6a99f3 100644 --- a/src/com/android/settings/users/EditUserInfoController.java +++ b/src/com/android/settings/users/EditUserInfoController.java @@ -20,10 +20,8 @@ import android.app.Activity; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; -import android.content.pm.UserInfo; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; -import android.os.AsyncTask; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; @@ -39,7 +37,6 @@ import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; import com.android.settings.R; -import com.android.settingslib.Utils; import com.android.settingslib.drawable.CircleFramedDrawable; import java.io.File; @@ -59,9 +56,24 @@ public class EditUserInfoController { private UserManager mUserManager; private boolean mWaitingForActivityResult = false; + /** + * Callback made when either the username text or photo choice changes. + */ public interface OnContentChangedCallback { - public void onPhotoChanged(Drawable photo); - public void onLabelChanged(CharSequence label); + /** Photo updated. */ + void onPhotoChanged(UserHandle user, Drawable photo); + /** Username updated. */ + void onLabelChanged(UserHandle user, CharSequence label); + } + + /** + * Callback made when the dialog finishes. + */ + public interface OnDialogCompleteCallback { + /** Dialog closed with positive button. */ + void onPositive(); + /** Dialog closed with negative button or cancelled. */ + void onNegativeOrCancel(); } public void clear() { @@ -111,7 +123,8 @@ public class EditUserInfoController { public Dialog createDialog(final Fragment fragment, final Drawable currentUserIcon, final CharSequence currentUserName, - int titleResId, final OnContentChangedCallback callback, UserHandle user) { + String title, final OnContentChangedCallback callback, UserHandle user, + OnDialogCompleteCallback completeCallback) { Activity activity = fragment.getActivity(); mUser = user; if (mUserManager == null) { @@ -120,10 +133,8 @@ public class EditUserInfoController { LayoutInflater inflater = activity.getLayoutInflater(); View content = inflater.inflate(R.layout.edit_user_info_dialog_content, null); - UserInfo info = mUserManager.getUserInfo(mUser.getIdentifier()); - final EditText userNameView = (EditText) content.findViewById(R.id.user_name); - userNameView.setText(info.name); + userNameView.setText(currentUserName); final ImageView userPhotoView = (ImageView) content.findViewById(R.id.user_photo); Drawable drawable = null; @@ -131,14 +142,11 @@ public class EditUserInfoController { drawable = CircleFramedDrawable.getInstance(activity, mSavedPhoto); } else { drawable = currentUserIcon; - if (drawable == null) { - drawable = Utils.getUserIcon(activity, mUserManager, info); - } } userPhotoView.setImageDrawable(drawable); mEditUserPhotoController = createEditUserPhotoController(fragment, userPhotoView, drawable); mEditUserInfoDialog = new AlertDialog.Builder(activity) - .setTitle(R.string.profile_info_settings_title) + .setTitle(title) .setView(content) .setCancelable(true) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @@ -149,41 +157,45 @@ public class EditUserInfoController { CharSequence userName = userNameView.getText(); if (!TextUtils.isEmpty(userName)) { if (currentUserName == null - || !userName.toString().equals(currentUserName.toString())) { + || !userName.toString().equals( + currentUserName.toString())) { if (callback != null) { - callback.onLabelChanged(userName.toString()); + callback.onLabelChanged(mUser, userName.toString()); } - mUserManager.setUserName(mUser.getIdentifier(), - userName.toString()); } } // Update the photo if changed. Drawable drawable = mEditUserPhotoController.getNewUserPhotoDrawable(); - Bitmap bitmap = mEditUserPhotoController.getNewUserPhotoBitmap(); - if (drawable != null && bitmap != null - && !drawable.equals(currentUserIcon)) { + if (drawable != null && !drawable.equals(currentUserIcon)) { if (callback != null) { - callback.onPhotoChanged(drawable); + callback.onPhotoChanged(mUser, drawable); } - new AsyncTask<Void, Void, Void>() { - @Override - protected Void doInBackground(Void... params) { - mUserManager.setUserIcon(mUser.getIdentifier(), - mEditUserPhotoController.getNewUserPhotoBitmap()); - return null; - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); } fragment.getActivity().removeDialog( RestrictedProfileSettings.DIALOG_ID_EDIT_USER_INFO); } clear(); + if (completeCallback != null) { + completeCallback.onPositive(); + } } }) .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { clear(); + if (completeCallback != null) { + completeCallback.onNegativeOrCancel(); + } + } + }) + .setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + clear(); + if (completeCallback != null) { + completeCallback.onNegativeOrCancel(); + } } }) .create(); diff --git a/src/com/android/settings/users/RestrictedProfileSettings.java b/src/com/android/settings/users/RestrictedProfileSettings.java index b00ee83f61..57c0d02886 100644 --- a/src/com/android/settings/users/RestrictedProfileSettings.java +++ b/src/com/android/settings/users/RestrictedProfileSettings.java @@ -23,12 +23,15 @@ import android.content.Intent; import android.content.pm.UserInfo; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.os.UserHandle; import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import com.android.internal.util.UserIcons; import com.android.settings.R; import com.android.settings.Utils; +import com.android.settingslib.utils.ThreadUtils; public class RestrictedProfileSettings extends AppRestrictionsFragment implements EditUserInfoController.OnContentChangedCallback { @@ -117,8 +120,8 @@ public class RestrictedProfileSettings extends AppRestrictionsFragment public Dialog onCreateDialog(int dialogId) { if (dialogId == DIALOG_ID_EDIT_USER_INFO) { return mEditUserInfoController.createDialog(this, mUserIconView.getDrawable(), - mUserNameView.getText(), R.string.profile_info_settings_title, - this, mUser); + mUserNameView.getText(), getString(R.string.profile_info_settings_title), + this, mUser, null); } else if (dialogId == DIALOG_CONFIRM_REMOVE) { Dialog dlg = UserDialogs.createRemoveDialog(getActivity(), mUser.getIdentifier(), @@ -156,12 +159,19 @@ public class RestrictedProfileSettings extends AppRestrictionsFragment } @Override - public void onPhotoChanged(Drawable photo) { + public void onPhotoChanged(UserHandle user, Drawable photo) { mUserIconView.setImageDrawable(photo); + ThreadUtils.postOnBackgroundThread(new Runnable() { + @Override + public void run() { + mUserManager.setUserIcon(user.getIdentifier(), UserIcons.convertToBitmap(photo)); + } + }); } @Override - public void onLabelChanged(CharSequence label) { + public void onLabelChanged(UserHandle user, CharSequence label) { mUserNameView.setText(label); + mUserManager.setUserName(user.getIdentifier(), label.toString()); } } diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java index 7a9f02654a..cd305e9743 100644 --- a/src/com/android/settings/users/UserSettings.java +++ b/src/com/android/settings/users/UserSettings.java @@ -16,6 +16,8 @@ package com.android.settings.users; +import static android.os.Process.myUserHandle; + import android.app.Activity; import android.app.ActivityManager; import android.app.Dialog; @@ -73,6 +75,7 @@ import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.RestrictedPreference; import com.android.settingslib.drawable.CircleFramedDrawable; import com.android.settingslib.search.SearchIndexable; +import com.android.settingslib.utils.ThreadUtils; import com.google.android.setupcompat.util.WizardManagerHelper; @@ -82,6 +85,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Random; /** * Screen that manages the list of users on the device. @@ -95,8 +99,7 @@ import java.util.List; public class UserSettings extends SettingsPreferenceFragment implements Preference.OnPreferenceClickListener, View.OnClickListener, MultiUserSwitchBarController.OnMultiUserSwitchChangedListener, - DialogInterface.OnDismissListener, - EditUserInfoController.OnContentChangedCallback { + DialogInterface.OnDismissListener { private static final String TAG = "UserSettings"; @@ -125,6 +128,8 @@ public class UserSettings extends SettingsPreferenceFragment private static final int DIALOG_NEED_LOCKSCREEN = 7; private static final int DIALOG_CONFIRM_EXIT_GUEST = 8; private static final int DIALOG_USER_PROFILE_EDITOR = 9; + private static final int DIALOG_USER_PROFILE_EDITOR_ADD_USER = 10; + private static final int DIALOG_USER_PROFILE_EDITOR_ADD_RESTRICTED_PROFILE = 11; private static final int MESSAGE_UPDATE_LIST = 1; private static final int MESSAGE_SETUP_USER = 2; @@ -168,6 +173,9 @@ public class UserSettings extends SettingsPreferenceFragment private AddUserWhenLockedPreferenceController mAddUserWhenLockedPreferenceController; private MultiUserFooterPreferenceController mMultiUserFooterPreferenceController; + private CharSequence mPendingUserName; + private Drawable mPendingUserIcon; + // A place to cache the generated default avatar private Drawable mDefaultIconDrawable; @@ -447,7 +455,7 @@ public class UserSettings extends SettingsPreferenceFragment break; case USER_TYPE_RESTRICTED_PROFILE: if (hasLockscreenSecurity()) { - addUserNow(USER_TYPE_RESTRICTED_PROFILE); + showDialog(DIALOG_USER_PROFILE_EDITOR_ADD_RESTRICTED_PROFILE); } else { showDialog(DIALOG_NEED_LOCKSCREEN); } @@ -466,22 +474,6 @@ public class UserSettings extends SettingsPreferenceFragment } } - private UserInfo createRestrictedProfile() { - UserInfo newUserInfo = mUserManager.createRestrictedProfile(mAddingUserName); - if (newUserInfo != null && !assignDefaultPhoto(getActivity(), newUserInfo.id)) { - return null; - } - return newUserInfo; - } - - private UserInfo createTrustedUser() { - UserInfo newUserInfo = mUserManager.createUser(mAddingUserName, 0); - if (newUserInfo != null && !assignDefaultPhoto(getActivity(), newUserInfo.id)) { - return null; - } - return newUserInfo; - } - private void onManageUserClicked(int userId, boolean newUser) { mAddingUser = false; if (userId == UserPreference.USERID_GUEST_DEFAULTS) { @@ -571,15 +563,13 @@ public class UserSettings extends SettingsPreferenceFragment final int messageResId = longMessageDisplayed ? R.string.user_add_user_message_short : R.string.user_add_user_message_long; - final int userType = dialogId == DIALOG_ADD_USER - ? USER_TYPE_USER : USER_TYPE_RESTRICTED_PROFILE; Dialog dlg = new AlertDialog.Builder(context) .setTitle(R.string.user_add_user_title) .setMessage(messageResId) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { - addUserNow(userType); + showDialog(DIALOG_USER_PROFILE_EDITOR_ADD_USER); if (!longMessageDisplayed) { preferences.edit().putBoolean( KEY_ADD_USER_LONG_MESSAGE_DISPLAYED, @@ -675,20 +665,96 @@ public class UserSettings extends SettingsPreferenceFragment return dlg; } case DIALOG_USER_PROFILE_EDITOR: { - Dialog dlg = mEditUserInfoController.createDialog( + UserHandle user = myUserHandle(); + UserInfo info = mUserManager.getUserInfo(user.getIdentifier()); + return mEditUserInfoController.createDialog( this, - null, - mMePreference.getTitle(), - R.string.profile_info_settings_title, - this /* callback */, - android.os.Process.myUserHandle()); - return dlg; + Utils.getUserIcon(getPrefContext(), mUserManager, info), + info.name, + getString(R.string.profile_info_settings_title), + new EditUserInfoController.OnContentChangedCallback() { + @Override + public void onPhotoChanged(UserHandle user, Drawable photo) { + ThreadUtils.postOnBackgroundThread(new Runnable() { + @Override + public void run() { + mUserManager.setUserIcon(user.getIdentifier(), + UserIcons.convertToBitmap(photo)); + } + }); + mMePreference.setIcon(photo); + } + + @Override + public void onLabelChanged(UserHandle user, CharSequence label) { + mMePreference.setTitle(label.toString()); + mUserManager.setUserName(user.getIdentifier(), label.toString()); + } + }, + user, + null); + } + case DIALOG_USER_PROFILE_EDITOR_ADD_USER: { + synchronized (mUserLock) { + mPendingUserIcon = UserIcons.getDefaultUserIcon(getPrefContext().getResources(), + new Random(System.currentTimeMillis()).nextInt(8), false); + mPendingUserName = getString(R.string.user_new_user_name); + } + return buildAddUserProfileEditorDialog(USER_TYPE_USER); + } + case DIALOG_USER_PROFILE_EDITOR_ADD_RESTRICTED_PROFILE: { + synchronized (mUserLock) { + mPendingUserIcon = UserIcons.getDefaultUserIcon(getPrefContext().getResources(), + new Random(System.currentTimeMillis()).nextInt(8), false); + mPendingUserName = getString(R.string.user_new_profile_name); + } + return buildAddUserProfileEditorDialog(USER_TYPE_RESTRICTED_PROFILE); } default: return null; } } + private Dialog buildAddUserProfileEditorDialog(int userType) { + Dialog d; + synchronized (mUserLock) { + d = mEditUserInfoController.createDialog( + this, + mPendingUserIcon, + mPendingUserName, + getString(userType == USER_TYPE_USER + ? R.string.user_info_settings_title + : R.string.profile_info_settings_title), + new EditUserInfoController.OnContentChangedCallback() { + @Override + public void onPhotoChanged(UserHandle user, Drawable photo) { + mPendingUserIcon = photo; + } + + @Override + public void onLabelChanged(UserHandle user, CharSequence label) { + mPendingUserName = label; + } + }, + myUserHandle(), + new EditUserInfoController.OnDialogCompleteCallback() { + @Override + public void onPositive() { + addUserNow(userType); + } + + @Override + public void onNegativeOrCancel() { + synchronized (mUserLock) { + mPendingUserIcon = null; + mPendingUserName = null; + } + } + }); + } + return d; + } + @Override public int getDialogMetricsCategory(int dialogId) { switch (dialogId) { @@ -709,6 +775,8 @@ public class UserSettings extends SettingsPreferenceFragment case DIALOG_CONFIRM_EXIT_GUEST: return SettingsEnums.DIALOG_USER_CONFIRM_EXIT_GUEST; case DIALOG_USER_PROFILE_EDITOR: + case DIALOG_USER_PROFILE_EDITOR_ADD_USER: + case DIALOG_USER_PROFILE_EDITOR_ADD_RESTRICTED_PROFILE: return SettingsEnums.DIALOG_USER_EDIT_PROFILE; default: return 0; @@ -719,14 +787,15 @@ public class UserSettings extends SettingsPreferenceFragment if (mRemovingUserId == UserHandle.myUserId()) { removeThisUser(); } else { - new Thread() { + ThreadUtils.postOnBackgroundThread(new Runnable() { + @Override public void run() { synchronized (mUserLock) { mUserManager.removeUser(mRemovingUserId); mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST); } } - }.start(); + }); } } @@ -746,39 +815,59 @@ public class UserSettings extends SettingsPreferenceFragment private void addUserNow(final int userType) { synchronized (mUserLock) { mAddingUser = true; - mAddingUserName = userType == USER_TYPE_USER ? getString(R.string.user_new_user_name) - : getString(R.string.user_new_profile_name); - //updateUserList(); - new Thread() { - public void run() { - UserInfo user; - // Could take a few seconds - if (userType == USER_TYPE_USER) { - user = createTrustedUser(); - } else { - user = createRestrictedProfile(); - } + mAddingUserName = userType == USER_TYPE_USER + ? (mPendingUserName != null ? mPendingUserName.toString() + : getString(R.string.user_new_user_name)) + : (mPendingUserName != null ? mPendingUserName.toString() + : getString(R.string.user_new_profile_name)); + } + ThreadUtils.postOnBackgroundThread(new Runnable() { + @Override + public void run() { + UserInfo user; + String username; + + synchronized (mUserLock) { + username = mAddingUserName; + } + + // Could take a few seconds + if (userType == USER_TYPE_USER) { + user = mUserManager.createUser(username, 0); + } else { + user = mUserManager.createRestrictedProfile(username); + } + + synchronized (mUserLock) { if (user == null) { mAddingUser = false; + mPendingUserIcon = null; + mPendingUserName = null; return; } - synchronized (mUserLock) { - if (userType == USER_TYPE_USER) { - mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST); - // Skip setting up user which results in user switching when the - // restriction is set. - if (!mUserCaps.mDisallowSwitchUser) { - mHandler.sendMessage(mHandler.obtainMessage( - MESSAGE_SETUP_USER, user.id, user.serialNumber)); - } - } else { + + if (mPendingUserIcon != null) { + mUserManager.setUserIcon(user.id, + UserIcons.convertToBitmap(mPendingUserIcon)); + } + + if (userType == USER_TYPE_USER) { + mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST); + // Skip setting up user which results in user switching when the + // restriction is set. + if (!mUserCaps.mDisallowSwitchUser) { mHandler.sendMessage(mHandler.obtainMessage( - MESSAGE_CONFIG_USER, user.id, user.serialNumber)); + MESSAGE_SETUP_USER, user.id, user.serialNumber)); } + } else { + mHandler.sendMessage(mHandler.obtainMessage( + MESSAGE_CONFIG_USER, user.id, user.serialNumber)); } + mPendingUserIcon = null; + mPendingUserName = null; } - }.start(); - } + } + }); } private void switchUserNow(int userId) { @@ -1123,16 +1212,6 @@ public class UserSettings extends SettingsPreferenceFragment return R.string.help_url_users; } - @Override - public void onPhotoChanged(Drawable photo) { - mMePreference.setIcon(photo); - } - - @Override - public void onLabelChanged(CharSequence label) { - mMePreference.setTitle(label); - } - /** * Returns a default user icon (as a {@link Bitmap}) for the given user. * |