From d2a1feba7f574bd7b89f12be2148d36da9352a41 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Fri, 29 Jan 2021 16:31:36 -0800 Subject: [PATCH] Dump install permission states for non-system users. If they are different from the system user. This helps debugging, or otherwise the information won't be available anywhere. Fixes: 178339792 Test: adb shell dumpsys package Change-Id: If8831842d8631fb17e4cf89c3f2ac7862d1ef693 (cherry picked from commit 63d811f4449a963c91bc9a963562e6f4fb0a3ad1) --- .../java/com/android/server/pm/Settings.java | 71 +++++++++++++------ .../pm/permission/LegacyPermissionState.java | 44 +++++++++++- 2 files changed, 91 insertions(+), 24 deletions(-) diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 2929568ab1d75..349d556eac874 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -4881,7 +4881,7 @@ public final class Settings implements Watchable, Snappable { } if (ps.sharedUser == null || permissionNames != null || dumpAll) { - dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState); + dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState, users); } if (dumpAllComponents) { @@ -5131,9 +5131,12 @@ public final class Settings implements Watchable, Snappable { continue; } - dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState); + List users = getAllUsers(UserManagerService.getInstance()); - for (int userId : UserManagerService.getInstance().getUserIds()) { + dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState, users); + + for (UserInfo user : users) { + final int userId = user.id; final int[] gids = mPermissionDataProvider.getGidsForUid(UserHandle.getUid( userId, su.userId)); final Collection permissions = @@ -5247,31 +5250,55 @@ public final class Settings implements Watchable, Snappable { } } - void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet permissionNames, - LegacyPermissionState permissionsState) { - Collection permissionStates = permissionsState.getPermissionStates( - UserHandle.USER_SYSTEM); - boolean hasInstallPermissions = false; - for (PermissionState permissionState : permissionStates) { - if (!permissionState.isRuntime()) { - hasInstallPermissions = true; - break; - } - } - if (hasInstallPermissions) { - pw.print(prefix); pw.println("install permissions:"); + void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, + ArraySet filterPermissionNames, LegacyPermissionState permissionsState, + List users) { + ArraySet dumpPermissionNames = new ArraySet<>(); + for (UserInfo user : users) { + int userId = user.id; + Collection permissionStates = permissionsState.getPermissionStates( + userId); for (PermissionState permissionState : permissionStates) { if (permissionState.isRuntime()) { continue; } - if (permissionNames != null - && !permissionNames.contains(permissionState.getName())) { + String permissionName = permissionState.getName(); + if (filterPermissionNames != null + && !filterPermissionNames.contains(permissionName)) { continue; } - pw.print(prefix); pw.print(" "); pw.print(permissionState.getName()); - pw.print(": granted="); pw.print(permissionState.isGranted()); - pw.println(permissionFlagsToString(", flags=", - permissionState.getFlags())); + dumpPermissionNames.add(permissionName); + } + } + boolean printedSomething = false; + for (String permissionName : dumpPermissionNames) { + PermissionState systemPermissionState = permissionsState.getPermissionState( + permissionName, UserHandle.USER_SYSTEM); + for (UserInfo user : users) { + int userId = user.id; + PermissionState permissionState; + if (userId == UserHandle.USER_SYSTEM) { + permissionState = systemPermissionState; + } else { + permissionState = permissionsState.getPermissionState(permissionName, userId); + if (Objects.equals(permissionState, systemPermissionState)) { + continue; + } + } + if (!printedSomething) { + pw.print(prefix); pw.println("install permissions:"); + printedSomething = true; + } + pw.print(prefix); pw.print(" "); pw.print(permissionName); + pw.print(": granted="); pw.print( + permissionState != null && permissionState.isGranted()); + pw.print(permissionFlagsToString(", flags=", + permissionState != null ? permissionState.getFlags() : 0)); + if (userId == UserHandle.USER_SYSTEM) { + pw.println(); + } else { + pw.print(", userId="); pw.println(userId); + } } } } diff --git a/services/core/java/com/android/server/pm/permission/LegacyPermissionState.java b/services/core/java/com/android/server/pm/permission/LegacyPermissionState.java index 92f22a4a7b8e0..e8eae471874a6 100644 --- a/services/core/java/com/android/server/pm/permission/LegacyPermissionState.java +++ b/services/core/java/com/android/server/pm/permission/LegacyPermissionState.java @@ -103,6 +103,26 @@ public final class LegacyPermissionState { return Objects.equals(mMissing, other.mMissing); } + /** + * Get the permission state for a permission and a user. + * + * @param permissionName the permission name + * @param userId the user ID + * @return the permission state + * + * @hide + */ + @Nullable + public PermissionState getPermissionState(@NonNull String permissionName, + @UserIdInt int userId) { + checkUserId(userId); + UserState userState = mUserStates.get(userId); + if (userState == null) { + return null; + } + return userState.getPermissionState(permissionName); + } + /** * Put a permission state for a user. * @@ -142,10 +162,10 @@ public final class LegacyPermissionState { } /** - * Get all the runtime permission states for a user. + * Get all the permission states for a user. * * @param userId the user ID - * @return the runtime permission states + * @return the permission states */ @NonNull public Collection getPermissionStates(@UserIdInt int userId) { @@ -301,5 +321,25 @@ public final class LegacyPermissionState { public int getFlags() { return mFlags; } + + @Override + public boolean equals(@Nullable Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + PermissionState that = (PermissionState) object; + return mRuntime == that.mRuntime + && mGranted == that.mGranted + && mFlags == that.mFlags + && Objects.equals(mName, that.mName); + } + + @Override + public int hashCode() { + return Objects.hash(mName, mRuntime, mGranted, mFlags); + } } }