RuntimePermissionsStubber

public final class RuntimePermissionsStubber


Helper class that makes it easy to stub runtime permissions for UI testing on Android M (API 23) and above.

When used in a test method this class will stub the granting/revoking of a runtime permission without showing Android's permissions dialog and therefore not block the App's UI.

These APIs are just a wrapper around Intents and are equivalent to the following Intento stubbing code: intending(PermissionMatcher).respondWith(PermissionActivityResult);

Note, a prerequisite to using this API is that every test needs to run in a single Instrumentation and adb shell pm clear must be run before or after each test. The reason for this limitation is how the Android framework revokes permissions at runtime. After a permission is granted for one test, it will remain granted for all other tests. This is problematic because the internal stubbing logic relies on intercepting requestPermissions which will be bypassed for subsequent tests. Thus, a previously granted permissions must be revoked after test execution is finished. However, the Android framework will kill the Instrumentation process after handling a permission revoking request which will abort all further test execution.

This class contains two APIs that can be used to stub runtime permissions. intendingGrantedPermissions and intendingRevokedPermissions To grant a permission use:

intendingGrantedPermissions(android.Manifest.permission.ACCESS_FINE_LOCATION);

Revoking a permission using intendingRevokedPermissions works very similar to granting a permission and will return the appropriate ActivityResult to make your app believe the runtime permission was revoked. To revoke a permission use:

intendingRevokedPermissions(android.Manifest.permission.ACCESS_FINE_LOCATION);

This API is currently in beta.

Summary

Nested types

public class RuntimePermissionsStubber.ActivityResultBuilder

Builds an ActivityResult for a corresponding permission request.

public class RuntimePermissionsStubber.Matchers

A collection of hamcrest matchers to help with runtime permission stubbing.

Constants

static final String
EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES"

Internal Android extra which used as a key for permission names in an Intent bundle.

Public constructors

Public methods

static void
intendingGrantedPermissions(String[] grantPermissions)

Intercepts the request permission Intent and returns a grant permission ActivityResult back to your app.

static void
intendingRevokedPermissions(String[] revokePermissions)

Intercepts the request permission Intent and returns a revocation permission ActivityResult back to your app.

Constants

EXTRA_REQUEST_PERMISSIONS_NAMES

public static final String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES"

Internal Android extra which used as a key for permission names in an Intent bundle.

Public constructors

RuntimePermissionsStubber

public RuntimePermissionsStubber()

Public methods

intendingGrantedPermissions

public static void intendingGrantedPermissions(String[] grantPermissions)

Intercepts the request permission Intent and returns a grant permission ActivityResult back to your app.

Stubbing a permission grant using this method, will not show the Android permissions dialog and return an ActivityResult to Activity#onRequestPermissionsResult(int, String[], int[]) which will make your app code believe the permission was actually granted. In order to avoid SecurityExceptions when invoking the method protected by a permission this helper will also physically grant the permission under the hood.

Calling this method on lower API levels than Android M (API 23) will have no effect.

Parameters
String[] grantPermissions

a list of permission to grant

intendingRevokedPermissions

public static void intendingRevokedPermissions(String[] revokePermissions)

Intercepts the request permission Intent and returns a revocation permission ActivityResult back to your app.

Revoking a permission using this method will not show the Android permissions dialog and return an ActivityResult to Activity#onRequestPermissionsResult(int, String[], int[]) which will make your app code believe the permission was actually revoked.

Calling this method on lower API levels than Android M (API 23) will have no effect.

Parameters
String[] revokePermissions

a list of permissions to revoke