diff options
author | Amith Yamasani <yamasani@google.com> | 2013-04-16 18:24:51 -0700 |
---|---|---|
committer | Amith Yamasani <yamasani@google.com> | 2013-04-17 10:44:44 -0700 |
commit | 7e99bc02c8e2f44dd92d70bfa6e654297e5286d8 (patch) | |
tree | 5b0fd3504a1b6939f1289772447aa598101b7652 | |
parent | 95a869f91bb9ab24300cec37037b0edcfa54f334 (diff) | |
download | frameworks_base-7e99bc02c8e2f44dd92d70bfa6e654297e5286d8.zip frameworks_base-7e99bc02c8e2f44dd92d70bfa6e654297e5286d8.tar.gz frameworks_base-7e99bc02c8e2f44dd92d70bfa6e654297e5286d8.tar.bz2 |
Modify restrictions bundle per api council recommendations
Use a Bundle for persisting and passing to the application, but use a
list to return data back from an application that's exposing restrictions.
Changed the xml reading/writing code to store the value type in the Bundle
so that it can be reproduced when reading. Earlier we were assuming only
String and String[].
Bug: 8633967
Change-Id: I523d5553728edcf28a1e9d432f490b4956f34215
-rw-r--r-- | api/current.txt | 6 | ||||
-rw-r--r-- | core/java/android/app/Application.java | 5 | ||||
-rw-r--r-- | core/java/android/content/Context.java | 9 | ||||
-rw-r--r-- | core/java/android/content/Intent.java | 25 | ||||
-rw-r--r-- | core/java/android/os/IUserManager.aidl | 5 | ||||
-rw-r--r-- | core/java/android/os/UserManager.java | 25 | ||||
-rw-r--r-- | services/java/com/android/server/pm/UserManagerService.java | 60 |
7 files changed, 85 insertions, 50 deletions
diff --git a/api/current.txt b/api/current.txt index 5a33193..9a0cf41 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5618,7 +5618,6 @@ package android.content { method public abstract java.lang.String[] fileList(); method public abstract android.content.Context getApplicationContext(); method public abstract android.content.pm.ApplicationInfo getApplicationInfo(); - method public java.util.List<android.content.RestrictionEntry> getApplicationRestrictions(); method public abstract android.content.res.AssetManager getAssets(); method public abstract java.io.File getCacheDir(); method public abstract java.lang.ClassLoader getClassLoader(); @@ -6205,8 +6204,9 @@ package android.content { field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER"; field public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token"; field public static final java.lang.String EXTRA_REPLACING = "android.intent.extra.REPLACING"; - field public static final java.lang.String EXTRA_RESTRICTIONS = "android.intent.extra.restrictions"; + field public static final java.lang.String EXTRA_RESTRICTIONS_BUNDLE = "android.intent.extra.restrictions_bundle"; field public static final java.lang.String EXTRA_RESTRICTIONS_INTENT = "android.intent.extra.restrictions_intent"; + field public static final java.lang.String EXTRA_RESTRICTIONS_LIST = "android.intent.extra.restrictions_list"; field public static final java.lang.String EXTRA_RETURN_RESULT = "android.intent.extra.RETURN_RESULT"; field public static final java.lang.String EXTRA_SHORTCUT_ICON = "android.intent.extra.shortcut.ICON"; field public static final java.lang.String EXTRA_SHORTCUT_ICON_RESOURCE = "android.intent.extra.shortcut.ICON_RESOURCE"; @@ -17556,7 +17556,7 @@ package android.os { } public class UserManager { - method public static synchronized android.os.UserManager get(android.content.Context); + method public android.os.Bundle getApplicationRestrictions(java.lang.String); method public long getSerialNumberForUser(android.os.UserHandle); method public int getUserCount(); method public android.os.UserHandle getUserForSerialNumber(long); diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java index 7b07438..0d7f0a7 100644 --- a/core/java/android/app/Application.java +++ b/core/java/android/app/Application.java @@ -134,11 +134,6 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - public List<RestrictionEntry> getApplicationRestrictions() { - return ((UserManager) getSystemService(USER_SERVICE)) - .getApplicationRestrictions(getPackageName(), android.os.Process.myUserHandle()); - } - public void registerComponentCallbacks(ComponentCallbacks callback) { synchronized (mComponentCallbacks) { mComponentCallbacks.add(callback); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 03e241a..5bd28b9 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -293,15 +293,6 @@ public abstract class Context { public abstract Context getApplicationContext(); /** - * Returns the list of restrictions for the application, or null if there are no - * restrictions. - * @return - */ - public List<RestrictionEntry> getApplicationRestrictions() { - return getApplicationContext().getApplicationRestrictions(); - } - - /** * Add a new {@link ComponentCallbacks} to the base application of the * Context, which will be called at the same times as the ComponentCallbacks * methods of activities and other components are called. Note that you diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 97ad7dd..1ab1eb8 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2417,11 +2417,16 @@ public class Intent implements Parcelable, Cloneable { /** * Broadcast to a specific application to query any supported restrictions to impose - * on restricted users. The response should contain an extra {@link #EXTRA_RESTRICTIONS}, + * on restricted users. The broadcast intent contains an extra + * {@link #EXTRA_RESTRICTIONS_BUNDLE} with the currently persisted + * restrictions as a Bundle of key/value pairs. The value types can be Boolean, String or + * String[] depending on the restriction type.<p/> + * The response should contain an extra {@link #EXTRA_RESTRICTIONS_LIST}, * which is of type <code>ArrayList<RestrictionEntry></code>. It can also * contain an extra {@link #EXTRA_RESTRICTIONS_INTENT}, which is of type <code>Intent</code>. * The activity specified by that intent will be launched for a result which must contain - * the extra {@link #EXTRA_RESTRICTIONS}. The returned restrictions will be persisted. + * the extra {@link #EXTRA_RESTRICTIONS_LIST}. The keys and values of the returned restrictions + * will be persisted. * @see RestrictionEntry */ public static final String ACTION_GET_RESTRICTION_ENTRIES = @@ -3160,7 +3165,8 @@ public class Intent implements Parcelable, Cloneable { "android.intent.extra.ALLOW_MULTIPLE"; /** - * The userHandle carried with broadcast intents related to addition, removal and switching of users + * The userHandle carried with broadcast intents related to addition, removal and switching of + * users * - {@link #ACTION_USER_ADDED}, {@link #ACTION_USER_REMOVED} and {@link #ACTION_USER_SWITCHED}. * @hide */ @@ -3169,9 +3175,18 @@ public class Intent implements Parcelable, Cloneable { /** * Extra used in the response from a BroadcastReceiver that handles - * {@link #ACTION_GET_RESTRICTION_ENTRIES}. + * {@link #ACTION_GET_RESTRICTION_ENTRIES}. The type of the extra is + * <code>ArrayList<RestrictionEntry></code>. + */ + public static final String EXTRA_RESTRICTIONS_LIST = "android.intent.extra.restrictions_list"; + + /** + * Extra sent in the intent to the BroadcastReceiver that handles + * {@link #ACTION_GET_RESTRICTION_ENTRIES}. The type of the extra is a Bundle containing + * the restrictions as key/value pairs. */ - public static final String EXTRA_RESTRICTIONS = "android.intent.extra.restrictions"; + public static final String EXTRA_RESTRICTIONS_BUNDLE = + "android.intent.extra.restrictions_bundle"; /** * Extra used in the response from a BroadcastReceiver that handles diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index 2e8092a..a11358a 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -42,7 +42,8 @@ interface IUserManager { int getUserHandle(int userSerialNumber); Bundle getUserRestrictions(int userHandle); void setUserRestrictions(in Bundle restrictions, int userHandle); - void setApplicationRestrictions(in String packageName, in List<RestrictionEntry> entries, + void setApplicationRestrictions(in String packageName, in Bundle restrictions, int userHandle); - List<RestrictionEntry> getApplicationRestrictions(in String packageName, int userHandle); + Bundle getApplicationRestrictions(in String packageName); + Bundle getApplicationRestrictionsForUser(in String packageName, int userHandle); } diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index e580e2b..df065e9 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -142,6 +142,7 @@ public class UserManager { private static UserManager sInstance = null; + /** @hide */ public synchronized static UserManager get(Context context) { if (sInstance == null) { sInstance = (UserManager) context.getSystemService(Context.USER_SERVICE); @@ -578,13 +579,29 @@ public class UserManager { return -1; } + /** + * Returns a Bundle containing any saved application restrictions for this user, for the + * given package name. Only an application with this package name can call this method. + * @param packageName the package name of the calling application + * @return a Bundle with the restrictions as key/value pairs, or null if there are no + * saved restrictions. The values can be of type Boolean, String or String[], depending + * on the restriction type, as defined by the application. + */ + public Bundle getApplicationRestrictions(String packageName) { + try { + return mService.getApplicationRestrictions(packageName); + } catch (RemoteException re) { + Log.w(TAG, "Could not get application restrictions for package " + packageName); + } + return null; + } /** * @hide */ - public List<RestrictionEntry> getApplicationRestrictions(String packageName, UserHandle user) { + public Bundle getApplicationRestrictions(String packageName, UserHandle user) { try { - return mService.getApplicationRestrictions(packageName, user.getIdentifier()); + return mService.getApplicationRestrictionsForUser(packageName, user.getIdentifier()); } catch (RemoteException re) { Log.w(TAG, "Could not get application restrictions for user " + user.getIdentifier()); } @@ -594,10 +611,10 @@ public class UserManager { /** * @hide */ - public void setApplicationRestrictions(String packageName, List<RestrictionEntry> entries, + public void setApplicationRestrictions(String packageName, Bundle restrictions, UserHandle user) { try { - mService.setApplicationRestrictions(packageName, entries, user.getIdentifier()); + mService.setApplicationRestrictions(packageName, restrictions, user.getIdentifier()); } catch (RemoteException re) { Log.w(TAG, "Could not set application restrictions for user " + user.getIdentifier()); } diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java index df90a56..11c6dab 100644 --- a/services/java/com/android/server/pm/UserManagerService.java +++ b/services/java/com/android/server/pm/UserManagerService.java @@ -88,8 +88,13 @@ public class UserManagerService extends IUserManager.Stub { private static final String TAG_ENTRY = "entry"; private static final String TAG_VALUE = "value"; private static final String ATTR_KEY = "key"; + private static final String ATTR_VALUE_TYPE = "type"; private static final String ATTR_MULTIPLE = "m"; + private static final String ATTR_TYPE_STRING_ARRAY = "sa"; + private static final String ATTR_TYPE_STRING = "s"; + private static final String ATTR_TYPE_BOOLEAN = "b"; + private static final String USER_INFO_DIR = "system" + File.separator + "users"; private static final String USER_LIST_FILENAME = "userlist.xml"; private static final String USER_PHOTO_FILENAME = "photo.png"; @@ -965,7 +970,12 @@ public class UserManagerService extends IUserManager.Stub { } @Override - public List<RestrictionEntry> getApplicationRestrictions(String packageName, int userId) { + public Bundle getApplicationRestrictions(String packageName) { + return getApplicationRestrictionsForUser(packageName, UserHandle.getCallingUserId()); + } + + @Override + public Bundle getApplicationRestrictionsForUser(String packageName, int userId) { if (UserHandle.getCallingUserId() != userId || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) { checkManageUsersPermission("Only system can get restrictions for other users/apps"); @@ -977,7 +987,7 @@ public class UserManagerService extends IUserManager.Stub { } @Override - public void setApplicationRestrictions(String packageName, List<RestrictionEntry> entries, + public void setApplicationRestrictions(String packageName, Bundle restrictions, int userId) { if (UserHandle.getCallingUserId() != userId || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) { @@ -985,7 +995,7 @@ public class UserManagerService extends IUserManager.Stub { } synchronized (mPackagesLock) { // Write the restrictions to XML - writeApplicationRestrictionsLocked(packageName, entries, userId); + writeApplicationRestrictionsLocked(packageName, restrictions, userId); } } @@ -1001,9 +1011,9 @@ public class UserManagerService extends IUserManager.Stub { } } - private List<RestrictionEntry> readApplicationRestrictionsLocked(String packageName, + private Bundle readApplicationRestrictionsLocked(String packageName, int userId) { - final ArrayList<RestrictionEntry> entries = new ArrayList<RestrictionEntry>(); + final Bundle restrictions = new Bundle(); final ArrayList<String> values = new ArrayList<String>(); FileInputStream fis = null; @@ -1023,12 +1033,13 @@ public class UserManagerService extends IUserManager.Stub { if (type != XmlPullParser.START_TAG) { Slog.e(LOG_TAG, "Unable to read restrictions file " + restrictionsFile.getBaseFile()); - return entries; + return restrictions; } while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) { String key = parser.getAttributeValue(null, ATTR_KEY); + String valType = parser.getAttributeValue(null, ATTR_VALUE_TYPE); String multiple = parser.getAttributeValue(null, ATTR_MULTIPLE); if (multiple != null) { int count = Integer.parseInt(multiple); @@ -1041,14 +1052,13 @@ public class UserManagerService extends IUserManager.Stub { } String [] valueStrings = new String[values.size()]; values.toArray(valueStrings); - Slog.d(LOG_TAG, "Got RestrictionEntry " + key + "," + valueStrings); - RestrictionEntry entry = new RestrictionEntry(key, valueStrings); - entries.add(entry); + restrictions.putStringArray(key, valueStrings); + } else if (ATTR_TYPE_BOOLEAN.equals(valType)) { + restrictions.putBoolean(key, Boolean.parseBoolean( + parser.nextText().trim())); } else { String value = parser.nextText().trim(); - Slog.d(LOG_TAG, "Got RestrictionEntry " + key + "," + value); - RestrictionEntry entry = new RestrictionEntry(key, value); - entries.add(entry); + restrictions.putString(key, value); } } } @@ -1063,11 +1073,11 @@ public class UserManagerService extends IUserManager.Stub { } } } - return entries; + return restrictions; } private void writeApplicationRestrictionsLocked(String packageName, - List<RestrictionEntry> entries, int userId) { + Bundle restrictions, int userId) { FileOutputStream fos = null; AtomicFile restrictionsFile = new AtomicFile( new File(Environment.getUserSystemDirectory(userId), @@ -1084,18 +1094,24 @@ public class UserManagerService extends IUserManager.Stub { serializer.startTag(null, TAG_RESTRICTIONS); - for (RestrictionEntry entry : entries) { + for (String key : restrictions.keySet()) { + Object value = restrictions.get(key); serializer.startTag(null, TAG_ENTRY); - serializer.attribute(null, ATTR_KEY, entry.getKey()); - if (entry.getSelectedString() != null || entry.getAllSelectedStrings() == null) { - String value = entry.getSelectedString(); - serializer.text(value != null ? value : ""); + serializer.attribute(null, ATTR_KEY, key); + + if (value instanceof Boolean) { + serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BOOLEAN); + serializer.text(value.toString()); + } else if (value == null || value instanceof String) { + serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING); + serializer.text(value != null ? (String) value : ""); } else { - String[] values = entry.getAllSelectedStrings(); + serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING_ARRAY); + String[] values = (String[]) value; serializer.attribute(null, ATTR_MULTIPLE, Integer.toString(values.length)); - for (String value : values) { + for (String choice : values) { serializer.startTag(null, TAG_VALUE); - serializer.text(value != null ? value : ""); + serializer.text(choice != null ? choice : ""); serializer.endTag(null, TAG_VALUE); } } |