diff options
author | Amith Yamasani <yamasani@google.com> | 2012-03-25 10:12:26 -0700 |
---|---|---|
committer | Amith Yamasani <yamasani@google.com> | 2012-03-27 12:06:29 -0700 |
commit | b810a0ddf9dd93a08789aff38901eeab9bfaf812 (patch) | |
tree | 196baf46ebbaebc14481b438d9539a92273b788d | |
parent | 7014dbca85ebb9a00b5943e57d75609023322744 (diff) | |
download | packages_apps_settings-b810a0ddf9dd93a08789aff38901eeab9bfaf812.zip packages_apps_settings-b810a0ddf9dd93a08789aff38901eeab9bfaf812.tar.gz packages_apps_settings-b810a0ddf9dd93a08789aff38901eeab9bfaf812.tar.bz2 |
User management screens
Customized Settings for restricted users
- Only some top-level settings panels available
User management
- Primary user can add and remove users
- User details screen to change name and list of enabled apps
Change-Id: Ia6beb991b427197a4ec2724ca3c9222073f6cf7d
-rw-r--r-- | proguard.flags | 1 | ||||
-rw-r--r-- | res/values/arrays.xml | 18 | ||||
-rw-r--r-- | res/values/bools.xml | 3 | ||||
-rw-r--r-- | res/values/strings.xml | 39 | ||||
-rw-r--r-- | res/xml/settings_headers.xml | 7 | ||||
-rw-r--r-- | res/xml/user_details.xml | 62 | ||||
-rw-r--r-- | res/xml/user_settings.xml | 26 | ||||
-rw-r--r-- | src/com/android/settings/SecuritySettings.java | 40 | ||||
-rw-r--r-- | src/com/android/settings/Settings.java | 23 | ||||
-rw-r--r-- | src/com/android/settings/users/UserDetailsSettings.java | 285 | ||||
-rw-r--r-- | src/com/android/settings/users/UserSettings.java | 109 |
11 files changed, 600 insertions, 13 deletions
diff --git a/proguard.flags b/proguard.flags index a07b2ec..0805d68 100644 --- a/proguard.flags +++ b/proguard.flags @@ -11,6 +11,7 @@ -keep class com.android.settings.MasterClearConfirm -keep class com.android.settings.accounts.* -keep class com.android.settings.fuelgauge.* +-keep class com.android.settings.users.* # Keep click responders -keepclassmembers class com.android.settings.inputmethod.UserDictionaryAddWordActivity { diff --git a/res/values/arrays.xml b/res/values/arrays.xml index c9bbd04..285b6e6 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -724,4 +724,22 @@ <!-- Status message when VPN is failed. --> <item>Unsuccessful</item> </string-array> + + <!-- User content ratings for restricted users [CHAR LIMIT=30] --> + <string-array name="user_content_ratings_entries"> + <item>Ascended being</item> + <item>Human</item> + <item>Neanderthal</item> + <item>Chimp</item> + <item>Monkey</item> + </string-array> + + <!-- Values for user content ratings for restricted users --> + <string-array name="user_content_ratings_values" translatable="false"> + <item>5</item> + <item>4</item> + <item>3</item> + <item>2</item> + <item>1</item> + </string-array> </resources> diff --git a/res/values/bools.xml b/res/values/bools.xml index 2d05fbf..23bdf0d 100644 --- a/res/values/bools.xml +++ b/res/values/bools.xml @@ -29,4 +29,7 @@ <!-- Whether the bluetooth activation confirmation dialogs should be auto dismissed. Can be overridden for specific product builds. --> <bool name="auto_confirm_bluetooth_activation_dialog">false</bool> + + <!-- Whether User management screen is available --> + <bool name="enable_user_management">false</bool> </resources> diff --git a/res/values/strings.xml b/res/values/strings.xml index 99def81..2edc905 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3854,4 +3854,43 @@ "system_update_settings_list_item_title" in this project. [CHAR LIMIT=25] --> <string name="additional_system_update_settings_list_item_title">Additional system updates</string> + <!-- User settings --> + <skip/> + + <!-- User settings screen title [CHAR LIMIT=25] --> + <string name="user_settings_title">Users & restrictions</string> + <!-- User settings user list section header [CHAR LIMIT=30] --> + <string name="user_list_title">Users</string> + <!-- User settings add user menu [CHAR LIMIT=20] --> + <string name="user_add_user_menu">Add user</string> + + <!-- User details --> + <skip/> + + <!-- User details screen title [CHAR LIMIT=25] --> + <string name="user_details_title">Edit details</string> + <!-- User information section title [CHAR LIMIT=30] --> + <string name="user_information_heading">User information</string> + <!-- User name title [CHAR LIMIT=25] --> + <string name="user_name_title">Name</string> + <!-- User restrictions section title [CHAR LIMIT=30] --> + <string name="user_restrictions_heading">Content restrictions</string> + <!-- User restrictions, does market require PIN protection [CHAR LIMIT=25] --> + <string name="user_market_requires_pin">Downloads require PIN</string> + <!-- User restrictions, maximum content rating for apps [CHAR LIMIT=25] --> + <string name="user_max_content_rating">Content rating</string> + <!-- Section title for list of system apps [CHAR LIMIT=30] --> + <string name="user_system_apps_heading">System apps to enable</string> + <!-- Section title for list of downloaded apps [CHAR LIMIT=30] --> + <string name="user_market_apps_heading">Installed apps to enable</string> + <!-- User details discard user menu [CHAR LIMIT=20] --> + <string name="user_discard_user_menu">Discard</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">Pesky kid</string> + <!-- User removal confirmation title [CHAR LIMIT=25] --> + <string name="user_confirm_remove_title">Remove user?</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> </resources> diff --git a/res/xml/settings_headers.xml b/res/xml/settings_headers.xml index 0f4dbb3..d8fb636 100644 --- a/res/xml/settings_headers.xml +++ b/res/xml/settings_headers.xml @@ -106,6 +106,13 @@ <!-- PERSONAL --> <header android:title="@string/header_category_personal" /> + <!-- Manage users --> + <header + android:fragment="com.android.settings.users.UserSettings" + android:icon="@drawable/ic_settings_sync" + android:title="@string/user_settings_title" + android:id="@+id/user_settings" /> + <!-- Data Sync. The settings activity will ensure this is resolved to an activity on the system image, otherwise it will remove this preference. --> diff --git a/res/xml/user_details.xml b/res/xml/user_details.xml new file mode 100644 index 0000000..257eee4 --- /dev/null +++ b/res/xml/user_details.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:settings="http://schemas.android.com/apk/res/com.android.settings" + android:title="@string/user_details_title"> + + <PreferenceCategory + android:key="information_category" + android:title="@string/user_information_heading"> + <EditTextPreference + android:key="user_name" + android:title="@string/user_name_title" + android:persistent="false" + /> + </PreferenceCategory> + + <PreferenceCategory + android:key="restrictions_category" + android:title="@string/user_restrictions_heading"> + <CheckBoxPreference + android:key="market_requires_pin" + android:title="@string/user_market_requires_pin" + android:persistent="false" + android:enabled="false" + /> + <ListPreference + android:key="content_rating" + android:title="@string/user_max_content_rating" + android:entries="@array/user_content_ratings_entries" + android:entryValues="@array/user_content_ratings_values" + android:persistent="false" + android:enabled="false" + /> + </PreferenceCategory> + + <PreferenceCategory + android:key="system_apps_category" + android:title="@string/user_system_apps_heading"> + <!-- Dynamically added content --> + </PreferenceCategory> + + <PreferenceCategory + android:key="market_apps_category" + android:title="@string/user_market_apps_heading"> + <!-- Dynamically added content --> + </PreferenceCategory> + +</PreferenceScreen> diff --git a/res/xml/user_settings.xml b/res/xml/user_settings.xml new file mode 100644 index 0000000..95bc703 --- /dev/null +++ b/res/xml/user_settings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:settings="http://schemas.android.com/apk/res/com.android.settings" + android:title="@string/user_settings_title"> + + <PreferenceCategory + android:key="user_list" + android:title="@string/user_list_title"> + </PreferenceCategory> + +</PreferenceScreen> diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java index 622e827..88a2d33 100644 --- a/src/com/android/settings/SecuritySettings.java +++ b/src/com/android/settings/SecuritySettings.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; +import android.os.UserId; import android.os.Vibrator; import android.preference.CheckBoxPreference; import android.preference.ListPreference; @@ -140,15 +141,17 @@ public class SecuritySettings extends SettingsPreferenceFragment DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); - switch (dpm.getStorageEncryptionStatus()) { - case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE: - // The device is currently encrypted. - addPreferencesFromResource(R.xml.security_settings_encrypted); - break; - case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE: - // This device supports encryption but isn't encrypted. - addPreferencesFromResource(R.xml.security_settings_unencrypted); - break; + if (UserId.myUserId() == 0) { + switch (dpm.getStorageEncryptionStatus()) { + case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE: + // The device is currently encrypted. + addPreferencesFromResource(R.xml.security_settings_encrypted); + break; + case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE: + // This device supports encryption but isn't encrypted. + addPreferencesFromResource(R.xml.security_settings_unencrypted); + break; + } } // lock after preference @@ -190,6 +193,11 @@ public class SecuritySettings extends SettingsPreferenceFragment } } + if (UserId.myUserId() > 0) { + return root; + } + // Rest are for primary user... + // Append the rest of the settings addPreferencesFromResource(R.xml.security_settings_misc); @@ -246,7 +254,9 @@ public class SecuritySettings extends SettingsPreferenceFragment public void onClick(DialogInterface dialog, int which) { if (dialog == mWarnInstallApps && which == DialogInterface.BUTTON_POSITIVE) { setNonMarketAppsAllowed(true); - mToggleAppInstallation.setChecked(true); + if (mToggleAppInstallation != null) { + mToggleAppInstallation.setChecked(true); + } } } @@ -343,11 +353,15 @@ public class SecuritySettings extends SettingsPreferenceFragment mPowerButtonInstantlyLocks.setChecked(lockPatternUtils.getPowerButtonInstantlyLocks()); } - mShowPassword.setChecked(Settings.System.getInt(getContentResolver(), - Settings.System.TEXT_SHOW_PASSWORD, 1) != 0); + if (mShowPassword != null) { + mShowPassword.setChecked(Settings.System.getInt(getContentResolver(), + Settings.System.TEXT_SHOW_PASSWORD, 1) != 0); + } KeyStore.State state = KeyStore.getInstance().state(); - mResetCredentials.setEnabled(state != KeyStore.State.UNINITIALIZED); + if (mResetCredentials != null) { + mResetCredentials.setEnabled(state != KeyStore.State.UNINITIALIZED); + } } @Override diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index eb30809..7e4e725 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -16,6 +16,7 @@ package com.android.settings; +import com.android.internal.util.ArrayUtils; import com.android.settings.accounts.AccountSyncSettings; import com.android.settings.bluetooth.BluetoothEnabler; import com.android.settings.deviceinfo.Memory; @@ -29,6 +30,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; +import android.os.UserId; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceFragment; @@ -76,6 +78,17 @@ public class Settings extends PreferenceActivity implements ButtonBarHandler { private Header mParentHeader; private boolean mInLocalHeaderSwitch; + // Show only these settings for restricted users + private int[] SETTINGS_FOR_RESTRICTED = { + R.id.wifi_settings, + R.id.bluetooth_settings, + R.id.sound_settings, + R.id.display_settings, + //R.id.security_settings, + R.id.sync_settings, + R.id.about_settings + }; + // TODO: Update Call Settings based on airplane mode state. protected HashMap<Integer, Integer> mHeaderIndexMap = new HashMap<Integer, Integer>(); @@ -337,6 +350,16 @@ public class Settings extends PreferenceActivity implements ButtonBarHandler { if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) { target.remove(header); } + } else if (id == R.id.user_settings) { + if (!UserId.MU_ENABLED || UserId.myUserId() != 0 + || !getResources().getBoolean(R.bool.enable_user_management) + || Utils.isMonkeyRunning()) { + target.remove(header); + } + } + if (UserId.MU_ENABLED && UserId.myUserId() != 0 + && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, id)) { + target.remove(header); } // Increment if the current one wasn't removed by the Utils code. diff --git a/src/com/android/settings/users/UserDetailsSettings.java b/src/com/android/settings/users/UserDetailsSettings.java new file mode 100644 index 0000000..84cabe9 --- /dev/null +++ b/src/com/android/settings/users/UserDetailsSettings.java @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.users; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageManager; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.UserInfo; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemProperties; +import android.preference.CheckBoxPreference; +import android.preference.EditTextPreference; +import android.preference.Preference; +import android.preference.PreferenceGroup; +import android.text.TextUtils; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; + +import com.android.settings.DialogCreatable; +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; + +import java.util.HashMap; +import java.util.List; + +public class UserDetailsSettings extends SettingsPreferenceFragment + implements Preference.OnPreferenceChangeListener, DialogCreatable { + + private static final String TAG = "UserDetailsSettings"; + + private static final int MENU_REMOVE_USER = Menu.FIRST; + private static final int DIALOG_CONFIRM_REMOVE = 1; + + private static final String KEY_USER_NAME = "user_name"; + private static final String KEY_INSTALLED_APPS = "market_apps_category"; + private static final String KEY_SYSTEM_APPS = "system_apps_category"; + public static final String EXTRA_USER_ID = "user_id"; + + private static final String[] SYSTEM_APPS = { + "com.google.android.browser", + "com.google.android.gm", + "com.google.android.youtube" + }; + + static class AppState { + boolean dirty; + boolean enabled; + + AppState(boolean enabled) { + this.enabled = enabled; + } + } + + private HashMap<String, AppState> mAppStates = new HashMap<String, AppState>(); + private PreferenceGroup mSystemAppGroup; + private PreferenceGroup mInstalledAppGroup; + private EditTextPreference mNamePref; + + private IPackageManager mIPm; + private PackageManager mPm; + private int mUserId; + private boolean mNewUser; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + addPreferencesFromResource(R.xml.user_details); + Bundle args = getArguments(); + mNewUser = args == null || args.getInt(EXTRA_USER_ID, -1) == -1; + mUserId = mNewUser ? -1 : args.getInt(EXTRA_USER_ID, -1); + mIPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); + + if (mUserId == -1) { + try { + mUserId = mIPm.createUser(getString(R.string.user_new_user_name), 0).id; + } catch (RemoteException re) { + } + } + mSystemAppGroup = (PreferenceGroup) findPreference(KEY_SYSTEM_APPS); + mInstalledAppGroup = (PreferenceGroup) findPreference(KEY_INSTALLED_APPS); + mNamePref = (EditTextPreference) findPreference(KEY_USER_NAME); + mNamePref.setOnPreferenceChangeListener(this); + + setHasOptionsMenu(true); + } + + @Override + public void onResume() { + super.onResume(); + mPm = getActivity().getPackageManager(); + if (mUserId > 0) { + initExistingUser(); + } else { + initNewUser(); + } + refreshApps(); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + MenuItem addAccountItem = menu.add(0, MENU_REMOVE_USER, 0, + mNewUser ? R.string.user_discard_user_menu : R.string.user_remove_user_menu); + addAccountItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM + | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final int itemId = item.getItemId(); + if (itemId == MENU_REMOVE_USER) { + onRemoveUserClicked(); + return true; + } else { + return super.onOptionsItemSelected(item); + } + } + + private void initExistingUser() { + List<UserInfo> users = mPm.getUsers(); + UserInfo foundUser = null; + for (UserInfo user : users) { + if (user.id == mUserId) { + foundUser = user; + break; + } + } + if (foundUser != null) { + mNamePref.setSummary(foundUser.name); + mNamePref.setText(foundUser.name); + } + } + + private void initNewUser() { + // TODO: Check if there's already a "New user" and localize + mNamePref.setText(getString(R.string.user_new_user_name)); + mNamePref.setSummary(getString(R.string.user_new_user_name)); + } + + private void onRemoveUserClicked() { + if (mNewUser) { + removeUserNow(); + } else { + showDialog(DIALOG_CONFIRM_REMOVE); + } + } + + private void removeUserNow() { + try { + mIPm.removeUser(mUserId); + } catch (RemoteException re) { + // Couldn't remove user. Shouldn't happen + Log.e(TAG, "Couldn't remove user " + mUserId + "\n" + re); + } + finish(); + } + + private void insertAppInfo(PreferenceGroup group, HashMap<String, AppState> appStateMap, + PackageInfo info, boolean defaultState) { + if (info != null) { + String pkgName = info.packageName; + String name = info.applicationInfo.loadLabel(mPm).toString(); + Drawable icon = info.applicationInfo.loadIcon(mPm); + AppState appState = appStateMap.get(info.packageName); + boolean enabled = appState == null ? defaultState : appState.enabled; + CheckBoxPreference appPref = new CheckBoxPreference(getActivity()); + appPref.setTitle(name != null ? name : pkgName); + appPref.setIcon(icon); + appPref.setChecked(enabled); + appPref.setKey(pkgName); + appPref.setPersistent(false); + appPref.setOnPreferenceChangeListener(this); + group.addPreference(appPref); + } + } + + private void refreshApps() { + mSystemAppGroup.removeAll(); + mInstalledAppGroup.removeAll(); + + boolean firstTime = mAppStates.isEmpty(); + + final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); + mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); + List<ResolveInfo> apps = mPm.queryIntentActivities(mainIntent, 0); + + for (ResolveInfo resolveInfo : apps) { + PackageInfo info; + try { + info = mIPm.getPackageInfo(resolveInfo.activityInfo.packageName, + 0 /* flags */, + mUserId < 0 ? 0 : mUserId); + } catch (RemoteException re) { + continue; + } + if (firstTime) { + mAppStates.put(resolveInfo.activityInfo.packageName, + new AppState(info.applicationInfo.enabled)); + } + if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { + if (mSystemAppGroup.findPreference(info.packageName) != null) { + continue; + } + insertAppInfo(mSystemAppGroup, mAppStates, info, false); + } else { + if (mInstalledAppGroup.findPreference(info.packageName) != null) { + continue; + } + insertAppInfo(mInstalledAppGroup, mAppStates, info, false); + } + } + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (preference instanceof CheckBoxPreference) { + String packageName = preference.getKey(); + int newState = ((Boolean) newValue) ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED + : PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; + try { + mIPm.setApplicationEnabledSetting(packageName, newState, 0, mUserId); + } catch (RemoteException re) { + Log.e(TAG, "Unable to change enabled state of package " + packageName + + " for user " + mUserId); + } + } else if (preference == mNamePref) { + String name = (String) newValue; + if (TextUtils.isEmpty(name)) { + return false; + } + try { + mIPm.updateUserName(mUserId, (String) newValue); + mNamePref.setSummary((String) newValue); + } catch (RemoteException re) { + return false; + } + } + return true; + } + + @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) + .setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + removeUserNow(); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .create(); + default: + return null; + } + } +} diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java new file mode 100644 index 0000000..9380586 --- /dev/null +++ b/src/com/android/settings/users/UserSettings.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.users; + +import android.content.pm.UserInfo; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceClickListener; +import android.preference.PreferenceActivity; +import android.preference.PreferenceGroup; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; + +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; + +import java.util.List; + +public class UserSettings extends SettingsPreferenceFragment + implements OnPreferenceClickListener { + + private static final String KEY_USER_LIST = "user_list"; + private static final int MENU_ADD_USER = Menu.FIRST; + + private PreferenceGroup mUserListCategory; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + addPreferencesFromResource(R.xml.user_settings); + mUserListCategory = (PreferenceGroup) findPreference(KEY_USER_LIST); + + setHasOptionsMenu(true); + } + + @Override + public void onResume() { + super.onResume(); + updateUserList(); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + MenuItem addAccountItem = menu.add(0, MENU_ADD_USER, 0, R.string.user_add_user_menu); + addAccountItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM + | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final int itemId = item.getItemId(); + if (itemId == MENU_ADD_USER) { + onAddUserClicked(); + return true; + } else { + return super.onOptionsItemSelected(item); + } + } + + private void onAddUserClicked() { + ((PreferenceActivity) getActivity()).startPreferencePanel( + UserDetailsSettings.class.getName(), null, R.string.user_details_title, + null, this, 0); + } + + private void updateUserList() { + List<UserInfo> users = getActivity().getPackageManager().getUsers(); + + mUserListCategory.removeAll(); + for (UserInfo user : users) { + if (user.id == 0) continue; + Preference pref = new Preference(getActivity()); + pref.setTitle(user.name); + pref.setOnPreferenceClickListener(this); + pref.setKey("id=" + user.id); + mUserListCategory.addPreference(pref); + } + } + + @Override + public boolean onPreferenceClick(Preference pref) { + String sid = pref.getKey(); + if (sid != null && sid.startsWith("id=")) { + int id = Integer.parseInt(sid.substring(3)); + Bundle args = new Bundle(); + args.putInt(UserDetailsSettings.EXTRA_USER_ID, id); + ((PreferenceActivity) getActivity()).startPreferencePanel( + UserDetailsSettings.class.getName(), + args, 0, pref.getTitle(), this, 0); + return true; + } + return false; + } +} |