Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf667ec1 authored by Manjeet Rulhania's avatar Manjeet Rulhania Committed by Hai Zhang
Browse files

Add dumpsys for new permissions subsystem

Bug: 270168418
Test: manual
Change-Id: Ieeb454a93e06a5014deab06351c5ab8aa3501396
parent 89cc5e9d
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -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
     */
+8 −0
Original line number Diff line number Diff line
@@ -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);
    }
}
+1 −8
Original line number Diff line number Diff line
@@ -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
+8 −0
Original line number Diff line number Diff line
@@ -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()
            }
    }
}
+139 −1
Original line number Diff line number Diff line
@@ -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<Int, MutableIndexedSet<String>> {
        val appIds = MutableIndexedSet<Int>()

        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<Int, MutableIndexedSet<String>>()
        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<String>?
    ) {
        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? {