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
This commit is contained in:
Tony Mak
2016-03-16 10:46:49 +00:00
parent 54f264fcdb
commit 4dc008cda2
5 changed files with 33 additions and 32 deletions

View File

@@ -1147,7 +1147,7 @@ public class ApplicationPackageManager extends PackageManager {
}
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 @@ public class ApplicationPackageManager extends PackageManager {
@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 @@ public class ApplicationPackageManager extends PackageManager {
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} */

View File

@@ -3173,16 +3173,9 @@ public class Notification implements Parcelable
}
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;
}

View File

@@ -4387,10 +4387,8 @@ public abstract class PackageManager {
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>

View File

@@ -972,7 +972,8 @@ public class UserManager {
/**
* 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

View File

@@ -641,7 +641,12 @@ public class UserManagerService extends IUserManager.Stub {
@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,17 +1201,27 @@ public class UserManagerService extends IUserManager.Stub {
*
* @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.