diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index e1d15defad381..125bdaf07b908 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -74,6 +74,7 @@ interface IUserManager { String getUserAccount(int userId); void setUserAccount(int userId, String accountName); long getUserCreationTime(int userId); + int getUserSwitchability(int userId); boolean isUserSwitcherEnabled(int mUserId); boolean isRestricted(int userId); boolean canHaveRestrictedProfile(int userId); diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 414ea83c1132f..aa0ac3187996b 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -58,7 +58,6 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.location.LocationManager; import android.provider.Settings; -import android.telephony.TelephonyManager; import android.util.AndroidException; import android.util.ArraySet; import android.util.Log; @@ -1673,7 +1672,7 @@ public class UserManager { public static final int SWITCHABILITY_STATUS_SYSTEM_USER_LOCKED = 1 << 2; /** - * Result returned in {@link #getUserSwitchability()} indicating user swichability. + * Result returned in {@link #getUserSwitchability()} indicating user switchability. * @hide */ @Retention(RetentionPolicy.SOURCE) @@ -2040,25 +2039,16 @@ public class UserManager { * @hide */ @Deprecated - @RequiresPermission(allOf = { - Manifest.permission.READ_PHONE_STATE, - Manifest.permission.MANAGE_USERS}, // Can be INTERACT_ACROSS_USERS instead. - conditional = true) + @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.INTERACT_ACROSS_USERS}) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @UserHandleAware public boolean canSwitchUsers() { - boolean allowUserSwitchingWhenSystemUserLocked = Settings.Global.getInt( - mContext.getContentResolver(), - Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED, 0) != 0; - boolean isSystemUserUnlocked = isUserUnlocked(UserHandle.SYSTEM); - boolean inCall = false; - TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class); - if (telephonyManager != null) { - inCall = telephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE; + try { + return mService.getUserSwitchability(mUserId) == SWITCHABILITY_STATUS_OK; + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); } - boolean isUserSwitchDisallowed = hasUserRestrictionForUser(DISALLOW_USER_SWITCH, mUserId); - return (allowUserSwitchingWhenSystemUserLocked || isSystemUserUnlocked) && !inCall - && !isUserSwitchDisallowed; } /** @@ -2092,34 +2082,14 @@ public class UserManager { * @return A {@link UserSwitchabilityResult} flag indicating if the user is switchable. * @hide */ - @RequiresPermission(allOf = {Manifest.permission.READ_PHONE_STATE, - android.Manifest.permission.MANAGE_USERS, - android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true) + @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.INTERACT_ACROSS_USERS}) public @UserSwitchabilityResult int getUserSwitchability(UserHandle userHandle) { - final TelephonyManager tm = - (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); - - int flags = SWITCHABILITY_STATUS_OK; - if (tm.getCallState() != TelephonyManager.CALL_STATE_IDLE) { - flags |= SWITCHABILITY_STATUS_USER_IN_CALL; + try { + return mService.getUserSwitchability(userHandle.getIdentifier()); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); } - if (hasUserRestrictionForUser(DISALLOW_USER_SWITCH, userHandle)) { - flags |= SWITCHABILITY_STATUS_USER_SWITCH_DISALLOWED; - } - - // System User is always unlocked in Headless System User Mode, so ignore this flag - if (!isHeadlessSystemUserMode()) { - final boolean allowUserSwitchingWhenSystemUserLocked = Settings.Global.getInt( - mContext.getContentResolver(), - Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED, 0) != 0; - final boolean systemUserUnlocked = isUserUnlocked(UserHandle.SYSTEM); - - if (!allowUserSwitchingWhenSystemUserLocked && !systemUserUnlocked) { - flags |= SWITCHABILITY_STATUS_SYSTEM_USER_LOCKED; - } - } - - return flags; } /** diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 00fb0651adc4e..866a995585cde 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -91,6 +91,7 @@ import android.security.GateKeeper; import android.service.gatekeeper.IGateKeeperService; import android.service.voice.VoiceInteractionManagerInternal; import android.stats.devicepolicy.DevicePolicyEnums; +import android.telecom.TelecomManager; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; @@ -1760,6 +1761,63 @@ public class UserManagerService extends IUserManager.Stub { } } + /** + * Returns whether switching users is currently allowed for the provided user. + *
+ * Switching users is not allowed in the following cases: + *