Disable switching users until user 0 is unlocked
Switching with user0 locked can be re-enabled by setting
allow_user_switching_when_system_user_locked flag to a non-zero value
Bug: 26933989
Change-Id: I0958058f1cc8a059db9c20930e07183c14c8460a
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 770cde7..64fb9ca 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8140,6 +8140,15 @@
"uninstalled_ephemeral_app_cache_duration_millis";
/**
+ * Allows switching users when system user is locked.
+ * <p>
+ * Type: int
+ * @hide
+ */
+ public static final String ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED =
+ "allow_user_switching_when_system_user_locked";
+
+ /**
* Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update.
*
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
index 33befd0..fcf758b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
@@ -103,6 +103,11 @@
mAvatar.setDisabled(disabled);
}
+ public void setEnabled(boolean enabled) {
+ mName.setEnabled(enabled);
+ mAvatar.setDisabled(!enabled);
+ }
+
@Override
protected void onFinishInflate() {
mAvatar = (UserAvatarView) findViewById(R.id.user_picture);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
index 2c8a478..da98762 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -82,6 +82,9 @@
}
v.setActivated(item.isCurrent);
v.setDisabledByAdmin(item.isDisabledByAdmin);
+ if (!item.isSwitchToEnabled) {
+ v.setEnabled(false);
+ }
v.setTag(item);
return v;
}
@@ -94,7 +97,7 @@
final Intent intent = RestrictedLockUtils.getShowAdminSupportDetailsIntent(
mContext, tag.enforcedAdmin);
mController.startActivity(intent);
- } else {
+ } else if (tag.isSwitchToEnabled) {
MetricsLogger.action(mContext, MetricsEvent.QS_SWITCH_USER);
switchTo(tag);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
index 867a8a3..fb310a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
@@ -21,6 +21,8 @@
import android.animation.ObjectAnimator;
import android.content.Context;
import android.database.DataSetObserver;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -242,7 +244,6 @@
@Override
public View getView(int position, View convertView, ViewGroup parent) {
UserSwitcherController.UserRecord item = getItem(position);
-
if (!(convertView instanceof UserDetailItemView)
|| !(convertView.getTag() instanceof UserSwitcherController.UserRecord)) {
convertView = LayoutInflater.from(mContext).inflate(
@@ -252,11 +253,17 @@
UserDetailItemView v = (UserDetailItemView) convertView;
String name = getName(mContext, item);
+ Drawable drawable;
if (item.picture == null) {
- v.bind(name, getDrawable(mContext, item));
+ drawable = getDrawable(mContext, item).mutate();
} else {
- v.bind(name, item.picture);
+ drawable = new BitmapDrawable(mContext.getResources(), item.picture);
}
+ // Disable the icon if switching is disabled
+ if (!item.isSwitchToEnabled) {
+ drawable.setTint(mContext.getColor(R.color.qs_tile_disabled_color));
+ }
+ v.bind(name, drawable);
convertView.setActivated(item.isCurrent);
convertView.setTag(item);
return convertView;
@@ -269,7 +276,7 @@
// Close the switcher if tapping the current user. Guest is excluded because
// tapping the guest user while it's current clears the session.
mKeyguardUserSwitcher.hideIfNotSimple(true /* animate */);
- } else {
+ } else if (user.isSwitchToEnabled) {
switchTo(user);
}
}
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 13369f2..4c67010 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -99,6 +99,7 @@
private boolean mSimpleUserSwitcher;
private boolean mAddUsersWhenLocked;
private boolean mPauseRefreshUsers;
+ private boolean mAllowUserSwitchingWhenSystemUserLocked;
private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2);
public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor,
@@ -115,6 +116,7 @@
filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
filter.addAction(Intent.ACTION_USER_SWITCHED);
filter.addAction(Intent.ACTION_USER_STOPPING);
+ filter.addAction(Intent.ACTION_USER_UNLOCKED);
mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter,
null /* permission */, null /* scheduler */);
@@ -130,6 +132,10 @@
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ADD_USERS_WHEN_LOCKED), true,
mSettingsObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(
+ Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED),
+ true, mSettingsObserver);
// Fetch initial values.
mSettingsObserver.onChange(false);
@@ -180,6 +186,8 @@
}
ArrayList<UserRecord> records = new ArrayList<>(infos.size());
int currentId = ActivityManager.getCurrentUser();
+ boolean allowUserSwitching = mAllowUserSwitchingWhenSystemUserLocked
+ || mUserManager.isUserUnlocked(UserHandle.SYSTEM);
UserInfo currentUserInfo = null;
UserRecord guestRecord = null;
int avatarSize = mContext.getResources()
@@ -190,10 +198,11 @@
if (isCurrent) {
currentUserInfo = info;
}
+ boolean switchToEnabled = allowUserSwitching || isCurrent;
if (info.isGuest()) {
guestRecord = new UserRecord(info, null /* picture */,
true /* isGuest */, isCurrent, false /* isAddUser */,
- false /* isRestricted */);
+ false /* isRestricted */, switchToEnabled);
} else if (info.isEnabled() && info.supportsSwitchToByUser()) {
Bitmap picture = bitmaps.get(info.id);
if (picture == null) {
@@ -206,7 +215,8 @@
}
int index = isCurrent ? 0 : records.size();
records.add(index, new UserRecord(info, picture, false /* isGuest */,
- isCurrent, false /* isAddUser */, false /* isRestricted */));
+ isCurrent, false /* isAddUser */, false /* isRestricted */,
+ switchToEnabled));
}
}
@@ -228,7 +238,7 @@
if (canCreateGuest) {
guestRecord = new UserRecord(null /* info */, null /* picture */,
true /* isGuest */, false /* isCurrent */,
- false /* isAddUser */, createIsRestricted);
+ false /* isAddUser */, createIsRestricted, allowUserSwitching);
checkIfAddUserDisallowedByAdminOnly(guestRecord);
records.add(guestRecord);
}
@@ -241,7 +251,7 @@
if (!mSimpleUserSwitcher && canCreateUser) {
UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */,
false /* isGuest */, false /* isCurrent */, true /* isAddUser */,
- createIsRestricted);
+ createIsRestricted, allowUserSwitching);
checkIfAddUserDisallowedByAdminOnly(addUserRecord);
records.add(addUserRecord);
}
@@ -463,6 +473,12 @@
} else if (Intent.ACTION_USER_INFO_CHANGED.equals(intent.getAction())) {
forcePictureLoadForId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
UserHandle.USER_NULL);
+ } else if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
+ // Unlocking the system user may require a refresh
+ int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ if (userId != UserHandle.USER_SYSTEM) {
+ return;
+ }
}
refreshUsers(forcePictureLoadForId);
if (unpauseRefreshUsers) {
@@ -525,6 +541,9 @@
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);
};
};
@@ -646,26 +665,29 @@
public final boolean isRestricted;
public boolean isDisabledByAdmin;
public EnforcedAdmin enforcedAdmin;
+ public boolean isSwitchToEnabled;
public UserRecord(UserInfo info, Bitmap picture, boolean isGuest, boolean isCurrent,
- boolean isAddUser, boolean isRestricted) {
+ boolean isAddUser, boolean isRestricted, boolean isSwitchToEnabled) {
this.info = info;
this.picture = picture;
this.isGuest = isGuest;
this.isCurrent = isCurrent;
this.isAddUser = isAddUser;
this.isRestricted = isRestricted;
+ this.isSwitchToEnabled = isSwitchToEnabled;
}
public UserRecord copyWithIsCurrent(boolean _isCurrent) {
- return new UserRecord(info, picture, isGuest, _isCurrent, isAddUser, isRestricted);
+ return new UserRecord(info, picture, isGuest, _isCurrent, isAddUser, isRestricted,
+ isSwitchToEnabled);
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("UserRecord(");
if (info != null) {
- sb.append("name=\"" + info.name + "\" id=" + info.id);
+ sb.append("name=\"").append(info.name).append("\" id=").append(info.id);
} else {
if (isGuest) {
sb.append("<add guest placeholder>");
@@ -680,7 +702,10 @@
if (isRestricted) sb.append(" <isRestricted>");
if (isDisabledByAdmin) {
sb.append(" <isDisabledByAdmin>");
- sb.append(" enforcedAdmin=" + enforcedAdmin);
+ sb.append(" enforcedAdmin=").append(enforcedAdmin);
+ }
+ if (isSwitchToEnabled) {
+ sb.append(" <isSwitchToEnabled>");
}
sb.append(')');
return sb.toString();