blob: 41b70f8537e75972c132315c30889376dfaab4cb [file] [log] [blame]
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -07001/*
2 * Copyright (C) 2018 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
17package com.android.systemui.statusbar.car;
18
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070019import android.content.Context;
20import android.content.pm.UserInfo;
Aarthi Balachander608b6e32018-04-11 18:41:52 -070021import android.content.res.ColorStateList;
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070022import android.content.res.Resources;
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070023import android.os.AsyncTask;
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070024import android.support.v7.widget.RecyclerView;
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070025import android.util.AttributeSet;
26import android.view.LayoutInflater;
27import android.view.View;
28import android.view.ViewGroup;
29import android.widget.ImageView;
30import android.widget.TextView;
31
Aarthi Balachander608b6e32018-04-11 18:41:52 -070032import androidx.car.widget.PagedListView;
33
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070034import com.android.settingslib.users.UserManagerHelper;
35import com.android.systemui.R;
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070036
37import java.util.ArrayList;
38import java.util.List;
39
40/**
41 * Displays a GridLayout with icons for the users in the system to allow switching between users.
42 * One of the uses of this is for the lock screen in auto.
43 */
Aarthi Balachander608b6e32018-04-11 18:41:52 -070044public class UserGridRecyclerView extends PagedListView implements
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070045 UserManagerHelper.OnUsersUpdateListener {
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070046 private UserSelectionListener mUserSelectionListener;
47 private UserAdapter mAdapter;
48 private UserManagerHelper mUserManagerHelper;
49 private Context mContext;
50
51 public UserGridRecyclerView(Context context, AttributeSet attrs) {
52 super(context, attrs);
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070053 mContext = context;
54 mUserManagerHelper = new UserManagerHelper(mContext);
55 }
56
57 /**
58 * Register listener for any update to the users
59 */
60 @Override
61 public void onFinishInflate() {
Aarthi Balachander608b6e32018-04-11 18:41:52 -070062 super.onFinishInflate();
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070063 mUserManagerHelper.registerOnUsersUpdateListener(this);
64 }
65
66 /**
67 * Unregisters listener checking for any change to the users
68 */
69 @Override
70 public void onDetachedFromWindow() {
Aarthi Balachander608b6e32018-04-11 18:41:52 -070071 super.onDetachedFromWindow();
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070072 mUserManagerHelper.unregisterOnUsersUpdateListener();
73 }
74
75 /**
76 * Initializes the adapter that populates the grid layout
77 *
78 * @return the adapter
79 */
80 public void buildAdapter() {
81 List<UserRecord> userRecords = createUserRecords(mUserManagerHelper
82 .getAllUsers());
83 mAdapter = new UserAdapter(mContext, userRecords);
84 super.setAdapter(mAdapter);
85 }
86
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070087 private List<UserRecord> createUserRecords(List<UserInfo> userInfoList) {
88 List<UserRecord> userRecords = new ArrayList<>();
89 for (UserInfo userInfo : userInfoList) {
jovanak80b48592018-04-11 17:09:53 -070090 if (userInfo.isGuest()) {
91 // Don't display guests in the switcher.
92 continue;
93 }
jovanak0535abc2018-04-10 15:14:50 -070094 boolean isForeground = mUserManagerHelper.getForegroundUserId() == userInfo.id;
jovanak80b48592018-04-11 17:09:53 -070095 UserRecord record = new UserRecord(userInfo, false /* isStartGuestSession */,
jovanak0535abc2018-04-10 15:14:50 -070096 false /* isAddUser */, isForeground);
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -070097 userRecords.add(record);
98 }
99
jovanak0535abc2018-04-10 15:14:50 -0700100 // Add guest user record if the foreground user is not a guest
jovanak82029ae2018-04-02 16:40:15 -0700101 if (!mUserManagerHelper.foregroundUserIsGuestUser()) {
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700102 userRecords.add(addGuestUserRecord());
103 }
104
jovanak0535abc2018-04-10 15:14:50 -0700105 // Add add user record if the foreground user can add users
jovanak82029ae2018-04-02 16:40:15 -0700106 if (mUserManagerHelper.foregroundUserCanAddUsers()) {
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700107 userRecords.add(addUserRecord());
108 }
109
110 return userRecords;
111 }
112
113 /**
114 * Create guest user record
115 */
116 private UserRecord addGuestUserRecord() {
117 UserInfo userInfo = new UserInfo();
118 userInfo.name = mContext.getString(R.string.car_guest);
jovanak80b48592018-04-11 17:09:53 -0700119 return new UserRecord(userInfo, true /* isStartGuestSession */,
jovanak0535abc2018-04-10 15:14:50 -0700120 false /* isAddUser */, false /* isForeground */);
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700121 }
122
123 /**
124 * Create add user record
125 */
126 private UserRecord addUserRecord() {
127 UserInfo userInfo = new UserInfo();
128 userInfo.name = mContext.getString(R.string.car_add_user);
jovanak80b48592018-04-11 17:09:53 -0700129 return new UserRecord(userInfo, false /* isStartGuestSession */,
jovanak0535abc2018-04-10 15:14:50 -0700130 true /* isAddUser */, false /* isForeground */);
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700131 }
132
133 public void setUserSelectionListener(UserSelectionListener userSelectionListener) {
134 mUserSelectionListener = userSelectionListener;
135 }
136
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700137 @Override
138 public void onUsersUpdate() {
139 mAdapter.clearUsers();
140 mAdapter.updateUsers(createUserRecords(mUserManagerHelper.getAllUsers()));
141 mAdapter.notifyDataSetChanged();
142 }
143
144 /**
145 * Adapter to populate the grid layout with the available user profiles
146 */
147 public final class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserAdapterViewHolder> {
148
149 private final Context mContext;
150 private List<UserRecord> mUsers;
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700151 private final Resources mRes;
152 private final String mGuestName;
153 private final String mNewUserName;
154
155 public UserAdapter(Context context, List<UserRecord> users) {
156 mRes = context.getResources();
157 mContext = context;
158 updateUsers(users);
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700159 mGuestName = mRes.getString(R.string.car_guest);
160 mNewUserName = mRes.getString(R.string.car_new_user);
161 }
162
163 public void clearUsers() {
164 mUsers.clear();
165 }
166
167 public void updateUsers(List<UserRecord> users) {
168 mUsers = users;
169 }
170
171 @Override
172 public UserAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
173 View view = LayoutInflater.from(mContext)
174 .inflate(R.layout.car_fullscreen_user_pod, parent, false);
175 view.setAlpha(1f);
176 view.bringToFront();
177 return new UserAdapterViewHolder(view);
178 }
179
180 @Override
181 public void onBindViewHolder(UserAdapterViewHolder holder, int position) {
182 UserRecord userRecord = mUsers.get(position);
Aarthi Balachander608b6e32018-04-11 18:41:52 -0700183 if (!userRecord.mIsAddUser) {
184 holder.mUserAvatarImageView.setImageBitmap(mUserManagerHelper
185 .getUserIcon(userRecord.mInfo));
186 } else {
187 holder.mUserAvatarImageView.setImageDrawable(mContext
188 .getDrawable(R.drawable.ic_add_circle_qs));
189 }
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700190 holder.mUserNameTextView.setText(userRecord.mInfo.name);
191 holder.mView.setOnClickListener(v -> {
192 if (userRecord == null) {
193 return;
194 }
195
Aarthi Balachander608b6e32018-04-11 18:41:52 -0700196 // Disable button so it cannot be clicked multiple times
197 holder.mView.setEnabled(false);
198
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700199 // Notify the listener which user was selected
200 if (mUserSelectionListener != null) {
201 mUserSelectionListener.onUserSelected(userRecord);
202 }
203
jovanak80b48592018-04-11 17:09:53 -0700204 // If the user selects Guest, start the guest session.
205 if (userRecord.mIsStartGuestSession) {
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700206 mUserManagerHelper.switchToGuest(mGuestName);
207 return;
208 }
209
210 // If the user wants to add a user, start task to add new user
211 if (userRecord.mIsAddUser) {
212 new AddNewUserTask().execute(mNewUserName);
213 return;
214 }
215
216 // If the user doesn't want to be a guest or add a user, switch to the user selected
217 mUserManagerHelper.switchToUser(userRecord.mInfo);
218 });
219
220 }
221
222 private class AddNewUserTask extends AsyncTask<String, Void, UserInfo> {
223
224 @Override
225 protected UserInfo doInBackground(String... userNames) {
226 return mUserManagerHelper.createNewUser(userNames[0]);
227 }
228
229 @Override
230 protected void onPreExecute() {
231 }
232
233 @Override
234 protected void onPostExecute(UserInfo user) {
235 if (user != null) {
236 mUserManagerHelper.switchToUser(user);
237 }
238 }
239 }
240
241 @Override
242 public int getItemCount() {
243 return mUsers.size();
244 }
245
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700246 public class UserAdapterViewHolder extends RecyclerView.ViewHolder {
247
248 public ImageView mUserAvatarImageView;
249 public TextView mUserNameTextView;
250 public View mView;
251
252 public UserAdapterViewHolder(View view) {
253 super(view);
254 mView = view;
255 mUserAvatarImageView = (ImageView) view.findViewById(R.id.user_avatar);
256 mUserNameTextView = (TextView) view.findViewById(R.id.user_name);
257 }
258 }
259 }
260
261 /**
262 * Object wrapper class for the userInfo. Use it to distinguish if a profile is a
jovanak0535abc2018-04-10 15:14:50 -0700263 * guest profile, add user profile, or the foreground user.
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700264 */
265 public static final class UserRecord {
266
267 public final UserInfo mInfo;
jovanak80b48592018-04-11 17:09:53 -0700268 public final boolean mIsStartGuestSession;
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700269 public final boolean mIsAddUser;
jovanak0535abc2018-04-10 15:14:50 -0700270 public final boolean mIsForeground;
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700271
jovanak80b48592018-04-11 17:09:53 -0700272 public UserRecord(UserInfo userInfo, boolean isStartGuestSession, boolean isAddUser,
jovanak0535abc2018-04-10 15:14:50 -0700273 boolean isForeground) {
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700274 mInfo = userInfo;
jovanak80b48592018-04-11 17:09:53 -0700275 mIsStartGuestSession = isStartGuestSession;
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700276 mIsAddUser = isAddUser;
jovanak0535abc2018-04-10 15:14:50 -0700277 mIsForeground = isForeground;
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700278 }
279 }
280
281 /**
282 * Listener used to notify when a user has been selected
283 */
284 interface UserSelectionListener {
285
286 void onUserSelected(UserRecord record);
287 }
288}