/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the Lice`nse is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package androidx.test.rule; import static androidx.test.internal.util.Checks.checkNotNull; import android.Manifest.permission; import android.support.annotation.NonNull; import android.support.annotation.VisibleForTesting; import androidx.test.annotation.Beta; import androidx.test.internal.platform.ServiceLoaderWrapper; import androidx.test.internal.platform.content.PermissionGranter; import androidx.test.runner.permission.PermissionRequester; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** * The {@code GrantPermissionRule} Rule allows granting of runtime permissions on Android M (API 23) * and above. Use this {@code Rule} when a test requires a runtime permission to do its work. * *
When applied to a test class this Rule attempts to grant all requested runtime permissions. * The requested permissions will then be granted on the device and will take immediate effect. * Permissions can only be requested on Android M (API 23) or above and will be ignored on all other * API levels. Once a permission is granted it will apply for all tests running in the current * Instrumentation. There is no way of revoking a permission after it was granted. Attempting to do * so will crash the Instrumentation process. * *
Note, this Rule is usually used to grant runtime permissions to avoid the permission dialog * from showing up and blocking the App's Ui. This is especially helpful for Ui-Testing to avoid * losing control over the app under test. * *
The requested permissions will be granted for all test methods in the test class. Use {@link
* #grant(String...)} static factory method to request a variable number of permissions. Usage:
*
* \@Rule
* public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule
* .grant(android.Manifest.permission.ACCESS_FINE_LOCATION);
*
*
*
Note: As per
* this rule will automatically grant {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} when
* {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} is requested.
*
* See Request App
* Permissions for more details on runtime permissions.
*
* This API is currently in beta.
*/
@Beta
public class GrantPermissionRule implements TestRule {
private PermissionGranter permissionGranter;
private GrantPermissionRule() {
this(ServiceLoaderWrapper.loadSingleService(PermissionGranter.class, PermissionRequester::new));
}
@VisibleForTesting
GrantPermissionRule(@NonNull PermissionGranter permissionGranter) {
setPermissionGranter(permissionGranter);
}
/**
* Static factory method that grants the requested permissions.
*
* Permissions will be granted before any methods annotated with {@code @Before} but before
* any test method execution.
*
* @param permissions a variable list of Android permissions
* @return {@link GrantPermissionRule}
* @see android.Manifest.permission
*/
public static GrantPermissionRule grant(String... permissions) {
GrantPermissionRule grantPermissionRule = new GrantPermissionRule();
grantPermissionRule.grantPermissions(permissions);
return grantPermissionRule;
}
private void grantPermissions(String... permissions) {
Set