13d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi/* 23d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi * Copyright (C) 2014 The Android Open Source Project 33d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi * 43d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License"); 53d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi * you may not use this file except in compliance with the License. 63d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi * You may obtain a copy of the License at 73d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi * 83d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi * http://www.apache.org/licenses/LICENSE-2.0 93d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi * 103d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi * Unless required by applicable law or agreed to in writing, software 113d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS, 123d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi * See the License for the specific language governing permissions and 143d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi * limitations under the License 153d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi */ 163d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 173d878be53d033365318733b84b764cd5b4e6357aJorim Jaggipackage com.android.systemui.statusbar.policy; 183d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 193d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.app.ActivityManagerNative; 203d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.content.BroadcastReceiver; 213d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.content.Context; 223d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.content.Intent; 233d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.content.IntentFilter; 243d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.content.pm.PackageManager; 253d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.content.pm.UserInfo; 262b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roosimport android.content.res.Resources; 273d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.database.Cursor; 283d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.graphics.Bitmap; 293d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.graphics.drawable.BitmapDrawable; 303d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.graphics.drawable.Drawable; 313d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.os.AsyncTask; 323d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.os.RemoteException; 333d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.os.UserHandle; 343d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.os.UserManager; 353d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.provider.ContactsContract; 363d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.util.Log; 373d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport android.util.Pair; 383d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 394d75c079f35d85b687d8349e5e2940447d01198eDan Sandlerimport com.android.systemui.BitmapHelper; 403d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport com.android.systemui.R; 4164d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.internal.util.UserIcons; 423d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 433d878be53d033365318733b84b764cd5b4e6357aJorim Jaggiimport java.util.ArrayList; 443d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 453d878be53d033365318733b84b764cd5b4e6357aJorim Jaggipublic final class UserInfoController { 463d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 473d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi private static final String TAG = "UserInfoController"; 483d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 493d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi private final Context mContext; 503d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi private final ArrayList<OnUserInfoChangedListener> mCallbacks = 513d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi new ArrayList<OnUserInfoChangedListener>(); 523d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi private AsyncTask<Void, Void, Pair<String, Drawable>> mUserInfoTask; 533d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 543d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi private boolean mUseDefaultAvatar; 553d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi private String mUserName; 563d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi private Drawable mUserDrawable; 573d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 583d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi public UserInfoController(Context context) { 593d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi mContext = context; 603d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi IntentFilter filter = new IntentFilter(); 613d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi filter.addAction(Intent.ACTION_USER_SWITCHED); 623d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 633d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi mContext.registerReceiver(mReceiver, filter); 643d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 653d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi IntentFilter profileFilter = new IntentFilter(); 663d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi profileFilter.addAction(ContactsContract.Intents.ACTION_PROFILE_CHANGED); 673d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi profileFilter.addAction(Intent.ACTION_USER_INFO_CHANGED); 683d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi mContext.registerReceiverAsUser(mProfileReceiver, UserHandle.ALL, profileFilter, 693d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi null, null); 703d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 713d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 723d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi public void addListener(OnUserInfoChangedListener callback) { 733d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi mCallbacks.add(callback); 743d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 753d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 763d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 773d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi @Override 783d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi public void onReceive(Context context, Intent intent) { 793d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi final String action = intent.getAction(); 803d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi if (Intent.ACTION_USER_SWITCHED.equals(action)) { 813d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi reloadUserInfo(); 823d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { 833d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi if (mUseDefaultAvatar) { 843d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi reloadUserInfo(); 853d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 863d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 873d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 883d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi }; 893d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 903d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi private final BroadcastReceiver mProfileReceiver = new BroadcastReceiver() { 913d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi @Override 923d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi public void onReceive(Context context, Intent intent) { 933d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi final String action = intent.getAction(); 943d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi if (ContactsContract.Intents.ACTION_PROFILE_CHANGED.equals(action) || 953d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi Intent.ACTION_USER_INFO_CHANGED.equals(action)) { 963d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi try { 973d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi final int currentUser = ActivityManagerNative.getDefault().getCurrentUser().id; 983d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi final int changedUser = 993d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()); 1003d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi if (changedUser == currentUser) { 1013d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi reloadUserInfo(); 1023d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1033d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } catch (RemoteException e) { 1043d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi Log.e(TAG, "Couldn't get current user id for profile change", e); 1053d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1063d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1073d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1083d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi }; 1093d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 1103d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi public void reloadUserInfo() { 1113d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi if (mUserInfoTask != null) { 1123d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi mUserInfoTask.cancel(false); 1133d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi mUserInfoTask = null; 1143d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1153d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi queryForUserInformation(); 1163d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1173d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 1183d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi private void queryForUserInformation() { 1193d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi Context currentUserContext; 1203d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi UserInfo userInfo; 1213d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi try { 1223d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi userInfo = ActivityManagerNative.getDefault().getCurrentUser(); 1233d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi currentUserContext = mContext.createPackageContextAsUser("android", 0, 1243d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi new UserHandle(userInfo.id)); 1253d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } catch (PackageManager.NameNotFoundException e) { 1263d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi Log.e(TAG, "Couldn't create user context", e); 1273d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi throw new RuntimeException(e); 1283d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } catch (RemoteException e) { 1293d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi Log.e(TAG, "Couldn't get user info", e); 1303d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi throw new RuntimeException(e); 1313d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1323d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi final int userId = userInfo.id; 13364d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina final boolean isGuest = userInfo.isGuest(); 1343d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi final String userName = userInfo.name; 1352b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roos 1362b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roos final Resources res = mContext.getResources(); 1372b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roos final int avatarSize = Math.max( 1382b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roos res.getDimensionPixelSize(R.dimen.multi_user_avatar_expanded_size), 1392b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roos res.getDimensionPixelSize(R.dimen.multi_user_avatar_keyguard_size)); 1403d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 1413d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi final Context context = currentUserContext; 1423d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi mUserInfoTask = new AsyncTask<Void, Void, Pair<String, Drawable>>() { 1433d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi @Override 1443d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi protected Pair<String, Drawable> doInBackground(Void... params) { 1453d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi final UserManager um = UserManager.get(mContext); 1463d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 1473d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi // Fall back to the UserManager nickname if we can't read the name from the local 1483d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi // profile below. 1493d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi String name = userName; 1503d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi Drawable avatar = null; 1513d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi Bitmap rawAvatar = um.getUserIcon(userId); 1523d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi if (rawAvatar != null) { 1534d75c079f35d85b687d8349e5e2940447d01198eDan Sandler avatar = new BitmapDrawable(mContext.getResources(), 1544d75c079f35d85b687d8349e5e2940447d01198eDan Sandler BitmapHelper.createCircularClip(rawAvatar, avatarSize, avatarSize)); 1553d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } else { 15664d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina avatar = UserIcons.getDefaultUserIcon(isGuest? UserHandle.USER_NULL : userId, 15764d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina /* light= */ true); 1583d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi mUseDefaultAvatar = true; 1593d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1603d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 1613d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi // If it's a single-user device, get the profile name, since the nickname is not 1623d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi // usually valid 1633d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi if (um.getUsers().size() <= 1) { 1643d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi // Try and read the display name from the local profile 1653d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi final Cursor cursor = context.getContentResolver().query( 1663d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi ContactsContract.Profile.CONTENT_URI, new String[] { 1672b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roos ContactsContract.CommonDataKinds.Phone._ID, 1682b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roos ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME 1692b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roos }, null, null, null); 1703d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi if (cursor != null) { 1713d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi try { 1723d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi if (cursor.moveToFirst()) { 1733d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi name = cursor.getString(cursor.getColumnIndex( 1743d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); 1753d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1763d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } finally { 1773d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi cursor.close(); 1783d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1793d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1803d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1813d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi return new Pair<String, Drawable>(name, avatar); 1823d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1833d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 1843d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi @Override 1853d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi protected void onPostExecute(Pair<String, Drawable> result) { 1863d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi mUserName = result.first; 1873d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi mUserDrawable = result.second; 1883d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi mUserInfoTask = null; 1893d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi notifyChanged(); 1903d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1913d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi }; 1923d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi mUserInfoTask.execute(); 1933d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1943d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 1953d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi private void notifyChanged() { 1963d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi for (OnUserInfoChangedListener listener : mCallbacks) { 1973d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi listener.onUserInfoChanged(mUserName, mUserDrawable); 1983d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 1993d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 2003d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi 2013d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi public interface OnUserInfoChangedListener { 2023d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi public void onUserInfoChanged(String name, Drawable picture); 2033d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi } 2043d878be53d033365318733b84b764cd5b4e6357aJorim Jaggi} 205