Remove permission requirement for some UserManager calls

Update javadocs to be explicit about permissions.
Minor fixes in UserManagerService

Change-Id: I0d355e0a60e5dbdb49ed06091111d480ff249f3d
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 0338ee7..de8e78c 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -56,6 +56,7 @@
 
     /**
      * Returns the user name of the user making this call.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * @return the user name
      */
     public String getUserName() {
@@ -69,6 +70,7 @@
 
     /**
      * Returns the UserInfo object describing a specific user.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * @param userHandle the user handle of the user whose information is being requested.
      * @return the UserInfo object for a specific user.
      * @hide
@@ -84,6 +86,7 @@
 
     /**
      * Creates a user with the specified name and options.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      *
      * @param name the user's name
      * @param flags flags that identify the type of user and other properties.
@@ -103,6 +106,7 @@
 
     /**
      * Returns information for all users on this device.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * @return the list of users that were created.
      * @hide
      */
@@ -117,6 +121,7 @@
 
     /**
      * Removes a user and all associated data.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * @param userHandle the integer handle of the user, where 0 is the primary user.
      * @hide
      */
@@ -131,6 +136,7 @@
 
     /**
      * Updates the user's name.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      *
      * @param userHandle the user's integer handle
      * @param name the new name for the user
@@ -162,6 +168,7 @@
     /**
      * Enable or disable the use of a guest account. If disabled, the existing guest account
      * will be wiped.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * @param enable whether to enable a guest account.
      * @hide
      */
@@ -175,6 +182,7 @@
 
     /**
      * Checks if a guest user is enabled for this device.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * @return whether a guest user is enabled
      * @hide
      */
@@ -189,6 +197,7 @@
 
     /**
      * Wipes all the data for a user, but doesn't remove the user.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * @param userHandle
      * @hide
      */
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 89be5cb..1c9b440 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -790,7 +790,7 @@
          third party applications. -->
     <permission android:name="android.permission.MANAGE_USERS"
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
-        android:protectionLevel="signature"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_manageUsers"
         android:description="@string/permdesc_manageUsers" />
     
diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java
index c292bbc..f5b4053 100644
--- a/services/java/com/android/server/pm/UserManagerService.java
+++ b/services/java/com/android/server/pm/UserManagerService.java
@@ -137,11 +137,17 @@
     public UserInfo getUserInfo(int userId) {
         checkManageUsersPermission("query user");
         synchronized (mUsers) {
-            UserInfo info = mUsers.get(userId);
-            return info;
+            return getUserInfoLocked(userId);
         }
     }
 
+    /*
+     * Should be locked on mUsers before calling this.
+     */
+    private UserInfo getUserInfoLocked(int userId) {
+        return mUsers.get(userId);
+    }
+
     public boolean exists(int userId) {
         synchronized (mUsers) {
             return ArrayUtils.contains(mUserIds, userId);
@@ -212,8 +218,9 @@
     }
 
     /**
-     * Enforces that only the system UID or root's UID can call a method exposed
-     * via Binder.
+     * Enforces that only the system UID or root's UID or apps that have the
+     * {@link android.Manifest.permission.MANAGE_USERS MANAGE_USERS}
+     * permission can make certain calls to the UserManager.
      *
      * @param message used as message if SecurityException is thrown
      * @throws SecurityException if the caller is not system or root
@@ -534,7 +541,7 @@
     public int getUserSerialNumber(int userHandle) {
         synchronized (mUsers) {
             if (!exists(userHandle)) return -1;
-            return getUserInfo(userHandle).serialNumber;
+            return getUserInfoLocked(userHandle).serialNumber;
         }
     }
 
@@ -542,7 +549,7 @@
     public int getUserHandle(int userSerialNumber) {
         synchronized (mUsers) {
             for (int userId : mUserIds) {
-                if (getUserInfo(userId).serialNumber == userSerialNumber) return userId;
+                if (getUserInfoLocked(userId).serialNumber == userSerialNumber) return userId;
             }
             // Not found
             return -1;
@@ -617,14 +624,16 @@
      * @return
      */
     private int getNextAvailableId() {
-        int i = 0;
-        while (i < Integer.MAX_VALUE) {
-            if (mUsers.indexOfKey(i) < 0) {
-                break;
+        synchronized (mUsers) {
+            int i = 0;
+            while (i < Integer.MAX_VALUE) {
+                if (mUsers.indexOfKey(i) < 0) {
+                    break;
+                }
+                i++;
             }
-            i++;
+            return i;
         }
-        return i;
     }
 
     private boolean createPackageFolders(int id, File userPath) {
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 89b2474..8aeb2af 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -34,7 +34,8 @@
     <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.MANAGE_USERS" />
-
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+    
     <application>
         <uses-library android:name="android.test.runner" />