1 /* 2 * Copyright (C) 2014 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 static android.os.UserHandle.USER_NULL; 20 21 import android.app.ActivityManager; 22 import android.app.Dialog; 23 import android.app.settings.SettingsEnums; 24 import android.content.Context; 25 import android.content.pm.UserInfo; 26 import android.os.Bundle; 27 import android.os.RemoteException; 28 import android.os.Trace; 29 import android.os.UserHandle; 30 import android.os.UserManager; 31 import android.util.Log; 32 33 import androidx.annotation.VisibleForTesting; 34 import androidx.preference.Preference; 35 import androidx.preference.TwoStatePreference; 36 37 import com.android.settings.R; 38 import com.android.settings.SettingsPreferenceFragment; 39 import com.android.settings.Utils; 40 import com.android.settings.core.SubSettingLauncher; 41 import com.android.settingslib.RestrictedLockUtils; 42 import com.android.settingslib.RestrictedLockUtilsInternal; 43 import com.android.settingslib.RestrictedPreference; 44 import com.android.settingslib.utils.CustomDialogHelper; 45 46 import java.util.concurrent.ExecutorService; 47 import java.util.concurrent.Executors; 48 import java.util.concurrent.atomic.AtomicBoolean; 49 50 /** 51 * Settings screen for configuring, deleting or switching to a specific user. 52 * It is shown when you tap on a user in the user management (UserSettings) screen. 53 * 54 * Arguments to this fragment must include the userId of the user (in EXTRA_USER_ID) for whom 55 * to display controls. 56 */ 57 public class UserDetailsSettings extends SettingsPreferenceFragment 58 implements Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener { 59 60 private static final String TAG = UserDetailsSettings.class.getSimpleName(); 61 62 private static final String KEY_SWITCH_USER = "switch_user"; 63 private static final String KEY_ENABLE_TELEPHONY = "enable_calling"; 64 private static final String KEY_REMOVE_USER = "remove_user"; 65 private static final String KEY_GRANT_ADMIN = "user_grant_admin"; 66 private static final String KEY_APP_AND_CONTENT_ACCESS = "app_and_content_access"; 67 private static final String KEY_APP_COPYING = "app_copying"; 68 69 /** Integer extra containing the userId to manage */ 70 static final String EXTRA_USER_ID = "user_id"; 71 72 private static final int DIALOG_CONFIRM_REMOVE = 1; 73 private static final int DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS = 2; 74 private static final int DIALOG_SETUP_USER = 3; 75 private static final int DIALOG_CONFIRM_RESET_GUEST = 4; 76 private static final int DIALOG_CONFIRM_RESET_GUEST_AND_SWITCH_USER = 5; 77 private static final int DIALOG_CONFIRM_REVOKE_ADMIN = 6; 78 private static final int DIALOG_CONFIRM_GRANT_ADMIN = 7; 79 80 /** Whether to enable the app_copying fragment. */ 81 private static final boolean SHOW_APP_COPYING_PREF = false; 82 private static final int MESSAGE_PADDING = 20; 83 84 private UserManager mUserManager; 85 private UserCapabilities mUserCaps; 86 private boolean mGuestUserAutoCreated; 87 private final AtomicBoolean mGuestCreationScheduled = new AtomicBoolean(); 88 private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); 89 90 @VisibleForTesting 91 RestrictedPreference mSwitchUserPref; 92 private TwoStatePreference mPhonePref; 93 @VisibleForTesting 94 Preference mAppAndContentAccessPref; 95 @VisibleForTesting 96 Preference mAppCopyingPref; 97 @VisibleForTesting 98 Preference mRemoveUserPref; 99 @VisibleForTesting 100 TwoStatePreference mGrantAdminPref; 101 102 @VisibleForTesting 103 /** The user being studied (not the user doing the studying). */ 104 UserInfo mUserInfo; 105 106 @Override getMetricsCategory()107 public int getMetricsCategory() { 108 return SettingsEnums.USER_DETAILS; 109 } 110 111 @Override onCreate(Bundle icicle)112 public void onCreate(Bundle icicle) { 113 super.onCreate(icicle); 114 115 final Context context = getActivity(); 116 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 117 mUserCaps = UserCapabilities.create(context); 118 addPreferencesFromResource(R.xml.user_details_settings); 119 120 mGuestUserAutoCreated = getPrefContext().getResources().getBoolean( 121 com.android.internal.R.bool.config_guestUserAutoCreated); 122 123 initialize(context, getArguments()); 124 } 125 126 @Override onResume()127 public void onResume() { 128 super.onResume(); 129 if (android.multiuser.Flags.newMultiuserSettingsUx()) { 130 mSwitchUserPref.setEnabled(canSwitchUserNow() && mUserCaps.mUserSwitcherEnabled); 131 } else { 132 mSwitchUserPref.setEnabled(canSwitchUserNow()); 133 } 134 if (mUserInfo.isGuest() && mGuestUserAutoCreated) { 135 mRemoveUserPref.setEnabled((mUserInfo.flags & UserInfo.FLAG_INITIALIZED) != 0); 136 } 137 } 138 139 @Override onPreferenceClick(Preference preference)140 public boolean onPreferenceClick(Preference preference) { 141 if (preference != null && preference.getKey() != null) { 142 mMetricsFeatureProvider.logSettingsTileClick(preference.getKey(), getMetricsCategory()); 143 } 144 if (preference == mRemoveUserPref) { 145 mMetricsFeatureProvider.action(getActivity(), 146 UserMetricsUtils.getRemoveUserMetricCategory(mUserInfo)); 147 if (canDeleteUser()) { 148 if (mUserInfo.isGuest()) { 149 showDialog(DIALOG_CONFIRM_RESET_GUEST); 150 } else { 151 showDialog(DIALOG_CONFIRM_REMOVE); 152 } 153 return true; 154 } 155 } else if (preference == mSwitchUserPref) { 156 mMetricsFeatureProvider.action(getActivity(), 157 UserMetricsUtils.getSwitchUserMetricCategory(mUserInfo)); 158 if (canSwitchUserNow()) { 159 if (shouldShowSetupPromptDialog()) { 160 showDialog(DIALOG_SETUP_USER); 161 } else if (mUserCaps.mIsGuest && mUserCaps.mIsEphemeral) { 162 // if we are switching away from a ephemeral guest then, 163 // show a dialog that guest user will be reset and then switch 164 // the user 165 showDialog(DIALOG_CONFIRM_RESET_GUEST_AND_SWITCH_USER); 166 } else { 167 switchUser(); 168 } 169 return true; 170 } 171 } else if (preference == mAppAndContentAccessPref) { 172 openAppAndContentAccessScreen(false); 173 return true; 174 } else if (preference == mAppCopyingPref) { 175 openAppCopyingScreen(); 176 return true; 177 } 178 return false; 179 } 180 181 @Override onPreferenceChange(Preference preference, Object newValue)182 public boolean onPreferenceChange(Preference preference, Object newValue) { 183 if (preference == mPhonePref) { 184 if (Boolean.TRUE.equals(newValue)) { 185 mMetricsFeatureProvider.action(getActivity(), 186 SettingsEnums.ACTION_ENABLE_USER_CALL); 187 showDialog(DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS); 188 return false; 189 } 190 mMetricsFeatureProvider.action(getActivity(), 191 SettingsEnums.ACTION_DISABLE_USER_CALL); 192 enableCallsAndSms(false); 193 } else if (preference == mGrantAdminPref) { 194 if (Boolean.FALSE.equals(newValue)) { 195 mMetricsFeatureProvider.action(getActivity(), 196 SettingsEnums.ACTION_REVOKE_ADMIN_FROM_SETTINGS); 197 showDialog(DIALOG_CONFIRM_REVOKE_ADMIN); 198 } else { 199 mMetricsFeatureProvider.action(getActivity(), 200 SettingsEnums.ACTION_GRANT_ADMIN_FROM_SETTINGS); 201 showDialog(DIALOG_CONFIRM_GRANT_ADMIN); 202 } 203 return false; 204 } 205 return true; 206 } 207 208 @Override getDialogMetricsCategory(int dialogId)209 public int getDialogMetricsCategory(int dialogId) { 210 switch (dialogId) { 211 case DIALOG_CONFIRM_REMOVE: 212 case DIALOG_CONFIRM_RESET_GUEST: 213 case DIALOG_CONFIRM_RESET_GUEST_AND_SWITCH_USER: 214 return SettingsEnums.DIALOG_USER_REMOVE; 215 case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS: 216 return SettingsEnums.DIALOG_USER_ENABLE_CALLING_AND_SMS; 217 case DIALOG_CONFIRM_REVOKE_ADMIN: 218 return SettingsEnums.DIALOG_REVOKE_USER_ADMIN; 219 case DIALOG_CONFIRM_GRANT_ADMIN: 220 return SettingsEnums.DIALOG_GRANT_USER_ADMIN; 221 case DIALOG_SETUP_USER: 222 return SettingsEnums.DIALOG_USER_SETUP; 223 default: 224 return 0; 225 } 226 } 227 228 @Override onCreateDialog(int dialogId)229 public Dialog onCreateDialog(int dialogId) { 230 Context context = getActivity(); 231 if (context == null) { 232 return null; 233 } 234 switch (dialogId) { 235 case DIALOG_CONFIRM_REMOVE: 236 return UserDialogs.createRemoveDialog(getActivity(), mUserInfo.id, 237 (dialog, which) -> removeUser()); 238 case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS: 239 return UserDialogs.createEnablePhoneCallsAndSmsDialog(getActivity(), 240 (dialog, which) -> enableCallsAndSms(true)); 241 case DIALOG_SETUP_USER: 242 return UserDialogs.createSetupUserDialog(getActivity(), 243 (dialog, which) -> { 244 if (canSwitchUserNow()) { 245 switchUser(); 246 } 247 }); 248 case DIALOG_CONFIRM_RESET_GUEST: 249 if (mGuestUserAutoCreated) { 250 return UserDialogs.createResetGuestDialog(getActivity(), 251 (dialog, which) -> resetGuest()); 252 } else { 253 return UserDialogs.createRemoveGuestDialog(getActivity(), 254 (dialog, which) -> resetGuest()); 255 } 256 case DIALOG_CONFIRM_RESET_GUEST_AND_SWITCH_USER: 257 if (mGuestUserAutoCreated) { 258 return UserDialogs.createResetGuestDialog(getActivity(), 259 (dialog, which) -> switchUser()); 260 } else { 261 return UserDialogs.createRemoveGuestDialog(getActivity(), 262 (dialog, which) -> switchUser()); 263 } 264 case DIALOG_CONFIRM_REVOKE_ADMIN: 265 return createRevokeAdminDialog(getContext()); 266 case DIALOG_CONFIRM_GRANT_ADMIN: 267 return createGrantAdminDialog(getContext()); 268 } 269 throw new IllegalArgumentException("Unsupported dialogId " + dialogId); 270 } 271 272 /** 273 * Creates dialog to confirm revoking admin rights. 274 * @return created confirmation dialog 275 */ 276 private Dialog createRevokeAdminDialog(Context context) { 277 CustomDialogHelper dialogHelper = new CustomDialogHelper(context); 278 dialogHelper.setIcon( 279 context.getDrawable(com.android.settingslib.R.drawable.ic_admin_panel_settings)); 280 dialogHelper.setTitle(R.string.user_revoke_admin_confirm_title); 281 dialogHelper.setMessage(R.string.user_revoke_admin_confirm_message); 282 dialogHelper.setMessagePadding(MESSAGE_PADDING); 283 dialogHelper.setPositiveButton(R.string.remove, view -> { 284 updateUserAdminStatus(false); 285 dialogHelper.getDialog().dismiss(); 286 }); 287 dialogHelper.setBackButton(R.string.cancel, view -> { 288 dialogHelper.getDialog().dismiss(); 289 }); 290 return dialogHelper.getDialog(); 291 } 292 293 /** 294 * Creates dialog to confirm granting admin rights. 295 * @return created confirmation dialog 296 */ 297 private Dialog createGrantAdminDialog(Context context) { 298 CustomDialogHelper dialogHelper = new CustomDialogHelper(context); 299 dialogHelper.setIcon( 300 context.getDrawable(com.android.settingslib.R.drawable.ic_admin_panel_settings)); 301 dialogHelper.setTitle(com.android.settingslib.R.string.user_grant_admin_title); 302 dialogHelper.setMessage(com.android.settingslib.R.string.user_grant_admin_message); 303 dialogHelper.setMessagePadding(MESSAGE_PADDING); 304 dialogHelper.setPositiveButton(com.android.settingslib.R.string.user_grant_admin_button, 305 view -> { 306 updateUserAdminStatus(true); 307 dialogHelper.getDialog().dismiss(); 308 }); 309 dialogHelper.setBackButton(R.string.cancel, view -> { 310 dialogHelper.getDialog().dismiss(); 311 }); 312 return dialogHelper.getDialog(); 313 } 314 315 /** 316 * Erase the current guest user and create a new one in the background. UserSettings will 317 * handle guest creation after receiving the {@link UserSettings.RESULT_GUEST_REMOVED} result. 318 */ 319 private void resetGuest() { 320 // Just to be safe, check that the selected user is a guest 321 if (!mUserInfo.isGuest()) { 322 return; 323 } 324 mMetricsFeatureProvider.action(getActivity(), 325 SettingsEnums.ACTION_USER_GUEST_EXIT_CONFIRMED); 326 327 mUserManager.removeUser(mUserInfo.id); 328 setResult(UserSettings.RESULT_GUEST_REMOVED); 329 finishFragment(); 330 } 331 332 @VisibleForTesting 333 @Override 334 protected void showDialog(int dialogId) { 335 super.showDialog(dialogId); 336 } 337 338 @VisibleForTesting 339 void initialize(Context context, Bundle arguments) { 340 int userId = arguments != null ? arguments.getInt(EXTRA_USER_ID, USER_NULL) : USER_NULL; 341 if (userId == USER_NULL) { 342 throw new IllegalStateException("Arguments to this fragment must contain the user id"); 343 } 344 boolean isNewUser = 345 arguments.getBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, false); 346 mUserInfo = mUserManager.getUserInfo(userId); 347 348 mSwitchUserPref = findPreference(KEY_SWITCH_USER); 349 mPhonePref = findPreference(KEY_ENABLE_TELEPHONY); 350 mRemoveUserPref = findPreference(KEY_REMOVE_USER); 351 mAppAndContentAccessPref = findPreference(KEY_APP_AND_CONTENT_ACCESS); 352 mAppCopyingPref = findPreference(KEY_APP_COPYING); 353 mGrantAdminPref = findPreference(KEY_GRANT_ADMIN); 354 355 mGrantAdminPref.setChecked(mUserInfo.isAdmin()); 356 357 mSwitchUserPref.setVisible(mUserCaps.mUserSwitchingUiEnabled); 358 359 mSwitchUserPref.setTitle( 360 context.getString(com.android.settingslib.R.string.user_switch_to_user, 361 mUserInfo.name)); 362 363 if (mUserCaps.mDisallowSwitchUser) { 364 mSwitchUserPref.setDisabledByAdmin(RestrictedLockUtilsInternal.getDeviceOwner(context)); 365 } else { 366 mSwitchUserPref.setDisabledByAdmin(null); 367 if (android.multiuser.Flags.newMultiuserSettingsUx()) { 368 mSwitchUserPref.setEnabled(mUserCaps.mUserSwitcherEnabled); 369 mSwitchUserPref.setSelectable(mUserCaps.mUserSwitcherEnabled); 370 } else { 371 mSwitchUserPref.setSelectable(true); 372 } 373 mSwitchUserPref.setOnPreferenceClickListener(this); 374 } 375 if (android.multiuser.Flags.unicornModeRefactoringForHsumReadOnly()) { 376 if (isChangingAdminStatusRestricted()) { 377 removePreference(KEY_GRANT_ADMIN); 378 } 379 } else { 380 if (mUserInfo.isMain() || mUserInfo.isGuest() || !UserManager.isMultipleAdminEnabled() 381 || mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_GRANT_ADMIN, 382 mUserInfo.getUserHandle()) || !mUserManager.isAdminUser()) { 383 removePreference(KEY_GRANT_ADMIN); 384 } 385 } 386 387 if (!mUserManager.isAdminUser()) { // non admin users can't remove users and allow calls 388 removePreference(KEY_ENABLE_TELEPHONY); 389 removePreference(KEY_REMOVE_USER); 390 removePreference(KEY_APP_AND_CONTENT_ACCESS); 391 removePreference(KEY_APP_COPYING); 392 } else { 393 if (!Utils.isVoiceCapable(context)) { // no telephony 394 removePreference(KEY_ENABLE_TELEPHONY); 395 } 396 if (mUserInfo.isMain() || UserManager.isHeadlessSystemUserMode()) { 397 removePreference(KEY_ENABLE_TELEPHONY); 398 } 399 if (mUserInfo.isRestricted()) { 400 removePreference(KEY_ENABLE_TELEPHONY); 401 if (isNewUser) { 402 // for newly created restricted users we should open the apps and content access 403 // screen to initialize the default restrictions 404 openAppAndContentAccessScreen(true); 405 } 406 } else { 407 removePreference(KEY_APP_AND_CONTENT_ACCESS); 408 } 409 410 if (mUserInfo.isGuest()) { 411 removePreference(KEY_ENABLE_TELEPHONY); 412 mRemoveUserPref.setTitle(mGuestUserAutoCreated 413 ? com.android.settingslib.R.string.guest_reset_guest 414 : com.android.settingslib.R.string.guest_exit_guest); 415 if (mGuestUserAutoCreated) { 416 mRemoveUserPref.setEnabled((mUserInfo.flags & UserInfo.FLAG_INITIALIZED) != 0); 417 } 418 if (!SHOW_APP_COPYING_PREF) { 419 removePreference(KEY_APP_COPYING); 420 } 421 } else { 422 mPhonePref.setChecked(!mUserManager.hasUserRestriction( 423 UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId))); 424 mRemoveUserPref.setTitle(R.string.user_remove_user); 425 removePreference(KEY_APP_COPYING); 426 } 427 428 // Remove preference KEY_REMOVE_USER if DISALLOW_REMOVE_USER restriction is set 429 // on the current user or the user selected in user details settings is a main user. 430 if (RestrictedLockUtilsInternal.hasBaseUserRestriction(context, 431 UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId()) 432 || mUserInfo.isMain()) { 433 removePreference(KEY_REMOVE_USER); 434 } 435 436 mRemoveUserPref.setOnPreferenceClickListener(this); 437 mPhonePref.setOnPreferenceChangeListener(this); 438 mGrantAdminPref.setOnPreferenceChangeListener(this); 439 mAppAndContentAccessPref.setOnPreferenceClickListener(this); 440 mAppCopyingPref.setOnPreferenceClickListener(this); 441 } 442 } 443 444 @VisibleForTesting 445 boolean canDeleteUser() { 446 if (!mUserManager.isAdminUser() || mUserInfo.isMain()) { 447 return false; 448 } 449 450 Context context = getActivity(); 451 if (context == null) { 452 return false; 453 } 454 455 final RestrictedLockUtils.EnforcedAdmin removeDisallowedAdmin = 456 RestrictedLockUtilsInternal.checkIfRestrictionEnforced(context, 457 UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId()); 458 if (removeDisallowedAdmin != null) { 459 RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, 460 removeDisallowedAdmin); 461 return false; 462 } 463 return true; 464 } 465 466 @VisibleForTesting 467 boolean canSwitchUserNow() { 468 return mUserManager.getUserSwitchability() == UserManager.SWITCHABILITY_STATUS_OK; 469 } 470 471 @VisibleForTesting 472 void switchUser() { 473 Trace.beginSection("UserDetailSettings.switchUser"); 474 try { 475 if (mUserCaps.mIsGuest && mUserCaps.mIsEphemeral) { 476 int guestUserId = UserHandle.myUserId(); 477 // Using markGuestForDeletion allows us to create a new guest before this one is 478 // fully removed. 479 boolean marked = mUserManager.markGuestForDeletion(guestUserId); 480 if (!marked) { 481 Log.w(TAG, "Couldn't mark the guest for deletion for user " + guestUserId); 482 return; 483 } 484 } 485 ActivityManager.getService().switchUser(mUserInfo.id); 486 } catch (RemoteException re) { 487 Log.e(TAG, "Error while switching to other user."); 488 } finally { 489 Trace.endSection(); 490 finishFragment(); 491 } 492 } 493 494 private void enableCallsAndSms(boolean enabled) { 495 mPhonePref.setChecked(enabled); 496 int[] userProfiles = mUserManager.getProfileIdsWithDisabled(mUserInfo.id); 497 for (int userId : userProfiles) { 498 UserHandle user = UserHandle.of(userId); 499 mUserManager.setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, !enabled, user); 500 mUserManager.setUserRestriction(UserManager.DISALLOW_SMS, !enabled, user); 501 } 502 } 503 504 /** 505 * Sets admin status of selected user. Method is called when toggle in 506 * user details settings is switched. 507 * @param isSetAdmin indicates if user admin status needs to be set to true. 508 */ 509 private void updateUserAdminStatus(boolean isSetAdmin) { 510 mGrantAdminPref.setChecked(isSetAdmin); 511 if (!isSetAdmin) { 512 mUserManager.revokeUserAdmin(mUserInfo.id); 513 } else if ((mUserInfo.flags & UserInfo.FLAG_ADMIN) == 0) { 514 mUserManager.setUserAdmin(mUserInfo.id); 515 } 516 } 517 518 private void removeUser() { 519 mUserManager.removeUser(mUserInfo.id); 520 finishFragment(); 521 } 522 523 /** 524 * @param isNewUser indicates if a user was created recently, for new users 525 * AppRestrictionsFragment should set the default restrictions 526 */ 527 private void openAppAndContentAccessScreen(boolean isNewUser) { 528 Bundle extras = new Bundle(); 529 extras.putInt(AppRestrictionsFragment.EXTRA_USER_ID, mUserInfo.id); 530 extras.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, isNewUser); 531 new SubSettingLauncher(getContext()) 532 .setDestination(AppRestrictionsFragment.class.getName()) 533 .setArguments(extras) 534 .setTitleRes(R.string.user_restrictions_title) 535 .setSourceMetricsCategory(getMetricsCategory()) 536 .launch(); 537 } 538 539 private void openAppCopyingScreen() { 540 if (!SHOW_APP_COPYING_PREF) { 541 return; 542 } 543 final Bundle extras = new Bundle(); 544 extras.putInt(AppRestrictionsFragment.EXTRA_USER_ID, mUserInfo.id); 545 new SubSettingLauncher(getContext()) 546 .setDestination(AppCopyFragment.class.getName()) 547 .setArguments(extras) 548 .setTitleRes(R.string.user_copy_apps_menu_title) 549 .setSourceMetricsCategory(getMetricsCategory()) 550 .launch(); 551 } 552 553 private boolean isSecondaryUser(UserInfo user) { 554 return UserManager.USER_TYPE_FULL_SECONDARY.equals(user.userType); 555 } 556 557 private boolean shouldShowSetupPromptDialog() { 558 // TODO: FLAG_INITIALIZED is set when a user is switched to for the first time, 559 // but what we would really need here is a flag that shows if the setup process was 560 // completed. After the user cancels the setup process, mUserInfo.isInitialized() will 561 // return true so there will be no setup prompt dialog shown to the user anymore. 562 return isSecondaryUser(mUserInfo) && !mUserInfo.isInitialized(); 563 } 564 565 /** 566 * Determines if changing admin status is restricted. 567 * 568 * <p>Admin status change is restricted under the following conditions of current & target user. 569 * 570 * <ul> 571 * <li>The <b>current</b> user is NOT an admin user.</li> 572 * <li>OR multiple admin support is NOT enabled.</li> 573 * <li>OR the <b>current</b> user has DISALLOW_GRANT_ADMIN restriction applied</li> 574 * 575 * <li>OR the <b>target</b> user ('mUserInfo') is a main user</li> 576 * <li>OR the <b>target</b> user ('mUserInfo') is not of type 577 * {@link UserManager#USER_TYPE_FULL_SECONDARY}</li> 578 * <li>OR the <b>target</b> user ('mUserInfo') has DISALLOW_GRANT_ADMIN restriction.</li> 579 * </ul> 580 * 581 * @return true if changing admin status is restricted, false otherwise 582 */ 583 private boolean isChangingAdminStatusRestricted() { 584 boolean currentUserRestricted = !mUserManager.isAdminUser() 585 || !UserManager.isMultipleAdminEnabled() 586 || mUserManager.hasUserRestriction(UserManager.DISALLOW_GRANT_ADMIN); 587 588 boolean targetUserRestricted = mUserInfo.isMain() 589 || !(UserManager.USER_TYPE_FULL_SECONDARY.equals(mUserInfo.userType)) 590 || mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_GRANT_ADMIN, 591 mUserInfo.getUserHandle()); 592 593 return currentUserRestricted || targetUserRestricted; 594 } 595 } 596