Compatibility framework changes (Android 12)

Figure 1. The App Compatibility Changes screen in developer options lists the changes that you can toggle.

This page describes each behavior change that is part of the compatibility framework in Android 12. Use this list in conjunction with the developer options and ADB commands to test and debug your app as you prepare to support and target Android 12.

Here are some of the things you can do using the compatibility framework tools:

  • Test targeted changes without actually changing the app's targetSdkVersion. You can use the toggles to force-enable specific targeted behavior changes to evaluate the impact on your existing app.
  • Focus your testing on specific changes only. Rather than having to address all targeted changes at once, the toggles let you disable all targeted changes except the ones you want to test against.
  • Manage toggles through adb. You can use adb commands to enable and disable the toggleable changes in your automated test environment.
  • Debug faster using standard change IDs. Toggleable changes each have a unique ID and name that you can use to quickly debug root cause in log output.

For complete details on using the tools for each of these use cases, see Compatibility framework tools.

Behavior changes included in the compatibility framework

The list in this section describes each behavior change that is included in the compatibility framework in the latest developer preview build of Android 12.

You can filter the list of changes by Default State.

Behavior changes added to the compatibility framework in Android 12

ALLOW_TEST_API_ACCESS

Change ID: 166236554
Default State: Disabled for all apps.

Allows apps to access @TestApi APIs.

Note: This change is disabled by default and should only be used by platform test code.

BLOCK_FLAG_SLIPPERY

Change ID: 157929241
Default State: Enabled for all apps.

For apps running on Android 12, checks if FLAG_SLIPPERY is being used with any windows in the app. We expect that this flag is likely only used by the system components as it is an unsupported field. If so, it will be restricted.

BLOCK_GPS_STATUS_USAGE

Change ID: 144027538
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, all GpsStatus API usage must be replaced with GnssStatus APIs.

BLOCK_IMMUTABLE_PENDING_INTENTS

Change ID: 171317480
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, immutable PendingIntent objects that are passed into location APIs will generate an IllegalArgumentException.

BLOCK_PENDING_INTENT_SYSTEM_API_USAGE

Change ID: 169887240
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, LocationRequest system APIs can't be used with PendingIntent location requests.

BLOCK_UNTRUSTED_TOUCHES

Change ID: 158002302
Default State: Enabled for all apps.

To preserve system security and a good user experience, Android 12 prevents apps from consuming touch events where an overlay blocks the app in an unsafe way.

To learn more about this change, see Untrusted touch events are blocked.

CAMERA_MIC_INDICATORS_NOT_PRESENT

Change ID: 162547999
Default State: Disabled for all apps.

Indicates that this device supports camera and microphone indicators. Will be false if present, because the CompatChanges#isChangeEnabled method returns true if the Change ID is not present.

CHANGE_ID_AUTH_STATE_DENIED

Change ID: 181350407
Default State: Enabled for apps that target Android 12 or higher.

For client apps targeting Android 12 and higher, a SecurityException is thrown when they are in the denied authorization state and attempt to send a message to a nanoapp.

CHANGE_ID_SAMPLING_RATE_SENSORS_PERMISSION

Change ID: 136069189
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, a SecurityException is thrown when they do not have HIGH_SAMPLING_RATE_SENSORS permission, run in debug mode, and request sampling rates that are faster than 200 Hz.

DELIVER_HISTORICAL_LOCATIONS

Change ID: 73144566
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, location clients may receive historical locations (from before the present time) under some circumstances.

DOWNSCALED

Change ID: 168419799
Default State: Disabled for all apps.

This change is the gatekeeper of all per-app buffer downscaling changes. Disabling this change prevents the following scaling factors from working:

When this change is enabled for an app package, the app is forcibly resized to the highest enabled scaling factor. For example, 80% is used if both 80% and 70% are enabled.

DOWNSCALE_50

Change ID: 176926741
Default State: Disabled for all apps.

When DOWNSCALED is also enabled, enabling this change for a package forces the app to assume it's running on a display with 50% vertical and horizontal resolution of the real display.

DOWNSCALE_60

Change ID: 176926771
Default State: Disabled for all apps.

When DOWNSCALED is also enabled, enabling this change for a package forces the app to assume it's running on a display with 60% vertical and horizontal resolution of the real display.

DOWNSCALE_70

Change ID: 176926829
Default State: Disabled for all apps.

When DOWNSCALED is also enabled, enabling this change for a package forces the app to assume it's running on a display with 70% vertical and horizontal resolution of the real display.

DOWNSCALE_80

Change ID: 176926753
Default State: Disabled for all apps.

When DOWNSCALED is also enabled, enabling this change for a package forces the app to assume it's running on a display with 80% vertical and horizontal resolution of the real display.

DOWNSCALE_90

Change ID: 182811243
Default State: Disabled for all apps.

When DOWNSCALED is also enabled, enabling this change for a package forces the app to assume it's running on a display with 90% vertical and horizontal resolution of the real display.

DROP_CLOSE_SYSTEM_DIALOGS

Change ID: 174664120
Default State: Enabled for all apps.

To improve user control when interacting with apps and the system, the ACTION_CLOSE_SYSTEM_DIALOGS intent action is deprecated as of Android 12.

To learn more about this change, see Apps can't close system dialogs.

ENABLE_CHECKS_FOR_PRIVATE_FILES

Change ID: 172100307
Default State: Enabled for apps that target Android 12 or higher.

Apps targeting Android 12 and higher can't insert or update private files using media provider.

ENABLE_DEFERRED_SCAN

Change ID: 180326732
Default State: Enabled for apps that target Android 12 or higher.

Enable this option to defer the scan that is triggered as part of MediaProvider#update().

ENABLE_INCLUDE_ALL_VOLUMES

Change ID: 182734110
Default State: Enabled for apps that target Android 12 or higher.

Enable this option to include database rows of files from a recently unmounted volume in MediaProvider#query.

ENABLE_OPTIMIZED_MANAGE_EXTERNAL_STORAGE_ACCESS

Change ID: 178209446
Default State: Enabled for apps that target Android 12 or higher.

Enable this option to allow apps holding the Manifest.permission.MANAGE_EXTERNAL_STORAGE permission to request optimized external storage access.

Change ID: 183372781
Default State: Enabled for apps that target Android 11 (API level 30) or higher.

Enable this option to allow apps holding the android.app.role#SYSTEM_GALLERY role to request optimized external storage access.

ENFORCE_NATIVE_SHARED_LIBRARY_DEPENDENCIES

Change ID: 142191088
Default State: Enabled for apps that target Android 12 or higher.

Apps targeting Android 12 and higher need to declare dependencies to the public native shared libraries that are defined by the device maker using uses-native-library tag in its AndroidManifest.xml. If any of the dependencies can't be satisfied—for example, one of the dependencies doesn't exist—the package manager won't install the app. The dependency can be specified as optional using the android:required attribute in the tag, in which case failing to satisfy the dependency won't stop the installation.

Once installed, an app is provided with only the native shared libraries that are specified in the app manifest. Calling dlopen on a native shared library that doesn't appear in the app manifest will fail even if it actually exists on the device.

ENFORCE_STRICT_QUERY_BUILDER

Change ID: 143231523
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, the SQLiteQueryBuilder now verifies all CalendarProvider2 query selections against malicious arguments.

FGS_BG_START_USE_EXEMPTION_LIST_CHANGE_ID

Change ID: 175801883
Default State: Enabled for all apps.

If set to false for a package, the system will not exempt it from FGS-BG-start, even if it's in ActiveServices.sFgsBgStartExemptedPackages.

FORCE_DISABLE_HEVC_SUPPORT

Change ID: 174227820
Default State: Disabled for all apps.

Force disable an app from supporting the HEVC media capability. Apps should declare their supported media capabilities in their manifest but this flag can be used to force an app into not supporting HEVC, hence forcing transcoding while accessing media encoded in HEVC. Setting this flag will override any OS level defaults for apps. It is disabled by default, meaning that the OS defaults take precedence. Setting this flag and FORCE_ENABLE_HEVC_SUPPORT is an undefined state and will result in the OS ignoring both flags.

FORCE_ENABLE_HEVC_SUPPORT

Change ID: 174228127
Default State: Disabled for all apps.

Force enable an app to support the HEVC media capability Apps should declare their supported media capabilities in their manifest but this flag can be used to force an app into supporting HEVC, hence avoiding transcoding while accessing media encoded in HEVC. Setting this flag will override any OS level defaults for apps. It is disabled by default, meaning that the OS defaults would take precedence. Setting this flag and FORCE_DISABLE_HEVC_SUPPORT is an undefined state and will result in the OS ignoring both flags.

FORCE_NON_RESIZE_APP

Change ID: 181136395
Default State: Disabled for all apps.

Forces the packages it is applied to to be non-resizable.

FORCE_RESIZE_APP

Change ID: 174042936
Default State: Disabled for all apps.

Forces the packages it is applied to to be resizeable. We only allow resizing in fullscreen windowing mode, but not forcing the app into resizeable multi-windowing mode.

HIDE_PROP_ICUBINARY_DATA_PATH

Change ID: 171979766
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, removes access to the android.icu.impl.ICUBinary.dataPath property.

IS_BACKUP_SERVICE_ACTIVE_ENFORCE_PERMISSION_IN_SERVICE

Change ID: 158482162
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, the BACKUP permission needed for isBackupServiceActive() is enforced on the service-side rather than client-side in BackupManager.

KEYSTORE_OPERATION_CREATION_MAY_FAIL

Change ID: 169897160
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, keystore operation creation might now fail. Keystore used to work under the assumption that the creation of cryptographic operations always succeeds. However, the KeyMint backend has only a limited number of operation slots.

In order to keep up the appearance of "infinite" operation slots, the Keystore daemon would prune least recently used operations if there was no available operation slot. As a result, good operations could be terminated prematurely. This opened up AndroidKeystore up to denial-of-service (DoS) and unintended livelock. For example, if multiple apps woke up at the same time due to power management optimizations and attempted to perform crypto operations, they start terminating each others operations without making any progress.

To break out of livelocks and to discourage DoS attempts, we have changed the pruning strategy for such that it prefers clients that use few operation slots briefly. As a result, single operations that don't linger inactive for more than 5 seconds will almost always conclude unhampered by the pruning strategy. There are still some operations related to file system encryption that can prune even these operations, but those cases are extremely rare. As a side effect of this new pruning strategy operation, creation can now fail if the client has a lower pruning power than all of the existing operations.

Pruning strategy: To find a suitable candidate, we compute the malus for the caller and each existing operation. The malus is the inverse of the pruning power (caller) or pruning resistance (existing operation). For the caller to be able to prune an operation, it must find an operation with a malus higher than its own. For more details on the pruning strategy, see the implementation of operation.rs. On Android 11 (API level 30) and lower, KeyStore2 will poll the Keystore daemon for a free operation slot. For apps targeting Android 11 (API level 30) and lower, it will still look like cipher and signature object initialization always succeeds—however, it may take longer to get an operation. All Android versions benefit from fairer operation slot scheduling and a better chance to successfully conclude an operation.

LOW_POWER_EXCEPTIONS

Change ID: 168936375
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, all LocationRequest objects marked as low power throw exceptions if the caller does not have the LOCATION_HARDWARE permission, instead of silently dropping the low power part of the request.

MISSING_EXPORTED_FLAG

Change ID: 150232615
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, an explicit value must be specified for the android:exported attribute whenever an intent filter is defined.

To learn more about this change, see Safer exporting of components.

NATIVE_HEAP_ZERO_INIT

Change ID: 178038272
Default State: Disabled for all apps.

Enable automatic zero-initialization of native heap memory allocations.

NATIVE_MEMTAG_ASYNC

Change ID: 135772972
Default State: Disabled for all apps.

Enable asynchronous (ASYNC) memory tag checking in this process. This flag only affects hardware supporting the ARM Memory Tagging Extension (MTE).

NATIVE_MEMTAG_SYNC

Change ID: 177438394
Default State: Disabled for all apps.

Enables synchronous (SYNC) memory tag checking in this process. This flag only affects hardware supporting the ARM Memory Tagging Extension (MTE). If both NATIVE_MEMTAG_ASYNC and this option are enabled, this option takes precedence and MTE is enabled in SYNC mode.

NOTIFICATION_CANCELLATION_REASONS

Change ID: 175319604
Default State: Enabled for apps that target Android 12 or higher.

Allows notification listeners to understand new cancellation reasons that are more specific.

NOTIFICATION_TRAMPOLINE_BLOCK

Change ID: 167676448
Default State: Enabled for apps that target Android 12 or higher.

To improve app performance and UX, apps that target Android 12 cannot use services or broadcast receivers as notification trampolines.

To learn more about this change, see Notification trampolines cannot be created from services or broadcast receivers.

OVERRIDE_MIN_ASPECT_RATIO

Change ID: 174042980
Default State: Disabled for all apps.

This change is the gatekeeper of all changes that force a given minimum aspect ratio. Enabling this change allows the following minimum aspect ratios to be applied:

When this change is enabled for an app package, the minimum aspect ratio given in the app's manifest is overridden to the largest enabled aspect ratio unless the app's manifest value is higher.

OVERRIDE_MIN_ASPECT_RATIO_LARGE

Change ID: 180326787
Default State: Disabled for all apps.

When OVERRIDE_MIN_ASPECT_RATIO is also enabled, enabling this change for a package sets the activity's minimum aspect ratio to a large value as defined by OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE.

OVERRIDE_MIN_ASPECT_RATIO_MEDIUM

Change ID: 180326845
Default State: Disabled for all apps.

When OVERRIDE_MIN_ASPECT_RATIO is also enabled, enabling this change for a package sets the activity's minimum aspect ratio to a medium value as defined by OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE.

PENDING_INTENT_EXPLICIT_MUTABILITY_REQUIRED

Change ID: 160794467
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, you must specify the mutability of each PendingIntent object that your app creates. This additional requirement improves your app's security.

To learn more about this change, see Pending intents must declare mutability.

RATE_LIMIT_TOASTS

Change ID: 174840628
Default State: This change can't be toggled. It is only logged by the compatibility framework.

Enables rate limiting on the number of Toast.show() calls to prevent overburdening the user with too many toasts in a limited time. Any attempt to show more toasts than allowed in a certain time frame will result in the toast being discarded.

REQUIRE_EXACT_ALARM_PERMISSION

Change ID: 171306433
Default State: Disabled for all apps.

For apps targeting Android 12 and higher, apps must have the new Manifest.permission.SCHEDULE_EXACT_ALARM permission in order to use setExactAndAllowWhileIdle(int, long, PendingIntent) and setAlarmClock(AlarmClockInfo, PendingIntent).

RETURN_NULL_HARDWARE_ADDRESS

Change ID: 170188668
Default State: Enabled for apps that target Android 11 (API level 30) or higher.

For apps targeting Android 11 (API level 30) and higher, getHardwareAddress() returns null when the hardware address is inaccessible. If the change is disabled, the default MAC address (02:00:00:00:00:00) is returned instead.

To learn more about this change, see Restrictions on Netlink MAC Address.

SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE

Change ID: 151105954
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, enforces that all attributionTags sent to noteOp(String, int, String), noteProxyOp(String, String), and startOp(String, int, String) are defined in the manifest of the package that is specified as a parameter of the methods.

To enable this change, both the package calling noteOp(String, int, String) as well as the package specified as a parameter of the method must have this change enabled.

SELINUX_LATEST_CHANGES

Change ID: 143539591
Default State: Enabled for apps that target Android 12 or higher.

For apps targeting Android 12 and higher, opts in to the latest SELinux changes. Turning this change off for an app targeting Android 12 or higher is a no-op. Has no effect for apps that use a shared user id.

SELINUX_R_CHANGES

Change ID: 168782947
Default State: Enabled for apps that target Android 11 (API level 30) or higher.

This change gates an app's access to the untrusted_app_R-targetSDk SELinux domain. This is one of the foundational changes in the compatibility framework that allows apps to toggle other changes that are gated by targetSdkVersion without changing their app's targetSDKVersion. For this reason, you should not disable this change for an app that targets Android 11, or the app will not function.

This change has no effect for apps that use a shared user ID.

SETTINGS_API_V2

Change ID: 171306433
Default State: Disabled for all apps.

The new user preference API for verifying domains marked android:autoVerify="true" in AndroidManifest.xml intent filters is not yet implemented in the current platform preview. For now, it is possible to preview the new user preference changes by enabling this change using adb shell pm set-app-links-user-selection and similar commands.

THROW_EXCEPTION_ON_REQUIRE_INSTALL_PACKAGES_TO_ADD_INSTALLER_PACKAGE

Change ID: 150857253
Default State: Enabled for apps that target Android 11 (API level 30) or higher.

For apps targeting Android 11 (API level 30) and higher, adding an installer package name to a package that does not have one set now requires the INSTALL_PACKAGES permission. If the caller targets Android 11 (API level 30), a SecurityException is thrown. Otherwise, the request fails silently. In both cases, and regardless of whether this change is enabled, the installer package remains unchanged.