Fix NotificationListenerService fail to mirror work notification

1. Instead of getting application info in runtime, just retrieve the
   one in the context to avoid cross user operation.

2. Functions in PackageManager that retrieve badged icon now return
   badged icon if the targer user is managed profile instead of checking
   whether target user is a managed profile of the user in mContext.

3. Relax the restriction of getUserInfo, if the caller is asking a user
   in the same profile group or having the manage user permission, we let
   it go.

Bug: 26469166

Change-Id: Ia1ffc5743f7d94bd489cdb7571eaed51499ebdd9
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index ca05091..cefb22d 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1147,7 +1147,7 @@
     }
 
     private Drawable getManagedProfileIconForDensity(UserHandle user, int drawableId, int density) {
-        UserInfo userInfo = getUserIfProfile(user.getIdentifier());
+        UserInfo userInfo = getUserInfo(user.getIdentifier());
         if (userInfo != null && userInfo.isManagedProfile()) {
             return getDrawableForDensity(drawableId, density);
         }
@@ -1156,7 +1156,7 @@
 
     @Override
     public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
-        UserInfo userInfo = getUserIfProfile(user.getIdentifier());
+        UserInfo userInfo = getUserInfo(user.getIdentifier());
         if (userInfo != null && userInfo.isManagedProfile()) {
             return Resources.getSystem().getString(
                     com.android.internal.R.string.managed_profile_label_badge, label);
@@ -2252,21 +2252,15 @@
 
     private int getBadgeResIdForUser(int userHandle) {
         // Return the framework-provided badge.
-        UserInfo userInfo = getUserIfProfile(userHandle);
+        UserInfo userInfo = getUserInfo(userHandle);
         if (userInfo != null && userInfo.isManagedProfile()) {
             return com.android.internal.R.drawable.ic_corp_icon_badge;
         }
         return 0;
     }
 
-    private UserInfo getUserIfProfile(int userHandle) {
-        List<UserInfo> userProfiles = getUserManager().getProfiles(mContext.getUserId());
-        for (UserInfo user : userProfiles) {
-            if (user.id == userHandle) {
-                return user;
-            }
-        }
-        return null;
+    private UserInfo getUserInfo(int userHandle) {
+        return getUserManager().getUserInfo(userHandle);
     }
 
     /** {@hide} */
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 88c8964..132b6dd 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3173,16 +3173,9 @@
         }
 
         private void bindHeaderAppName(RemoteViews contentView) {
-            PackageManager packageManager = mContext.getPackageManager();
-            ApplicationInfo info = null;
-            try {
-                info = packageManager.getApplicationInfo(mContext.getApplicationInfo().packageName,
-                        0);
-            } catch (final NameNotFoundException e) {
-                return;
-            }
-            CharSequence appName = info != null ? packageManager.getApplicationLabel(info)
-                    : null;
+            CharSequence appName = mContext.getPackageManager()
+                    .getApplicationLabel(mContext.getApplicationInfo());
+
             if (TextUtils.isEmpty(appName)) {
                 return;
             }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e1e8a07..c1017fb 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4387,10 +4387,8 @@
         int badgeDensity);
 
     /**
-     * If the target user is a managed profile of the calling user or if the
-     * target user is the caller and is itself a managed profile, then this
-     * returns a badged copy of the given icon to be able to distinguish it from
-     * the original icon. For badging an arbitrary drawable use
+     * If the target user is a managed profile, then this returns a badged copy of the given icon
+     * to be able to distinguish it from the original icon. For badging an arbitrary drawable use
      * {@link #getUserBadgedDrawableForDensity(
      * android.graphics.drawable.Drawable, UserHandle, android.graphics.Rect, int)}.
      * <p>
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 7223dfb..e2675b1 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -972,7 +972,8 @@
 
     /**
      * Returns the UserInfo object describing a specific user.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission or the caller is
+     * in the same profile group of target user.
      * @param userHandle the user handle of the user whose information is being requested.
      * @return the UserInfo object for a specific user.
      * @hide
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 8206bda..5342f98 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -641,7 +641,12 @@
 
     @Override
     public UserInfo getUserInfo(int userId) {
-        checkManageUsersPermission("query user");
+        if (!hasManageUsersPermission()
+                && !isSameProfileGroupLP(UserHandle.getCallingUserId(), userId)) {
+            throw new SecurityException(
+                    "You need MANAGE_USERS permission to: query users outside profile group");
+        }
+
         synchronized (mUsersLock) {
             return getUserInfoLU(userId);
         }
@@ -1196,18 +1201,28 @@
      *
      * @param message used as message if SecurityException is thrown
      * @throws SecurityException if the caller is not system or root
+     * @see #hasManageUsersPermission()
      */
     private static final void checkManageUsersPermission(String message) {
-        final int uid = Binder.getCallingUid();
-        if (!UserHandle.isSameApp(uid, Process.SYSTEM_UID) && uid != Process.ROOT_UID
-                && ActivityManager.checkComponentPermission(
-                        android.Manifest.permission.MANAGE_USERS,
-                        uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
+        if (!hasManageUsersPermission()) {
             throw new SecurityException("You need MANAGE_USERS permission to: " + message);
         }
     }
 
     /**
+     * @return whether the calling UID is system UID or root's UID or the calling app has the
+     * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}.
+     */
+    private static final boolean hasManageUsersPermission() {
+        final int callingUid = Binder.getCallingUid();
+        return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
+                || callingUid == Process.ROOT_UID
+                || ActivityManager.checkComponentPermission(
+                        android.Manifest.permission.MANAGE_USERS,
+                        callingUid, -1, true) == PackageManager.PERMISSION_GRANTED;
+    }
+
+    /**
      * Enforces that only the system UID or root's UID (on any user) can make certain calls to the
      * UserManager.
      *