Using UserManagerInternal for access control instead of UserManager

Bug: 36067387
Test: for C in {1..10}; do adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest$C \
      -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner; done
      atest CtsDevicePolicyManagerTestCases:LauncherAppsSingleUserTest \
            CtsDevicePolicyManagerTestCases:LauncherAppsProfileTest \
            CtsDevicePolicyManagerTestCases:LauncherAppsMultiUserTest
      atest CtsShortcutManagerTestCases
Change-Id: Ia4ddea58f66861ef760865b6d8831563584f85c9
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 2c7df6c..ced2a7e 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -781,14 +781,7 @@
     @Override
     public int getProfileParentId(int userHandle) {
         checkManageUsersPermission("get the profile parent");
-        synchronized (mUsersLock) {
-            UserInfo profileParent = getProfileParentLU(userHandle);
-            if (profileParent == null) {
-                return userHandle;
-            }
-
-            return profileParent.id;
-        }
+        return mLocalService.getProfileParentId(userHandle);
     }
 
     private UserInfo getProfileParentLU(int userHandle) {
@@ -3928,6 +3921,56 @@
         public boolean exists(int userId) {
             return getUserInfoNoChecks(userId) != null;
         }
+
+        @Override
+        public boolean isProfileAccessible(int callingUserId, int targetUserId, String debugMsg,
+                boolean throwSecurityException) {
+            if (targetUserId == callingUserId) {
+                return true;
+            }
+            synchronized (mUsersLock) {
+                UserInfo callingUserInfo = getUserInfoLU(callingUserId);
+                if (callingUserInfo == null || callingUserInfo.isManagedProfile()) {
+                    if (throwSecurityException) {
+                        throw new SecurityException(
+                                debugMsg + " for another profile "
+                                        + targetUserId + " from " + callingUserId);
+                    }
+                }
+
+                UserInfo targetUserInfo = getUserInfoLU(targetUserId);
+                if (targetUserInfo == null || !targetUserInfo.isEnabled()) {
+                    // Do not throw any exception here as this could happen due to race conditions
+                    // between the system updating its state and the client getting notified.
+                    if (throwSecurityException) {
+                        Slog.w(LOG_TAG, debugMsg + " for disabled profile "
+                                + targetUserId + " from " + callingUserId);
+                    }
+                    return false;
+                }
+
+                if (targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID ||
+                        targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) {
+                    if (throwSecurityException) {
+                        throw new SecurityException(
+                                debugMsg + " for unrelated profile " + targetUserId);
+                    }
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        @Override
+        public int getProfileParentId(int userId) {
+            synchronized (mUsersLock) {
+                UserInfo profileParent = getProfileParentLU(userId);
+                if (profileParent == null) {
+                    return userId;
+                }
+                return profileParent.id;
+            }
+        }
     }
 
     /* Remove all the users except of the system one. */