Commit b810a0dd authored by Amith Yamasani's avatar Amith Yamasani

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
parent 7014dbca
......@@ -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 {
......
......@@ -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>
......@@ -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>
......@@ -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 &amp; 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>
......@@ -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. -->
......
<?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>
<?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>
......@@ -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
......
......@@ -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.
......
This diff is collapsed.
/*
* 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;
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment