• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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