| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.settings.users; |
| |
| import android.app.admin.DevicePolicyIdentifiers; |
| import android.app.admin.DevicePolicyManager; |
| import android.app.admin.PolicyEnforcementInfo; |
| import android.app.admin.flags.Flags; |
| import android.content.Context; |
| import android.content.pm.UserInfo; |
| import android.os.UserHandle; |
| import android.os.UserManager; |
| import android.provider.Settings; |
| |
| import com.android.settings.R; |
| import com.android.settings.Utils; |
| import com.android.settingslib.RestrictedLockUtils; |
| import com.android.settingslib.RestrictedLockUtilsInternal; |
| |
| public class UserCapabilities { |
| boolean mEnabled = true; |
| boolean mCanAddUser = true; |
| boolean mCanAddRestrictedProfile; |
| boolean mIsMain; |
| boolean mIsAdmin; |
| boolean mIsGuest; |
| boolean mIsEphemeral; |
| boolean mUserSwitchingUiEnabled; |
| boolean mUserSwitcherEnabled; |
| boolean mCanAddGuest; |
| boolean mDisallowAddUser; |
| boolean mDisallowAddUserSetByAdmin; |
| boolean mDisallowSwitchUser; |
| // TODO(b/414733570): Remove when cleaning up Flags.policyTransparencyRefactorEnabled() and |
| // all callers are updated to use mDisallowAddUserEnforcementInfo. |
| RestrictedLockUtils.EnforcedAdmin mEnforcedAdmin; |
| // PolicyEnforcementInfo contains the information about user restriction both set by admins |
| // or system entities. |
| PolicyEnforcementInfo mDisallowAddUserRestrictionEnforcementInfo; |
| PolicyEnforcementInfo mDisallowSwitchUserRestrictionEnforcementInfo; |
| |
| private UserCapabilities() { |
| } |
| |
| public static UserCapabilities create(Context context) { |
| UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE); |
| UserCapabilities caps = new UserCapabilities(); |
| |
| if (!UserManager.supportsMultipleUsers() || Utils.isMonkeyRunning()) { |
| caps.mEnabled = false; |
| return caps; |
| } |
| |
| final UserInfo myUserInfo = userManager.getUserInfo(UserHandle.myUserId()); |
| caps.mIsGuest = myUserInfo.isGuest(); |
| caps.mIsAdmin = myUserInfo.isAdmin(); |
| caps.mIsMain = myUserInfo.isMain(); |
| caps.mIsEphemeral = myUserInfo.isEphemeral(); |
| DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( |
| Context.DEVICE_POLICY_SERVICE); |
| |
| boolean offerRestricted = |
| context.getResources().getBoolean(R.bool.config_offer_restricted_profiles); |
| caps.mCanAddRestrictedProfile = |
| offerRestricted && !dpm.isDeviceManaged() && userManager.isUserTypeSupported( |
| UserManager.USER_TYPE_FULL_RESTRICTED); |
| caps.mUserSwitchingUiEnabled = context.getResources().getBoolean( |
| com.android.internal.R.bool.config_allowChangeUserSwitcherEnabled); |
| caps.updateAddUserCapabilities(context); |
| return caps; |
| } |
| |
| public void updateAddUserCapabilities(Context context) { |
| final UserManager userManager = |
| (UserManager) context.getSystemService(Context.USER_SERVICE); |
| final UserInfo myUserInfo = userManager.getUserInfo(UserHandle.myUserId()); |
| mIsAdmin = myUserInfo.isAdmin(); |
| |
| updateAddUserRestriction(context); |
| |
| mUserSwitcherEnabled = userManager.isUserSwitcherEnabled(); |
| mCanAddUser = true; |
| if (!mIsAdmin |
| || !UserManager.supportsMultipleUsers() |
| || mDisallowAddUser |
| || (!userManager.isUserTypeSupported(UserManager.USER_TYPE_FULL_SECONDARY) |
| && !mCanAddRestrictedProfile)) { |
| mCanAddUser = false; |
| } |
| |
| final boolean canAddUsersWhenLocked = mIsAdmin || Settings.Global.getInt( |
| context.getContentResolver(), Settings.Global.ADD_USERS_WHEN_LOCKED, 0) == 1; |
| mCanAddGuest = |
| !mIsGuest |
| && !mDisallowAddUser |
| && canAddUsersWhenLocked |
| && userManager.isUserTypeSupported(UserManager.USER_TYPE_FULL_GUEST) |
| && !isGuestEphemeralAndUnswitchable(context); |
| updateSwitchUserRestriction(context); |
| } |
| |
| public boolean isAdmin() { |
| return mIsAdmin; |
| } |
| |
| public boolean disallowAddUser() { |
| return mDisallowAddUser; |
| } |
| |
| public boolean disallowAddUserSetByAdmin() { |
| return mDisallowAddUserSetByAdmin; |
| } |
| |
| public RestrictedLockUtils.EnforcedAdmin getEnforcedAdmin() { |
| return mEnforcedAdmin; |
| } |
| |
| private boolean isGuestEphemeralAndUnswitchable(Context context) { |
| // If guest users are ephemeral and switching users is not allowed in Settings, creating a |
| // guest user is meaningless since this user is going to be deleted on logout anyways, and |
| // this user cannot be accessed by switching to it. |
| boolean isGuestUserEphemeral = |
| context.getResources() |
| .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral); |
| boolean disallowUserSwitchInSettings = |
| context.getResources() |
| .getBoolean( |
| com.android.internal.R.bool |
| .config_userSwitchingMustGoThroughLoginScreen); |
| return isGuestUserEphemeral && disallowUserSwitchInSettings; |
| } |
| |
| @Override |
| public String toString() { |
| return "UserCapabilities{" + |
| "mEnabled=" + mEnabled + |
| ", mCanAddUser=" + mCanAddUser + |
| ", mCanAddRestrictedProfile=" + mCanAddRestrictedProfile + |
| ", mIsAdmin=" + mIsAdmin + |
| ", mIsGuest=" + mIsGuest + |
| ", mCanAddGuest=" + mCanAddGuest + |
| ", mDisallowAddUser=" + mDisallowAddUser + |
| ", mEnforcedAdmin=" + mEnforcedAdmin + |
| ", mDisallowSwitchUser=" + mDisallowSwitchUser + |
| ", mDisallowAddUserSetByAdmin=" + mDisallowAddUserSetByAdmin + |
| ", mUserSwitchingUiEnabled=" + mUserSwitchingUiEnabled + |
| ", mUserSwitcherEnabled=" + mUserSwitcherEnabled + |
| '}'; |
| } |
| |
| private void updateAddUserRestriction(Context context) { |
| if (Flags.policyTransparencyRefactorEnabled()) { |
| DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class); |
| if (dpm == null) { |
| return; |
| } |
| String identifier = DevicePolicyIdentifiers.getIdentifierForUserRestriction( |
| UserManager.DISALLOW_ADD_USER); |
| PolicyEnforcementInfo policyEnforcementInfo = dpm.getEnforcingAdminsForPolicy( |
| identifier, UserHandle.myUserId()); |
| // policyEnforcementInfo contains both the base restrictions (system enforced) and |
| // admin restrictions. |
| mDisallowAddUser = !policyEnforcementInfo.getAllAdmins().isEmpty(); |
| mDisallowAddUserSetByAdmin = |
| mDisallowAddUser && !policyEnforcementInfo.isOnlyEnforcedBySystem(); |
| mDisallowAddUserRestrictionEnforcementInfo = policyEnforcementInfo; |
| } else { |
| mEnforcedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(context, |
| UserManager.DISALLOW_ADD_USER, UserHandle.myUserId()); |
| final boolean hasBaseUserRestriction = RestrictedLockUtilsInternal.hasBaseUserRestriction( |
| context, UserManager.DISALLOW_ADD_USER, UserHandle.myUserId()); |
| mDisallowAddUserSetByAdmin = mEnforcedAdmin != null && !hasBaseUserRestriction; |
| mDisallowAddUser = (mEnforcedAdmin != null || hasBaseUserRestriction); |
| } |
| } |
| |
| private void updateSwitchUserRestriction(Context context) { |
| if (Flags.policyTransparencyRefactorEnabled()) { |
| DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class); |
| if (dpm == null) { |
| return; |
| } |
| PolicyEnforcementInfo policyEnforcementInfo = dpm.getEnforcingAdminsForPolicy( |
| DevicePolicyIdentifiers.getIdentifierForUserRestriction( |
| UserManager.DISALLOW_USER_SWITCH), UserHandle.myUserId()); |
| mDisallowSwitchUser = !policyEnforcementInfo.getAllAdmins().isEmpty(); |
| mDisallowSwitchUserRestrictionEnforcementInfo = policyEnforcementInfo; |
| } else { |
| UserManager userManager = context.getSystemService(UserManager.class); |
| mDisallowSwitchUser = userManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH); |
| } |
| } |
| } |