More user management ui work

Show setup dialog after adding user.
Write user profile to nickname on setup.
Remove self.
Correct dialog text for user creation.

Bug: 7104261
Bug: 7174751
Bug: 7174685

Change-Id: I0ecd688f3edaef61332f974012454ceb87762e9f
This commit is contained in:
Amith Yamasani
2012-09-16 17:53:35 -07:00
parent d41fd604cb
commit ae47ef43fa
4 changed files with 161 additions and 64 deletions

View File

@@ -23,25 +23,41 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.preference.Preference;
import android.preference.PreferenceActivity.Header;
import android.preference.PreferenceFrameLayout;
import android.preference.PreferenceGroup;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Profile;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TabWidget;
import com.android.settings.users.ProfileUpdateReceiver;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.Iterator;
import java.util.List;
@@ -445,4 +461,55 @@ public class Utils {
return R.string.tether_settings_title_bluetooth;
}
}
/* Used by UserSettings as well. Call this on a non-ui thread. */
public static boolean copyMeProfilePhoto(Context context, UserInfo user) {
Uri contactUri = Profile.CONTENT_URI;
InputStream avatarDataStream = Contacts.openContactPhotoInputStream(
context.getContentResolver(),
contactUri, true);
// If there's no profile photo, assign a default avatar
if (avatarDataStream == null) {
return false;
}
int userId = user != null ? user.id : UserHandle.myUserId();
UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
ParcelFileDescriptor fd = um.setUserIcon(userId);
FileOutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
byte[] buffer = new byte[4096];
int readSize;
try {
while ((readSize = avatarDataStream.read(buffer)) > 0) {
os.write(buffer, 0, readSize);
}
return true;
} catch (IOException ioe) {
Log.e("copyProfilePhoto", "Error copying profile photo " + ioe);
} finally {
try {
os.close();
avatarDataStream.close();
} catch (IOException ioe) { }
}
return false;
}
public static String getMeProfileName(Context context) {
Cursor cursor = context.getContentResolver().query(
Profile.CONTENT_URI, new String[] {Phone._ID, Phone.DISPLAY_NAME},
null, null, null);
if (cursor == null) {
return null;
}
try {
if (cursor.moveToFirst()) {
return cursor.getString(cursor.getColumnIndex(Phone.DISPLAY_NAME));
}
} finally {
cursor.close();
}
return null;
}
}

View File

@@ -19,64 +19,45 @@ package com.android.settings.users;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.content.SharedPreferences;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Profile;
import android.util.Log;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import com.android.settings.Utils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Watches for changes to Me Profile in Contacts and writes the photo to the User Manager.
*/
public class ProfileUpdateReceiver extends BroadcastReceiver {
private static final String KEY_PROFILE_NAME_COPIED_ONCE = "name_copied_once";
@Override
public void onReceive(final Context context, Intent intent) {
// Profile changed, lets get the photo and write to user manager
new Thread() {
public void run() {
copyProfilePhoto(context, null);
Utils.copyMeProfilePhoto(context, null);
copyProfileName(context);
}
}.start();
}
/* Used by UserSettings as well. Call this on a non-ui thread. */
static boolean copyProfilePhoto(Context context, UserInfo user) {
Uri contactUri = Profile.CONTENT_URI;
static void copyProfileName(Context context) {
SharedPreferences prefs = context.getSharedPreferences("profile", Context.MODE_PRIVATE);
if (prefs.contains(KEY_PROFILE_NAME_COPIED_ONCE)) {
return;
}
InputStream avatarDataStream = Contacts.openContactPhotoInputStream(
context.getContentResolver(),
contactUri, true);
// If there's no profile photo, assign a default avatar
if (avatarDataStream == null) {
return false;
}
int userId = user != null ? user.id : UserHandle.myUserId();
int userId = UserHandle.myUserId();
UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
ParcelFileDescriptor fd = um.setUserIcon(userId);
FileOutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
byte[] buffer = new byte[4096];
int readSize;
try {
while ((readSize = avatarDataStream.read(buffer)) > 0) {
os.write(buffer, 0, readSize);
}
return true;
} catch (IOException ioe) {
Log.e("copyProfilePhoto", "Error copying profile photo " + ioe);
} finally {
try {
os.close();
avatarDataStream.close();
} catch (IOException ioe) { }
String profileName = Utils.getMeProfileName(context);
if (profileName != null && profileName.length() > 0) {
um.setUserName(userId, profileName);
// Flag that we've written the profile one time at least. No need to do it in the future.
prefs.edit().putBoolean(KEY_PROFILE_NAME_COPIED_ONCE, true).commit();
}
return false;
}
}

View File

@@ -16,6 +16,7 @@
package com.android.settings.users;
import android.app.ActivityManagerNative;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
@@ -36,6 +37,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.preference.EditTextPreference;
@@ -46,6 +48,7 @@ import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.text.InputType;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
@@ -54,8 +57,10 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
import com.android.internal.telephony.MccTable;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -77,8 +82,10 @@ public class UserSettings extends SettingsPreferenceFragment
private static final int DIALOG_CONFIRM_REMOVE = 1;
private static final int DIALOG_ADD_USER = 2;
private static final int DIALOG_SETUP_USER = 3;
private static final int MESSAGE_UPDATE_LIST = 1;
private static final int MESSAGE_SETUP_USER = 2;
private static final int[] USER_DRAWABLES = {
R.drawable.ic_user,
@@ -98,6 +105,7 @@ public class UserSettings extends SettingsPreferenceFragment
private Preference mMePreference;
private EditTextPreference mNicknamePreference;
private int mRemovingUserId = -1;
private int mAddedUserId = 0;
private boolean mAddingUser;
private boolean mProfileExists;
@@ -111,6 +119,9 @@ public class UserSettings extends SettingsPreferenceFragment
case MESSAGE_UPDATE_LIST:
updateUserList();
break;
case MESSAGE_SETUP_USER:
onUserCreated(msg.arg1);
break;
}
}
};
@@ -136,7 +147,8 @@ public class UserSettings extends SettingsPreferenceFragment
}
mNicknamePreference = (EditTextPreference) findPreference(KEY_USER_NICKNAME);
mNicknamePreference.setOnPreferenceChangeListener(this);
mNicknamePreference.setSummary(mUserManager.getUserInfo(UserHandle.myUserId()).name);
mNicknamePreference.getEditText().setInputType(
InputType.TYPE_TEXT_VARIATION_NORMAL | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
loadProfile();
setHasOptionsMenu(true);
getActivity().registerReceiver(mUserChangeReceiver,
@@ -229,13 +241,22 @@ public class UserSettings extends SettingsPreferenceFragment
}
}
private void onUserCreated(int userId) {
mAddedUserId = userId;
showDialog(DIALOG_SETUP_USER);
}
@Override
public Dialog onCreateDialog(int dialogId) {
switch (dialogId) {
case DIALOG_CONFIRM_REMOVE:
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.user_confirm_remove_title)
.setMessage(R.string.user_confirm_remove_message)
.setTitle(UserHandle.myUserId() == mRemovingUserId
? R.string.user_confirm_remove_self_title
: R.string.user_confirm_remove_title)
.setMessage(UserHandle.myUserId() == mRemovingUserId
? R.string.user_confirm_remove_self_message
: R.string.user_confirm_remove_message)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
@@ -256,6 +277,19 @@ public class UserSettings extends SettingsPreferenceFragment
})
.setNegativeButton(android.R.string.cancel, null)
.create();
case DIALOG_SETUP_USER:
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.user_setup_dialog_title)
.setMessage(R.string.user_setup_dialog_message)
.setPositiveButton(R.string.user_setup_button_setup_now,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
switchUserNow(mAddedUserId);
}
})
.setNegativeButton(R.string.user_setup_button_setup_later, null)
.create();
default:
return null;
}
@@ -279,11 +313,12 @@ public class UserSettings extends SettingsPreferenceFragment
}
private void removeThisUser() {
// TODO:
Toast.makeText(getActivity(), "Not implemented yet!", Toast.LENGTH_SHORT).show();
synchronized (mUserLock) {
mRemovingUserId = -1;
try {
ActivityManagerNative.getDefault().switchUser(UserHandle.USER_OWNER);
((UserManager) getActivity().getSystemService(Context.USER_SERVICE))
.removeUser(UserHandle.myUserId());
} catch (RemoteException re) {
Log.e(TAG, "Unable to remove self user");
}
}
@@ -302,12 +337,22 @@ public class UserSettings extends SettingsPreferenceFragment
synchronized (mUserLock) {
mAddingUser = false;
mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
mHandler.sendMessage(mHandler.obtainMessage(
MESSAGE_SETUP_USER, user.id, user.serialNumber));
}
}
}.start();
}
}
private void switchUserNow(int userId) {
try {
ActivityManagerNative.getDefault().switchUser(userId);
} catch (RemoteException re) {
// Nothing to do
}
}
private void updateUserList() {
List<UserInfo> users = mUserManager.getUsers();
@@ -318,6 +363,8 @@ public class UserSettings extends SettingsPreferenceFragment
Preference pref;
if (user.id == UserHandle.myUserId()) {
pref = mMePreference;
mNicknamePreference.setText(user.name);
mNicknamePreference.setSummary(user.name);
} else {
pref = new UserPreference(getActivity(), null, user.id,
UserHandle.myUserId() == UserHandle.USER_OWNER, this);
@@ -347,29 +394,17 @@ public class UserSettings extends SettingsPreferenceFragment
}
private void assignProfilePhoto(final UserInfo user) {
if (!ProfileUpdateReceiver.copyProfilePhoto(getActivity(), user)) {
if (!Utils.copyMeProfilePhoto(getActivity(), user)) {
assignDefaultPhoto(user);
}
}
private String getProfileName() {
Cursor cursor = getActivity().getContentResolver().query(
Profile.CONTENT_URI, CONTACT_PROJECTION, null, null, null);
if (cursor == null) {
Log.w(TAG, "getProfileName() returned NULL cursor!"
+ " contact uri used " + Profile.CONTENT_URI);
return null;
String name = Utils.getMeProfileName(getActivity());
if (name != null) {
mProfileExists = true;
}
try {
if (cursor.moveToFirst()) {
mProfileExists = true;
return cursor.getString(cursor.getColumnIndex(Phone.DISPLAY_NAME));
}
} finally {
cursor.close();
}
return null;
return name;
}
private void assignDefaultPhoto(UserInfo user) {