diff options
16 files changed, 278 insertions, 57 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java index f6caaa9642c4..2706e255d2af 100644 --- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java @@ -190,18 +190,27 @@ public class RestrictedLockUtils { * Send the intent to trigger the {@link android.settings.ShowAdminSupportDetailsDialog}. */ public static void sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) { - Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS); + final Intent intent = getShowAdminSupportDetailsIntent(context, admin); int adminUserId = UserHandle.myUserId(); + if (admin.userId != UserHandle.USER_NULL) { + adminUserId = admin.userId; + } + context.startActivityAsUser(intent, new UserHandle(adminUserId)); + } + + public static Intent getShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) { + final Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS); if (admin != null) { if (admin.component != null) { intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin.component); } + int adminUserId = UserHandle.myUserId(); if (admin.userId != UserHandle.USER_NULL) { adminUserId = admin.userId; } intent.putExtra(Intent.EXTRA_USER_ID, adminUserId); } - context.startActivityAsUser(intent, new UserHandle(adminUserId)); + return intent; } public static void setTextViewPadlock(Context context, @@ -224,6 +233,34 @@ public class RestrictedLockUtils { this.userId = userId; } + @Override + public boolean equals(Object object) { + if (object == this) return true; + if (!(object instanceof EnforcedAdmin)) return false; + EnforcedAdmin other = (EnforcedAdmin) object; + if (userId != other.userId) { + return false; + } + if ((component == null && other == null) || + (component != null && component.equals(other))) { + return true; + } + return false; + } + + @Override + public String toString() { + return "EnforcedAdmin{component=" + component + ",userId=" + userId + "}"; + } + + public void copyTo(EnforcedAdmin other) { + if (other == null) { + other = new EnforcedAdmin(); + } + other.component = component; + other.userId = userId; + } + public EnforcedAdmin() {} } }
\ No newline at end of file diff --git a/packages/SystemUI/res/color/qs_tile_text.xml b/packages/SystemUI/res/color/qs_tile_text.xml new file mode 100644 index 000000000000..90e0bceadbe6 --- /dev/null +++ b/packages/SystemUI/res/color/qs_tile_text.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- + ~ Copyright (C) 2015 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_enabled="false" android:color="@color/qs_tile_disabled_color" /> + <item android:color="#B3FFFFFF" /> <!-- 70% white --> +</selector>
\ No newline at end of file diff --git a/packages/SystemUI/res/color/qs_user_detail_name.xml b/packages/SystemUI/res/color/qs_user_detail_name.xml index 57f7e6528e61..35c7a4fe754b 100644 --- a/packages/SystemUI/res/color/qs_user_detail_name.xml +++ b/packages/SystemUI/res/color/qs_user_detail_name.xml @@ -18,5 +18,6 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_activated="true" android:color="@color/current_user_border_color" /> + <item android:state_enabled="false" android:color="@color/qs_tile_disabled_color" /> <item android:color="#66ffffff" /> <!-- 40% white --> </selector>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml new file mode 100644 index 000000000000..603ebbfc8ffb --- /dev/null +++ b/packages/SystemUI/res/layout/qs_tile_label.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2016 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView android:id="@+id/tile_label" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/qs_tile_text" + android:gravity="center_horizontal" + android:minLines="2" + android:padding="0dp" + android:fontFamily="sans-serif-condensed" + android:textStyle="normal" + android:textSize="@dimen/qs_tile_text_size" + android:clickable="false" /> + <ImageView android:id="@+id/restricted_padlock" + android:layout_width="@dimen/qs_tile_text_size" + android:layout_height="@dimen/qs_tile_text_size" + android:src="@drawable/ic_settings_lock_outline" + android:layout_marginLeft="@dimen/restricted_padlock_pading" + android:baselineAlignBottom="true" + android:scaleType="centerInside" + android:visibility="gone" /> +</LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/qs_user_detail_item.xml b/packages/SystemUI/res/layout/qs_user_detail_item.xml index af22f03c606a..a22c3603632e 100644 --- a/packages/SystemUI/res/layout/qs_user_detail_item.xml +++ b/packages/SystemUI/res/layout/qs_user_detail_item.xml @@ -40,12 +40,25 @@ systemui:framePadding="6dp" systemui:activeFrameColor="@color/current_user_border_color"/> - <TextView - android:id="@+id/user_name" + <LinearLayout android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textSize="@dimen/qs_detail_item_secondary_text_size" - android:textColor="@color/qs_user_detail_name" - android:gravity="center_horizontal" /> + android:layout_height="wrap_content"> + <TextView + android:id="@+id/user_name" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="@dimen/qs_detail_item_secondary_text_size" + android:textColor="@color/qs_user_detail_name" + android:gravity="center_horizontal" /> + <ImageView + android:id="@+id/restricted_padlock" + android:layout_width="@dimen/qs_detail_item_secondary_text_size" + android:layout_height="@dimen/qs_detail_item_secondary_text_size" + android:src="@drawable/ic_settings_lock_outline" + android:layout_marginLeft="@dimen/restricted_padlock_pading" + android:baselineAlignBottom="true" + android:scaleType="centerInside" + android:visibility="gone" /> + </LinearLayout> </com.android.systemui.qs.tiles.UserDetailItemView>
\ No newline at end of file diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 61c71dd445b9..a80a5de3a4ec 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -36,7 +36,6 @@ <color name="system_warning_color">#fff4511e</color><!-- deep orange 600 --> <color name="qs_text">#FFFFFFFF</color> <color name="qs_tile_divider">#29ffffff</color><!-- 16% white --> - <color name="qs_tile_text">#B3FFFFFF</color><!-- 70% white --> <color name="qs_subhead">#99FFFFFF</color><!-- 60% white --> <color name="qs_detail_empty">#24B0BEC5</color><!-- 14% blue grey 200 --> <color name="qs_detail_button">#FFB0BEC5</color><!-- 100% blue grey 200 --> @@ -48,6 +47,7 @@ <color name="data_usage_graph_warning">#FFFFFFFF</color> <color name="status_bar_clock_color">#FFFFFFFF</color> <color name="qs_user_detail_icon_muted">#FFFFFFFF</color> <!-- not so muted after all --> + <color name="qs_tile_disabled_color">#9E9E9E</color> <!-- 38% black --> <!-- Tint color for the content on the notification overflow card. --> <color name="keyguard_overflow_content_color">#ff686868</color> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 097c35266f98..1a9b87476c30 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -167,6 +167,8 @@ <dimen name="segmented_button_spacing">0dp</dimen> <dimen name="borderless_button_radius">2dp</dimen> + <dimen name="restricted_padlock_pading">4dp</dimen> + <!-- How far the expanded QS panel peeks from the header in collapsed state. --> <dimen name="qs_peek_height">0dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java b/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java index 01eb5f941fee..7651ae8c6f8f 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 @@ public class QSIconView extends ViewGroup { } } } - + 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 2d9d10595b3a..de7c02dddb92 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.graphics.drawable.Drawable; 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; @@ -47,6 +50,8 @@ import java.util.ArrayList; 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. * @@ -256,6 +261,18 @@ public abstract class QSTile<TState extends State> implements Listenable { mCallbacks.clear(); } + 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 ADD_CALLBACK = 1; private static final int CLICK = 2; @@ -282,8 +299,14 @@ public abstract class QSTile<TState extends State> implements Listenable { handleAddCallback((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(); @@ -437,6 +460,8 @@ public abstract class QSTile<TState extends State> implements Listenable { 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(); @@ -446,12 +471,16 @@ public abstract class QSTile<TState extends State> implements Listenable { || !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; } @@ -467,6 +496,8 @@ public abstract class QSTile<TState extends State> implements Listenable { 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 41ac4d9413dd..664ca39dbdb5 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 @@ package com.android.systemui.qs; 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 @@ public class QSTileView extends QSTileBaseView { 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 @@ public class QSTileView extends QSTileBaseView { 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 4d9b266a3513..39eda6b3b86e 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.Intent; 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 @@ public class DndTile extends QSTile<QSTile.BooleanState> { @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 @@ public class DndTile extends QSTile<QSTile.BooleanState> { 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 21c5c967ce96..167c61194b33 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 @@ public class UserDetailItemView extends LinearLayout { private TextView mName; private Typeface mRegularTypeface; private Typeface mActivatedTypeface; + private View mRestrictedPadlock; public UserDetailItemView(Context context) { this(context, null); @@ -59,6 +60,7 @@ public class UserDetailItemView extends LinearLayout { 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 @@ public class UserDetailItemView extends LinearLayout { 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 @@ public class UserDetailItemView extends LinearLayout { 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 d4f54b64adc2..b44ef0b46493 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 class UserDetailView extends PseudoGridView { 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 @@ public class UserDetailView extends PseudoGridView { v.bind(name, item.picture); } v.setActivated(item.isCurrent); + v.setDisabledByAdmin(item.isDisabledByAdmin); v.setTag(item); return v; } @@ -85,8 +89,14 @@ public class UserDetailView extends PseudoGridView { 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 50e88d39f1f9..5be52caed487 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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, 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 101a5f39d8d9..4f33d8278f1c 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.content.res.TypedArray; 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 @@ public class UserAvatarView extends View { 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 @@ public class UserAvatarView extends View { 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 f3a355445ccf..ffec6159a004 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.Dialog; 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.Bitmap; 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 android.widget.BaseAdapter; 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.lang.ref.WeakReference; 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 @@ public class UserSwitcherController { = 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 @@ public class UserSwitcherController { 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 @@ public class UserSwitcherController { } } - 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 @@ public class UserSwitcherController { } 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 @@ public class UserSwitcherController { } } + 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 class UserSwitcherController { 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 @@ public class UserSwitcherController { 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(); } |