Add restricted padlocks to tiles in quick settings.
Change-Id: Ib11a38f8512b811e5713a33055a04a72f1b825f1
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java b/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
index 01eb5f9..7651ae8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
@@ -81,7 +81,11 @@
}
}
}
-
+ if (state.disabledByPolicy) {
+ iv.setColorFilter(getContext().getColor(R.color.qs_tile_disabled_color));
+ } else {
+ iv.clearColorFilter();
+ }
}
protected int getIconMeasureMode() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 8ce6da2..6079b30 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -23,10 +23,13 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.UserHandle;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
+
+import com.android.settingslib.RestrictedLockUtils;
import com.android.systemui.qs.QSTile.State;
import com.android.systemui.qs.external.TileServices;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -46,6 +49,8 @@
import java.util.Collection;
import java.util.Objects;
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
/**
* Base quick-settings tile, extend this to create a new tile.
*
@@ -253,6 +258,18 @@
mCallback = null;
}
+ protected void checkIfRestrictionEnforced(State state, String userRestriction) {
+ EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
+ userRestriction, UserHandle.myUserId());
+ if (admin != null) {
+ state.disabledByPolicy = true;
+ state.enforcedAdmin = admin;
+ } else {
+ state.disabledByPolicy = false;
+ state.enforcedAdmin = null;
+ }
+ }
+
protected final class H extends Handler {
private static final int SET_CALLBACK = 1;
private static final int CLICK = 2;
@@ -279,8 +296,14 @@
handleSetCallback((QSTile.Callback)msg.obj);
} else if (msg.what == CLICK) {
name = "handleClick";
- mAnnounceNextStateChange = true;
- handleClick();
+ if (mState.disabledByPolicy) {
+ Intent intent = RestrictedLockUtils.getShowAdminSupportDetailsIntent(
+ mContext, mState.enforcedAdmin);
+ mHost.startActivityDismissingKeyguard(intent);
+ } else {
+ mAnnounceNextStateChange = true;
+ handleClick();
+ }
} else if (msg.what == SECONDARY_CLICK) {
name = "handleSecondaryClick";
handleSecondaryClick();
@@ -433,6 +456,8 @@
public CharSequence contentDescription;
public CharSequence dualLabelContentDescription;
public boolean autoMirrorDrawable = true;
+ public boolean disabledByPolicy;
+ public EnforcedAdmin enforcedAdmin;
public boolean copyTo(State other) {
if (other == null) throw new IllegalArgumentException();
@@ -442,12 +467,16 @@
|| !Objects.equals(other.contentDescription, contentDescription)
|| !Objects.equals(other.autoMirrorDrawable, autoMirrorDrawable)
|| !Objects.equals(other.dualLabelContentDescription,
- dualLabelContentDescription);
+ dualLabelContentDescription)
+ || !Objects.equals(other.disabledByPolicy, disabledByPolicy)
+ || !Objects.equals(other.enforcedAdmin, enforcedAdmin);
other.icon = icon;
other.label = label;
other.contentDescription = contentDescription;
other.dualLabelContentDescription = dualLabelContentDescription;
other.autoMirrorDrawable = autoMirrorDrawable;
+ other.disabledByPolicy = disabledByPolicy;
+ enforcedAdmin.copyTo(other.enforcedAdmin);
return changed;
}
@@ -463,6 +492,8 @@
sb.append(",contentDescription=").append(contentDescription);
sb.append(",dualLabelContentDescription=").append(dualLabelContentDescription);
sb.append(",autoMirrorDrawable=").append(autoMirrorDrawable);
+ sb.append(",disabledByPolicy=").append(disabledByPolicy);
+ sb.append(",enforcedAdmin=").append(enforcedAdmin);
return sb.append(']');
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index 41ac4d9..664ca39 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -19,32 +19,33 @@
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.graphics.Typeface;
import android.util.MathUtils;
-import android.util.TypedValue;
import android.view.Gravity;
+import android.view.LayoutInflater;
import android.view.View;
+import android.widget.ImageView;
import android.widget.TextView;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
/** View that represents a standard quick settings tile. **/
public class QSTileView extends QSTileBaseView {
- private static final Typeface CONDENSED = Typeface.create("sans-serif-condensed",
- Typeface.NORMAL);
-
protected final Context mContext;
+ private QSIconView mIconView;
private final int mTileSpacingPx;
private int mTilePaddingTopPx;
private TextView mLabel;
+ private ImageView mPadLock;
public QSTileView(Context context, QSIconView icon) {
super(context, icon);
mContext = context;
+ mIconView = icon;
final Resources res = context.getResources();
mTileSpacingPx = res.getDimensionPixelSize(R.dimen.qs_tile_spacing);
+
setClipChildren(false);
setClickable(true);
@@ -76,16 +77,10 @@
private void createLabel() {
final Resources res = mContext.getResources();
- mLabel = new TextView(mContext);
- mLabel.setTextColor(mContext.getColor(R.color.qs_tile_text));
- mLabel.setGravity(Gravity.CENTER_HORIZONTAL);
- mLabel.setMinLines(2);
- mLabel.setPadding(0, 0, 0, 0);
- mLabel.setTypeface(CONDENSED);
- mLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
- res.getDimensionPixelSize(R.dimen.qs_tile_text_size));
- mLabel.setClickable(false);
- addView(mLabel);
+ View view = LayoutInflater.from(mContext).inflate(R.layout.qs_tile_label, null);
+ mLabel = (TextView) view.findViewById(R.id.tile_label);
+ mPadLock = (ImageView) view.findViewById(R.id.restricted_padlock);
+ addView(view);
}
public void init(OnClickListener clickPrimary, OnLongClickListener longClick) {
@@ -96,5 +91,7 @@
protected void handleStateChanged(QSTile.State state) {
super.handleStateChanged(state);
mLabel.setText(state.label);
+ mLabel.setEnabled(!state.disabledByPolicy);
+ mPadLock.setVisibility(state.disabledByPolicy ? View.VISIBLE : View.GONE);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 4d9b266..39eda6b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -22,6 +22,7 @@
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.UserManager;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.view.LayoutInflater;
@@ -99,14 +100,6 @@
@Override
public void handleClick() {
- if (mController.isVolumeRestricted()) {
- // Collapse the panels, so the user can see the toast.
- mHost.collapsePanels();
- SysUIToast.makeText(mContext, mContext.getString(
- com.android.internal.R.string.error_message_change_not_allowed),
- Toast.LENGTH_LONG).show();
- return;
- }
MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
if (mState.value) {
mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
@@ -123,6 +116,8 @@
final boolean newValue = zen != Global.ZEN_MODE_OFF;
final boolean valueChanged = state.value != newValue;
state.value = newValue;
+ state.disabledByPolicy = mController.isVolumeRestricted();
+ checkIfRestrictionEnforced(state, UserManager.DISALLOW_ADJUST_VOLUME);
switch (zen) {
case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
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 21c5c96..167c611 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
@@ -43,6 +43,7 @@
private TextView mName;
private Typeface mRegularTypeface;
private Typeface mActivatedTypeface;
+ private View mRestrictedPadlock;
public UserDetailItemView(Context context) {
this(context, null);
@@ -59,6 +60,7 @@
public UserDetailItemView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
+
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.UserDetailItemView, defStyleAttr, defStyleRes);
final int N = a.getIndexCount();
@@ -95,6 +97,12 @@
mAvatar.setDrawable(picture);
}
+ public void setDisabledByAdmin(boolean disabled) {
+ mRestrictedPadlock.setVisibility(disabled ? View.VISIBLE : View.GONE);
+ mName.setEnabled(!disabled);
+ mAvatar.setDisabled(disabled);
+ }
+
@Override
protected void onFinishInflate() {
mAvatar = (UserAvatarView) findViewById(R.id.user_picture);
@@ -106,6 +114,7 @@
mActivatedTypeface = mName.getTypeface();
}
updateTypeface();
+ mRestrictedPadlock = findViewById(R.id.restricted_padlock);
}
@Override
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 d4f54b6..b44ef0b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -16,17 +16,18 @@
package com.android.systemui.qs.tiles;
-import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
-import com.android.systemui.qs.PseudoGridView;
-import com.android.systemui.statusbar.policy.UserSwitcherController;
-
import android.content.Context;
+import android.content.Intent;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import com.android.internal.logging.MetricsLogger;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.systemui.R;
+import com.android.systemui.qs.PseudoGridView;
+import com.android.systemui.statusbar.policy.UserSwitcherController;
/**
* Quick settings detail view for user switching.
*/
@@ -55,11 +56,13 @@
public static class Adapter extends UserSwitcherController.BaseUserAdapter
implements OnClickListener {
- private Context mContext;
+ private final Context mContext;
+ private final UserSwitcherController mController;
public Adapter(Context context, UserSwitcherController controller) {
super(controller);
mContext = context;
+ mController = controller;
}
@Override
@@ -77,6 +80,7 @@
v.bind(name, item.picture);
}
v.setActivated(item.isCurrent);
+ v.setDisabledByAdmin(item.isDisabledByAdmin);
v.setTag(item);
return v;
}
@@ -85,8 +89,14 @@
public void onClick(View view) {
UserSwitcherController.UserRecord tag =
(UserSwitcherController.UserRecord) view.getTag();
- MetricsLogger.action(mContext, MetricsLogger.QS_SWITCH_USER);
- switchTo(tag);
+ if (tag.isDisabledByAdmin) {
+ final Intent intent = RestrictedLockUtils.getShowAdminSupportDetailsIntent(
+ mContext, tag.enforcedAdmin);
+ mController.startActivity(intent);
+ } else {
+ MetricsLogger.action(mContext, MetricsLogger.QS_SWITCH_USER);
+ switchTo(tag);
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 50e88d3..5be52ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -866,7 +866,7 @@
mKeyguardMonitor = new KeyguardMonitor(mContext);
if (UserManager.get(mContext).isUserSwitcherEnabled()) {
mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
- mHandler);
+ mHandler, this);
if (mUserSwitcherController.useFullscreenUserSwitcher()) {
mFullscreenUserSwitcher = new FullscreenUserSwitcher(this, mUserSwitcherController,
(ViewStub) mStatusBarWindow.findViewById(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java
index 101a5f3..4f33d82 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java
@@ -23,6 +23,9 @@
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
@@ -41,6 +44,7 @@
private float mFramePadding;
private Bitmap mBitmap;
private Drawable mDrawable;
+ private boolean mIsDisabled;
private final Paint mFramePaint = new Paint();
private final Paint mBitmapPaint = new Paint();
@@ -239,4 +243,28 @@
mDrawable.setState(getDrawableState());
}
}
+
+ public void setDisabled(boolean disabled) {
+ if (mIsDisabled == disabled) {
+ return;
+ }
+ mIsDisabled = disabled;
+ int disabledColor = getContext().getColor(R.color.qs_tile_disabled_color);
+ PorterDuffColorFilter filter = new PorterDuffColorFilter(disabledColor,
+ PorterDuff.Mode.SRC_ATOP);
+ if (mBitmap != null) {
+ if (disabled) {
+ mBitmapPaint.setColorFilter(filter);
+ } else {
+ mBitmapPaint.setColorFilter(null);
+ }
+ } else if (mDrawable != null) {
+ if (disabled) {
+ mDrawable.setColorFilter(filter);
+ } else {
+ mDrawable.setColorFilter(null);
+ }
+ }
+ invalidate();
+ }
}
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 f3a3554..ffec615 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -22,7 +22,9 @@
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -33,6 +35,7 @@
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
+import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -48,11 +51,13 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.util.UserIcons;
+import com.android.settingslib.RestrictedLockUtils;
import com.android.systemui.BitmapHelper;
import com.android.systemui.GuestResumeSessionReceiver;
import com.android.systemui.R;
import com.android.systemui.qs.QSTile;
import com.android.systemui.qs.tiles.UserDetailView;
+import com.android.systemui.statusbar.phone.ActivityStarter;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import java.io.FileDescriptor;
@@ -61,6 +66,8 @@
import java.util.ArrayList;
import java.util.List;
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
/**
* Keeps a list of all users on the device for user switching.
*/
@@ -88,6 +95,7 @@
= new GuestResumeSessionReceiver();
private final KeyguardMonitor mKeyguardMonitor;
private final Handler mHandler;
+ private final ActivityStarter mActivityStarter;
private ArrayList<UserRecord> mUsers = new ArrayList<>();
private Dialog mExitGuestDialog;
@@ -99,11 +107,12 @@
private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2);
public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor,
- Handler handler) {
+ Handler handler, ActivityStarter activityStarter) {
mContext = context;
mGuestResumeSessionReceiver.register(context);
mKeyguardMonitor = keyguardMonitor;
mHandler = handler;
+ mActivityStarter = activityStarter;
mUserManager = UserManager.get(context);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_ADDED);
@@ -206,25 +215,23 @@
}
}
- boolean systemCanCreateUsers = !mUserManager.hasUserRestriction(
- UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM);
boolean currentUserCanCreateUsers = currentUserInfo != null
&& (currentUserInfo.isAdmin()
- || currentUserInfo.id == UserHandle.USER_SYSTEM)
- && systemCanCreateUsers;
- boolean anyoneCanCreateUsers = systemCanCreateUsers && addUsersWhenLocked;
- boolean canCreateGuest = (currentUserCanCreateUsers || anyoneCanCreateUsers)
+ || currentUserInfo.id == UserHandle.USER_SYSTEM);
+ boolean canCreateGuest = (currentUserCanCreateUsers || addUsersWhenLocked)
&& guestRecord == null;
- boolean canCreateUser = (currentUserCanCreateUsers || anyoneCanCreateUsers)
+ boolean canCreateUser = (currentUserCanCreateUsers || addUsersWhenLocked)
&& mUserManager.canAddMoreUsers();
boolean createIsRestricted = !addUsersWhenLocked;
if (!mSimpleUserSwitcher) {
if (guestRecord == null) {
if (canCreateGuest) {
- records.add(new UserRecord(null /* info */, null /* picture */,
+ guestRecord = new UserRecord(null /* info */, null /* picture */,
true /* isGuest */, false /* isCurrent */,
- false /* isAddUser */, createIsRestricted));
+ false /* isAddUser */, createIsRestricted);
+ checkIfAddUserDisallowed(guestRecord);
+ records.add(guestRecord);
}
} else {
int index = guestRecord.isCurrent ? 0 : records.size();
@@ -233,9 +240,11 @@
}
if (!mSimpleUserSwitcher && canCreateUser) {
- records.add(new UserRecord(null /* info */, null /* picture */,
+ UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */,
false /* isGuest */, false /* isCurrent */, true /* isAddUser */,
- createIsRestricted));
+ createIsRestricted);
+ checkIfAddUserDisallowed(addUserRecord);
+ records.add(addUserRecord);
}
return records;
@@ -594,6 +603,22 @@
}
}
+ private void checkIfAddUserDisallowed(UserRecord record) {
+ EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
+ UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
+ if (admin != null) {
+ record.isDisabledByAdmin = true;
+ record.enforcedAdmin = admin;
+ } else {
+ record.isDisabledByAdmin = false;
+ record.enforcedAdmin = null;
+ }
+ }
+
+ public void startActivity(Intent intent) {
+ mActivityStarter.startActivity(intent, true);
+ }
+
public static final class UserRecord {
public final UserInfo info;
public final Bitmap picture;
@@ -602,6 +627,8 @@
public final boolean isAddUser;
/** If true, the record is only visible to the owner and only when unlocked. */
public final boolean isRestricted;
+ public boolean isDisabledByAdmin;
+ public EnforcedAdmin enforcedAdmin;
public UserRecord(UserInfo info, Bitmap picture, boolean isGuest, boolean isCurrent,
boolean isAddUser, boolean isRestricted) {
@@ -634,6 +661,10 @@
if (isCurrent) sb.append(" <isCurrent>");
if (picture != null) sb.append(" <hasPicture>");
if (isRestricted) sb.append(" <isRestricted>");
+ if (isDisabledByAdmin) {
+ sb.append(" <isDisabledByAdmin>");
+ sb.append(" enforcedAdmin=" + enforcedAdmin);
+ }
sb.append(')');
return sb.toString();
}