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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user