Merge changes I21aaab57,Ie174f7ec
* changes: Expose APIs to configure transports to be restricted by VCN Add restrictions on underlying networks with VcnConfig
This commit is contained in:
@@ -27285,6 +27285,7 @@ package android.net.vcn {
|
|||||||
public final class VcnConfig implements android.os.Parcelable {
|
public final class VcnConfig implements android.os.Parcelable {
|
||||||
method public int describeContents();
|
method public int describeContents();
|
||||||
method @NonNull public java.util.Set<android.net.vcn.VcnGatewayConnectionConfig> getGatewayConnectionConfigs();
|
method @NonNull public java.util.Set<android.net.vcn.VcnGatewayConnectionConfig> getGatewayConnectionConfigs();
|
||||||
|
method @NonNull public java.util.Set<java.lang.Integer> getRestrictedUnderlyingNetworkTransports();
|
||||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.vcn.VcnConfig> CREATOR;
|
field @NonNull public static final android.os.Parcelable.Creator<android.net.vcn.VcnConfig> CREATOR;
|
||||||
}
|
}
|
||||||
@@ -27293,6 +27294,7 @@ package android.net.vcn {
|
|||||||
ctor public VcnConfig.Builder(@NonNull android.content.Context);
|
ctor public VcnConfig.Builder(@NonNull android.content.Context);
|
||||||
method @NonNull public android.net.vcn.VcnConfig.Builder addGatewayConnectionConfig(@NonNull android.net.vcn.VcnGatewayConnectionConfig);
|
method @NonNull public android.net.vcn.VcnConfig.Builder addGatewayConnectionConfig(@NonNull android.net.vcn.VcnGatewayConnectionConfig);
|
||||||
method @NonNull public android.net.vcn.VcnConfig build();
|
method @NonNull public android.net.vcn.VcnConfig build();
|
||||||
|
method @NonNull public android.net.vcn.VcnConfig.Builder setRestrictedUnderlyingNetworkTransports(@NonNull java.util.Set<java.lang.Integer>);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class VcnGatewayConnectionConfig {
|
public final class VcnGatewayConnectionConfig {
|
||||||
|
|||||||
@@ -15,16 +15,23 @@
|
|||||||
*/
|
*/
|
||||||
package android.net.vcn;
|
package android.net.vcn;
|
||||||
|
|
||||||
|
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||||
|
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||||
|
|
||||||
import static com.android.internal.annotations.VisibleForTesting.Visibility;
|
import static com.android.internal.annotations.VisibleForTesting.Visibility;
|
||||||
|
import static com.android.server.vcn.util.PersistableBundleUtils.INTEGER_DESERIALIZER;
|
||||||
|
import static com.android.server.vcn.util.PersistableBundleUtils.INTEGER_SERIALIZER;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.NetworkRequest;
|
import android.net.NetworkRequest;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.os.PersistableBundle;
|
import android.os.PersistableBundle;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.util.Preconditions;
|
import com.android.internal.util.Preconditions;
|
||||||
@@ -32,6 +39,7 @@ import com.android.server.vcn.util.PersistableBundleUtils;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -46,22 +54,36 @@ import java.util.Set;
|
|||||||
public final class VcnConfig implements Parcelable {
|
public final class VcnConfig implements Parcelable {
|
||||||
@NonNull private static final String TAG = VcnConfig.class.getSimpleName();
|
@NonNull private static final String TAG = VcnConfig.class.getSimpleName();
|
||||||
|
|
||||||
|
private static final Set<Integer> ALLOWED_TRANSPORTS = new ArraySet<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
ALLOWED_TRANSPORTS.add(TRANSPORT_WIFI);
|
||||||
|
ALLOWED_TRANSPORTS.add(TRANSPORT_CELLULAR);
|
||||||
|
}
|
||||||
|
|
||||||
private static final String PACKAGE_NAME_KEY = "mPackageName";
|
private static final String PACKAGE_NAME_KEY = "mPackageName";
|
||||||
@NonNull private final String mPackageName;
|
@NonNull private final String mPackageName;
|
||||||
|
|
||||||
private static final String GATEWAY_CONNECTION_CONFIGS_KEY = "mGatewayConnectionConfigs";
|
private static final String GATEWAY_CONNECTION_CONFIGS_KEY = "mGatewayConnectionConfigs";
|
||||||
@NonNull private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs;
|
@NonNull private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs;
|
||||||
|
|
||||||
|
private static final Set<Integer> RESTRICTED_TRANSPORTS_DEFAULT =
|
||||||
|
Collections.singleton(TRANSPORT_WIFI);
|
||||||
|
private static final String RESTRICTED_TRANSPORTS_KEY = "mRestrictedTransports";
|
||||||
|
@NonNull private final Set<Integer> mRestrictedTransports;
|
||||||
|
|
||||||
private static final String IS_TEST_MODE_PROFILE_KEY = "mIsTestModeProfile";
|
private static final String IS_TEST_MODE_PROFILE_KEY = "mIsTestModeProfile";
|
||||||
private final boolean mIsTestModeProfile;
|
private final boolean mIsTestModeProfile;
|
||||||
|
|
||||||
private VcnConfig(
|
private VcnConfig(
|
||||||
@NonNull String packageName,
|
@NonNull String packageName,
|
||||||
@NonNull Set<VcnGatewayConnectionConfig> gatewayConnectionConfigs,
|
@NonNull Set<VcnGatewayConnectionConfig> gatewayConnectionConfigs,
|
||||||
|
@NonNull Set<Integer> restrictedTransports,
|
||||||
boolean isTestModeProfile) {
|
boolean isTestModeProfile) {
|
||||||
mPackageName = packageName;
|
mPackageName = packageName;
|
||||||
mGatewayConnectionConfigs =
|
mGatewayConnectionConfigs =
|
||||||
Collections.unmodifiableSet(new ArraySet<>(gatewayConnectionConfigs));
|
Collections.unmodifiableSet(new ArraySet<>(gatewayConnectionConfigs));
|
||||||
|
mRestrictedTransports = Collections.unmodifiableSet(new ArraySet<>(restrictedTransports));
|
||||||
mIsTestModeProfile = isTestModeProfile;
|
mIsTestModeProfile = isTestModeProfile;
|
||||||
|
|
||||||
validate();
|
validate();
|
||||||
@@ -82,6 +104,20 @@ public final class VcnConfig implements Parcelable {
|
|||||||
new ArraySet<>(
|
new ArraySet<>(
|
||||||
PersistableBundleUtils.toList(
|
PersistableBundleUtils.toList(
|
||||||
gatewayConnectionConfigsBundle, VcnGatewayConnectionConfig::new));
|
gatewayConnectionConfigsBundle, VcnGatewayConnectionConfig::new));
|
||||||
|
|
||||||
|
final PersistableBundle restrictedTransportsBundle =
|
||||||
|
in.getPersistableBundle(RESTRICTED_TRANSPORTS_KEY);
|
||||||
|
if (restrictedTransportsBundle == null) {
|
||||||
|
// RESTRICTED_TRANSPORTS_KEY was added in U and does not exist in VcnConfigs created in
|
||||||
|
// older platforms
|
||||||
|
mRestrictedTransports = RESTRICTED_TRANSPORTS_DEFAULT;
|
||||||
|
} else {
|
||||||
|
mRestrictedTransports =
|
||||||
|
new ArraySet<Integer>(
|
||||||
|
PersistableBundleUtils.toList(
|
||||||
|
restrictedTransportsBundle, INTEGER_DESERIALIZER));
|
||||||
|
}
|
||||||
|
|
||||||
mIsTestModeProfile = in.getBoolean(IS_TEST_MODE_PROFILE_KEY);
|
mIsTestModeProfile = in.getBoolean(IS_TEST_MODE_PROFILE_KEY);
|
||||||
|
|
||||||
validate();
|
validate();
|
||||||
@@ -91,6 +127,19 @@ public final class VcnConfig implements Parcelable {
|
|||||||
Objects.requireNonNull(mPackageName, "packageName was null");
|
Objects.requireNonNull(mPackageName, "packageName was null");
|
||||||
Preconditions.checkCollectionNotEmpty(
|
Preconditions.checkCollectionNotEmpty(
|
||||||
mGatewayConnectionConfigs, "gatewayConnectionConfigs was empty");
|
mGatewayConnectionConfigs, "gatewayConnectionConfigs was empty");
|
||||||
|
|
||||||
|
final Iterator<Integer> iterator = mRestrictedTransports.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
final int transport = iterator.next();
|
||||||
|
if (!ALLOWED_TRANSPORTS.contains(transport)) {
|
||||||
|
iterator.remove();
|
||||||
|
Log.w(
|
||||||
|
TAG,
|
||||||
|
"Found invalid transport "
|
||||||
|
+ transport
|
||||||
|
+ " which might be from a new version of VcnConfig");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -109,6 +158,16 @@ public final class VcnConfig implements Parcelable {
|
|||||||
return Collections.unmodifiableSet(mGatewayConnectionConfigs);
|
return Collections.unmodifiableSet(mGatewayConnectionConfigs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the transports that will be restricted by the VCN.
|
||||||
|
*
|
||||||
|
* @see Builder#setRestrictedUnderlyingNetworkTransports(Set)
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Set<Integer> getRestrictedUnderlyingNetworkTransports() {
|
||||||
|
return Collections.unmodifiableSet(mRestrictedTransports);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not this VcnConfig is restricted to test networks.
|
* Returns whether or not this VcnConfig is restricted to test networks.
|
||||||
*
|
*
|
||||||
@@ -134,6 +193,12 @@ public final class VcnConfig implements Parcelable {
|
|||||||
new ArrayList<>(mGatewayConnectionConfigs),
|
new ArrayList<>(mGatewayConnectionConfigs),
|
||||||
VcnGatewayConnectionConfig::toPersistableBundle);
|
VcnGatewayConnectionConfig::toPersistableBundle);
|
||||||
result.putPersistableBundle(GATEWAY_CONNECTION_CONFIGS_KEY, gatewayConnectionConfigsBundle);
|
result.putPersistableBundle(GATEWAY_CONNECTION_CONFIGS_KEY, gatewayConnectionConfigsBundle);
|
||||||
|
|
||||||
|
final PersistableBundle restrictedTransportsBundle =
|
||||||
|
PersistableBundleUtils.fromList(
|
||||||
|
new ArrayList<>(mRestrictedTransports), INTEGER_SERIALIZER);
|
||||||
|
result.putPersistableBundle(RESTRICTED_TRANSPORTS_KEY, restrictedTransportsBundle);
|
||||||
|
|
||||||
result.putBoolean(IS_TEST_MODE_PROFILE_KEY, mIsTestModeProfile);
|
result.putBoolean(IS_TEST_MODE_PROFILE_KEY, mIsTestModeProfile);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -141,7 +206,8 @@ public final class VcnConfig implements Parcelable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(mPackageName, mGatewayConnectionConfigs, mIsTestModeProfile);
|
return Objects.hash(
|
||||||
|
mPackageName, mGatewayConnectionConfigs, mRestrictedTransports, mIsTestModeProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -153,6 +219,7 @@ public final class VcnConfig implements Parcelable {
|
|||||||
final VcnConfig rhs = (VcnConfig) other;
|
final VcnConfig rhs = (VcnConfig) other;
|
||||||
return mPackageName.equals(rhs.mPackageName)
|
return mPackageName.equals(rhs.mPackageName)
|
||||||
&& mGatewayConnectionConfigs.equals(rhs.mGatewayConnectionConfigs)
|
&& mGatewayConnectionConfigs.equals(rhs.mGatewayConnectionConfigs)
|
||||||
|
&& mRestrictedTransports.equals(rhs.mRestrictedTransports)
|
||||||
&& mIsTestModeProfile == rhs.mIsTestModeProfile;
|
&& mIsTestModeProfile == rhs.mIsTestModeProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,12 +256,15 @@ public final class VcnConfig implements Parcelable {
|
|||||||
@NonNull
|
@NonNull
|
||||||
private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs = new ArraySet<>();
|
private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs = new ArraySet<>();
|
||||||
|
|
||||||
|
@NonNull private final Set<Integer> mRestrictedTransports = new ArraySet<>();
|
||||||
|
|
||||||
private boolean mIsTestModeProfile = false;
|
private boolean mIsTestModeProfile = false;
|
||||||
|
|
||||||
public Builder(@NonNull Context context) {
|
public Builder(@NonNull Context context) {
|
||||||
Objects.requireNonNull(context, "context was null");
|
Objects.requireNonNull(context, "context was null");
|
||||||
|
|
||||||
mPackageName = context.getOpPackageName();
|
mPackageName = context.getOpPackageName();
|
||||||
|
mRestrictedTransports.addAll(RESTRICTED_TRANSPORTS_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -225,6 +295,36 @@ public final class VcnConfig implements Parcelable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateRestrictedTransportsOrThrow(Set<Integer> restrictedTransports) {
|
||||||
|
Objects.requireNonNull(restrictedTransports, "transports was null");
|
||||||
|
|
||||||
|
for (int transport : restrictedTransports) {
|
||||||
|
if (!ALLOWED_TRANSPORTS.contains(transport)) {
|
||||||
|
throw new IllegalArgumentException("Invalid transport " + transport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets transports that will be restricted by the VCN.
|
||||||
|
*
|
||||||
|
* @param transports transports that will be restricted by VCN. Networks that include any
|
||||||
|
* of the transports will be marked as restricted. Only {@link
|
||||||
|
* NetworkCapabilities#TRANSPORT_WIFI} and {@link
|
||||||
|
* NetworkCapabilities#TRANSPORT_CELLULAR} are allowed. {@link
|
||||||
|
* NetworkCapabilities#TRANSPORT_WIFI} is marked restricted by default.
|
||||||
|
* @return this {@link Builder} instance, for chaining
|
||||||
|
* @throws IllegalArgumentException if the input contains unsupported transport types.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder setRestrictedUnderlyingNetworkTransports(@NonNull Set<Integer> transports) {
|
||||||
|
validateRestrictedTransportsOrThrow(transports);
|
||||||
|
|
||||||
|
mRestrictedTransports.clear();
|
||||||
|
mRestrictedTransports.addAll(transports);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restricts this VcnConfig to matching with test networks (only).
|
* Restricts this VcnConfig to matching with test networks (only).
|
||||||
*
|
*
|
||||||
@@ -248,7 +348,11 @@ public final class VcnConfig implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public VcnConfig build() {
|
public VcnConfig build() {
|
||||||
return new VcnConfig(mPackageName, mGatewayConnectionConfigs, mIsTestModeProfile);
|
return new VcnConfig(
|
||||||
|
mPackageName,
|
||||||
|
mGatewayConnectionConfigs,
|
||||||
|
mRestrictedTransports,
|
||||||
|
mIsTestModeProfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -371,8 +371,9 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
|||||||
return new LocationPermissionChecker(context);
|
return new LocationPermissionChecker(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the transports that need to be marked as restricted by the VCN */
|
/** Gets transports that need to be marked as restricted by the VCN from CarrierConfig */
|
||||||
public Set<Integer> getRestrictedTransports(
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
|
public Set<Integer> getRestrictedTransportsFromCarrierConfig(
|
||||||
ParcelUuid subGrp, TelephonySubscriptionSnapshot lastSnapshot) {
|
ParcelUuid subGrp, TelephonySubscriptionSnapshot lastSnapshot) {
|
||||||
if (!Build.IS_ENG && !Build.IS_USERDEBUG) {
|
if (!Build.IS_ENG && !Build.IS_USERDEBUG) {
|
||||||
return RESTRICTED_TRANSPORTS_DEFAULT;
|
return RESTRICTED_TRANSPORTS_DEFAULT;
|
||||||
@@ -398,6 +399,22 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
|||||||
}
|
}
|
||||||
return restrictedTransports;
|
return restrictedTransports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets the transports that need to be marked as restricted by the VCN */
|
||||||
|
public Set<Integer> getRestrictedTransports(
|
||||||
|
ParcelUuid subGrp,
|
||||||
|
TelephonySubscriptionSnapshot lastSnapshot,
|
||||||
|
VcnConfig vcnConfig) {
|
||||||
|
final Set<Integer> restrictedTransports = new ArraySet<>();
|
||||||
|
restrictedTransports.addAll(vcnConfig.getRestrictedUnderlyingNetworkTransports());
|
||||||
|
|
||||||
|
// TODO: b/262269892 Remove the ability to configure restricted transports
|
||||||
|
// via CarrierConfig
|
||||||
|
restrictedTransports.addAll(
|
||||||
|
getRestrictedTransportsFromCarrierConfig(subGrp, lastSnapshot));
|
||||||
|
|
||||||
|
return restrictedTransports;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Notifies the VcnManagementService that external dependencies can be set up. */
|
/** Notifies the VcnManagementService that external dependencies can be set up. */
|
||||||
@@ -719,6 +736,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
|||||||
if (mVcns.containsKey(subscriptionGroup)) {
|
if (mVcns.containsKey(subscriptionGroup)) {
|
||||||
final Vcn vcn = mVcns.get(subscriptionGroup);
|
final Vcn vcn = mVcns.get(subscriptionGroup);
|
||||||
vcn.updateConfig(config);
|
vcn.updateConfig(config);
|
||||||
|
notifyAllPolicyListenersLocked();
|
||||||
} else {
|
} else {
|
||||||
// TODO(b/193687515): Support multiple VCNs active at the same time
|
// TODO(b/193687515): Support multiple VCNs active at the same time
|
||||||
if (isActiveSubGroup(subscriptionGroup, mLastSnapshot)) {
|
if (isActiveSubGroup(subscriptionGroup, mLastSnapshot)) {
|
||||||
@@ -936,7 +954,6 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Adds the provided listener for receiving VcnUnderlyingNetworkPolicy updates. */
|
/** Adds the provided listener for receiving VcnUnderlyingNetworkPolicy updates. */
|
||||||
@GuardedBy("mLock")
|
|
||||||
@Override
|
@Override
|
||||||
public void addVcnUnderlyingNetworkPolicyListener(
|
public void addVcnUnderlyingNetworkPolicyListener(
|
||||||
@NonNull IVcnUnderlyingNetworkPolicyListener listener) {
|
@NonNull IVcnUnderlyingNetworkPolicyListener listener) {
|
||||||
@@ -963,16 +980,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
|
||||||
void addVcnUnderlyingNetworkPolicyListenerForTest(
|
|
||||||
@NonNull IVcnUnderlyingNetworkPolicyListener listener) {
|
|
||||||
synchronized (mLock) {
|
|
||||||
addVcnUnderlyingNetworkPolicyListener(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Removes the provided listener from receiving VcnUnderlyingNetworkPolicy updates. */
|
/** Removes the provided listener from receiving VcnUnderlyingNetworkPolicy updates. */
|
||||||
@GuardedBy("mLock")
|
|
||||||
@Override
|
@Override
|
||||||
public void removeVcnUnderlyingNetworkPolicyListener(
|
public void removeVcnUnderlyingNetworkPolicyListener(
|
||||||
@NonNull IVcnUnderlyingNetworkPolicyListener listener) {
|
@NonNull IVcnUnderlyingNetworkPolicyListener listener) {
|
||||||
@@ -1062,8 +1070,8 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
|||||||
isVcnManagedNetwork = true;
|
isVcnManagedNetwork = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Set<Integer> restrictedTransports =
|
final Set<Integer> restrictedTransports = mDeps.getRestrictedTransports(
|
||||||
mDeps.getRestrictedTransports(subGrp, mLastSnapshot);
|
subGrp, mLastSnapshot, mConfigs.get(subGrp));
|
||||||
for (int restrictedTransport : restrictedTransports) {
|
for (int restrictedTransport : restrictedTransports) {
|
||||||
if (ncCopy.hasTransport(restrictedTransport)) {
|
if (ncCopy.hasTransport(restrictedTransport)) {
|
||||||
if (restrictedTransport == TRANSPORT_CELLULAR) {
|
if (restrictedTransport == TRANSPORT_CELLULAR) {
|
||||||
|
|||||||
@@ -16,7 +16,12 @@
|
|||||||
|
|
||||||
package android.net.vcn;
|
package android.net.vcn;
|
||||||
|
|
||||||
|
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||||
|
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@@ -24,6 +29,7 @@ import static org.mockito.Mockito.mock;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
|
import android.util.ArraySet;
|
||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
import androidx.test.runner.AndroidJUnit4;
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
@@ -42,19 +48,36 @@ public class VcnConfigTest {
|
|||||||
private static final Set<VcnGatewayConnectionConfig> GATEWAY_CONNECTION_CONFIGS =
|
private static final Set<VcnGatewayConnectionConfig> GATEWAY_CONNECTION_CONFIGS =
|
||||||
Collections.singleton(VcnGatewayConnectionConfigTest.buildTestConfig());
|
Collections.singleton(VcnGatewayConnectionConfigTest.buildTestConfig());
|
||||||
|
|
||||||
|
private static final Set<Integer> RESTRICTED_TRANSPORTS = new ArraySet<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
RESTRICTED_TRANSPORTS.add(TRANSPORT_WIFI);
|
||||||
|
RESTRICTED_TRANSPORTS.add(TRANSPORT_CELLULAR);
|
||||||
|
}
|
||||||
|
|
||||||
private final Context mContext = mock(Context.class);
|
private final Context mContext = mock(Context.class);
|
||||||
|
|
||||||
// Public visibility for VcnManagementServiceTest
|
// Public visibility for VcnManagementServiceTest
|
||||||
public static VcnConfig buildTestConfig(@NonNull Context context) {
|
public static VcnConfig buildTestConfig(
|
||||||
|
@NonNull Context context, Set<Integer> restrictedTransports) {
|
||||||
VcnConfig.Builder builder = new VcnConfig.Builder(context);
|
VcnConfig.Builder builder = new VcnConfig.Builder(context);
|
||||||
|
|
||||||
for (VcnGatewayConnectionConfig gatewayConnectionConfig : GATEWAY_CONNECTION_CONFIGS) {
|
for (VcnGatewayConnectionConfig gatewayConnectionConfig : GATEWAY_CONNECTION_CONFIGS) {
|
||||||
builder.addGatewayConnectionConfig(gatewayConnectionConfig);
|
builder.addGatewayConnectionConfig(gatewayConnectionConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (restrictedTransports != null) {
|
||||||
|
builder.setRestrictedUnderlyingNetworkTransports(restrictedTransports);
|
||||||
|
}
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Public visibility for VcnManagementServiceTest
|
||||||
|
public static VcnConfig buildTestConfig(@NonNull Context context) {
|
||||||
|
return buildTestConfig(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
doReturn(TEST_PACKAGE_NAME).when(mContext).getOpPackageName();
|
doReturn(TEST_PACKAGE_NAME).when(mContext).getOpPackageName();
|
||||||
@@ -91,11 +114,25 @@ public class VcnConfigTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBuilderAndGetters() {
|
public void testBuilderAndGettersDefaultValues() {
|
||||||
final VcnConfig config = buildTestConfig(mContext);
|
final VcnConfig config = buildTestConfig(mContext);
|
||||||
|
|
||||||
assertEquals(TEST_PACKAGE_NAME, config.getProvisioningPackageName());
|
assertEquals(TEST_PACKAGE_NAME, config.getProvisioningPackageName());
|
||||||
assertEquals(GATEWAY_CONNECTION_CONFIGS, config.getGatewayConnectionConfigs());
|
assertEquals(GATEWAY_CONNECTION_CONFIGS, config.getGatewayConnectionConfigs());
|
||||||
|
assertFalse(config.isTestModeProfile());
|
||||||
|
assertEquals(
|
||||||
|
Collections.singleton(TRANSPORT_WIFI),
|
||||||
|
config.getRestrictedUnderlyingNetworkTransports());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuilderAndGettersConfigRestrictedTransports() {
|
||||||
|
final VcnConfig config = buildTestConfig(mContext, RESTRICTED_TRANSPORTS);
|
||||||
|
|
||||||
|
assertEquals(TEST_PACKAGE_NAME, config.getProvisioningPackageName());
|
||||||
|
assertEquals(GATEWAY_CONNECTION_CONFIGS, config.getGatewayConnectionConfigs());
|
||||||
|
assertFalse(config.isTestModeProfile());
|
||||||
|
assertEquals(RESTRICTED_TRANSPORTS, config.getRestrictedUnderlyingNetworkTransports());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -105,6 +142,24 @@ public class VcnConfigTest {
|
|||||||
assertEquals(config, new VcnConfig(config.toPersistableBundle()));
|
assertEquals(config, new VcnConfig(config.toPersistableBundle()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPersistableBundleWithRestrictedTransports() {
|
||||||
|
final VcnConfig config = buildTestConfig(mContext, RESTRICTED_TRANSPORTS);
|
||||||
|
|
||||||
|
assertEquals(config, new VcnConfig(config.toPersistableBundle()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualityWithRestrictedTransports() {
|
||||||
|
final VcnConfig config = buildTestConfig(mContext, RESTRICTED_TRANSPORTS);
|
||||||
|
final VcnConfig configEqual = buildTestConfig(mContext, RESTRICTED_TRANSPORTS);
|
||||||
|
final VcnConfig configNotEqual =
|
||||||
|
buildTestConfig(mContext, Collections.singleton(TRANSPORT_WIFI));
|
||||||
|
|
||||||
|
assertEquals(config, configEqual);
|
||||||
|
assertNotEquals(config, configNotEqual);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParceling() {
|
public void testParceling() {
|
||||||
final VcnConfig config = buildTestConfig(mContext);
|
final VcnConfig config = buildTestConfig(mContext);
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ public class VcnManagementServiceTest {
|
|||||||
|
|
||||||
doReturn(Collections.singleton(TRANSPORT_WIFI))
|
doReturn(Collections.singleton(TRANSPORT_WIFI))
|
||||||
.when(mMockDeps)
|
.when(mMockDeps)
|
||||||
.getRestrictedTransports(any(), any());
|
.getRestrictedTransports(any(), any(), any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1038,18 +1038,18 @@ public class VcnManagementServiceTest {
|
|||||||
new LinkProperties());
|
new LinkProperties());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkGetRestrictedTransports(
|
private void checkGetRestrictedTransportsFromCarrierConfig(
|
||||||
ParcelUuid subGrp,
|
ParcelUuid subGrp,
|
||||||
TelephonySubscriptionSnapshot lastSnapshot,
|
TelephonySubscriptionSnapshot lastSnapshot,
|
||||||
Set<Integer> expectedTransports) {
|
Set<Integer> expectedTransports) {
|
||||||
Set<Integer> result =
|
Set<Integer> result =
|
||||||
new VcnManagementService.Dependencies()
|
new VcnManagementService.Dependencies()
|
||||||
.getRestrictedTransports(subGrp, lastSnapshot);
|
.getRestrictedTransportsFromCarrierConfig(subGrp, lastSnapshot);
|
||||||
assertEquals(expectedTransports, result);
|
assertEquals(expectedTransports, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetRestrictedTransports() {
|
public void testGetRestrictedTransportsFromCarrierConfig() {
|
||||||
final Set<Integer> restrictedTransports = new ArraySet<>();
|
final Set<Integer> restrictedTransports = new ArraySet<>();
|
||||||
restrictedTransports.add(TRANSPORT_CELLULAR);
|
restrictedTransports.add(TRANSPORT_CELLULAR);
|
||||||
restrictedTransports.add(TRANSPORT_WIFI);
|
restrictedTransports.add(TRANSPORT_WIFI);
|
||||||
@@ -1065,11 +1065,12 @@ public class VcnManagementServiceTest {
|
|||||||
mock(TelephonySubscriptionSnapshot.class);
|
mock(TelephonySubscriptionSnapshot.class);
|
||||||
doReturn(carrierConfig).when(lastSnapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2));
|
doReturn(carrierConfig).when(lastSnapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2));
|
||||||
|
|
||||||
checkGetRestrictedTransports(TEST_UUID_2, lastSnapshot, restrictedTransports);
|
checkGetRestrictedTransportsFromCarrierConfig(
|
||||||
|
TEST_UUID_2, lastSnapshot, restrictedTransports);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetRestrictedTransports_noRestrictPolicyConfigured() {
|
public void testGetRestrictedTransportsFromCarrierConfig_noRestrictPolicyConfigured() {
|
||||||
final Set<Integer> restrictedTransports = Collections.singleton(TRANSPORT_WIFI);
|
final Set<Integer> restrictedTransports = Collections.singleton(TRANSPORT_WIFI);
|
||||||
|
|
||||||
final PersistableBundleWrapper carrierConfig =
|
final PersistableBundleWrapper carrierConfig =
|
||||||
@@ -1078,17 +1079,54 @@ public class VcnManagementServiceTest {
|
|||||||
mock(TelephonySubscriptionSnapshot.class);
|
mock(TelephonySubscriptionSnapshot.class);
|
||||||
doReturn(carrierConfig).when(lastSnapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2));
|
doReturn(carrierConfig).when(lastSnapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2));
|
||||||
|
|
||||||
checkGetRestrictedTransports(TEST_UUID_2, lastSnapshot, restrictedTransports);
|
checkGetRestrictedTransportsFromCarrierConfig(
|
||||||
|
TEST_UUID_2, lastSnapshot, restrictedTransports);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetRestrictedTransports_noCarrierConfig() {
|
public void testGetRestrictedTransportsFromCarrierConfig_noCarrierConfig() {
|
||||||
final Set<Integer> restrictedTransports = Collections.singleton(TRANSPORT_WIFI);
|
final Set<Integer> restrictedTransports = Collections.singleton(TRANSPORT_WIFI);
|
||||||
|
|
||||||
final TelephonySubscriptionSnapshot lastSnapshot =
|
final TelephonySubscriptionSnapshot lastSnapshot =
|
||||||
mock(TelephonySubscriptionSnapshot.class);
|
mock(TelephonySubscriptionSnapshot.class);
|
||||||
|
|
||||||
checkGetRestrictedTransports(TEST_UUID_2, lastSnapshot, restrictedTransports);
|
checkGetRestrictedTransportsFromCarrierConfig(
|
||||||
|
TEST_UUID_2, lastSnapshot, restrictedTransports);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetRestrictedTransportsFromCarrierConfigAndVcnConfig() {
|
||||||
|
// Configure restricted transport in CarrierConfig
|
||||||
|
final Set<Integer> restrictedTransportInCarrierConfig =
|
||||||
|
Collections.singleton(TRANSPORT_WIFI);
|
||||||
|
|
||||||
|
PersistableBundle carrierConfigBundle = new PersistableBundle();
|
||||||
|
carrierConfigBundle.putIntArray(
|
||||||
|
VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY,
|
||||||
|
restrictedTransportInCarrierConfig.stream().mapToInt(i -> i).toArray());
|
||||||
|
final PersistableBundleWrapper carrierConfig =
|
||||||
|
new PersistableBundleWrapper(carrierConfigBundle);
|
||||||
|
|
||||||
|
final TelephonySubscriptionSnapshot lastSnapshot =
|
||||||
|
mock(TelephonySubscriptionSnapshot.class);
|
||||||
|
doReturn(carrierConfig).when(lastSnapshot).getCarrierConfigForSubGrp(eq(TEST_UUID_2));
|
||||||
|
|
||||||
|
// Configure restricted transport in VcnConfig
|
||||||
|
final Context mockContext = mock(Context.class);
|
||||||
|
doReturn(TEST_PACKAGE_NAME).when(mockContext).getOpPackageName();
|
||||||
|
final VcnConfig vcnConfig =
|
||||||
|
VcnConfigTest.buildTestConfig(
|
||||||
|
mockContext, Collections.singleton(TRANSPORT_CELLULAR));
|
||||||
|
|
||||||
|
// Verifications
|
||||||
|
final Set<Integer> expectedTransports = new ArraySet<>();
|
||||||
|
expectedTransports.add(TRANSPORT_CELLULAR);
|
||||||
|
expectedTransports.add(TRANSPORT_WIFI);
|
||||||
|
|
||||||
|
Set<Integer> result =
|
||||||
|
new VcnManagementService.Dependencies()
|
||||||
|
.getRestrictedTransports(TEST_UUID_2, lastSnapshot, vcnConfig);
|
||||||
|
assertEquals(expectedTransports, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkGetUnderlyingNetworkPolicy(
|
private void checkGetUnderlyingNetworkPolicy(
|
||||||
@@ -1103,7 +1141,7 @@ public class VcnManagementServiceTest {
|
|||||||
if (isTransportRestricted) {
|
if (isTransportRestricted) {
|
||||||
restrictedTransports.add(transportType);
|
restrictedTransports.add(transportType);
|
||||||
}
|
}
|
||||||
doReturn(restrictedTransports).when(mMockDeps).getRestrictedTransports(any(), any());
|
doReturn(restrictedTransports).when(mMockDeps).getRestrictedTransports(any(), any(), any());
|
||||||
|
|
||||||
final VcnUnderlyingNetworkPolicy policy =
|
final VcnUnderlyingNetworkPolicy policy =
|
||||||
startVcnAndGetPolicyForTransport(
|
startVcnAndGetPolicyForTransport(
|
||||||
@@ -1201,7 +1239,7 @@ public class VcnManagementServiceTest {
|
|||||||
public void testGetUnderlyingNetworkPolicyCell_restrictWifi() throws Exception {
|
public void testGetUnderlyingNetworkPolicyCell_restrictWifi() throws Exception {
|
||||||
doReturn(Collections.singleton(TRANSPORT_WIFI))
|
doReturn(Collections.singleton(TRANSPORT_WIFI))
|
||||||
.when(mMockDeps)
|
.when(mMockDeps)
|
||||||
.getRestrictedTransports(any(), any());
|
.getRestrictedTransports(any(), any(), any());
|
||||||
|
|
||||||
setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isVcnActive */);
|
setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isVcnActive */);
|
||||||
|
|
||||||
@@ -1343,6 +1381,23 @@ public class VcnManagementServiceTest {
|
|||||||
verify(mMockPolicyListener).onPolicyChanged();
|
verify(mMockPolicyListener).onPolicyChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVcnConfigChangeUpdatesPolicyListener() throws Exception {
|
||||||
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
|
|
||||||
|
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||||
|
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
||||||
|
|
||||||
|
final Context mockContext = mock(Context.class);
|
||||||
|
doReturn(TEST_PACKAGE_NAME).when(mockContext).getOpPackageName();
|
||||||
|
final VcnConfig vcnConfig =
|
||||||
|
VcnConfigTest.buildTestConfig(
|
||||||
|
mockContext, Collections.singleton(TRANSPORT_CELLULAR));
|
||||||
|
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, vcnConfig, TEST_PACKAGE_NAME);
|
||||||
|
|
||||||
|
verify(mMockPolicyListener).onPolicyChanged();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRemoveVcnUpdatesPolicyListener() throws Exception {
|
public void testRemoveVcnUpdatesPolicyListener() throws Exception {
|
||||||
setupActiveSubscription(TEST_UUID_2);
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
@@ -1375,7 +1430,7 @@ public class VcnManagementServiceTest {
|
|||||||
setupActiveSubscription(TEST_UUID_2);
|
setupActiveSubscription(TEST_UUID_2);
|
||||||
|
|
||||||
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||||
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListenerForTest(mMockPolicyListener);
|
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
||||||
|
|
||||||
final TelephonySubscriptionSnapshot snapshot =
|
final TelephonySubscriptionSnapshot snapshot =
|
||||||
buildSubscriptionSnapshot(
|
buildSubscriptionSnapshot(
|
||||||
|
|||||||
Reference in New Issue
Block a user