Loading src/com/android/settings/users/UserDetailsSettings.java +46 −2 Original line number Diff line number Diff line Loading @@ -42,6 +42,9 @@ import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.RestrictedPreference; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; /** * Settings screen for configuring, deleting or switching to a specific user. Loading @@ -67,9 +70,13 @@ public class UserDetailsSettings extends SettingsPreferenceFragment private static final int DIALOG_CONFIRM_ENABLE_CALLING = 2; private static final int DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS = 3; private static final int DIALOG_SETUP_USER = 4; private static final int DIALOG_CONFIRM_RESET_GUEST = 5; private UserManager mUserManager; private UserCapabilities mUserCaps; private boolean mGuestUserAutoCreated; private final AtomicBoolean mGuestCreationScheduled = new AtomicBoolean(); private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); @VisibleForTesting RestrictedPreference mSwitchUserPref; Loading Loading @@ -97,6 +104,9 @@ public class UserDetailsSettings extends SettingsPreferenceFragment mUserCaps = UserCapabilities.create(context); addPreferencesFromResource(R.xml.user_details_settings); mGuestUserAutoCreated = getPrefContext().getResources().getBoolean( com.android.internal.R.bool.config_guestUserAutoCreated); initialize(context, getArguments()); } Loading @@ -104,13 +114,20 @@ public class UserDetailsSettings extends SettingsPreferenceFragment public void onResume() { super.onResume(); mSwitchUserPref.setEnabled(canSwitchUserNow()); if (mGuestUserAutoCreated) { mRemoveUserPref.setEnabled((mUserInfo.flags & UserInfo.FLAG_INITIALIZED) != 0); } } @Override public boolean onPreferenceClick(Preference preference) { if (preference == mRemoveUserPref) { if (canDeleteUser()) { if (mUserInfo.isGuest()) { showDialog(DIALOG_CONFIRM_RESET_GUEST); } else { showDialog(DIALOG_CONFIRM_REMOVE); } return true; } } else if (preference == mSwitchUserPref) { Loading Loading @@ -144,6 +161,7 @@ public class UserDetailsSettings extends SettingsPreferenceFragment public int getDialogMetricsCategory(int dialogId) { switch (dialogId) { case DIALOG_CONFIRM_REMOVE: case DIALOG_CONFIRM_RESET_GUEST: return SettingsEnums.DIALOG_USER_REMOVE; case DIALOG_CONFIRM_ENABLE_CALLING: return SettingsEnums.DIALOG_USER_ENABLE_CALLING; Loading Loading @@ -179,10 +197,30 @@ public class UserDetailsSettings extends SettingsPreferenceFragment switchUser(); } }); case DIALOG_CONFIRM_RESET_GUEST: return UserDialogs.createResetGuestDialog(getActivity(), (dialog, which) -> resetGuest()); } throw new IllegalArgumentException("Unsupported dialogId " + dialogId); } /** * Erase the current guest user and create a new one in the background. UserSettings will * handle guest creation after receiving the {@link UserSettings.RESULT_GUEST_REMOVED} result. */ private void resetGuest() { // Just to be safe, check that the selected user is a guest if (!mUserInfo.isGuest()) { return; } mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_USER_GUEST_EXIT_CONFIRMED); mUserManager.removeUser(mUserInfo.id); setResult(UserSettings.RESULT_GUEST_REMOVED); finishFragment(); } @VisibleForTesting @Override protected void showDialog(int dialogId) { Loading Loading @@ -239,11 +277,17 @@ public class UserDetailsSettings extends SettingsPreferenceFragment if (mUserInfo.isGuest()) { // These are not for an existing user, just general Guest settings. // Default title is for calling and SMS. Change to calling-only here // TODO(b/191483069): These settings can't be changed unless guest user exists mPhonePref.setTitle(R.string.user_enable_calling); mDefaultGuestRestrictions = mUserManager.getDefaultGuestRestrictions(); mPhonePref.setChecked( !mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS)); mRemoveUserPref.setTitle(R.string.user_exit_guest_title); mRemoveUserPref.setTitle(mGuestUserAutoCreated ? com.android.settingslib.R.string.guest_reset_guest : R.string.user_exit_guest_title); if (mGuestUserAutoCreated) { mRemoveUserPref.setEnabled((mUserInfo.flags & UserInfo.FLAG_INITIALIZED) != 0); } } else { mPhonePref.setChecked(!mUserManager.hasUserRestriction( UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId))); Loading src/com/android/settings/users/UserDialogs.java +20 −0 Original line number Diff line number Diff line Loading @@ -154,4 +154,24 @@ public final class UserDialogs { null) .create(); } /** * Creates a dialog to confirm with the user if it's ok to reset the guest user, which will * delete all the guest user's data. * * @param context a Context object * @param onConfirmListener Callback object for positive action * @return the created Dialog */ public static Dialog createResetGuestDialog(Context context, DialogInterface.OnClickListener onConfirmListener) { return new AlertDialog.Builder(context) .setTitle(com.android.settingslib.R.string.guest_reset_guest_dialog_title) .setMessage(R.string.user_exit_guest_confirm_message) .setPositiveButton( com.android.settingslib.R.string.guest_reset_guest_confirm_button, onConfirmListener) .setNegativeButton(android.R.string.cancel, null) .create(); } } src/com/android/settings/users/UserSettings.java +96 −7 Original line number Diff line number Diff line Loading @@ -87,6 +87,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; /** * Screen that manages the list of users on the device. Loading Loading @@ -128,6 +131,7 @@ public class UserSettings extends SettingsPreferenceFragment 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 DIALOG_CONFIRM_RESET_GUEST = 12; private static final int MESSAGE_UPDATE_LIST = 1; private static final int MESSAGE_USER_CREATED = 2; Loading @@ -136,6 +140,9 @@ public class UserSettings extends SettingsPreferenceFragment private static final int USER_TYPE_RESTRICTED_PROFILE = 2; private static final int REQUEST_CHOOSE_LOCK = 10; private static final int REQUEST_EDIT_GUEST = 11; static final int RESULT_GUEST_REMOVED = 100; private static final String KEY_ADD_USER_LONG_MESSAGE_DISPLAYED = "key_add_user_long_message_displayed"; Loading @@ -160,6 +167,7 @@ public class UserSettings extends SettingsPreferenceFragment SparseArray<Bitmap> mUserIcons = new SparseArray<>(); private int mRemovingUserId = -1; private boolean mAddingUser; private boolean mGuestUserAutoCreated; private String mAddingUserName; private UserCapabilities mUserCaps; private boolean mShouldUpdateUserList = true; Loading @@ -173,6 +181,8 @@ public class UserSettings extends SettingsPreferenceFragment private AddUserWhenLockedPreferenceController mAddUserWhenLockedPreferenceController; private MultiUserTopIntroPreferenceController mMultiUserTopIntroPreferenceController; private UserCreatingDialog mUserCreatingDialog; private final AtomicBoolean mGuestCreationScheduled = new AtomicBoolean(); private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); private CharSequence mPendingUserName; private Drawable mPendingUserIcon; Loading Loading @@ -240,6 +250,9 @@ public class UserSettings extends SettingsPreferenceFragment return; } mGuestUserAutoCreated = getPrefContext().getResources().getBoolean( com.android.internal.R.bool.config_guestUserAutoCreated); mAddUserWhenLockedPreferenceController = new AddUserWhenLockedPreferenceController( activity, KEY_ADD_USER_WHEN_LOCKED); Loading Loading @@ -343,7 +356,10 @@ public class UserSettings extends SettingsPreferenceFragment @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { int pos = 0; if (!mUserCaps.mIsAdmin && canSwitchUserNow()) { // TODO(b/191509236): The menu item does not need to be accessible for guest users, // regardless of mGuestUserAutoCreated if (!mUserCaps.mIsAdmin && canSwitchUserNow() && !(isCurrentUserGuest() && mGuestUserAutoCreated)) { String nickname = mUserManager.getUserName(); MenuItem removeThisUser = menu.add(0, MENU_REMOVE_USER, pos++, getResources().getString(R.string.user_remove_user_menu, nickname)); Loading Loading @@ -387,7 +403,9 @@ public class UserSettings extends SettingsPreferenceFragment if (isCurrentUserGuest()) { // No need to load profile information mMePreference.setIcon(getEncircledDefaultIcon()); mMePreference.setTitle(R.string.user_exit_guest_title); mMePreference.setTitle( mGuestUserAutoCreated ? com.android.settingslib.R.string.guest_reset_guest : R.string.user_exit_guest_title); mMePreference.setSelectable(true); // removing a guest will result in switching back to the admin user mMePreference.setEnabled(canSwitchUserNow()); Loading Loading @@ -445,6 +463,9 @@ public class UserSettings extends SettingsPreferenceFragment if (resultCode != Activity.RESULT_CANCELED && hasLockscreenSecurity()) { addUserNow(USER_TYPE_RESTRICTED_PROFILE); } } else if (mGuestUserAutoCreated && requestCode == REQUEST_EDIT_GUEST && resultCode == RESULT_GUEST_REMOVED) { scheduleGuestCreation(); } else { mEditUserInfoController.onActivityResult(requestCode, resultCode, data); } Loading Loading @@ -508,12 +529,15 @@ public class UserSettings extends SettingsPreferenceFragment extras.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, newUser); final Context context = getContext(); new SubSettingLauncher(context) SubSettingLauncher launcher = new SubSettingLauncher(context) .setDestination(UserDetailsSettings.class.getName()) .setArguments(extras) .setTitleText(getUserName(context, userInfo)) .setSourceMetricsCategory(getMetricsCategory()) .launch(); .setSourceMetricsCategory(getMetricsCategory()); if (mGuestUserAutoCreated && userInfo.isGuest()) { launcher.setResultListener(this, REQUEST_EDIT_GUEST); } launcher.launch(); } @Override Loading Loading @@ -651,6 +675,10 @@ public class UserSettings extends SettingsPreferenceFragment } return buildAddUserDialog(USER_TYPE_RESTRICTED_PROFILE); } case DIALOG_CONFIRM_RESET_GUEST: { return UserDialogs.createResetGuestDialog(getActivity(), (dialog, which) -> resetGuest()); } default: return null; } Loading Loading @@ -727,6 +755,7 @@ public class UserSettings extends SettingsPreferenceFragment case DIALOG_NEED_LOCKSCREEN: return SettingsEnums.DIALOG_USER_NEED_LOCKSCREEN; case DIALOG_CONFIRM_EXIT_GUEST: case DIALOG_CONFIRM_RESET_GUEST: return SettingsEnums.DIALOG_USER_CONFIRM_EXIT_GUEST; case DIALOG_USER_PROFILE_EDITOR: case DIALOG_USER_PROFILE_EDITOR_ADD_USER: Loading Loading @@ -840,6 +869,55 @@ public class UserSettings extends SettingsPreferenceFragment removeThisUser(); } /** * Erase the current user (assuming it is a guest user), and create a new one in the background */ @VisibleForTesting void resetGuest() { // Just to be safe if (!isCurrentUserGuest()) { return; } int guestUserId = UserHandle.myUserId(); // Using markGuestForDeletion allows us to create a new guest before this one is // fully removed. This could happen if someone calls scheduleGuestCreation() // immediately after calling this method. boolean marked = mUserManager.markGuestForDeletion(guestUserId); if (!marked) { Log.w(TAG, "Couldn't mark the guest for deletion for user " + guestUserId); return; } exitGuest(); scheduleGuestCreation(); } /** * Create a guest user in the background */ @VisibleForTesting void scheduleGuestCreation() { // TODO(b/191067027): Move guest recreation to system_server if (mGuestCreationScheduled.compareAndSet(/* expect= */ false, /* update= */ true)) { // Once mGuestCreationScheduled=true, mAddGuest needs to be updated so that it shows // "Resetting guest..." mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST); mExecutor.execute(() -> { UserInfo guest = mUserManager.createGuest( getContext(), getString(com.android.settingslib.R.string.user_guest)); mGuestCreationScheduled.set(false); if (guest == null) { Log.e(TAG, "Unable to automatically recreate guest user"); } // The list needs to be updated whether or not guest creation worked. If guest // creation failed, the list needs to update so that "Add guest" is displayed. // Otherwise, the UX could be stuck in a state where there is no way to switch to // the guest user (e.g. Guest would not be selectable, and it would be stuck // saying "Resetting guest...") mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST); }); } } @VisibleForTesting void updateUserList() { final Context context = getActivity(); Loading Loading @@ -988,8 +1066,15 @@ public class UserSettings extends SettingsPreferenceFragment && mUserCaps.mUserSwitcherEnabled) { mAddGuest.setVisible(true); mAddGuest.setIcon(getEncircledDefaultIcon()); mAddGuest.setEnabled(canSwitchUserNow()); mAddGuest.setSelectable(true); if (mGuestUserAutoCreated && mGuestCreationScheduled.get()) { mAddGuest.setTitle(com.android.settingslib.R.string.user_guest); mAddGuest.setSummary(R.string.guest_resetting); mAddGuest.setEnabled(false); } else { mAddGuest.setTitle(com.android.settingslib.R.string.guest_new_guest); mAddGuest.setEnabled(canSwitchUserNow()); } } else { mAddGuest.setVisible(false); } Loading Loading @@ -1077,7 +1162,11 @@ public class UserSettings extends SettingsPreferenceFragment public boolean onPreferenceClick(Preference pref) { if (pref == mMePreference) { if (isCurrentUserGuest()) { if (mGuestUserAutoCreated) { showDialog(DIALOG_CONFIRM_RESET_GUEST); } else { showDialog(DIALOG_CONFIRM_EXIT_GUEST); } } else { showDialog(DIALOG_USER_PROFILE_EDITOR); } Loading Loading
src/com/android/settings/users/UserDetailsSettings.java +46 −2 Original line number Diff line number Diff line Loading @@ -42,6 +42,9 @@ import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.RestrictedPreference; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; /** * Settings screen for configuring, deleting or switching to a specific user. Loading @@ -67,9 +70,13 @@ public class UserDetailsSettings extends SettingsPreferenceFragment private static final int DIALOG_CONFIRM_ENABLE_CALLING = 2; private static final int DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS = 3; private static final int DIALOG_SETUP_USER = 4; private static final int DIALOG_CONFIRM_RESET_GUEST = 5; private UserManager mUserManager; private UserCapabilities mUserCaps; private boolean mGuestUserAutoCreated; private final AtomicBoolean mGuestCreationScheduled = new AtomicBoolean(); private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); @VisibleForTesting RestrictedPreference mSwitchUserPref; Loading Loading @@ -97,6 +104,9 @@ public class UserDetailsSettings extends SettingsPreferenceFragment mUserCaps = UserCapabilities.create(context); addPreferencesFromResource(R.xml.user_details_settings); mGuestUserAutoCreated = getPrefContext().getResources().getBoolean( com.android.internal.R.bool.config_guestUserAutoCreated); initialize(context, getArguments()); } Loading @@ -104,13 +114,20 @@ public class UserDetailsSettings extends SettingsPreferenceFragment public void onResume() { super.onResume(); mSwitchUserPref.setEnabled(canSwitchUserNow()); if (mGuestUserAutoCreated) { mRemoveUserPref.setEnabled((mUserInfo.flags & UserInfo.FLAG_INITIALIZED) != 0); } } @Override public boolean onPreferenceClick(Preference preference) { if (preference == mRemoveUserPref) { if (canDeleteUser()) { if (mUserInfo.isGuest()) { showDialog(DIALOG_CONFIRM_RESET_GUEST); } else { showDialog(DIALOG_CONFIRM_REMOVE); } return true; } } else if (preference == mSwitchUserPref) { Loading Loading @@ -144,6 +161,7 @@ public class UserDetailsSettings extends SettingsPreferenceFragment public int getDialogMetricsCategory(int dialogId) { switch (dialogId) { case DIALOG_CONFIRM_REMOVE: case DIALOG_CONFIRM_RESET_GUEST: return SettingsEnums.DIALOG_USER_REMOVE; case DIALOG_CONFIRM_ENABLE_CALLING: return SettingsEnums.DIALOG_USER_ENABLE_CALLING; Loading Loading @@ -179,10 +197,30 @@ public class UserDetailsSettings extends SettingsPreferenceFragment switchUser(); } }); case DIALOG_CONFIRM_RESET_GUEST: return UserDialogs.createResetGuestDialog(getActivity(), (dialog, which) -> resetGuest()); } throw new IllegalArgumentException("Unsupported dialogId " + dialogId); } /** * Erase the current guest user and create a new one in the background. UserSettings will * handle guest creation after receiving the {@link UserSettings.RESULT_GUEST_REMOVED} result. */ private void resetGuest() { // Just to be safe, check that the selected user is a guest if (!mUserInfo.isGuest()) { return; } mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_USER_GUEST_EXIT_CONFIRMED); mUserManager.removeUser(mUserInfo.id); setResult(UserSettings.RESULT_GUEST_REMOVED); finishFragment(); } @VisibleForTesting @Override protected void showDialog(int dialogId) { Loading Loading @@ -239,11 +277,17 @@ public class UserDetailsSettings extends SettingsPreferenceFragment if (mUserInfo.isGuest()) { // These are not for an existing user, just general Guest settings. // Default title is for calling and SMS. Change to calling-only here // TODO(b/191483069): These settings can't be changed unless guest user exists mPhonePref.setTitle(R.string.user_enable_calling); mDefaultGuestRestrictions = mUserManager.getDefaultGuestRestrictions(); mPhonePref.setChecked( !mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS)); mRemoveUserPref.setTitle(R.string.user_exit_guest_title); mRemoveUserPref.setTitle(mGuestUserAutoCreated ? com.android.settingslib.R.string.guest_reset_guest : R.string.user_exit_guest_title); if (mGuestUserAutoCreated) { mRemoveUserPref.setEnabled((mUserInfo.flags & UserInfo.FLAG_INITIALIZED) != 0); } } else { mPhonePref.setChecked(!mUserManager.hasUserRestriction( UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId))); Loading
src/com/android/settings/users/UserDialogs.java +20 −0 Original line number Diff line number Diff line Loading @@ -154,4 +154,24 @@ public final class UserDialogs { null) .create(); } /** * Creates a dialog to confirm with the user if it's ok to reset the guest user, which will * delete all the guest user's data. * * @param context a Context object * @param onConfirmListener Callback object for positive action * @return the created Dialog */ public static Dialog createResetGuestDialog(Context context, DialogInterface.OnClickListener onConfirmListener) { return new AlertDialog.Builder(context) .setTitle(com.android.settingslib.R.string.guest_reset_guest_dialog_title) .setMessage(R.string.user_exit_guest_confirm_message) .setPositiveButton( com.android.settingslib.R.string.guest_reset_guest_confirm_button, onConfirmListener) .setNegativeButton(android.R.string.cancel, null) .create(); } }
src/com/android/settings/users/UserSettings.java +96 −7 Original line number Diff line number Diff line Loading @@ -87,6 +87,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; /** * Screen that manages the list of users on the device. Loading Loading @@ -128,6 +131,7 @@ public class UserSettings extends SettingsPreferenceFragment 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 DIALOG_CONFIRM_RESET_GUEST = 12; private static final int MESSAGE_UPDATE_LIST = 1; private static final int MESSAGE_USER_CREATED = 2; Loading @@ -136,6 +140,9 @@ public class UserSettings extends SettingsPreferenceFragment private static final int USER_TYPE_RESTRICTED_PROFILE = 2; private static final int REQUEST_CHOOSE_LOCK = 10; private static final int REQUEST_EDIT_GUEST = 11; static final int RESULT_GUEST_REMOVED = 100; private static final String KEY_ADD_USER_LONG_MESSAGE_DISPLAYED = "key_add_user_long_message_displayed"; Loading @@ -160,6 +167,7 @@ public class UserSettings extends SettingsPreferenceFragment SparseArray<Bitmap> mUserIcons = new SparseArray<>(); private int mRemovingUserId = -1; private boolean mAddingUser; private boolean mGuestUserAutoCreated; private String mAddingUserName; private UserCapabilities mUserCaps; private boolean mShouldUpdateUserList = true; Loading @@ -173,6 +181,8 @@ public class UserSettings extends SettingsPreferenceFragment private AddUserWhenLockedPreferenceController mAddUserWhenLockedPreferenceController; private MultiUserTopIntroPreferenceController mMultiUserTopIntroPreferenceController; private UserCreatingDialog mUserCreatingDialog; private final AtomicBoolean mGuestCreationScheduled = new AtomicBoolean(); private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); private CharSequence mPendingUserName; private Drawable mPendingUserIcon; Loading Loading @@ -240,6 +250,9 @@ public class UserSettings extends SettingsPreferenceFragment return; } mGuestUserAutoCreated = getPrefContext().getResources().getBoolean( com.android.internal.R.bool.config_guestUserAutoCreated); mAddUserWhenLockedPreferenceController = new AddUserWhenLockedPreferenceController( activity, KEY_ADD_USER_WHEN_LOCKED); Loading Loading @@ -343,7 +356,10 @@ public class UserSettings extends SettingsPreferenceFragment @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { int pos = 0; if (!mUserCaps.mIsAdmin && canSwitchUserNow()) { // TODO(b/191509236): The menu item does not need to be accessible for guest users, // regardless of mGuestUserAutoCreated if (!mUserCaps.mIsAdmin && canSwitchUserNow() && !(isCurrentUserGuest() && mGuestUserAutoCreated)) { String nickname = mUserManager.getUserName(); MenuItem removeThisUser = menu.add(0, MENU_REMOVE_USER, pos++, getResources().getString(R.string.user_remove_user_menu, nickname)); Loading Loading @@ -387,7 +403,9 @@ public class UserSettings extends SettingsPreferenceFragment if (isCurrentUserGuest()) { // No need to load profile information mMePreference.setIcon(getEncircledDefaultIcon()); mMePreference.setTitle(R.string.user_exit_guest_title); mMePreference.setTitle( mGuestUserAutoCreated ? com.android.settingslib.R.string.guest_reset_guest : R.string.user_exit_guest_title); mMePreference.setSelectable(true); // removing a guest will result in switching back to the admin user mMePreference.setEnabled(canSwitchUserNow()); Loading Loading @@ -445,6 +463,9 @@ public class UserSettings extends SettingsPreferenceFragment if (resultCode != Activity.RESULT_CANCELED && hasLockscreenSecurity()) { addUserNow(USER_TYPE_RESTRICTED_PROFILE); } } else if (mGuestUserAutoCreated && requestCode == REQUEST_EDIT_GUEST && resultCode == RESULT_GUEST_REMOVED) { scheduleGuestCreation(); } else { mEditUserInfoController.onActivityResult(requestCode, resultCode, data); } Loading Loading @@ -508,12 +529,15 @@ public class UserSettings extends SettingsPreferenceFragment extras.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, newUser); final Context context = getContext(); new SubSettingLauncher(context) SubSettingLauncher launcher = new SubSettingLauncher(context) .setDestination(UserDetailsSettings.class.getName()) .setArguments(extras) .setTitleText(getUserName(context, userInfo)) .setSourceMetricsCategory(getMetricsCategory()) .launch(); .setSourceMetricsCategory(getMetricsCategory()); if (mGuestUserAutoCreated && userInfo.isGuest()) { launcher.setResultListener(this, REQUEST_EDIT_GUEST); } launcher.launch(); } @Override Loading Loading @@ -651,6 +675,10 @@ public class UserSettings extends SettingsPreferenceFragment } return buildAddUserDialog(USER_TYPE_RESTRICTED_PROFILE); } case DIALOG_CONFIRM_RESET_GUEST: { return UserDialogs.createResetGuestDialog(getActivity(), (dialog, which) -> resetGuest()); } default: return null; } Loading Loading @@ -727,6 +755,7 @@ public class UserSettings extends SettingsPreferenceFragment case DIALOG_NEED_LOCKSCREEN: return SettingsEnums.DIALOG_USER_NEED_LOCKSCREEN; case DIALOG_CONFIRM_EXIT_GUEST: case DIALOG_CONFIRM_RESET_GUEST: return SettingsEnums.DIALOG_USER_CONFIRM_EXIT_GUEST; case DIALOG_USER_PROFILE_EDITOR: case DIALOG_USER_PROFILE_EDITOR_ADD_USER: Loading Loading @@ -840,6 +869,55 @@ public class UserSettings extends SettingsPreferenceFragment removeThisUser(); } /** * Erase the current user (assuming it is a guest user), and create a new one in the background */ @VisibleForTesting void resetGuest() { // Just to be safe if (!isCurrentUserGuest()) { return; } int guestUserId = UserHandle.myUserId(); // Using markGuestForDeletion allows us to create a new guest before this one is // fully removed. This could happen if someone calls scheduleGuestCreation() // immediately after calling this method. boolean marked = mUserManager.markGuestForDeletion(guestUserId); if (!marked) { Log.w(TAG, "Couldn't mark the guest for deletion for user " + guestUserId); return; } exitGuest(); scheduleGuestCreation(); } /** * Create a guest user in the background */ @VisibleForTesting void scheduleGuestCreation() { // TODO(b/191067027): Move guest recreation to system_server if (mGuestCreationScheduled.compareAndSet(/* expect= */ false, /* update= */ true)) { // Once mGuestCreationScheduled=true, mAddGuest needs to be updated so that it shows // "Resetting guest..." mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST); mExecutor.execute(() -> { UserInfo guest = mUserManager.createGuest( getContext(), getString(com.android.settingslib.R.string.user_guest)); mGuestCreationScheduled.set(false); if (guest == null) { Log.e(TAG, "Unable to automatically recreate guest user"); } // The list needs to be updated whether or not guest creation worked. If guest // creation failed, the list needs to update so that "Add guest" is displayed. // Otherwise, the UX could be stuck in a state where there is no way to switch to // the guest user (e.g. Guest would not be selectable, and it would be stuck // saying "Resetting guest...") mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST); }); } } @VisibleForTesting void updateUserList() { final Context context = getActivity(); Loading Loading @@ -988,8 +1066,15 @@ public class UserSettings extends SettingsPreferenceFragment && mUserCaps.mUserSwitcherEnabled) { mAddGuest.setVisible(true); mAddGuest.setIcon(getEncircledDefaultIcon()); mAddGuest.setEnabled(canSwitchUserNow()); mAddGuest.setSelectable(true); if (mGuestUserAutoCreated && mGuestCreationScheduled.get()) { mAddGuest.setTitle(com.android.settingslib.R.string.user_guest); mAddGuest.setSummary(R.string.guest_resetting); mAddGuest.setEnabled(false); } else { mAddGuest.setTitle(com.android.settingslib.R.string.guest_new_guest); mAddGuest.setEnabled(canSwitchUserNow()); } } else { mAddGuest.setVisible(false); } Loading Loading @@ -1077,7 +1162,11 @@ public class UserSettings extends SettingsPreferenceFragment public boolean onPreferenceClick(Preference pref) { if (pref == mMePreference) { if (isCurrentUserGuest()) { if (mGuestUserAutoCreated) { showDialog(DIALOG_CONFIRM_RESET_GUEST); } else { showDialog(DIALOG_CONFIRM_EXIT_GUEST); } } else { showDialog(DIALOG_USER_PROFILE_EDITOR); } Loading