As Android evolves across major OS versions, Google frequently introduces breaking behavioral changes, restricted API boundaries, and privacy interventions designed to modernize the platform. To avoid breaking thousands of legacy applications immediately upon a system update, Android gates many of these changes behind the application’s declared targetSdkVersion. The Platform Compatibility Framework allows the operating system to toggle specific behavioral adjustments individually on a per-package basis, ensuring existing apps continue to run as expected while providing developers with a streamlined mechanism to test future requirements.
When an application crashes unexpectedly on a newer Android version, exhibits altered lifecycle events, or behaves erratically under strict privacy sandbox rules, developers and quality assurance engineers can inspect and manipulate the compatibility framework using Android Debug Bridge (ADB). The dumpsys platform_compat command exposes all registered compatibility change IDs, their default enabled states, per-package overrides, and logging histories. This guide covers how to inspect platform compatibility changes, toggle individual overrides via ADB, and diagnose app incompatibilities.
Understanding the Platform Compatibility Framework
Introduced in Android 11 and enhanced in subsequent versions, the Platform Compatibility Framework decouples breaking system changes from raw OS updates. Each behavioral change is assigned a unique 64-bit integer identifier (Change ID) and descriptive metadata:
- Target SDK Gating (
@EnabledAfter): Many changes only activate automatically if the application’stargetSdkVersionmeets or exceeds a specific API level (e.g., changes enabled after Android 13 / API 33). - Security and Privacy Interventions: Certain changes apply system-wide across all apps regardless of target SDK to protect device integrity or enforce background execution limits.
- Developer Overrides: On debuggable or userdebug builds, developers can force-enable or force-disable specific change IDs for their package without recompiling the application or modifying
AndroidManifest.xml. - Logging and Telemetry: Whenever an app triggers an active compatibility code path, the framework records the event, allowing developers to see which modernized APIs require attention.
Dumping Platform Compatibility Status via ADB
To inspect the entire compatibility configuration of your connected Android device, execute dumpsys platform_compat from your computer terminal:
# Dump complete platform compatibility subsystem state
adb shell dumpsys platform_compat
The console output produces an exhaustive list of all registered platform changes, categorised by their target SDK thresholds and status:
PlatformCompat:
===============
Installed compatibility changes:
Change ID: 171306433; Name: DONT_KILL_APP_WHEN_LOCALE_CHANGES; Enabled after: API 32
Change ID: 171228096; Name: OVERRIDE_MIN_ASPECT_RATIO_LARGE; Logging only: false
Change ID: 181883858; Name: FINISH_INPUT_NO_FALLBACK_CONNECTION; Enabled after: API 33
Change ID: 214251106; Name: REQUIRE_READ_MEDIA_PERMISSION; Enabled after: API 32
Change ID: 221265842; Name: BLOCK_UNTRUSTED_TOUCHES; Enabled: true; Overridable: false
Package Overrides:
com.example.enterprise.app:
Change ID: 214251106 (REQUIRE_READ_MEDIA_PERMISSION) -> FORCE_DISABLED
Change ID: 171228096 (OVERRIDE_MIN_ASPECT_RATIO_LARGE) -> FORCE_ENABLED
Filtering Compatibility Changes for a Specific Package
Because the full dump contains hundreds of system-wide changes, isolate changes affecting a specific application package by passing the package name to dumpsys platform_compat:
# Query platform compatibility changes for a specific application
adb shell dumpsys platform_compat com.example.enterprise.app
This filtered output lists every change affecting the app, indicating whether the change is currently Enabled, Disabled, or governed by a manual Override.
Inspecting Gated API Permissions and Storage Changes
Recent Android versions have introduced strict restrictions on granular storage access and background services. Reviewing specific Change IDs reveals whether an app is subject to modern security controls:
REQUIRE_READ_MEDIA_PERMISSION(Change ID: 214251106): Forces the app to request granular media permissions (READ_MEDIA_IMAGES,READ_MEDIA_VIDEO) instead of the broad legacyREAD_EXTERNAL_STORAGE.BLOCK_UNTRUSTED_TOUCHES(Change ID: 221265842): Blocks tapjacking and overlay attacks by discarding touch events that pass through an untrusted overlay window.DEFAULT_RESCUE_PARTY: Controls automated system recovery interventions if the package crashes during startup loops.
Toggling Compatibility Overrides via ADB am compat
To test how your application behaves under future Android rules—or to temporarily disable a problematic change while debugging—use the am compat command to force overrides.
Force-Enabling a Future Behavioral Change
To simulate running your app under newer target SDK rules without rebuilding the APK:
# Force-enable a specific compatibility change by name or ID
adb shell am compat enable REQUIRE_READ_MEDIA_PERMISSION com.example.enterprise.app
Alternatively, reference the numeric Change ID:
# Force-enable change using numeric identifier
adb shell am compat enable 214251106 com.example.enterprise.app
Force-Disabling a Breaking Change for Testing
If an app crashes due to a newly introduced background restriction, force-disable the change to confirm whether it is the direct culprit:
# Force-disable the compatibility change
adb shell am compat disable BLOCK_UNTRUSTED_TOUCHES com.example.enterprise.app
Resetting Overrides to Factory Defaults
Once testing is complete, restore the application’s default target SDK evaluation rules:
# Clear all manual overrides for the package
adb shell am compat reset-all com.example.enterprise.app
Auditing Active Compatibility Change Logs
Whenever an application invokes an API governed by a compatibility rule, the framework emits a diagnostic log to logcat. To monitor compatibility hits live as you navigate the app:
# Filter live logcat stream for compatibility events
adb logcat -s PlatformCompat
The resulting log entries confirm when gated logic triggers:
I PlatformCompat: Compatibility change REQUIRE_READ_MEDIA_PERMISSION evaluated for com.example.enterprise.app: ENABLED (targetSdkVersion: 33)
I PlatformCompat: Compatibility change BLOCK_UNTRUSTED_TOUCHES evaluated for com.example.enterprise.app: ENABLED (overridden)
Troubleshooting Platform Compatibility Issues
When working with compatibility overrides, keep these limitations in mind:
- App Not Debuggable (Permission Denied): On production commercial user builds, the Android framework forbids toggling compatibility overrides on non-debuggable applications. To use
am compaton production builds, the app must haveandroid:debuggable="true"declared in its manifest, or you must execute commands on auserdebugor emulator build. - Overridable: false Constraints: Critical platform security changes (such as core kernel mitigations) are flagged with
Overridable: false. The framework rejects any attempts to disable these changes via ADB to maintain system security. - App Process Must Restart: Applying an override via
am compatautomatically terminates the target application’s process so the changes take effect cleanly upon the next launch.
Using dumpsys platform_compat and am compat gives developers and engineers full control over Android’s behavioral modernizations, accelerating testing and root-cause analysis across OS versions.