1 /* 2 * Copyright (C) 2020 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 package com.google.android.car.kitchensink.users; 17 18 import android.annotation.NonNull; 19 import android.annotation.Nullable; 20 import android.annotation.UserIdInt; 21 import android.content.Context; 22 import android.content.pm.UserInfo; 23 import android.os.UserHandle; 24 import android.text.TextUtils; 25 import android.util.AttributeSet; 26 import android.util.Log; 27 import android.view.View; 28 import android.widget.AdapterView; 29 import android.widget.ArrayAdapter; 30 import android.widget.Spinner; 31 32 import java.util.Arrays; 33 import java.util.List; 34 35 /** 36 * Custom {@link Spinner} to show a list of Android users. 37 */ 38 public final class UsersSpinner extends Spinner { 39 40 private static final String TAG = UsersSpinner.class.getSimpleName(); 41 42 private UserInfo[] mUsers; 43 private String[] mEntries; 44 private OnUserSelectedListener mListener; 45 UsersSpinner(Context context, AttributeSet attrs)46 public UsersSpinner(Context context, AttributeSet attrs) { 47 super(context, attrs); 48 } 49 50 /** 51 * Initializes the spinner with the given users. 52 */ init(List<UserInfo> users)53 public void init(List<UserInfo> users) { 54 Log.v(TAG, "init(): " + users.size() + " users (" + users + ")"); 55 int size = users.size(); 56 mUsers = new UserInfo[size]; 57 users.toArray(mUsers); 58 mEntries = new String[size]; 59 for (int i = 0; i < size; i++) { 60 UserInfo user = mUsers[i]; 61 StringBuilder entry = new StringBuilder().append(user.id).append('-'); 62 if (!TextUtils.isEmpty(user.name)) { 63 entry.append(user.name); 64 } else { 65 if (user.id == UserHandle.USER_SYSTEM) { 66 entry.append("SYSTEM"); 67 } else { 68 entry.append(UserInfo.flagsToString(user.flags)); 69 } 70 } 71 mEntries[i] = entry.toString(); 72 } 73 Log.v(TAG, "initializing spinner with " + size + " entries: " + Arrays.toString(mEntries)); 74 setAdapter(new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, 75 mEntries)); 76 setOnItemSelectedListener(new OnItemSelectedListener() { 77 @Override 78 public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 79 UserInfo user = getSelectedUser(); 80 Log.v(TAG, "onItemSelected(): index=" + position + ", user=" + user); 81 if (mListener != null) { 82 mListener.onUserSelected(user); 83 } 84 } 85 86 @Override 87 public void onNothingSelected(AdapterView<?> parent) { 88 Log.v(TAG, "nothing selected"); 89 } 90 }); 91 } 92 93 /** 94 * Gets the selected user id, or {@link UserHandle#USER_NULL}. 95 */ getSelectedUserId()96 public @UserIdInt int getSelectedUserId() { 97 UserInfo user = getSelectedUser(); 98 return user == null ? UserHandle.USER_NULL : user.id; 99 } 100 101 /** 102 * Gets the selected user info. 103 */ getSelectedUser()104 public @Nullable UserInfo getSelectedUser() { 105 int selectedIndex = getSelectedItemPosition(); 106 Log.v(TAG, "getSelectedUser(): index=" + selectedIndex); 107 try { 108 return mUsers[selectedIndex]; 109 } catch (RuntimeException e) { 110 Log.e(TAG, "getSelectedUserId(): failed to get user at index " + selectedIndex 111 + ". Users: " + Arrays.toString(mUsers)); 112 return null; 113 } 114 } 115 116 /** 117 * Sets the listener called when the spinner value change. 118 */ setOnUserSelectedListener(@ullable OnUserSelectedListener listener)119 public void setOnUserSelectedListener(@Nullable OnUserSelectedListener listener) { 120 mListener = listener; 121 } 122 123 /** 124 * Listener called when the spinner value change. 125 */ 126 public interface OnUserSelectedListener { 127 /** 128 * Callback for the selected user. 129 */ onUserSelected(@onNull UserInfo user)130 void onUserSelected(@NonNull UserInfo user); 131 } 132 } 133