Added getProfileIds method returning array of userIds

Previously many usages of UserManager.getProfiles and getEnabledProfiles
were only using ids of returned users. Given that the list of users needs
to be parceled and unparceled for Binder calls, returning array of ids
minimizes memory usage and serialization time.

A new method getProfileIds was introduced which returns an array of userIds.
Existing method calls were updated where appropriate.

Bug: 27705805
Change-Id: Ic5d5decd77567ba0f749e48837a2c6fa10e812c0
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index ac7872a..da65dae 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -66,7 +66,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
-import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -1050,12 +1049,8 @@
     }
 
     void updateCurrentProfileIds() {
-        List<UserInfo> profiles = mUserManager.getProfiles(mSettings.getCurrentUserId());
-        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
-        for (int i = 0; i < currentProfileIds.length; i++) {
-            currentProfileIds[i] = profiles.get(i).id;
-        }
-        mSettings.setCurrentProfileIds(currentProfileIds);
+        mSettings.setCurrentProfileIds(
+                mUserManager.getProfileIdsWithDisabled(mSettings.getCurrentUserId()));
     }
 
     @Override
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 9884a70..7c48634 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -21,6 +21,7 @@
 import com.android.internal.location.ProviderProperties;
 import com.android.internal.location.ProviderRequest;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.ArrayUtils;
 import com.android.server.location.ActivityRecognitionProxy;
 import com.android.server.location.FlpHardwareProvider;
 import com.android.server.location.FusedProxy;
@@ -53,7 +54,6 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.pm.Signature;
-import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.hardware.location.ActivityRecognitionHardware;
@@ -359,12 +359,9 @@
      * @param currentUserId the current user, who might have an alter-ego.
      */
     void updateUserProfiles(int currentUserId) {
-        List<UserInfo> profiles = mUserManager.getProfiles(currentUserId);
+        int[] profileIds = mUserManager.getProfileIdsWithDisabled(currentUserId);
         synchronized (mLock) {
-            mCurrentUserProfiles = new int[profiles.size()];
-            for (int i = 0; i < mCurrentUserProfiles.length; i++) {
-                mCurrentUserProfiles[i] = profiles.get(i).id;
-            }
+            mCurrentUserProfiles = profileIds;
         }
     }
 
@@ -374,12 +371,7 @@
      */
     private boolean isCurrentProfile(int userId) {
         synchronized (mLock) {
-            for (int i = 0; i < mCurrentUserProfiles.length; i++) {
-                if (mCurrentUserProfiles[i] == userId) {
-                    return true;
-                }
-            }
-            return false;
+            return ArrayUtils.contains(mCurrentUserProfiles, userId);
         }
     }
 
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 3eb20a0..801d6e0 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -43,7 +43,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
-import android.content.pm.UserInfo;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -195,12 +194,8 @@
     }
 
     void updateCurrentProfileIds() {
-        final List<UserInfo> profiles = mUserManager.getProfiles(mSettings.getCurrentUserId());
-        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
-        for (int i = 0; i < currentProfileIds.length; i++) {
-            currentProfileIds[i] = profiles.get(i).id;
-        }
-        mSettings.setCurrentProfileIds(currentProfileIds);
+        mSettings.setCurrentProfileIds(
+                mUserManager.getProfileIdsWithDisabled(mSettings.getCurrentUserId()));
     }
 
     private class TextServicesMonitor extends PackageMonitor {
diff --git a/services/core/java/com/android/server/camera/CameraService.java b/services/core/java/com/android/server/camera/CameraService.java
index cd8eb4e..7d9adf2 100644
--- a/services/core/java/com/android/server/camera/CameraService.java
+++ b/services/core/java/com/android/server/camera/CameraService.java
@@ -15,32 +15,28 @@
  */
 package com.android.server.camera;
 
-import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.UserInfo;
 import android.hardware.ICameraService;
 import android.hardware.ICameraServiceProxy;
 import android.nfc.INfcAdapter;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Binder;
 import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
-import android.os.UserManager;
 import android.os.SystemProperties;
-import android.util.Slog;
+import android.os.UserManager;
 import android.util.ArraySet;
+import android.util.Slog;
 
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
 
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
 /**
@@ -225,11 +221,11 @@
     }
 
     private Set<Integer> getEnabledUserHandles(int currentUserHandle) {
-        List<UserInfo> userProfiles = mUserManager.getEnabledProfiles(currentUserHandle);
-        Set<Integer> handles = new HashSet<>(userProfiles.size());
+        int[] userProfiles = mUserManager.getEnabledProfileIds(currentUserHandle);
+        Set<Integer> handles = new ArraySet<>(userProfiles.length);
 
-        for (UserInfo i : userProfiles) {
-            handles.add(i.id);
+        for (int id : userProfiles) {
+            handles.add(id);
         }
 
         return handles;
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 3d8bf51..e3f3849 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -541,10 +541,8 @@
         UserManager um = UserManager.get(mContext);
 
         // Allow current user or profiles of the current user...
-        List<UserInfo> profiles = um.getEnabledProfiles(userId);
-        final int n = profiles.size();
-        for (int i = 0; i < n; i++) {
-            if (profiles.get(i).id == userId) {
+        for (int profileId : um.getEnabledProfileIds(userId)) {
+            if (profileId == userId) {
                 return true;
             }
         }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 60a0d62..60ea254 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -65,6 +65,7 @@
 import android.system.Os;
 import android.system.OsConstants;
 import android.util.AtomicFile;
+import android.util.IntArray;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -483,13 +484,50 @@
         }
     }
 
+    @Override
+    public int[] getProfileIds(int userId, boolean enabledOnly) {
+        if (userId != UserHandle.getCallingUserId()) {
+            checkManageUsersPermission("getting profiles related to user " + userId);
+        }
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (mUsersLock) {
+                return getProfileIdsLU(userId, enabledOnly).toArray();
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
     /** Assume permissions already checked and caller's identity cleared */
     private List<UserInfo> getProfilesLU(int userId, boolean enabledOnly, boolean fullInfo) {
+        IntArray profileIds = getProfileIdsLU(userId, enabledOnly);
+        ArrayList<UserInfo> users = new ArrayList<>(profileIds.size());
+        for (int i = 0; i < profileIds.size(); i++) {
+            int profileId = profileIds.get(i);
+            UserInfo userInfo = mUsers.get(profileId).info;
+            // If full info is not required - clear PII data to prevent 3P apps from reading it
+            if (!fullInfo) {
+                userInfo = new UserInfo(userInfo);
+                userInfo.name = null;
+                userInfo.iconPath = null;
+            } else {
+                userInfo = userWithName(userInfo);
+            }
+            users.add(userInfo);
+        }
+        return users;
+    }
+
+    /**
+     *  Assume permissions already checked and caller's identity cleared
+     */
+    private IntArray getProfileIdsLU(int userId, boolean enabledOnly) {
         UserInfo user = getUserInfoLU(userId);
-        ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
+        IntArray result = new IntArray(mUsers.size());
         if (user == null) {
             // Probably a dying user
-            return users;
+            return result;
         }
         final int userSize = mUsers.size();
         for (int i = 0; i < userSize; i++) {
@@ -506,16 +544,9 @@
             if (profile.partial) {
                 continue;
             }
-            UserInfo userInfo = userWithName(profile);
-            // If full info is not required - clear PII data to prevent 3P apps from reading it
-            if (!fullInfo) {
-                userInfo = new UserInfo(userInfo);
-                userInfo.name = null;
-                userInfo.iconPath = null;
-            }
-            users.add(userInfo);
+            result.add(profile.id);
         }
-        return users;
+        return result;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/vr/EnabledComponentsObserver.java b/services/core/java/com/android/server/vr/EnabledComponentsObserver.java
index eb926c1..30194bf 100644
--- a/services/core/java/com/android/server/vr/EnabledComponentsObserver.java
+++ b/services/core/java/com/android/server/vr/EnabledComponentsObserver.java
@@ -24,7 +24,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
-import android.content.pm.UserInfo;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.UserHandle;
@@ -213,18 +212,7 @@
         if (userManager == null) {
             return null;
         }
-        int currentUserId = ActivityManager.getCurrentUser();
-        List<UserInfo> profiles = userManager.getProfiles(currentUserId);
-        if (profiles == null) {
-            return null;
-        }
-        final int s = profiles.size();
-        int[] userIds = new int[s];
-        int ctr = 0;
-        for (UserInfo info : profiles) {
-            userIds[ctr++] = info.id;
-        }
-        return userIds;
+        return userManager.getProfileIdsWithDisabled(ActivityManager.getCurrentUser());
     }
 
     public static ArraySet<ComponentName> loadComponentNames(PackageManager pm, int userId,