10d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk/* 20d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * Copyright (C) 2014 The Android Open Source Project 30d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * 40d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * Licensed under the Apache License, Version 2.0 (the "License"); 50d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * you may not use this file except in compliance with the License. 60d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * You may obtain a copy of the License at 70d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * 80d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * http://www.apache.org/licenses/LICENSE-2.0 90d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * 100d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * Unless required by applicable law or agreed to in writing, software 110d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * distributed under the License is distributed on an "AS IS" BASIS, 120d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * See the License for the specific language governing permissions and 140d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * limitations under the License. 150d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk */ 160d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 170d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkpackage com.android.settingslib.drawer; 180d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 190d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.app.ActivityManager; 200d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 210d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.content.Context; 220d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.content.pm.UserInfo; 230d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.database.DataSetObserver; 240d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.graphics.drawable.BitmapDrawable; 250d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.graphics.drawable.Drawable; 260d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.os.UserHandle; 270d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.os.UserManager; 280d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.view.LayoutInflater; 290d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.view.View; 300d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.view.ViewGroup; 310d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.widget.ImageView; 320d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.widget.ListAdapter; 330d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.widget.SpinnerAdapter; 340d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport android.widget.TextView; 350d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport com.android.internal.util.UserIcons; 36aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Roskyimport com.android.settingslib.drawable.UserIconDrawable; 370d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 380d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport com.android.settingslib.R; 390d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 400d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport java.util.ArrayList; 410d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkimport java.util.List; 420d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 430d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk/** 440d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * Adapter for a spinner that shows a list of users. 450d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk */ 460d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monkpublic class UserAdapter implements SpinnerAdapter, ListAdapter { 470d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk /** Holder for user details */ 480d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public static class UserDetails { 490d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk private final UserHandle mUserHandle; 500d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk private final String mName; 510d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk private final Drawable mIcon; 520d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 530d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public UserDetails(UserHandle userHandle, UserManager um, Context context) { 540d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk mUserHandle = userHandle; 550d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk UserInfo userInfo = um.getUserInfo(mUserHandle.getIdentifier()); 560d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk Drawable icon; 570d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk if (userInfo.isManagedProfile()) { 580d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk mName = context.getString(R.string.managed_user_title); 590d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk icon = context.getDrawable( 600d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk com.android.internal.R.drawable.ic_corp_icon); 610d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } else { 620d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk mName = userInfo.name; 630d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk final int userId = userInfo.id; 640d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk if (um.getUserIcon(userId) != null) { 650d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk icon = new BitmapDrawable(context.getResources(), um.getUserIcon(userId)); 660d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } else { 670d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk icon = UserIcons.getDefaultUserIcon(userId, /* light= */ false); 680d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 690d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 700d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk this.mIcon = encircle(context, icon); 710d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 720d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 730d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk private static Drawable encircle(Context context, Drawable icon) { 74aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky return new UserIconDrawable(UserIconDrawable.getSizeForList(context)) 75aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky .setIconDrawable(icon).bake(); 760d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 770d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 780d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk private ArrayList<UserDetails> data; 790d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk private final LayoutInflater mInflater; 800d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 810d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public UserAdapter(Context context, ArrayList<UserDetails> users) { 820d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk if (users == null) { 830d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk throw new IllegalArgumentException("A list of user details must be provided"); 840d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 850d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk this.data = users; 860d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 870d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 880d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 890d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public UserHandle getUserHandle(int position) { 900d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk if (position < 0 || position >= data.size()) { 910d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return null; 920d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 930d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return data.get(position).mUserHandle; 940d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 950d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 960d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk @Override 970d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public View getDropDownView(int position, View convertView, ViewGroup parent) { 980d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk final View row = convertView != null ? convertView : createUser(parent); 990d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1000d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk UserDetails user = data.get(position); 1010d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk ((ImageView) row.findViewById(android.R.id.icon)).setImageDrawable(user.mIcon); 1020d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk ((TextView) row.findViewById(android.R.id.title)).setText(getTitle(user)); 1030d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return row; 1040d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1050d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1060d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk private int getTitle(UserDetails user) { 1070d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk int userHandle = user.mUserHandle.getIdentifier(); 1080d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk if (userHandle == UserHandle.USER_CURRENT 1090d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk || userHandle == ActivityManager.getCurrentUser()) { 1100d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return R.string.category_personal; 1110d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } else { 1120d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return R.string.category_work; 1130d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1140d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1150d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1160d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk private View createUser(ViewGroup parent) { 1170d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return mInflater.inflate(R.layout.user_preference, parent, false); 1180d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1190d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1200d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk @Override 1210d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public void registerDataSetObserver(DataSetObserver observer) { 1220d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk // We don't support observers 1230d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1240d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1250d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk @Override 1260d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public void unregisterDataSetObserver(DataSetObserver observer) { 1270d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk // We don't support observers 1280d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1290d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1300d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk @Override 1310d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public int getCount() { 1320d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return data.size(); 1330d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1340d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1350d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk @Override 1360d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public UserDetails getItem(int position) { 1370d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return data.get(position); 1380d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1390d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1400d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk @Override 1410d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public long getItemId(int position) { 1420d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return data.get(position).mUserHandle.getIdentifier(); 1430d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1440d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1450d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk @Override 1460d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public boolean hasStableIds() { 1470d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return false; 1480d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1490d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1500d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk @Override 1510d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public View getView(int position, View convertView, ViewGroup parent) { 1520d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return getDropDownView(position, convertView, parent); 1530d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1540d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1550d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk @Override 1560d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public int getItemViewType(int position) { 1570d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return 0; 1580d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1590d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1600d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk @Override 1610d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public int getViewTypeCount() { 1620d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return 1; 1630d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1640d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1650d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk @Override 1660d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public boolean isEmpty() { 1670d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return data.isEmpty(); 1680d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1690d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1700d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk @Override 1710d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public boolean areAllItemsEnabled() { 1720d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return true; 1730d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1740d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1750d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk @Override 1760d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public boolean isEnabled(int position) { 1770d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return true; 1780d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1790d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1800d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk /** 1810d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * Creates a {@link UserAdapter} if there is more than one profile on the device. 1820d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * 1830d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * <p> The adapter can be used to populate a spinner that switches between the Settings 1840d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * app on the different profiles. 1850d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * 1860d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk * @return a {@link UserAdapter} or null if there is only one profile. 1870d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk */ 1880d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public static UserAdapter createUserSpinnerAdapter(UserManager userManager, 1890d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk Context context) { 1900d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk List<UserHandle> userProfiles = userManager.getUserProfiles(); 1910d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk if (userProfiles.size() < 2) { 1920d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return null; 1930d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 1940d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 1950d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk UserHandle myUserHandle = new UserHandle(UserHandle.myUserId()); 1960d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk // The first option should be the current profile 1970d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk userProfiles.remove(myUserHandle); 1980d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk userProfiles.add(0, myUserHandle); 1990d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 2000d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return createUserAdapter(userManager, context, userProfiles); 2010d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 2020d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk 2030d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk public static UserAdapter createUserAdapter(UserManager userManager, 2040d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk Context context, List<UserHandle> userProfiles) { 2050d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk ArrayList<UserDetails> userDetails = new ArrayList<UserDetails>(userProfiles.size()); 2060d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk final int count = userProfiles.size(); 2070d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk for (int i = 0; i < count; i++) { 2080d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk userDetails.add(new UserDetails(userProfiles.get(i), userManager, context)); 2090d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 2100d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk return new UserAdapter(context, userDetails); 2110d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk } 2120d72d20c2f2a3c5c98a73e97914e96a82b04eff8Jason Monk} 213