In modern Android releases (Android 11 through Android 15), the security model governing application access to sensitive sensors, private storage, and user data is coordinated by PermissionManagerService. While standard settings menus provide a simplified toggle interface for permissions like Camera or Location, underlying platform decisions depend on detailed grant flags, split permissions, background exemptions, and UID mappings. For security researchers, mobile developers, and enterprise device administrators, Android Debug Bridge (ADB) exposes complete runtime permission state tables via the dumpsys permission command.
Architecture of the Android Permission Manager
Android categorizes permissions into distinct protection tiers:
- Normal Permissions: Automatically granted at install time (e.g., Internet, Bluetooth connect) without user interaction.
- Dangerous / Runtime Permissions: Guarded by explicit runtime dialogs (e.g.,
ACCESS_FINE_LOCATION,READ_MEDIA_IMAGES,RECORD_AUDIO). - Signature / Privileged Permissions: Reserved for pre-installed system apps or applications signed with the platform signing key.
Every runtime permission assigned to a package or user ID (UID) contains bitmask flags that dictate its evaluation lifecycle:
USER_SET: The user explicitly decided to allow or deny the permission.USER_FIXED: The user selected \”Don’t ask again\” (or denied twice), preventing further prompts.POLICY_FIXED: Enforced by Enterprise Device Policy Management (MDM/EMM), blocking user overrides.SYSTEM_FIXED: Mandated by system critical packages.ONE_TIME: Granted temporarily for the current app foreground session only.
Querying the Permission Subsystem via ADB
Connect your Android device with USB or Wi-Fi debugging enabled and authorize the host machine. To generate the full diagnostic dump of all system permissions, run:
adb shell dumpsys permission
The command outputs comprehensive sections detailing declared permission definitions, permission trees, dangerous permission mappings, and per-package grant tables.
Analysing Key Sections of dumpsys permission
1. Inspecting Package-Specific Permissions and Flags
To inspect runtime permissions for a specific application package (e.g., com.example.app), filter the output by package name:
adb shell dumpsys permission com.example.app
A typical output block shows requested and granted states:
Package [com.example.app] (uid=10245):
User 0:
runtime permissions:
android.permission.ACCESS_FINE_LOCATION: granted=true, flags=[ USER_SET ]
android.permission.RECORD_AUDIO: granted=false, flags=[ USER_FIXED ]
android.permission.CAMERA: granted=true, flags=[ USER_SET | ONE_TIME ]
android.permission.POST_NOTIFICATIONS: granted=true, flags=[ USER_SET ]
Notice the flag values. If android.permission.RECORD_AUDIO has USER_FIXED, runtime permission dialogs will no longer appear when the app calls requestPermissions(); the API returns immediately with a denied status.
2. Reviewing Permission Trees and Shared UIDs
To audit permissions shared across multiple packages running under the same UID (using sharedUserId):
adb shell dumpsys permission --uid 1000
This allows administrators to verify whether third-party or OEM packages are inheriting privileged system permissions through shared UID mappings.
3. Querying Permission Definition Trees
To inspect custom permissions registered by third-party applications or SDKs to prevent permission squatting:
adb shell dumpsys permission trees
Auditing and Testing Permission Modifiers via ADB
Developers can test application resilience against permission revocations, one-time expirations, and policy locks directly using the pm (Package Manager) command, subsequently confirming state transitions with dumpsys permission:
1. Grant a Runtime Permission
adb shell pm grant com.example.app android.permission.ACCESS_FINE_LOCATION
2. Revoke a Runtime Permission
adb shell pm revoke com.example.app android.permission.ACCESS_FINE_LOCATION
3. Reset Permission Flags (Clearing USER_FIXED)
When debugging permission flows, if you have clicked \”Don’t ask again\” and need to re-test the initial prompt dialog:
adb shell pm reset-permissions
Or clear application state entirely:
adb shell pm clear com.example.app
Filtering Dangerous and Revoked Permissions Across the System
To identify all apps currently holding sensitive background access across user profiles:
# Find all packages with background location granted
adb shell dumpsys permission | grep -B 2 -A 2 "ACCESS_BACKGROUND_LOCATION: granted=true"
# Find permissions restricted by enterprise MDM policy
adb shell dumpsys permission | grep -B 2 -A 2 "POLICY_FIXED"
By leveraging dumpsys permission, security auditors and developers gain complete, low-level transparency into Android’s permission evaluation pipeline, ensuring robust compliance verification and seamless user experience debugging.