Merge "Move getUserSwitchability from UserManager to UserManagerService." into tm-qpr-dev

This commit is contained in:
Yasin Kilicdere
2023-01-10 17:59:42 +00:00
committed by Android (Google) Code Review
3 changed files with 72 additions and 43 deletions

View File

@@ -74,6 +74,7 @@ interface IUserManager {
String getUserAccount(int userId); String getUserAccount(int userId);
void setUserAccount(int userId, String accountName); void setUserAccount(int userId, String accountName);
long getUserCreationTime(int userId); long getUserCreationTime(int userId);
int getUserSwitchability(int userId);
boolean isUserSwitcherEnabled(int mUserId); boolean isUserSwitcherEnabled(int mUserId);
boolean isRestricted(int userId); boolean isRestricted(int userId);
boolean canHaveRestrictedProfile(int userId); boolean canHaveRestrictedProfile(int userId);

View File

@@ -58,7 +58,6 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.location.LocationManager; import android.location.LocationManager;
import android.provider.Settings; import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.AndroidException; import android.util.AndroidException;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.Log; import android.util.Log;
@@ -1673,7 +1672,7 @@ public class UserManager {
public static final int SWITCHABILITY_STATUS_SYSTEM_USER_LOCKED = 1 << 2; 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 * @hide
*/ */
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@@ -2040,25 +2039,16 @@ public class UserManager {
* @hide * @hide
*/ */
@Deprecated @Deprecated
@RequiresPermission(allOf = { @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.INTERACT_ACROSS_USERS})
Manifest.permission.MANAGE_USERS}, // Can be INTERACT_ACROSS_USERS instead.
conditional = true)
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@UserHandleAware @UserHandleAware
public boolean canSwitchUsers() { public boolean canSwitchUsers() {
boolean allowUserSwitchingWhenSystemUserLocked = Settings.Global.getInt( try {
mContext.getContentResolver(), return mService.getUserSwitchability(mUserId) == SWITCHABILITY_STATUS_OK;
Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED, 0) != 0; } catch (RemoteException re) {
boolean isSystemUserUnlocked = isUserUnlocked(UserHandle.SYSTEM); throw re.rethrowFromSystemServer();
boolean inCall = false;
TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
if (telephonyManager != null) {
inCall = telephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE;
} }
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. * @return A {@link UserSwitchabilityResult} flag indicating if the user is switchable.
* @hide * @hide
*/ */
@RequiresPermission(allOf = {Manifest.permission.READ_PHONE_STATE, @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS})
android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
public @UserSwitchabilityResult int getUserSwitchability(UserHandle userHandle) { public @UserSwitchabilityResult int getUserSwitchability(UserHandle userHandle) {
final TelephonyManager tm = try {
(TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); return mService.getUserSwitchability(userHandle.getIdentifier());
} catch (RemoteException re) {
int flags = SWITCHABILITY_STATUS_OK; throw re.rethrowFromSystemServer();
if (tm.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
flags |= SWITCHABILITY_STATUS_USER_IN_CALL;
} }
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;
} }
/** /**

View File

@@ -91,6 +91,7 @@ import android.security.GateKeeper;
import android.service.gatekeeper.IGateKeeperService; import android.service.gatekeeper.IGateKeeperService;
import android.service.voice.VoiceInteractionManagerInternal; import android.service.voice.VoiceInteractionManagerInternal;
import android.stats.devicepolicy.DevicePolicyEnums; import android.stats.devicepolicy.DevicePolicyEnums;
import android.telecom.TelecomManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.ArraySet; 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.
* <p>
* Switching users is not allowed in the following cases:
* <li>the user is in a phone call</li>
* <li>{@link UserManager#DISALLOW_USER_SWITCH} is set</li>
* <li>system user hasn't been unlocked yet</li>
*
* @return A {@link UserManager.UserSwitchabilityResult} flag indicating if the user is
* switchable.
*/
public @UserManager.UserSwitchabilityResult int getUserSwitchability(int userId) {
checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "getUserSwitchability");
final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
t.traceBegin("getUserSwitchability-" + userId);
int flags = UserManager.SWITCHABILITY_STATUS_OK;
t.traceBegin("TM.isInCall");
final long identity = Binder.clearCallingIdentity();
try {
final TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
if (telecomManager != null && telecomManager.isInCall()) {
flags |= UserManager.SWITCHABILITY_STATUS_USER_IN_CALL;
}
} finally {
Binder.restoreCallingIdentity(identity);
}
t.traceEnd();
t.traceBegin("hasUserRestriction-DISALLOW_USER_SWITCH");
if (mLocalService.hasUserRestriction(DISALLOW_USER_SWITCH, userId)) {
flags |= UserManager.SWITCHABILITY_STATUS_USER_SWITCH_DISALLOWED;
}
t.traceEnd();
// System User is always unlocked in Headless System User Mode, so ignore this flag
if (!UserManager.isHeadlessSystemUserMode()) {
t.traceBegin("getInt-ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED");
final boolean allowUserSwitchingWhenSystemUserLocked = Settings.Global.getInt(
mContext.getContentResolver(),
Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED, 0) != 0;
t.traceEnd();
t.traceBegin("isUserUnlocked-USER_SYSTEM");
final boolean systemUserUnlocked = mLocalService.isUserUnlocked(UserHandle.USER_SYSTEM);
t.traceEnd();
if (!allowUserSwitchingWhenSystemUserLocked && !systemUserUnlocked) {
flags |= UserManager.SWITCHABILITY_STATUS_SYSTEM_USER_LOCKED;
}
}
t.traceEnd();
return flags;
}
@Override @Override
public boolean isUserSwitcherEnabled(@UserIdInt int mUserId) { public boolean isUserSwitcherEnabled(@UserIdInt int mUserId) {
boolean multiUserSettingOn = Settings.Global.getInt(mContext.getContentResolver(), boolean multiUserSettingOn = Settings.Global.getInt(mContext.getContentResolver(),