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