Making permissions auto-reset available to billions more devices

Published 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 the phone

Most users spend a lot of time on their smartphones. Whether they work, play games or connect with friends, people often use apps as the primary gateway to their digital lives. In order to work, apps often need to request certain permissions, but with dozens of apps on a given device, it can be difficult to keep up with the permissions you have previously granted – especially if you have not used an app for an extended period.

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

The feature is enabled by default for apps targeted at Android 11 (API level 30) or higher. However, users can manually enable automatic reset permission for apps targeted at API levels 23 through 29.

So what does this mean for developers?

Exceptions

Some apps and permissions are automatically exempt from revocation, e.g. Active device manager apps used by companies and permissions set forth in company policy.

Ask the user to disable auto reset

If necessary, developers can ask the user to prevent the system from resetting their apps permissions. This is useful in situations where users expect the app to work primarily in the background, even without interacting with it. The most important application cases are listed here.

Comparison of current and new behaviors

Current behavior New behavior
Permits are reset automatically Android 11 (API level 30) and higher devices. Permissions are automatically reset on the following devices:

  • Devices with Google Play services running a version between Android 6.0 (API Level 23) and Android 10 (API Level 29), inclusive.
  • All devices are running Android 11 (API level 30) and higher devices.
Permissions are reset by default for apps targeted at Android 11 or later. The user can manually enable auto-reset for apps targeted at Android 6.0 (API level 23) or later. No change from current behavior.
Apps may prompt the user to disable auto-reset for the app. No change from current behavior.

Necessary code changes

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

Note: This API is only for apps whose targetSDK is API 30 or higher, because auto-reset permission only applies to these apps by default. Developers do not 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 released in Android 11):

Action Android 11 API
(Works only on Android 11 and later devices)
New API across platforms
(Works on Android 6.0 and newer devices, including Android 11 and newer devices)
Check if allowed auto reset is enabled on the device Check again 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 the user to disable auto-reset for your app Submit 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.

Example 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 works on Android 6.0 – Android 10 and also Android 11+ devices. It’s enough to just use the new APIs; you no longer need to call the Android 11 auto-reset APIs.

Compatibility with App Hibernation in Android 12

The new APIs are also compatible with the 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 prior to Android 12.

That getUnusedAppRestrictionsStatus() API returns API_31 if both auto-reset permission and app sleep apply to an app.

Start 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 secure, even on devices that do not support auto-reset permission (the API returns FEATURE_NOT_AVAILABLE on these devices).
  • October 2021 The cross-platform auto-reset APIs will be available as stable APIs (Jetpack Core 1.7.0).
  • December 2021 The auto-reset permission starts a gradual rollout across devices powered by Google Play Services running 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 automatically – reset for specific apps. The system automatically starts resetting the permissions for unused apps a few weeks after the feature is launched on a device.
  • 1st quarter 2022 The auto-reset permission will reach all devices running a version between Android 6.0 and Android 10.
William

Leave a Reply

Your email address will not be published.