diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 20b3798b56b89..6e9e4569c46ad 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -36,6 +36,7 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.storage.StorageManager;
import android.provider.Settings;
+import android.telephony.TelephonyManager;
import android.view.WindowManager.LayoutParams;
import com.android.internal.R;
@@ -679,6 +680,22 @@ public class UserManager {
return SystemProperties.getBoolean("ro.fw.system_user_split", false);
}
+ /**
+ * Returns whether switching users is currently allowed.
+ *
For instance switching users is not allowed if the current user is in a phone call,
+ * or system user hasn't been unlocked yet
+ * @hide
+ */
+ 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 = TelephonyManager.getDefault().getCallState()
+ != TelephonyManager.CALL_STATE_IDLE;
+ return (allowUserSwitchingWhenSystemUserLocked || isSystemUserUnlocked) && !inCall;
+ }
+
/**
* Returns the user handle for the user that this process is running under.
*
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 53fd446b24449..b6a32343448e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -37,6 +37,8 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -99,7 +101,6 @@ public class UserSwitcherController {
private boolean mSimpleUserSwitcher;
private boolean mAddUsersWhenLocked;
private boolean mPauseRefreshUsers;
- private boolean mAllowUserSwitchingWhenSystemUserLocked;
private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2);
public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor,
@@ -140,6 +141,7 @@ public class UserSwitcherController {
mSettingsObserver.onChange(false);
keyguardMonitor.addCallback(mCallback);
+ listenForCallState();
refreshUsers(UserHandle.USER_NULL);
}
@@ -186,8 +188,7 @@ public class UserSwitcherController {
}
ArrayList records = new ArrayList<>(infos.size());
int currentId = ActivityManager.getCurrentUser();
- boolean allowUserSwitching = mAllowUserSwitchingWhenSystemUserLocked
- || mUserManager.isUserUnlocked(UserHandle.SYSTEM);
+ boolean canSwitchUsers = mUserManager.canSwitchUsers();
UserInfo currentUserInfo = null;
UserRecord guestRecord = null;
int avatarSize = mContext.getResources()
@@ -198,12 +199,14 @@ public class UserSwitcherController {
if (isCurrent) {
currentUserInfo = info;
}
- boolean switchToEnabled = allowUserSwitching || isCurrent;
+ boolean switchToEnabled = canSwitchUsers || isCurrent;
if (info.isEnabled()) {
if (info.isGuest()) {
+ // Tapping guest icon triggers remove and a user switch therefore
+ // the icon shouldn't be enabled even if the user is current
guestRecord = new UserRecord(info, null /* picture */,
true /* isGuest */, isCurrent, false /* isAddUser */,
- false /* isRestricted */, switchToEnabled);
+ false /* isRestricted */, canSwitchUsers);
} else if (info.supportsSwitchToByUser()) {
Bitmap picture = bitmaps.get(info.id);
if (picture == null) {
@@ -240,7 +243,7 @@ public class UserSwitcherController {
if (canCreateGuest) {
guestRecord = new UserRecord(null /* info */, null /* picture */,
true /* isGuest */, false /* isCurrent */,
- false /* isAddUser */, createIsRestricted, allowUserSwitching);
+ false /* isAddUser */, createIsRestricted, canSwitchUsers);
checkIfAddUserDisallowedByAdminOnly(guestRecord);
records.add(guestRecord);
}
@@ -253,7 +256,7 @@ public class UserSwitcherController {
if (!mSimpleUserSwitcher && canCreateUser) {
UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */,
false /* isGuest */, false /* isCurrent */, true /* isAddUser */,
- createIsRestricted, allowUserSwitching);
+ createIsRestricted, canSwitchUsers);
checkIfAddUserDisallowedByAdminOnly(addUserRecord);
records.add(addUserRecord);
}
@@ -359,19 +362,6 @@ public class UserSwitcherController {
switchToUserId(id);
}
- public void switchTo(int userId) {
- final int count = mUsers.size();
- for (int i = 0; i < count; ++i) {
- UserRecord record = mUsers.get(i);
- if (record.info != null && record.info.id == userId) {
- switchTo(record);
- return;
- }
- }
-
- Log.e(TAG, "Couldn't switch to user, id=" + userId);
- }
-
private void switchToUserId(int id) {
try {
pauseRefreshUsers();
@@ -417,6 +407,24 @@ public class UserSwitcherController {
mUserManager.removeUser(id);
}
+ private void listenForCallState() {
+ TelephonyManager.from(mContext).listen(new PhoneStateListener() {
+ private int mCallState;
+ @Override
+ public void onCallStateChanged(int state, String incomingNumber) {
+ if (mCallState == state) return;
+ if (DEBUG) Log.v(TAG, "Call state changed: " + state);
+ mCallState = state;
+ int currentUserId = ActivityManager.getCurrentUser();
+ UserInfo userInfo = mUserManager.getUserInfo(currentUserId);
+ if (userInfo != null && userInfo.isGuest()) {
+ showGuestNotification(currentUserId);
+ }
+ refreshUsers(UserHandle.USER_NULL);
+ }
+ }, PhoneStateListener.LISTEN_CALL_STATE);
+ }
+
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -488,25 +496,6 @@ public class UserSwitcherController {
}
}
- private void showGuestNotification(int guestUserId) {
- PendingIntent removeGuestPI = PendingIntent.getBroadcastAsUser(mContext,
- 0, new Intent(ACTION_REMOVE_GUEST), 0, UserHandle.SYSTEM);
- Notification notification = new Notification.Builder(mContext)
- .setVisibility(Notification.VISIBILITY_SECRET)
- .setPriority(Notification.PRIORITY_MIN)
- .setSmallIcon(R.drawable.ic_person)
- .setContentTitle(mContext.getString(R.string.guest_notification_title))
- .setContentText(mContext.getString(R.string.guest_notification_text))
- .setContentIntent(removeGuestPI)
- .setShowWhen(false)
- .addAction(R.drawable.ic_delete,
- mContext.getString(R.string.guest_notification_remove_action),
- removeGuestPI)
- .build();
- NotificationManager.from(mContext).notifyAsUser(TAG_REMOVE_GUEST, ID_REMOVE_GUEST,
- notification, new UserHandle(guestUserId));
- }
-
private void showLogoutNotification(int userId) {
PendingIntent logoutPI = PendingIntent.getBroadcastAsUser(mContext,
0, new Intent(ACTION_LOGOUT_USER), 0, UserHandle.SYSTEM);
@@ -528,6 +517,28 @@ public class UserSwitcherController {
}
};
+ private void showGuestNotification(int guestUserId) {
+ boolean canSwitchUsers = mUserManager.canSwitchUsers();
+ // Disable 'Remove guest' action if cannot switch users right now
+ PendingIntent removeGuestPI = canSwitchUsers ? PendingIntent.getBroadcastAsUser(mContext,
+ 0, new Intent(ACTION_REMOVE_GUEST), 0, UserHandle.SYSTEM) : null;
+
+ Notification notification = new Notification.Builder(mContext)
+ .setVisibility(Notification.VISIBILITY_SECRET)
+ .setPriority(Notification.PRIORITY_MIN)
+ .setSmallIcon(R.drawable.ic_person)
+ .setContentTitle(mContext.getString(R.string.guest_notification_title))
+ .setContentText(mContext.getString(R.string.guest_notification_text))
+ .setContentIntent(removeGuestPI)
+ .setShowWhen(false)
+ .addAction(R.drawable.ic_delete,
+ mContext.getString(R.string.guest_notification_remove_action),
+ removeGuestPI)
+ .build();
+ NotificationManager.from(mContext).notifyAsUser(TAG_REMOVE_GUEST, ID_REMOVE_GUEST,
+ notification, new UserHandle(guestUserId));
+ }
+
private final Runnable mUnpauseRefreshUsers = new Runnable() {
@Override
public void run() {
@@ -543,9 +554,6 @@ public class UserSwitcherController {
SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0;
mAddUsersWhenLocked = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0;
- mAllowUserSwitchingWhenSystemUserLocked = Settings.Global.getInt(
- mContext.getContentResolver(),
- Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED, 0) != 0;
refreshUsers(UserHandle.USER_NULL);
};
};