OSDN Git Service

More user management ui work
authorAmith Yamasani <yamasani@google.com>
Mon, 17 Sep 2012 00:53:35 +0000 (17:53 -0700)
committerAmith Yamasani <yamasani@google.com>
Mon, 17 Sep 2012 06:15:42 +0000 (23:15 -0700)
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

res/values/strings.xml
src/com/android/settings/Utils.java
src/com/android/settings/users/ProfileUpdateReceiver.java
src/com/android/settings/users/UserSettings.java

index cc2bb44..072b844 100644 (file)
     <string name="user_summary_active">Active</string>
     <!-- User summary to indicate that user is currently inactive in the background [CHAR LIMIT=100] -->
     <string name="user_summary_inactive">Not active</string>
+    <!-- User summary to indicate that user is currently not set up [CHAR LIMIT=100] -->
+    <string name="user_summary_not_set_up">Not set up</string>
     <!-- User information string to represent the owner of the device [CHAR LIMIT=25] -->
     <string name="user_owner">Owner</string>
     <!-- Title for the preference to enter the nickname of the userto display in the user switcher [CHAR LIMIT=25]-->
     <!-- Title for add user confirmation dialog [CHAR LIMIT=30] -->
     <string name="user_add_user_title">Add new user</string>
     <!-- Message for add user confirmation dialog [CHAR LIMIT=none] -->
-    <string name="user_add_user_message">Adding a user to this device will take them through guided setup.\n\nEach user will have their own apps and personal space on this device.\nUsers can accept permissions for updates on behalf of other users of this device.\nYou can switch between users on the lock screen.</string>
+    <string name="user_add_user_message">Each user you add can go to their own space from the lock screen and perform most routine tasks such as installing, updating, or uninstalling apps. After you create a new user, that person needs to go through a setup process.</string>
+    <!-- Title of dialog to setup a new user [CHAR LIMIT=30] -->
+    <string name="user_setup_dialog_title">Set up user now?</string>
+    <!-- Message in dialog to setup a new user after creation [CHAR LIMIT=none] -->
+    <string name="user_setup_dialog_message">Make sure the person is available to take the tablet and set up their space</string>
+    <!-- Button text to setup the new user now [CHAR LIMIT=25] -->
+    <string name="user_setup_button_setup_now">Set up now</string>
+    <!-- Button text to setup the new user later [CHAR LIMIT=25] -->
+    <string name="user_setup_button_setup_later">Not now</string>
 
     <!-- User details remove user menu [CHAR LIMIT=20] -->
     <string name="user_remove_user_menu">Remove user</string>
     <!-- User details new user name [CHAR LIMIT=30] -->
     <string name="user_new_user_name">New user</string>
+    <!-- User (self) removal confirmation title [CHAR LIMIT=30] -->
+    <string name="user_confirm_remove_self_title">Delete yourself?</string>
     <!-- User removal confirmation title [CHAR LIMIT=25] -->
     <string name="user_confirm_remove_title">Remove user?</string>
+    <!-- User (self) removal confirmation message [CHAR LIMIT=none] -->
+    <string name="user_confirm_remove_self_message">You will lose your space and data on this delete. Are you sure you want to remove the user and all associated data from the device?</string>
     <!-- User removal confirmation message [CHAR LIMIT=none] -->
     <string name="user_confirm_remove_message">Are you sure you want to remove the user and all associated data from the device?</string>
     <!-- Setting label to show that a new user is being added [CHAR LIMIT=30] -->
index 777a712..ee1bfee 100644 (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;
+    }
 }
index 5513608..88daa58 100644 (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;
-
-        InputStream avatarDataStream = Contacts.openContactPhotoInputStream(
-                    context.getContentResolver(),
-                    contactUri, true);
-        // If there's no profile photo, assign a default avatar
-        if (avatarDataStream == null) {
-            return false;
+    static void copyProfileName(Context context) {
+        SharedPreferences prefs = context.getSharedPreferences("profile", Context.MODE_PRIVATE);
+        if (prefs.contains(KEY_PROFILE_NAME_COPIED_ONCE)) {
+            return;
         }
-        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;
     }
 }
index 28fe4c1..11948b4 100644 (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;
-        }
-
-        try {
-            if (cursor.moveToFirst()) {
-                mProfileExists = true;
-                return cursor.getString(cursor.getColumnIndex(Phone.DISPLAY_NAME));
-            }
-        } finally {
-            cursor.close();
+        String name = Utils.getMeProfileName(getActivity());
+        if (name != null) {
+            mProfileExists = true;
         }
-        return null;
+        return name;
     }
 
     private void assignDefaultPhoto(UserInfo user) {