Making permissions auto-reset available to billions more devices

Posted by Peter Visontay, Software Engineer; Bessie Jiang, Software Engineer

Contributors: Inara Ramji, Software Engineer; Rodrigo Farell, Interaction Designer; James Kelly, Product Manager; Henry Chin, Program Manager.

Illustration of person holding phone

Most users spend a lot of time on their smartphones. Whether working, playing games, or connecting with friends, people often use apps as the primary gateway for their digital lives. In order to work, apps often need to request certain permissions, but with dozens of apps on any given device, it can be tough to keep up with the permissions you’ve previously granted – especially if you haven’t used an app for an extended period of time.

In Android 11, we introduced the permission auto-reset feature. This feature helps protect user privacy by automatically resetting an app’s runtime permissions – which are permissions that display a prompt to the user when requested – if the app isn’t used for a few months. Starting in December 2021, we are expanding this to billions more devices. This feature will automatically be enabled on devices with Google Play services that are running Android 6.0 (API level 23) or higher.

The feature will be enabled by default for apps targeting Android 11 (API level 30) or higher. However, users can enable permission auto-reset manually for apps targeting API levels 23 to 29.

So what does this mean for developers?


Exceptions

Some apps and permissions are automatically exempted from revocation, like active Device Administrator apps used by enterprises, and permissions fixed by enterprise policy.


Request user to disable auto-reset

If needed, developers can ask the user to prevent the system from resetting their app's permissions. This is useful in situations where users expect the app to work primarily in the background, even without interacting with it. The main use cases are listed here.


Comparing current and new behavior

Current behavior New behavior
Permissions are automatically reset on Android 11 (API level 30) and higher devices. Permissions are automatically reset on the following devices:
  • Devices with Google Play services that are running a version between Android 6.0 (API level 23) and Android 10 (API level 29), inclusive.
  • All devices running Android 11 (API level 30) and higher devices.
Permissions are reset by default for apps targeting Android 11 or later. The user can manually enable auto-reset for apps targeting Android 6.0 (API level 23) or later. No change from the current behavior.
Apps can request the user to disable auto-reset for the app. No change from the current behavior.


Necessary code changes

If an app targets at least API 30, and asks the user to disable permission auto-reset, then developers will need to make a few simple code changes. If the app does not disable auto-reset, then no code changes are required.

Note: this API is only intended for apps whose targetSDK is API 30 or higher, because permission auto-reset only applies to these apps by default. Developers don’t need to change anything if the app‘s targetSDK is API 29 or lower.

The table below summarizes the new, cross-platform API (compared to the API published in Android 11):

Action Android 11 API
(works only on Android 11 and later devices)
New, cross-platform API
(works on Android 6.0 and later devices, including Android 11 and later devices)
Check if permission auto-reset is enabled on the device Check if Build.VERSION.SDK_INT >= Build.VERSION_CODES.R Call androidx.core.content.PackageManagerCompat.getUnusedAppRestrictionsStatus()
Check if auto-reset is disabled for your app Call PackageManager.
isAutoRevokeWhitelisted()
Call androidx.core.content.
PackageManagerCompat.
getUnusedAppRestrictionsStatus()
Request that the user disable auto-reset for your app Send an intent with action
Intent.ACTION_AUTO_REVOKE_PERMISSIONS
Send an intent created with androidx.core.content.
IntentCompat.
createManageUnusedAppRestrictionsIntent()


This cross-platform API is part of the Jetpack Core library, and will be available in Jetpack Core v1.7.0. This API is now available in beta.

Sample logic for an app that needs the user to disable auto-reset:

val future: ListenableFuture<Int> =
    PackageManagerCompat.getUnusedAppRestrictionsStatus(context)
future.addListener(
  { onResult(future.get()) },
   ContextCompat.getMainExecutor(context)
)

fun onResult(appRestrictionsStatus: Int) {
  when (appRestrictionsStatus) {
    // Status could not be fetched. Check logs for details.
    ERROR -> { }

    // Restrictions do not apply to your app on this device.
    FEATURE_NOT_AVAILABLE -> { }
    // Restrictions have been disabled by the user for your app.
    DISABLED -> { }

    // If the user doesn't start your app for months, its permissions 
    // will be revoked and/or it will be hibernated. 
    // See the API_* constants for details.
    API_30_BACKPORT, API_30, API_31 -> 
      handleRestrictions(appRestrictionsStatus)
  }
}

fun handleRestrictions(appRestrictionsStatus: Int) {
  // If your app works primarily in the background, you can ask the user
  // to disable these restrictions. Check if you have already asked the
  // user to disable these restrictions. If not, you can show a message to 
  // the user explaining why permission auto-reset and Hibernation should be 
  // disabled. Tell them that they will now be redirected to a page where 
  // they can disable these features.

  Intent intent = IntentCompat.createManageUnusedAppRestrictionsIntent
    (context, packageName)

  // Must use startActivityForResult(), not startActivity(), even if 
  // you don't use the result code returned in onActivityResult().
  startActivityForResult(intent, REQUEST_CODE)
}

The above logic will work on Android 6.0 – Android 10 and also Android 11+ devices. It is enough to use just the new APIs; you won’t need to call the Android 11 auto-reset APIs anymore.


Compatibility with App Hibernation in Android 12

The new APIs are also compatible with app hibernation introduced by Android 12 (API level 31). Hibernation is a new restriction applied to unused apps. This feature is not available on OS versions before Android 12.

The getUnusedAppRestrictionsStatus() API will return API_31 if both permission auto-reset and app hibernation apply to an app.


Launch Timeline

  • September 15, 2021 - The cross-platform auto-reset APIs are now in beta (Jetpack Core 1.7.0 beta library), so developers can start using these APIs today. Their use is safe even on devices that don’t support permission auto-reset (the API will return FEATURE_NOT_AVAILABLE on these devices).
  • October 2021 - The cross-platform auto-reset APIs become available as stable APIs (Jetpack Core 1.7.0).
  • December 2021 - The permission auto-reset feature will begin a gradual rollout across devices powered by Google Play Services that run a version between Android 6.0 and Android 10. On these devices, users can now go to the auto-reset settings page and enable/disable auto-reset for specific apps. The system will start to automatically reset the permissions of unused apps a few weeks after the feature launches on a device.
  • Q1 2022 - The permission auto-reset feature will reach all devices running a version between Android 6.0 and Android 10.