Merge "Change user setup prompt dialog showing logic" into rvc-dev
diff --git a/src/com/android/settings/users/UserDetailsSettings.java b/src/com/android/settings/users/UserDetailsSettings.java
index c7cf90d..897b3c7 100644
--- a/src/com/android/settings/users/UserDetailsSettings.java
+++ b/src/com/android/settings/users/UserDetailsSettings.java
@@ -39,6 +39,7 @@
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
+import com.android.settingslib.RestrictedPreference;
import java.util.List;
@@ -65,10 +66,13 @@
private static final int DIALOG_CONFIRM_REMOVE = 1;
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 UserManager mUserManager;
+ private UserCapabilities mUserCaps;
+
@VisibleForTesting
- Preference mSwitchUserPref;
+ RestrictedPreference mSwitchUserPref;
private SwitchPreference mPhonePref;
@VisibleForTesting
Preference mAppAndContentAccessPref;
@@ -90,6 +94,7 @@
final Context context = getActivity();
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ mUserCaps = UserCapabilities.create(context);
addPreferencesFromResource(R.xml.user_details_settings);
initialize(context, getArguments());
@@ -106,15 +111,20 @@
if (preference == mRemoveUserPref) {
if (canDeleteUser()) {
showDialog(DIALOG_CONFIRM_REMOVE);
+ return true;
}
- return true;
} else if (preference == mSwitchUserPref) {
if (canSwitchUserNow()) {
- switchUser();
+ if (shouldShowSetupPromptDialog()) {
+ showDialog(DIALOG_SETUP_USER);
+ } else {
+ switchUser();
+ }
+ return true;
}
- return true;
} else if (preference == mAppAndContentAccessPref) {
openAppAndContentAccessScreen(false);
+ return true;
}
return false;
}
@@ -139,6 +149,8 @@
return SettingsEnums.DIALOG_USER_ENABLE_CALLING;
case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS:
return SettingsEnums.DIALOG_USER_ENABLE_CALLING_AND_SMS;
+ case DIALOG_SETUP_USER:
+ return SettingsEnums.DIALOG_USER_SETUP;
default:
return 0;
}
@@ -160,6 +172,13 @@
case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS:
return UserDialogs.createEnablePhoneCallsAndSmsDialog(getActivity(),
(dialog, which) -> enableCallsAndSms(true));
+ case DIALOG_SETUP_USER:
+ return UserDialogs.createSetupUserDialog(getActivity(),
+ (dialog, which) -> {
+ if (canSwitchUserNow()) {
+ switchUser();
+ }
+ });
}
throw new IllegalArgumentException("Unsupported dialogId " + dialogId);
}
@@ -188,7 +207,14 @@
mSwitchUserPref.setTitle(
context.getString(com.android.settingslib.R.string.user_switch_to_user,
mUserInfo.name));
- mSwitchUserPref.setOnPreferenceClickListener(this);
+
+ if (mUserCaps.mDisallowSwitchUser) {
+ mSwitchUserPref.setDisabledByAdmin(RestrictedLockUtilsInternal.getDeviceOwner(context));
+ } else {
+ mSwitchUserPref.setDisabledByAdmin(null);
+ mSwitchUserPref.setSelectable(true);
+ mSwitchUserPref.setOnPreferenceClickListener(this);
+ }
if (!mUserManager.isAdminUser()) { // non admin users can't remove users and allow calls
removePreference(KEY_ENABLE_TELEPHONY);
@@ -321,4 +347,16 @@
.setSourceMetricsCategory(getMetricsCategory())
.launch();
}
+
+ private boolean isSecondaryUser(UserInfo user) {
+ return UserManager.USER_TYPE_FULL_SECONDARY.equals(user.userType);
+ }
+
+ private boolean shouldShowSetupPromptDialog() {
+ // TODO: FLAG_INITIALIZED is set when a user is switched to for the first time,
+ // but what we would really need here is a flag that shows if the setup process was
+ // completed. After the user cancels the setup process, mUserInfo.isInitialized() will
+ // return true so there will be no setup prompt dialog shown to the user anymore.
+ return isSecondaryUser(mUserInfo) && !mUserInfo.isInitialized();
+ }
}
diff --git a/src/com/android/settings/users/UserDialogs.java b/src/com/android/settings/users/UserDialogs.java
index 2361e44..0fb9636 100644
--- a/src/com/android/settings/users/UserDialogs.java
+++ b/src/com/android/settings/users/UserDialogs.java
@@ -138,4 +138,21 @@
.setNegativeButton(android.R.string.cancel, null)
.create();
}
+
+ /**
+ * Creates a dialog to confirm that the user is ok to start setting up a new user.
+ *
+ * @param onConfirmListener Callback object for positive action
+ */
+ public static Dialog createSetupUserDialog(Context context,
+ DialogInterface.OnClickListener onConfirmListener) {
+ return new AlertDialog.Builder(context)
+ .setTitle(com.android.settingslib.R.string.user_setup_dialog_title)
+ .setMessage(com.android.settingslib.R.string.user_setup_dialog_message)
+ .setPositiveButton(com.android.settingslib.R.string.user_setup_button_setup_now,
+ onConfirmListener)
+ .setNegativeButton(com.android.settingslib.R.string.user_setup_button_setup_later,
+ null)
+ .create();
+ }
}
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 719ed4a..910917a 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -102,8 +102,6 @@
/** UserId of the user being removed */
private static final String SAVE_REMOVING_USER = "removing_user";
- /** UserId of the user that was just added */
- private static final String SAVE_ADDING_USER = "adding_user";
private static final String KEY_USER_LIST = "user_list";
private static final String KEY_USER_ME = "user_me";
@@ -119,8 +117,7 @@
private static final int DIALOG_CONFIRM_REMOVE = 1;
private static final int DIALOG_ADD_USER = 2;
- private static final int DIALOG_SETUP_USER = 3;
- private static final int DIALOG_SETUP_PROFILE = 4;
+ // Dialogs with id 3 and 4 got removed
private static final int DIALOG_USER_CANNOT_MANAGE = 5;
private static final int DIALOG_CHOOSE_USER_TYPE = 6;
private static final int DIALOG_NEED_LOCKSCREEN = 7;
@@ -130,8 +127,7 @@
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;
- private static final int MESSAGE_CONFIG_USER = 3;
+ private static final int MESSAGE_USER_CREATED = 2;
private static final int USER_TYPE_USER = 1;
private static final int USER_TYPE_RESTRICTED_PROFILE = 2;
@@ -160,7 +156,6 @@
@VisibleForTesting
SparseArray<Bitmap> mUserIcons = new SparseArray<>();
private int mRemovingUserId = -1;
- private int mAddedUserId = 0;
private boolean mAddingUser;
private String mAddingUserName;
private UserCapabilities mUserCaps;
@@ -187,12 +182,9 @@
case MESSAGE_UPDATE_LIST:
updateUserList();
break;
- case MESSAGE_SETUP_USER:
+ case MESSAGE_USER_CREATED:
onUserCreated(msg.arg1);
break;
- case MESSAGE_CONFIG_USER:
- onManageUserClicked(msg.arg1, true);
- break;
}
}
};
@@ -254,9 +246,6 @@
.setOnPreferenceChangeListener(mAddUserWhenLockedPreferenceController);
if (icicle != null) {
- if (icicle.containsKey(SAVE_ADDING_USER)) {
- mAddedUserId = icicle.getInt(SAVE_ADDING_USER);
- }
if (icicle.containsKey(SAVE_REMOVING_USER)) {
mRemovingUserId = icicle.getInt(SAVE_REMOVING_USER);
}
@@ -334,7 +323,6 @@
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mEditUserInfoController.onSaveInstanceState(outState);
- outState.putInt(SAVE_ADDING_USER, mAddedUserId);
outState.putInt(SAVE_REMOVING_USER, mRemovingUserId);
}
@@ -482,37 +470,22 @@
}
}
- private void onManageUserClicked(int userId, boolean newUser) {
+ private void onUserCreated(int userId) {
mAddingUser = false;
UserInfo userInfo = mUserManager.getUserInfo(userId);
- if (userId == UserHandle.myUserId()) {
- // Jump to owner info panel
- OwnerInfoSettings.show(this);
- } else {
- Bundle extras = new Bundle();
- extras.putInt(UserDetailsSettings.EXTRA_USER_ID, userId);
- extras.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, newUser);
- new SubSettingLauncher(getContext())
- .setDestination(UserDetailsSettings.class.getName())
- .setArguments(extras)
- .setTitleText(userInfo.name)
- .setSourceMetricsCategory(getMetricsCategory())
- .launch();
- }
+ openUserDetails(userInfo, true);
}
- private void onUserCreated(int userId) {
- mAddedUserId = userId;
- mAddingUser = false;
- if (!isResumed()) {
- Log.w(TAG, "Cannot show dialog after onPause");
- return;
- }
- if (mUserManager.getUserInfo(userId).isRestricted()) {
- showDialog(DIALOG_SETUP_PROFILE);
- } else {
- showDialog(DIALOG_SETUP_USER);
- }
+ private void openUserDetails(UserInfo userInfo, boolean newUser) {
+ Bundle extras = new Bundle();
+ extras.putInt(UserDetailsSettings.EXTRA_USER_ID, userInfo.id);
+ extras.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, newUser);
+ new SubSettingLauncher(getContext())
+ .setDestination(UserDetailsSettings.class.getName())
+ .setArguments(extras)
+ .setTitleText(userInfo.name)
+ .setSourceMetricsCategory(getMetricsCategory())
+ .launch();
}
@Override
@@ -571,37 +544,6 @@
.create();
return dlg;
}
- case DIALOG_SETUP_USER: {
- Dialog dlg = new AlertDialog.Builder(context)
- .setTitle(com.android.settingslib.R.string.user_setup_dialog_title)
- .setMessage(com.android.settingslib.R.string.user_setup_dialog_message)
- .setPositiveButton(
- com.android.settingslib.R.string.user_setup_button_setup_now,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- switchUserNow(mAddedUserId);
- }
- })
- .setNegativeButton(
- com.android.settingslib.R.string.user_setup_button_setup_later,
- null)
- .create();
- return dlg;
- }
- case DIALOG_SETUP_PROFILE: {
- Dialog dlg = new AlertDialog.Builder(context)
- .setMessage(
- com.android.settingslib.R.string.user_setup_profile_dialog_message)
- .setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- switchUserNow(mAddedUserId);
- }
- })
- .setNegativeButton(android.R.string.cancel, null)
- .create();
- return dlg;
- }
case DIALOG_CHOOSE_USER_TYPE: {
List<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();
HashMap<String, String> addUserItem = new HashMap<String, String>();
@@ -764,10 +706,6 @@
return SettingsEnums.DIALOG_USER_CANNOT_MANAGE;
case DIALOG_ADD_USER:
return SettingsEnums.DIALOG_USER_ADD;
- case DIALOG_SETUP_USER:
- return SettingsEnums.DIALOG_USER_SETUP;
- case DIALOG_SETUP_PROFILE:
- return SettingsEnums.DIALOG_USER_SETUP_PROFILE;
case DIALOG_CHOOSE_USER_TYPE:
return SettingsEnums.DIALOG_USER_CHOOSE_TYPE;
case DIALOG_NEED_LOCKSCREEN:
@@ -853,16 +791,11 @@
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 {
- mHandler.sendMessage(mHandler.obtainMessage(
- MESSAGE_CONFIG_USER, user.id, user.serialNumber));
}
+
+ mHandler.sendMessage(mHandler.obtainMessage(
+ MESSAGE_USER_CREATED, user.id, user.serialNumber));
+
mPendingUserIcon = null;
mPendingUserName = null;
}
@@ -870,18 +803,6 @@
});
}
- private void switchUserNow(int userId) {
- if (!canSwitchUserNow()) {
- return;
- }
-
- try {
- ActivityManager.getService().switchUser(userId);
- } catch (RemoteException re) {
- Log.e(TAG, "Error while switching to other user.");
- }
- }
-
/**
* Erase the current user (guest) and switch to another user.
*/
@@ -1125,21 +1046,14 @@
if (pref == mMePreference) {
if (isCurrentUserGuest()) {
showDialog(DIALOG_CONFIRM_EXIT_GUEST);
- return true;
- }
- showDialog(DIALOG_USER_PROFILE_EDITOR);
- } else if (pref instanceof UserPreference) {
- int userId = ((UserPreference) pref).getUserId();
- // Get the latest status of the user
- UserInfo user = mUserManager.getUserInfo(userId);
- if (!user.isInitialized() && isSecondaryUser(user)) {
- // for uninitialized secondary users we should show a prompt dialog before
- // starting the setup
- mHandler.sendMessage(mHandler.obtainMessage(
- MESSAGE_SETUP_USER, user.id, user.serialNumber));
} else {
- onManageUserClicked(userId, false);
+ showDialog(DIALOG_USER_PROFILE_EDITOR);
}
+ return true;
+ } else if (pref instanceof UserPreference) {
+ UserInfo userInfo = mUserManager.getUserInfo(((UserPreference) pref).getUserId());
+ openUserDetails(userInfo, false);
+ return true;
} else if (pref == mAddUser) {
// If we allow both types, show a picker, otherwise directly go to
// flow for full user.
@@ -1148,10 +1062,12 @@
} else {
onAddUserClicked(USER_TYPE_USER);
}
+ return true;
} else if (pref == mAddGuest) {
UserInfo guest = mUserManager.createGuest(
getContext(), getString(com.android.settingslib.R.string.user_guest));
- switchUserNow(guest.id);
+ openUserDetails(guest, true);
+ return true;
}
return false;
}
@@ -1265,8 +1181,4 @@
return niks;
}
};
-
- private boolean isSecondaryUser(UserInfo user) {
- return UserManager.USER_TYPE_FULL_SECONDARY.equals(user.userType);
- }
}
diff --git a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
index 56e4957..90c9172 100644
--- a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
@@ -34,6 +34,7 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.robolectric.Shadows.shadowOf;
+import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -53,6 +54,8 @@
import com.android.settings.SubSettings;
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
import com.android.settings.testutils.shadow.ShadowUserManager;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedPreference;
import org.junit.After;
import org.junit.Before;
@@ -91,7 +94,7 @@
private ShadowUserManager mUserManager;
@Mock
- private Preference mSwitchUserPref;
+ private RestrictedPreference mSwitchUserPref;
@Mock
private SwitchPreference mPhonePref;
@Mock
@@ -101,6 +104,7 @@
private FragmentActivity mActivity;
private Context mContext;
+ private UserCapabilities mUserCapabilities;
private UserDetailsSettings mFragment;
private Bundle mArguments;
private UserInfo mUserInfo;
@@ -111,6 +115,8 @@
mActivity = spy(ActivityController.of(new FragmentActivity()).get());
mContext = spy(RuntimeEnvironment.application);
+ mUserCapabilities = UserCapabilities.create(mContext);
+ mUserCapabilities.mUserSwitcherEnabled = true;
mFragment = spy(new UserDetailsSettings());
mArguments = new Bundle();
@@ -121,6 +127,7 @@
doReturn(mTelephonyManager).when(mActivity).getSystemService(Context.TELEPHONY_SERVICE);
ReflectionHelpers.setField(mFragment, "mUserManager", userManager);
+ ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities);
doReturn(mActivity).when(mFragment).getActivity();
doReturn(mActivity).when(mFragment).getContext();
@@ -427,6 +434,33 @@
}
@Test
+ public void initialize_switchUserDisallowed_shouldSetAdminDisabledOnSwitchPreference() {
+ setupSelectedUser();
+ mUserCapabilities.mDisallowSwitchUser = true;
+ DevicePolicyManager devicePolicyManager = mock(DevicePolicyManager.class);
+ doReturn(devicePolicyManager).when(mActivity)
+ .getSystemService(Context.DEVICE_POLICY_SERVICE);
+ doReturn(mock(ComponentName.class)).when(devicePolicyManager)
+ .getDeviceOwnerComponentOnAnyUser();
+
+ mFragment.initialize(mActivity, mArguments);
+
+ verify(mSwitchUserPref).setDisabledByAdmin(any(RestrictedLockUtils.EnforcedAdmin.class));
+ }
+
+ @Test
+ public void initialize_switchUserAllowed_shouldSetSwitchPreferenceEnabled() {
+ setupSelectedUser();
+ mUserCapabilities.mDisallowSwitchUser = false;
+
+ mFragment.initialize(mActivity, mArguments);
+
+ verify(mSwitchUserPref).setDisabledByAdmin(null);
+ verify(mSwitchUserPref).setSelectable(true);
+ verify(mSwitchUserPref).setOnPreferenceClickListener(mFragment);
+ }
+
+ @Test
public void onPreferenceClick_switchClicked_canSwitch_shouldSwitch() {
setupSelectedUser();
mUserManager.setSwitchabilityStatus(SWITCHABILITY_STATUS_OK);
diff --git a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
index 3104c3c..2057788 100644
--- a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
@@ -33,13 +33,16 @@
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.robolectric.Shadows.shadowOf;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.UserInfo;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -53,6 +56,8 @@
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
+import com.android.settings.SettingsActivity;
+import com.android.settings.SubSettings;
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.RestrictedLockUtils;
@@ -70,6 +75,7 @@
import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowIntent;
import org.robolectric.util.ReflectionHelpers;
import java.util.Arrays;
@@ -590,6 +596,30 @@
}
@Test
+ public void onPreferenceClick_addGuestClicked_createGuestAndOpenDetails() {
+ UserInfo createdGuest = getGuest(false);
+ removeFlag(createdGuest, UserInfo.FLAG_INITIALIZED);
+ doReturn(createdGuest).when(mUserManager).createGuest(mActivity, "Guest");
+ doReturn(mActivity).when(mFragment).getContext();
+
+ mFragment.onPreferenceClick(mAddGuestPreference);
+
+ verify(mUserManager).createGuest(mActivity, "Guest");
+ Intent startedIntent = shadowOf(mActivity).getNextStartedActivity();
+ ShadowIntent shadowIntent = shadowOf(startedIntent);
+ assertThat(shadowIntent.getIntentClass()).isEqualTo(SubSettings.class);
+ assertThat(startedIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
+ .isEqualTo(UserDetailsSettings.class.getName());
+ Bundle arguments = startedIntent.getBundleExtra(
+ SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
+ assertThat(arguments).isNotNull();
+ assertThat(arguments.getInt(UserDetailsSettings.EXTRA_USER_ID, 0))
+ .isEqualTo(createdGuest.id);
+ assertThat(arguments.getBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, false))
+ .isEqualTo(true);
+ }
+
+ @Test
public void getRealUsersCount_onlyAdmin_shouldCount() {
givenUsers(getAdminUser(true));