KeyguardUserSwitcher.java revision 4d75c079f35d85b687d8349e5e2940447d01198e
1/* 2 * Copyright (C) 2014 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.policy; 18 19import com.android.systemui.BitmapHelper; 20import com.android.systemui.R; 21import com.android.systemui.statusbar.phone.StatusBarHeaderView; 22import com.android.systemui.statusbar.phone.UserAvatarView; 23 24import android.app.ActivityManagerNative; 25import android.content.Context; 26import android.content.pm.UserInfo; 27import android.graphics.Bitmap; 28import android.os.AsyncTask; 29import android.os.RemoteException; 30import android.os.UserManager; 31import android.util.Log; 32import android.view.LayoutInflater; 33import android.view.View; 34import android.view.ViewGroup; 35import android.view.ViewStub; 36import android.view.WindowManagerGlobal; 37import android.widget.TextView; 38 39import java.util.ArrayList; 40import java.util.List; 41 42/** 43 * Manages the user switcher on the Keyguard. 44 */ 45public class KeyguardUserSwitcher implements View.OnClickListener { 46 47 private static final String TAG = "KeyguardUserSwitcher"; 48 49 private final Context mContext; 50 private final ViewGroup mUserSwitcher; 51 private final UserManager mUserManager; 52 private final StatusBarHeaderView mHeader; 53 54 public KeyguardUserSwitcher(Context context, ViewStub userSwitcher, 55 StatusBarHeaderView header) { 56 mContext = context; 57 if (context.getResources().getBoolean(R.bool.config_keyguardUserSwitcher)) { 58 mUserSwitcher = (ViewGroup) userSwitcher.inflate(); 59 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 60 mHeader = header; 61 refresh(); 62 } else { 63 mUserSwitcher = null; 64 mUserManager = null; 65 mHeader = null; 66 } 67 } 68 69 public void setKeyguard(boolean keyguard) { 70 if (mUserSwitcher != null) { 71 // TODO: Cache showUserSwitcherOnKeyguard(). 72 if (keyguard && showUserSwitcherOnKeyguard()) { 73 show(); 74 refresh(); 75 } else { 76 hide(); 77 } 78 } 79 } 80 81 /** 82 * @return true if the user switcher should be shown on the lock screen. 83 * @see android.os.UserManager#isUserSwitcherEnabled() 84 */ 85 private boolean showUserSwitcherOnKeyguard() { 86 // TODO: Set isEdu. The edu provisioning process can add settings to Settings.Global. 87 boolean isEdu = false; 88 if (isEdu) { 89 return true; 90 } 91 List<UserInfo> users = mUserManager.getUsers(true /* excludeDying */); 92 int N = users.size(); 93 int switchableUsers = 0; 94 for (int i = 0; i < N; i++) { 95 if (users.get(i).supportsSwitchTo()) { 96 switchableUsers++; 97 } 98 } 99 return switchableUsers > 1; 100 } 101 102 public void show() { 103 if (mUserSwitcher != null) { 104 // TODO: animate 105 mUserSwitcher.setVisibility(View.VISIBLE); 106 mHeader.setKeyguardUserSwitcherShowing(true); 107 } 108 } 109 110 private void hide() { 111 if (mUserSwitcher != null) { 112 // TODO: animate 113 mUserSwitcher.setVisibility(View.GONE); 114 mHeader.setKeyguardUserSwitcherShowing(false); 115 } 116 } 117 118 private void refresh() { 119 if (mUserSwitcher != null) { 120 new AsyncTask<Void, Void, ArrayList<UserData>>() { 121 @Override 122 protected ArrayList<UserData> doInBackground(Void... params) { 123 return loadUsers(); 124 } 125 126 @Override 127 protected void onPostExecute(ArrayList<UserData> userInfos) { 128 bind(userInfos); 129 } 130 }.execute((Void[]) null); 131 } 132 } 133 134 private void bind(ArrayList<UserData> userList) { 135 mUserSwitcher.removeAllViews(); 136 int N = userList.size(); 137 for (int i = 0; i < N; i++) { 138 mUserSwitcher.addView(inflateUser(userList.get(i))); 139 } 140 // TODO: add Guest 141 // TODO: add (+) button 142 } 143 144 private View inflateUser(UserData user) { 145 View v = LayoutInflater.from(mUserSwitcher.getContext()).inflate( 146 R.layout.keyguard_user_switcher_item, mUserSwitcher, false); 147 TextView name = (TextView) v.findViewById(R.id.name); 148 UserAvatarView picture = (UserAvatarView) v.findViewById(R.id.picture); 149 name.setText(user.userInfo.name); 150 picture.setActivated(user.isCurrent); 151 if (user.userInfo.isGuest()) { 152 picture.setDrawable(mContext.getResources().getDrawable(R.drawable.ic_account_circle)); 153 } else { 154 picture.setBitmap(user.userIcon); 155 } 156 v.setOnClickListener(this); 157 v.setTag(user.userInfo); 158 // TODO: mark which user is current for accessibility. 159 return v; 160 } 161 162 @Override 163 public void onClick(View v) { 164 switchUser(((UserInfo)v.getTag()).id); 165 } 166 167 // TODO: Factor out logic below and share with QS implementation. 168 169 private ArrayList<UserData> loadUsers() { 170 ArrayList<UserInfo> users = (ArrayList<UserInfo>) mUserManager 171 .getUsers(true /* excludeDying */); 172 int N = users.size(); 173 ArrayList<UserData> result = new ArrayList<>(N); 174 int currentUser = -1; 175 try { 176 currentUser = ActivityManagerNative.getDefault().getCurrentUser().id; 177 } catch (RemoteException e) { 178 Log.e(TAG, "Couln't get current user.", e); 179 } 180 final int avatarSize 181 = mContext.getResources().getDimensionPixelSize(R.dimen.max_avatar_size); 182 for (int i = 0; i < N; i++) { 183 UserInfo user = users.get(i); 184 if (user.supportsSwitchTo()) { 185 boolean isCurrent = user.id == currentUser; 186 final Bitmap picture = BitmapHelper.createCircularClip( 187 mUserManager.getUserIcon(user.id), 188 avatarSize, avatarSize); 189 result.add(new UserData(user, picture, isCurrent)); 190 } 191 } 192 return result; 193 } 194 195 private void switchUser(int userId) { 196 try { 197 WindowManagerGlobal.getWindowManagerService().lockNow(null); 198 ActivityManagerNative.getDefault().switchUser(userId); 199 } catch (RemoteException e) { 200 Log.e(TAG, "Couldn't switch user.", e); 201 } 202 } 203 204 private static class UserData { 205 final UserInfo userInfo; 206 final Bitmap userIcon; 207 final boolean isCurrent; 208 209 UserData(UserInfo userInfo, Bitmap userIcon, boolean isCurrent) { 210 this.userInfo = userInfo; 211 this.userIcon = userIcon; 212 this.isCurrent = isCurrent; 213 } 214 } 215} 216