1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.systemui.qs.tiles; 18 19 import static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_DISABLED_ALPHA; 20 import static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_ENABLED_ALPHA; 21 22 import android.content.Context; 23 import android.content.Intent; 24 import android.graphics.drawable.Drawable; 25 import android.graphics.drawable.LayerDrawable; 26 import android.util.AttributeSet; 27 import android.view.LayoutInflater; 28 import android.view.View; 29 import android.view.ViewGroup; 30 31 import androidx.annotation.Nullable; 32 33 import com.android.internal.logging.MetricsLogger; 34 import com.android.internal.logging.UiEventLogger; 35 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 36 import com.android.settingslib.RestrictedLockUtils; 37 import com.android.settingslib.drawable.CircleFramedDrawable; 38 import com.android.systemui.R; 39 import com.android.systemui.plugins.FalsingManager; 40 import com.android.systemui.qs.PseudoGridView; 41 import com.android.systemui.qs.QSUserSwitcherEvent; 42 import com.android.systemui.qs.user.UserSwitchDialogController; 43 import com.android.systemui.statusbar.phone.SystemUIDialog; 44 import com.android.systemui.statusbar.policy.UserSwitcherController; 45 46 import javax.inject.Inject; 47 48 /** 49 * Quick settings detail view for user switching. 50 */ 51 public class UserDetailView extends PseudoGridView { 52 53 protected Adapter mAdapter; 54 UserDetailView(Context context, AttributeSet attrs)55 public UserDetailView(Context context, AttributeSet attrs) { 56 super(context, attrs); 57 } 58 inflate(Context context, ViewGroup parent, boolean attach)59 public static UserDetailView inflate(Context context, ViewGroup parent, boolean attach) { 60 return (UserDetailView) LayoutInflater.from(context).inflate( 61 R.layout.qs_user_detail, parent, attach); 62 } 63 64 /** Set a {@link android.widget.BaseAdapter} */ setAdapter(Adapter adapter)65 public void setAdapter(Adapter adapter) { 66 mAdapter = adapter; 67 ViewGroupAdapterBridge.link(this, mAdapter); 68 } 69 refreshAdapter()70 public void refreshAdapter() { 71 mAdapter.refresh(); 72 } 73 74 public static class Adapter extends UserSwitcherController.BaseUserAdapter 75 implements OnClickListener { 76 77 private final Context mContext; 78 protected UserSwitcherController mController; 79 private View mCurrentUserView; 80 private final UiEventLogger mUiEventLogger; 81 private final FalsingManager mFalsingManager; 82 private @Nullable UserSwitchDialogController.DialogShower mDialogShower; 83 84 @Inject Adapter(Context context, UserSwitcherController controller, UiEventLogger uiEventLogger, FalsingManager falsingManager)85 public Adapter(Context context, UserSwitcherController controller, 86 UiEventLogger uiEventLogger, FalsingManager falsingManager) { 87 super(controller); 88 mContext = context; 89 mController = controller; 90 mUiEventLogger = uiEventLogger; 91 mFalsingManager = falsingManager; 92 } 93 94 @Override getView(int position, View convertView, ViewGroup parent)95 public View getView(int position, View convertView, ViewGroup parent) { 96 UserSwitcherController.UserRecord item = getItem(position); 97 return createUserDetailItemView(convertView, parent, item); 98 } 99 100 /** 101 * If this adapter is inside a dialog, passing a 102 * {@link UserSwitchDialogController.DialogShower} will help animate to and from the parent 103 * dialog. This will also allow for dismissing the whole stack of dialogs in a single 104 * animation. 105 * 106 * @param shower 107 * @see SystemUIDialog#dismissStack() 108 */ injectDialogShower(UserSwitchDialogController.DialogShower shower)109 public void injectDialogShower(UserSwitchDialogController.DialogShower shower) { 110 mDialogShower = shower; 111 } 112 createUserDetailItemView(View convertView, ViewGroup parent, UserSwitcherController.UserRecord item)113 public UserDetailItemView createUserDetailItemView(View convertView, ViewGroup parent, 114 UserSwitcherController.UserRecord item) { 115 UserDetailItemView v = UserDetailItemView.convertOrInflate( 116 parent.getContext(), convertView, parent); 117 if (!item.isCurrent || item.isGuest) { 118 v.setOnClickListener(this); 119 } else { 120 v.setOnClickListener(null); 121 v.setClickable(false); 122 } 123 String name = getName(mContext, item); 124 if (item.picture == null) { 125 v.bind(name, getDrawable(mContext, item).mutate(), item.resolveId()); 126 } else { 127 int avatarSize = 128 (int) mContext.getResources().getDimension(R.dimen.qs_framed_avatar_size); 129 Drawable drawable = new CircleFramedDrawable(item.picture, avatarSize); 130 drawable.setColorFilter( 131 item.isSwitchToEnabled ? null : getDisabledUserAvatarColorFilter()); 132 v.bind(name, drawable, item.info.id); 133 } 134 v.setActivated(item.isCurrent); 135 v.setDisabledByAdmin(item.isDisabledByAdmin); 136 v.setEnabled(item.isSwitchToEnabled); 137 v.setAlpha(v.isEnabled() ? USER_SWITCH_ENABLED_ALPHA : USER_SWITCH_DISABLED_ALPHA); 138 139 if (item.isCurrent) { 140 mCurrentUserView = v; 141 } 142 v.setTag(item); 143 return v; 144 } 145 getDrawable(Context context, UserSwitcherController.UserRecord item)146 private static Drawable getDrawable(Context context, 147 UserSwitcherController.UserRecord item) { 148 Drawable icon = getIconDrawable(context, item); 149 int iconColorRes; 150 if (item.isCurrent) { 151 iconColorRes = R.color.qs_user_switcher_selected_avatar_icon_color; 152 } else if (!item.isSwitchToEnabled) { 153 iconColorRes = R.color.GM2_grey_600; 154 } else { 155 iconColorRes = R.color.qs_user_switcher_avatar_icon_color; 156 } 157 icon.setTint(context.getResources().getColor(iconColorRes, context.getTheme())); 158 159 int bgRes = item.isCurrent ? R.drawable.bg_avatar_selected : R.drawable.qs_bg_avatar; 160 Drawable bg = context.getDrawable(bgRes); 161 LayerDrawable drawable = new LayerDrawable(new Drawable[]{bg, icon}); 162 return drawable; 163 } 164 165 @Override onClick(View view)166 public void onClick(View view) { 167 if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { 168 return; 169 } 170 171 UserSwitcherController.UserRecord tag = 172 (UserSwitcherController.UserRecord) view.getTag(); 173 if (tag.isDisabledByAdmin) { 174 final Intent intent = RestrictedLockUtils.getShowAdminSupportDetailsIntent( 175 mContext, tag.enforcedAdmin); 176 mController.startActivity(intent); 177 } else if (tag.isSwitchToEnabled) { 178 MetricsLogger.action(mContext, MetricsEvent.QS_SWITCH_USER); 179 mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_SWITCH); 180 if (!tag.isAddUser && !tag.isRestricted && !tag.isDisabledByAdmin) { 181 if (mCurrentUserView != null) { 182 mCurrentUserView.setActivated(false); 183 } 184 view.setActivated(true); 185 } 186 onUserListItemClicked(tag, mDialogShower); 187 } 188 } 189 linkToViewGroup(ViewGroup viewGroup)190 public void linkToViewGroup(ViewGroup viewGroup) { 191 PseudoGridView.ViewGroupAdapterBridge.link(viewGroup, this); 192 } 193 } 194 } 195