From bf667ec10d99c9fcc9c8cb886ffbf9fb00a29612 Mon Sep 17 00:00:00 2001 From: Manjeet Rulhania Date: Thu, 27 Apr 2023 10:17:32 -0700 Subject: [PATCH] Add dumpsys for new permissions subsystem Bug: 270168418 Test: manual Change-Id: Ieeb454a93e06a5014deab06351c5ab8aa3501396 --- .../android/content/pm/PermissionInfo.java | 34 +++++ .../permission/PermissionManagerService.java | 8 + .../PermissionManagerServiceImpl.java | 9 +- .../access/permission/Permission.kt | 8 + .../access/permission/PermissionService.kt | 140 +++++++++++++++++- 5 files changed, 190 insertions(+), 9 deletions(-) diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index 4fa80d7d7f40a..9114ea3eba675 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -610,6 +610,40 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { return protLevel.toString(); } + /** @hide */ + public static @NonNull String flagsToString(@Flags int flags) { + StringBuilder sb = new StringBuilder("["); + while (flags != 0) { + final int flag = 1 << Integer.numberOfTrailingZeros(flags); + flags &= ~flag; + switch (flag) { + case PermissionInfo.FLAG_COSTS_MONEY: + sb.append("costsMoney"); + break; + case PermissionInfo.FLAG_REMOVED: + sb.append("removed"); + break; + case PermissionInfo.FLAG_HARD_RESTRICTED: + sb.append("hardRestricted"); + break; + case PermissionInfo.FLAG_SOFT_RESTRICTED: + sb.append("softRestricted"); + break; + case PermissionInfo.FLAG_IMMUTABLY_RESTRICTED: + sb.append("immutablyRestricted"); + break; + case PermissionInfo.FLAG_INSTALLED: + sb.append("installed"); + break; + default: sb.append(flag); + } + if (flags != 0) { + sb.append("|"); + } + } + return sb.append("]").toString(); + } + /** * @hide */ diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 2b780294e2598..8c6e62013bb59 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -79,6 +79,8 @@ import com.android.server.pm.permission.PermissionManagerServiceInternal.Hotword import com.android.server.pm.pkg.AndroidPackage; import com.android.server.pm.pkg.PackageState; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -1763,4 +1765,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { return false; } } + + @Override + protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, + @Nullable String[] args) { + mPermissionManagerServiceImpl.dump(fd, writer, args); + } } diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java index 572a446945991..4fb7e32ff261b 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java @@ -122,7 +122,6 @@ import com.android.internal.logging.nano.MetricsProto; import com.android.internal.os.RoSystemProperties; import com.android.internal.util.ArrayUtils; import com.android.internal.util.CollectionUtils; -import com.android.internal.util.DumpUtils; import com.android.internal.util.IntPair; import com.android.internal.util.Preconditions; import com.android.server.FgThread; @@ -461,13 +460,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt } @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) { - return; - } - - mContext.getSystemService(PermissionControllerManager.class).dump(fd, args); - } + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {} /** * This method should typically only be used when granting or revoking diff --git a/services/permission/java/com/android/server/permission/access/permission/Permission.kt b/services/permission/java/com/android/server/permission/access/permission/Permission.kt index 39b4eafefcb67..c7fe1a9e744e8 100644 --- a/services/permission/java/com/android/server/permission/access/permission/Permission.kt +++ b/services/permission/java/com/android/server/permission/access/permission/Permission.kt @@ -168,5 +168,13 @@ data class Permission( const val TYPE_CONFIG = 1 // The permission is defined dynamically. const val TYPE_DYNAMIC = 2 + + fun typeToString(type: Int): String = + when (type) { + TYPE_MANIFEST -> "TYPE_MANIFEST" + TYPE_CONFIG -> "TYPE_CONFIG" + TYPE_DYNAMIC -> "TYPE_DYNAMIC" + else -> type.toString() + } } } diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt index 358893ee7e3ad..4d5b2c9c79cc4 100644 --- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt +++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt @@ -48,6 +48,7 @@ import android.provider.Settings import android.util.ArrayMap import android.util.ArraySet import android.util.DebugUtils +import android.util.IndentingPrintWriter import android.util.IntArray as GrowingIntArray import android.util.Log import android.util.SparseBooleanArray @@ -63,6 +64,7 @@ import com.android.server.PermissionThread import com.android.server.ServiceThread import com.android.server.SystemConfig import com.android.server.permission.access.AccessCheckingService +import com.android.server.permission.access.AccessState import com.android.server.permission.access.AppOpUri import com.android.server.permission.access.GetStateScope import com.android.server.permission.access.MutateStateScope @@ -1743,7 +1745,143 @@ class PermissionService( if (!DumpUtils.checkDumpPermission(context, LOG_TAG, pw)) { return } - context.getSystemService(PermissionControllerManager::class.java)!!.dump(fd, args) + + val writer = IndentingPrintWriter(pw, " ") + + if (args.isNullOrEmpty()) { + service.getState { + writer.dumpSystemState(state) + getAllAppIdPackageNames(state).forEachIndexed { _, appId, packageNames -> + if (appId != Process.INVALID_UID) { + writer.dumpAppIdState(appId, state, packageNames) + } + } + } + } else if (args[0] == "--app-id" && args.size == 2) { + val appId = args[1].toInt() + service.getState { + val appIdPackageNames = getAllAppIdPackageNames(state) + if (appId in appIdPackageNames) { + writer.dumpAppIdState(appId, state, appIdPackageNames[appId]) + } else { + writer.println("Unknown app ID $appId.") + } + } + } else { + writer.println("Usage: dumpsys permission [--app-id APP_ID]") + } + } + + private fun getAllAppIdPackageNames( + state: AccessState + ): IndexedMap> { + val appIds = MutableIndexedSet() + + val packageStates = packageManagerLocal.withUnfilteredSnapshot().use { + it.packageStates + } + state.userStates.forEachIndexed { _, _, userState -> + userState.appIdPermissionFlags.forEachIndexed { _, appId, _ -> + appIds.add(appId) + } + userState.appIdAppOpModes.forEachIndexed { _, appId, _ -> + appIds.add(appId) + } + userState.packageVersions.forEachIndexed packageVersions@ { _, packageName, _ -> + val appId = packageStates[packageName]?.appId ?: return@packageVersions + appIds.add(appId) + } + userState.packageAppOpModes.forEachIndexed packageAppOpModes@ { _, packageName, _ -> + val appId = packageStates[packageName]?.appId ?: return@packageAppOpModes + appIds.add(appId) + } + } + + val appIdPackageNames = MutableIndexedMap>() + packageStates.forEach { (_, packageState) -> + appIdPackageNames.getOrPut(packageState.appId) { MutableIndexedSet() } + .add(packageState.packageName) + } + // add non-package app IDs which might not be reported by package manager. + appIds.forEachIndexed { _, appId -> + appIdPackageNames.getOrPut(appId) { MutableIndexedSet() } + } + + return appIdPackageNames + } + + private fun IndentingPrintWriter.dumpSystemState(state: AccessState) { + println("Permissions:") + withIndent { + state.systemState.permissions.forEachIndexed { _, _, permission -> + val protectionLevel = PermissionInfo.protectionToString(permission.protectionLevel) + println("${permission.name}: appId=${permission.appId}, " + + "type=${Permission.typeToString(permission.type)}, " + + "gids=${permission.gids.contentToString()}, " + + "protection=[$protectionLevel], " + + "flags=${PermissionInfo.flagsToString(permission.permissionInfo.flags)}" + ) + } + } + println("Permission trees:") + withIndent { + state.systemState.permissionTrees.forEachIndexed { _, _, permissionTree -> + println("${permissionTree.name}: appId=${permissionTree.appId}") + } + } + } + + private fun IndentingPrintWriter.dumpAppIdState( + appId: Int, + state: AccessState, + packageNames: IndexedSet? + ) { + println("App ID: $appId") + withIndent { + state.userStates.forEachIndexed { _, userId, userState -> + println("User: $userId") + withIndent { + println("Permissions:") + withIndent { + userState.appIdPermissionFlags[appId]?.forEachIndexed { + _, permissionName, flags -> + val isGranted = PermissionFlags.isPermissionGranted(flags) + println( + "$permissionName: granted=$isGranted, flags=" + + PermissionFlags.toString(flags) + ) + } + } + + println("App ops:") + withIndent { + userState.appIdAppOpModes[appId]?.forEachIndexed {_, appOpName, appOpMode -> + println("$appOpName: mode=${AppOpsManager.modeToName(appOpMode)}") + } + } + packageNames?.forEachIndexed { _, packageName -> + println("Package: $packageName") + withIndent { + println("version=${userState.packageVersions[packageName]}") + println("App ops:") + withIndent { + userState.packageAppOpModes[packageName]?.forEachIndexed { + _, appOpName, appOpMode -> + val modeName = AppOpsManager.modeToName(appOpMode) + println("$appOpName: mode=$modeName") + } + } + } + } + } + } + } + } + + private inline fun IndentingPrintWriter.withIndent(block: IndentingPrintWriter.() -> Unit) { + increaseIndent() + block() + decreaseIndent() } override fun getPermissionTEMP(permissionName: String): LegacyPermission2? {