1 /* 2 * Copyright (C) 2023 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.car.userpicker; 18 19 import android.content.Context; 20 import android.view.LayoutInflater; 21 import android.view.View; 22 import android.view.ViewGroup; 23 import android.widget.FrameLayout; 24 import android.widget.ImageView; 25 import android.widget.TextView; 26 27 import androidx.annotation.ColorInt; 28 import androidx.annotation.NonNull; 29 import androidx.recyclerview.widget.RecyclerView; 30 import androidx.recyclerview.widget.RecyclerView.Adapter; 31 32 import com.android.systemui.R; 33 34 import java.io.PrintWriter; 35 import java.util.List; 36 37 final class UserPickerAdapter extends Adapter<UserPickerAdapter.UserPickerAdapterViewHolder> { 38 private final Context mContext; 39 private final int mDisplayId; 40 private final float mDisabledAlpha; 41 @ColorInt 42 private final int mCurrentUserSubtitleColor; 43 @ColorInt 44 private final int mOtherUserSubtitleColor; 45 private final int mVerticalSpacing; 46 private final int mHorizontalSpacing; 47 private final int mNumCols; 48 49 private List<UserRecord> mUsers; 50 private String mLoggedInText; 51 private String mPrefixOtherSeatLoggedInInfo; 52 private String mStoppingUserText; 53 UserPickerAdapter(Context context)54 UserPickerAdapter(Context context) { 55 mContext = context; 56 mDisplayId = mContext.getDisplayId(); 57 mDisabledAlpha = mContext.getResources().getFloat(R.fraction.user_picker_disabled_alpha); 58 mCurrentUserSubtitleColor = mContext.getColor( 59 R.color.user_picker_current_login_state_color); 60 mOtherUserSubtitleColor = mContext.getColor(R.color.user_picker_other_login_state_color); 61 mVerticalSpacing = mContext.getResources().getDimensionPixelSize( 62 R.dimen.user_picker_vertical_space_between_users); 63 mHorizontalSpacing = mContext.getResources().getDimensionPixelSize( 64 R.dimen.user_picker_horizontal_space_between_users); 65 mNumCols = mContext.getResources().getInteger(R.integer.user_fullscreen_switcher_num_col); 66 67 updateTexts(); 68 } 69 updateUsers(List<UserRecord> users)70 void updateUsers(List<UserRecord> users) { 71 mUsers = users; 72 } 73 setUserLoggedInInfo(UserPickerAdapterViewHolder holder, UserRecord userRecord)74 private void setUserLoggedInInfo(UserPickerAdapterViewHolder holder, UserRecord userRecord) { 75 if (!userRecord.mIsStopping && !userRecord.mIsLoggedIn) { 76 holder.mUserBorderImageView.setVisibility(View.INVISIBLE); 77 holder.mLoggedInTextView.setText(""); 78 updateAlpha(holder, /* disabled= */ false); 79 return; 80 } 81 82 if (userRecord.mIsStopping) { 83 holder.mUserBorderImageView.setVisibility(View.INVISIBLE); 84 holder.mLoggedInTextView.setText(mStoppingUserText); 85 holder.mLoggedInTextView.setTextColor(mOtherUserSubtitleColor); 86 updateAlpha(holder, /* disabled= */ true); 87 } else if (userRecord.mIsLoggedIn) { 88 if (userRecord.mLoggedInDisplay == mDisplayId) { 89 holder.mUserBorderImageView.setVisibility(View.VISIBLE); 90 holder.mLoggedInTextView.setText(mLoggedInText); 91 holder.mLoggedInTextView.setTextColor(mCurrentUserSubtitleColor); 92 updateAlpha(holder, /* disabled= */ false); 93 } else { 94 holder.mUserBorderImageView.setVisibility(View.INVISIBLE); 95 holder.mLoggedInTextView.setText(String.format(mPrefixOtherSeatLoggedInInfo, 96 userRecord.mSeatLocationName)); 97 holder.mLoggedInTextView.setTextColor(mOtherUserSubtitleColor); 98 updateAlpha(holder, /* disabled= */ true); 99 } 100 } 101 } 102 updateAlpha(UserPickerAdapterViewHolder holder, boolean disabled)103 private void updateAlpha(UserPickerAdapterViewHolder holder, boolean disabled) { 104 float alpha = disabled ? mDisabledAlpha : 1.0f; 105 holder.mUserAvatarImageView.setAlpha(alpha); 106 holder.mUserNameTextView.setAlpha(alpha); 107 holder.mLoggedInTextView.setAlpha(alpha); 108 } 109 110 @Override onCreateViewHolder(@onNull ViewGroup parent, int viewType)111 public UserPickerAdapterViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 112 View view = LayoutInflater.from(mContext) 113 .inflate(R.layout.user_picker_user_pod, parent, false); 114 view.setAlpha(1f); 115 view.bringToFront(); 116 return new UserPickerAdapterViewHolder(view); 117 } 118 119 @Override onBindViewHolder(@onNull UserPickerAdapterViewHolder holder, int position)120 public void onBindViewHolder(@NonNull UserPickerAdapterViewHolder holder, int position) { 121 setItemSpacing(holder.mView, position); 122 UserRecord userRecord = mUsers.get(position); 123 holder.mUserAvatarImageView.setImageDrawable(userRecord.mIcon); 124 holder.mFrame.setBackgroundResource(0); 125 holder.mUserNameTextView.setText(userRecord.mName); 126 setUserLoggedInInfo(holder, userRecord); 127 holder.mView.setOnClickListener(userRecord.mOnClickListener); 128 } 129 130 @Override getItemCount()131 public int getItemCount() { 132 return mUsers != null ? mUsers.size() : 0; 133 } 134 onConfigurationChanged()135 void onConfigurationChanged() { 136 updateTexts(); 137 } 138 updateTexts()139 private void updateTexts() { 140 mLoggedInText = mContext.getString(R.string.logged_in_text); 141 mPrefixOtherSeatLoggedInInfo = mContext 142 .getString(R.string.prefix_logged_in_info_for_other_seat); 143 mStoppingUserText = mContext.getString(R.string.stopping_user_text); 144 } 145 146 // TODO(b/281729191) use RecyclerView.ItemDecoration when supported by CarUiRecyclerView setItemSpacing(View rootItemView, int position)147 private void setItemSpacing(View rootItemView, int position) { 148 ViewGroup.LayoutParams params = rootItemView.getLayoutParams(); 149 if (params instanceof ViewGroup.MarginLayoutParams) { 150 ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams) params; 151 marginLayoutParams.bottomMargin = mVerticalSpacing; 152 153 int splitHorizontalSpacing = mHorizontalSpacing / mNumCols; 154 int col = position % mNumCols; 155 marginLayoutParams.leftMargin = col * splitHorizontalSpacing; 156 marginLayoutParams.rightMargin = (mNumCols - (col + 1)) * splitHorizontalSpacing; 157 158 rootItemView.setLayoutParams(marginLayoutParams); 159 } 160 } 161 dump(@onNull PrintWriter pw)162 void dump(@NonNull PrintWriter pw) { 163 pw.println(" UserRecords : "); 164 for (int i = 0; i < mUsers.size(); i++) { 165 UserRecord userRecord = mUsers.get(i); 166 pw.println(" " + userRecord.toString()); 167 } 168 } 169 170 static final class UserPickerAdapterViewHolder extends RecyclerView.ViewHolder { 171 public final ImageView mUserAvatarImageView; 172 public final TextView mUserNameTextView; 173 public final ImageView mUserBorderImageView; 174 public final TextView mLoggedInTextView; 175 public final View mView; 176 public final FrameLayout mFrame; 177 UserPickerAdapterViewHolder(View view)178 UserPickerAdapterViewHolder(View view) { 179 super(view); 180 mView = view; 181 mUserAvatarImageView = view.findViewById(R.id.user_avatar); 182 mUserNameTextView = view.findViewById(R.id.user_name); 183 mUserBorderImageView = view.findViewById(R.id.user_avatar_border); 184 mLoggedInTextView = view.findViewById(R.id.logged_in_info); 185 mFrame = view.findViewById(R.id.current_user_frame); 186 } 187 } 188 } 189