blob: cdf79927ccf9952c98e04ba1fb9f83937107081c [file] [log] [blame]
/*
* Copyright (C) 2021 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 License 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 com.android.bedstead.nene.permissions;
import com.android.bedstead.nene.TestApis;
import com.android.bedstead.nene.exceptions.NeneException;
import com.android.bedstead.nene.utils.Versions;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* Default implementation of {@link PermissionContext}
*/
public final class PermissionContextImpl implements PermissionContextModifier {
private final Permissions mPermissions;
private final Set<String> mGrantedPermissions = new HashSet<>();
private final Set<String> mDeniedPermissions = new HashSet<>();
private final Set<String> mGrantedAppOps = new HashSet<>();
private final Set<String> mDeniedAppOps = new HashSet<>();
PermissionContextImpl(Permissions permissions) {
mPermissions = permissions;
}
Set<String> grantedPermissions() {
return mGrantedPermissions;
}
Set<String> deniedPermissions() {
return mDeniedPermissions;
}
Set<String> grantedAppOps() {
return mGrantedAppOps;
}
Set<String> deniedAppOps() {
return mDeniedAppOps;
}
/**
* See {@link Permissions#withPermission(String...)}
*/
@Override
public PermissionContextImpl withPermission(String... permissions) {
for (String permission : permissions) {
if (mDeniedPermissions.contains(permission)) {
mPermissions.clearPermissions();
throw new NeneException(
permission + " cannot be required to be both granted and denied");
}
}
mGrantedPermissions.addAll(Arrays.asList(permissions));
mPermissions.applyPermissions();
return this;
}
/**
* See {@link Permissions#withPermissionOnVersion(int, String...)}
*/
@Override
public PermissionContextImpl withPermissionOnVersion(int sdkVersion, String... permissions) {
return withPermissionOnVersionBetween(sdkVersion, sdkVersion, permissions);
}
/**
* See {@link Permissions#withPermissionOnVersionAtLeast(int, String...)}
*/
@Override
public PermissionContextImpl withPermissionOnVersionAtLeast(
int sdkVersion, String... permissions) {
return withPermissionOnVersionBetween(sdkVersion, Versions.ANY, permissions);
}
/**
* See {@link Permissions#withPermissionOnVersionAtMost(int, String...)}
*/
@Override
public PermissionContextImpl withPermissionOnVersionAtMost(
int sdkVersion, String... permissions) {
return withPermissionOnVersionBetween(Versions.ANY, sdkVersion, permissions);
}
/**
* See {@link Permissions#withPermissionOnVersionBetween(int, String...)}
*/
@Override
public PermissionContextImpl withPermissionOnVersionBetween(
int minSdkVersion, int maxSdkVersion, String... permissions) {
if (Versions.meetsSdkVersionRequirements(minSdkVersion, maxSdkVersion)) {
return withPermission(permissions);
}
return this;
}
/**
* See {@link Permissions#withoutPermission(String...)}
*/
@Override
public PermissionContextImpl withoutPermission(String... permissions) {
for (String permission : permissions) {
if (mGrantedPermissions.contains(permission)) {
mPermissions.clearPermissions();
throw new NeneException(
permission + " cannot be required to be both granted and denied");
}
}
if (TestApis.packages().instrumented().isInstantApp()) {
throw new NeneException(
"Tests which use withoutPermission must not run as instant apps");
}
mDeniedPermissions.addAll(Arrays.asList(permissions));
mPermissions.applyPermissions();
return this;
}
/**
* See {@link Permissions#withAppOp(String...)}
*/
@Override
public PermissionContextImpl withAppOp(String... appOps) {
for (String appOp : appOps) {
if (mDeniedAppOps.contains(appOp)) {
mPermissions.clearPermissions();
throw new NeneException(
appOp + " cannot be required to be both granted and denied");
}
}
mGrantedAppOps.addAll(Arrays.asList(appOps));
mPermissions.applyPermissions();
return this;
}
/**
* See {@link Permissions#withAppOpOnVersion(int, String...)}
*/
@Override
public PermissionContextImpl withAppOpOnVersion(int sdkVersion, String... appOps) {
return withAppOpOnVersionBetween(sdkVersion, sdkVersion, appOps);
}
/**
* See {@link Permissions#withAppOpOnVersionAtMost(int, String...)}
*/
@Override
public PermissionContextImpl withAppOpOnVersionAtMost(int sdkVersion, String... appOps) {
return withAppOpOnVersionBetween(Versions.ANY, sdkVersion, appOps);
}
/**
* See {@link Permissions#withAppOpOnVersionAtLeast(int, String...)}
*/
@Override
public PermissionContextImpl withAppOpOnVersionAtLeast(int sdkVersion, String... appOps) {
return withAppOpOnVersionBetween(sdkVersion, Versions.ANY, appOps);
}
/**
* See {@link Permissions#withAppOpOnVersionBetween(int, String...)}
*/
@Override
public PermissionContextImpl withAppOpOnVersionBetween(
int minSdkVersion, int maxSdkVersion, String... appOps) {
if (Versions.meetsSdkVersionRequirements(minSdkVersion, maxSdkVersion)) {
return withAppOp(appOps);
}
return this;
}
/**
* See {@link Permissions#withoutAppOp(String...)}.
*/
@Override
public PermissionContextImpl withoutAppOp(String... appOps) {
for (String appOp : appOps) {
if (mGrantedAppOps.contains(appOp)) {
mPermissions.clearPermissions();
throw new NeneException(
appOp + " cannot be required to be both granted and denied");
}
}
mDeniedAppOps.addAll(Arrays.asList(appOps));
mPermissions.applyPermissions();
return this;
}
@Override
public void close() {
Permissions.sInstance.undoPermission(this);
}
}