From 2601cd9142bda1953c1e7b0302f7e0d0f02b0c1b Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Sun, 31 Mar 2013 17:50:55 -0700 Subject: [PATCH] Implement proper settings restrictions Settings restrictions for limited users translate to user restrictions specified in UserManager. Added required strings. TODO: Add NFC restriction. Change-Id: If1f81319131855f5dc1b27fe5bd54a4fef616d7f --- AndroidManifest.xml | 6 - res/values/strings.xml | 2 +- src/com/android/settings/Settings.java | 10 -- .../users/AppRestrictionsFragment.java | 148 ++++++++++-------- .../settings/users/RestrictionUtils.java | 93 +++++++++++ .../settings/users/RestrictionsReceiver.java | 128 --------------- 6 files changed, 177 insertions(+), 210 deletions(-) create mode 100644 src/com/android/settings/users/RestrictionUtils.java delete mode 100644 src/com/android/settings/users/RestrictionsReceiver.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index f4b4bc66f48..143a394a5f8 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1602,11 +1602,5 @@ - - - - - - diff --git a/res/values/strings.xml b/res/values/strings.xml index 0690d1277d8..573f4a0ef61 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4440,7 +4440,7 @@ Allow data exchange when the phone touches another device - NFC + Location access Let apps use your location information diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index f7bdf270761..e29874bd869 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -57,7 +57,6 @@ import com.android.settings.accounts.AuthenticatorHelper; import com.android.settings.accounts.ManageAccountsSettings; import com.android.settings.bluetooth.BluetoothEnabler; import com.android.settings.bluetooth.BluetoothSettings; -import com.android.settings.users.RestrictionsReceiver; import com.android.settings.wfd.WifiDisplaySettings; import com.android.settings.wifi.WifiEnabler; import com.android.settings.wifi.WifiSettings; @@ -457,15 +456,6 @@ public class Settings extends PreferenceActivity if (!showDev) { target.remove(i); } - } else if (id == R.id.application_settings) { - if (mAppRestrictions != null) { - for (RestrictionEntry entry : mAppRestrictions) { - if (entry.getKey().equals(RestrictionsReceiver.KEY_ENABLE_APPS) - && !entry.getSelectedState()) { - target.remove(i); - } - } - } } else if (id == R.id.account_add) { if (um.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) { target.remove(i); diff --git a/src/com/android/settings/users/AppRestrictionsFragment.java b/src/com/android/settings/users/AppRestrictionsFragment.java index 7f80686a3c3..f2d893c8c8c 100644 --- a/src/com/android/settings/users/AppRestrictionsFragment.java +++ b/src/com/android/settings/users/AppRestrictionsFragment.java @@ -228,7 +228,7 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen final List existingApps = pm.queryIntentActivitiesAsUser(launcherIntent, 0, mUser.getIdentifier()); int i = 0; - if (receivers != null && receivers.size() > 0) { + if (mApps != null && mApps.size() > 0) { for (ResolveInfo app : mApps) { if (app.activityInfo == null || app.activityInfo.packageName == null) continue; String packageName = app.activityInfo.packageName; @@ -238,7 +238,8 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen p.setIcon(icon); p.setTitle(label); p.setKey(PKG_PREFIX + packageName); - p.setSettingsEnabled(hasPackage(receivers, packageName)); + p.setSettingsEnabled(hasPackage(receivers, packageName) + || packageName.equals(getActivity().getPackageName())); p.setPersistent(false); p.setOnPreferenceChangeListener(this); p.setOnPreferenceClickListener(this); @@ -346,8 +347,12 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen default: continue; } - mUserManager.setApplicationRestrictions(packageName, restrictions, - mUser); + if (packageName.equals(getActivity().getPackageName())) { + RestrictionUtils.setRestrictions(getActivity(), restrictions, mUser); + } else { + mUserManager.setApplicationRestrictions(packageName, restrictions, + mUser); + } break; } } @@ -371,15 +376,22 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen preference.childPreferences.clear(); } else { String packageName = preference.getKey().substring(PKG_PREFIX.length()); - List oldEntries = - mUserManager.getApplicationRestrictions(packageName, mUser); - Intent intent = new Intent(Intent.ACTION_GET_RESTRICTION_ENTRIES); - intent.setPackage(packageName); - intent.putParcelableArrayListExtra(Intent.EXTRA_RESTRICTIONS, - new ArrayList(oldEntries)); - getActivity().sendOrderedBroadcast(intent, null, - new RestrictionsResultReceiver(packageName, preference), - null, Activity.RESULT_OK, null, null); + if (packageName.equals(getActivity().getPackageName())) { + // Settings, fake it by using user restrictions + ArrayList restrictions = RestrictionUtils.getRestrictions( + getActivity(), mUser); + onRestrictionsReceived(preference, packageName, restrictions); + } else { + List oldEntries = + mUserManager.getApplicationRestrictions(packageName, mUser); + Intent intent = new Intent(Intent.ACTION_GET_RESTRICTION_ENTRIES); + intent.setPackage(packageName); + intent.putParcelableArrayListExtra(Intent.EXTRA_RESTRICTIONS, + new ArrayList(oldEntries)); + getActivity().sendOrderedBroadcast(intent, null, + new RestrictionsResultReceiver(packageName, preference), + null, Activity.RESULT_OK, null, null); + } } preference.panelOpen = !preference.panelOpen; } @@ -404,58 +416,7 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen Intent.EXTRA_RESTRICTIONS); Intent restrictionsIntent = (Intent) results.getParcelable(CUSTOM_RESTRICTIONS_INTENT); if (restrictions != null && restrictionsIntent == null) { - // Non-custom-activity case - expand the restrictions in-place - int count = 1; - for (RestrictionEntry entry : restrictions) { - Preference p = null; - switch (entry.getType()) { - case RestrictionEntry.TYPE_BOOLEAN: - p = new CheckBoxPreference(context); - p.setTitle(entry.getTitle()); - p.setSummary(entry.getDescription()); - ((CheckBoxPreference)p).setChecked(entry.getSelectedState()); - break; - case RestrictionEntry.TYPE_CHOICE: - case RestrictionEntry.TYPE_CHOICE_LEVEL: - p = new ListPreference(context); - p.setTitle(entry.getTitle()); - String value = entry.getSelectedString(); - if (value == null) { - value = entry.getDescription(); - } - p.setSummary(findInArray(entry.getChoiceEntries(), entry.getChoiceValues(), - value)); - ((ListPreference)p).setEntryValues(entry.getChoiceValues()); - ((ListPreference)p).setEntries(entry.getChoiceEntries()); - ((ListPreference)p).setValue(value); - break; - case RestrictionEntry.TYPE_MULTI_SELECT: - p = new MultiSelectListPreference(context); - p.setTitle(entry.getTitle()); - ((MultiSelectListPreference)p).setEntryValues(entry.getChoiceValues()); - ((MultiSelectListPreference)p).setEntries(entry.getChoiceEntries()); - HashSet set = new HashSet(); - for (String s : entry.getAllSelectedStrings()) { - set.add(s); - } - ((MultiSelectListPreference)p).setValues(set); - break; - case RestrictionEntry.TYPE_NULL: - default: - } - if (p != null) { - p.setPersistent(false); - p.setOrder(preference.getOrder() + count); - // Store the restrictions key string as a key for the preference - p.setKey(preference.getKey().substring(PKG_PREFIX.length()) + DELIMITER - + entry.getKey()); - mAppList.addPreference(p); - p.setOnPreferenceChangeListener(AppRestrictionsFragment.this); - preference.childPreferences.add(p); - count++; - } - } - preference.setRestrictions(restrictions); + onRestrictionsReceived(preference, packageName, restrictions); mUserManager.setApplicationRestrictions(packageName, restrictions, mUser); } else if (restrictionsIntent != null) { final Intent customIntent = restrictionsIntent; @@ -481,6 +442,63 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen } } + private void onRestrictionsReceived(AppRestrictionsPreference preference, String packageName, + ArrayList restrictions) { + // Non-custom-activity case - expand the restrictions in-place + final Context context = preference.getContext(); + int count = 1; + for (RestrictionEntry entry : restrictions) { + Preference p = null; + switch (entry.getType()) { + case RestrictionEntry.TYPE_BOOLEAN: + p = new CheckBoxPreference(context); + p.setTitle(entry.getTitle()); + p.setSummary(entry.getDescription()); + ((CheckBoxPreference)p).setChecked(entry.getSelectedState()); + break; + case RestrictionEntry.TYPE_CHOICE: + case RestrictionEntry.TYPE_CHOICE_LEVEL: + p = new ListPreference(context); + p.setTitle(entry.getTitle()); + String value = entry.getSelectedString(); + if (value == null) { + value = entry.getDescription(); + } + p.setSummary(findInArray(entry.getChoiceEntries(), entry.getChoiceValues(), + value)); + ((ListPreference)p).setEntryValues(entry.getChoiceValues()); + ((ListPreference)p).setEntries(entry.getChoiceEntries()); + ((ListPreference)p).setValue(value); + break; + case RestrictionEntry.TYPE_MULTI_SELECT: + p = new MultiSelectListPreference(context); + p.setTitle(entry.getTitle()); + ((MultiSelectListPreference)p).setEntryValues(entry.getChoiceValues()); + ((MultiSelectListPreference)p).setEntries(entry.getChoiceEntries()); + HashSet set = new HashSet(); + for (String s : entry.getAllSelectedStrings()) { + set.add(s); + } + ((MultiSelectListPreference)p).setValues(set); + break; + case RestrictionEntry.TYPE_NULL: + default: + } + if (p != null) { + p.setPersistent(false); + p.setOrder(preference.getOrder() + count); + // Store the restrictions key string as a key for the preference + p.setKey(preference.getKey().substring(PKG_PREFIX.length()) + DELIMITER + + entry.getKey()); + mAppList.addPreference(p); + p.setOnPreferenceChangeListener(AppRestrictionsFragment.this); + preference.childPreferences.add(p); + count++; + } + } + preference.setRestrictions(restrictions); + } + /** * Generates a request code that is stored in a map to retrieve the associated * AppRestrictionsPreference. diff --git a/src/com/android/settings/users/RestrictionUtils.java b/src/com/android/settings/users/RestrictionUtils.java new file mode 100644 index 00000000000..8b675a55498 --- /dev/null +++ b/src/com/android/settings/users/RestrictionUtils.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2013 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.Context; +import android.content.RestrictionEntry; +import android.content.res.Resources; +import android.os.Bundle; +import android.os.UserHandle; +import android.os.UserManager; +import android.provider.Settings.Secure; + +import com.android.settings.R; + +import java.util.ArrayList; + +public class RestrictionUtils { + + public static final String [] sRestrictionKeys = { + UserManager.DISALLOW_CONFIG_WIFI, + UserManager.DISALLOW_CONFIG_BLUETOOTH, + UserManager.DISALLOW_SHARE_LOCATION, + UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES + }; + + public static final int [] sRestrictionTitles = { + R.string.restriction_wifi_config_title, + R.string.restriction_bluetooth_config_title, + R.string.restriction_location_enable_title, + R.string.install_applications + }; + + public static final int [] sRestrictionDescriptions = { + R.string.restriction_wifi_config_summary, + R.string.restriction_bluetooth_config_summary, + R.string.restriction_location_enable_summary, + R.string.install_unknown_applications + }; + + /** + * Returns the current user restrictions in the form of application + * restriction entries. + * @return list of RestrictionEntry objects with user-visible text. + */ + public static ArrayList getRestrictions(Context context, UserHandle user) { + Resources res = context.getResources(); + ArrayList entries = new ArrayList(); + UserManager um = UserManager.get(context); + Bundle userRestrictions = um.getUserRestrictions(user); + + for (int i = 0; i < sRestrictionKeys.length; i++) { + RestrictionEntry entry = new RestrictionEntry( + sRestrictionKeys[i], + !userRestrictions.getBoolean(sRestrictionKeys[i], false)); + entry.setTitle(res.getString(sRestrictionTitles[i])); + entry.setDescription(res.getString(sRestrictionDescriptions[i])); + entry.setType(RestrictionEntry.TYPE_BOOLEAN); + entries.add(entry); + } + + return entries; + } + + public static void setRestrictions(Context context, ArrayList entries, + UserHandle user) { + UserManager um = UserManager.get(context); + Bundle userRestrictions = um.getUserRestrictions(user); + + for (RestrictionEntry entry : entries) { + userRestrictions.putBoolean(entry.getKey(), !entry.getSelectedState()); + if (entry.getKey().equals(UserManager.DISALLOW_SHARE_LOCATION) + && !entry.getSelectedState()) { + Secure.putStringForUser(context.getContentResolver(), + Secure.LOCATION_PROVIDERS_ALLOWED, "", user.getIdentifier()); + } + } + um.setUserRestrictions(userRestrictions, user); + } +} diff --git a/src/com/android/settings/users/RestrictionsReceiver.java b/src/com/android/settings/users/RestrictionsReceiver.java deleted file mode 100644 index 52436b46412..00000000000 --- a/src/com/android/settings/users/RestrictionsReceiver.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2013 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.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.RestrictionEntry; -import android.os.Bundle; -import android.util.Log; - -import com.android.settings.R; - -import java.util.ArrayList; -import java.util.List; - -/** Test class, to demonstrate the features. TODO: Remove or modify with real restrictions */ -public class RestrictionsReceiver extends BroadcastReceiver { - - private static final String TAG = RestrictionsReceiver.class.getSimpleName(); - - public static final String KEY_VERSION = "version"; - public static final String KEY_ENABLE_APPS = "enable_apps"; - public static final String KEY_SECTIONS_TO_SHOW = "enable_sections"; - public static final String KEY_CONTENT_RATING = "content_rating"; - - private static final int[] SECTION_IDS = { - R.id.wifi_settings, - R.id.bluetooth_settings, - R.id.data_usage_settings, - R.id.app_settings, - R.id.date_time_settings, - R.id.about_settings - }; - - private static final int[] SECTION_TITLE_IDS = { - R.string.wifi_settings, - R.string.bluetooth_settings, - R.string.data_usage_summary_title, - R.string.manageapplications_settings_title, - R.string.date_and_time, - R.string.about_settings - }; - - @Override - public void onReceive(final Context context, Intent intent) { - final PendingResult result = goAsync(); - final ArrayList oldRestrictions = - intent.getParcelableArrayListExtra(Intent.EXTRA_RESTRICTIONS); - Log.i(TAG, "oldRestrictions = " + oldRestrictions); - new Thread() { - public void run() { - createRestrictions(context, result, oldRestrictions); - } - }.start(); - } - - private void createRestrictions(Context context, - PendingResult result, List old) { - ArrayList newRestrictions = new ArrayList(); - boolean oldEnableApps = false; - String oldContentRating = ""; - String[] oldEnabledSections = new String[0]; - if (old != null) { - for (RestrictionEntry r : old) { - if (r.getKey().equals(KEY_ENABLE_APPS)) { - oldEnableApps = r.getSelectedState(); - } else if (r.getKey().equals(KEY_CONTENT_RATING)) { - oldContentRating = r.getSelectedString(); - } else if (r.getKey().equals(KEY_SECTIONS_TO_SHOW)) { - oldEnabledSections = r.getAllSelectedStrings(); - } - } - } - - RestrictionEntry r0 = new RestrictionEntry(KEY_VERSION, "1"); - newRestrictions.add(r0); - - RestrictionEntry r1 = new RestrictionEntry(KEY_ENABLE_APPS, - Boolean.toString(oldEnableApps)); - r1.setTitle("Enable apps"); - r1.setDescription("Show the Apps section in Settings"); - r1.setType(RestrictionEntry.TYPE_BOOLEAN); - newRestrictions.add(r1); - - RestrictionEntry r2 = new RestrictionEntry(KEY_CONTENT_RATING, oldContentRating); - r2.setTitle("Test: Content rating"); - r2.setDescription("Limit content to chosen rating and lower"); - r2.setType(RestrictionEntry.TYPE_CHOICE_LEVEL); - r2.setChoiceValues(new String[] { "G", "PG", "PG13", "R", "NR"}); - r2.setChoiceEntries(new String[] { "G", "PG", "PG-13", "Restricted", "Not Rated" }); - newRestrictions.add(r2); - - String [] values = new String[SECTION_IDS.length]; - String [] choices = new String[SECTION_IDS.length]; - int i = 0; - for (int sectionId : SECTION_IDS) { - values[i] = Integer.toString(sectionId); - choices[i] = context.getString(SECTION_TITLE_IDS[i]); - i++; - } - RestrictionEntry r3 = new RestrictionEntry(KEY_SECTIONS_TO_SHOW, oldEnabledSections); - r3.setType(RestrictionEntry.TYPE_MULTI_SELECT); - r3.setChoiceEntries(choices); - r3.setChoiceValues(values); - r3.setTitle("Test: Sections to show"); - newRestrictions.add(r3); - - Bundle extras = new Bundle(); - extras.putParcelableArrayList(Intent.EXTRA_RESTRICTIONS, newRestrictions); - result.setResult(0, null, extras); - result.finish(); - } -}