Loading core/java/android/net/vcn/VcnConfig.java +39 −4 Original line number Diff line number Diff line Loading @@ -52,12 +52,17 @@ public final class VcnConfig implements Parcelable { private static final String GATEWAY_CONNECTION_CONFIGS_KEY = "mGatewayConnectionConfigs"; @NonNull private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs; private static final String IS_TEST_MODE_PROFILE_KEY = "mIsTestModeProfile"; private final boolean mIsTestModeProfile; private VcnConfig( @NonNull String packageName, @NonNull Set<VcnGatewayConnectionConfig> gatewayConnectionConfigs) { @NonNull Set<VcnGatewayConnectionConfig> gatewayConnectionConfigs, boolean isTestModeProfile) { mPackageName = packageName; mGatewayConnectionConfigs = Collections.unmodifiableSet(new ArraySet<>(gatewayConnectionConfigs)); mIsTestModeProfile = isTestModeProfile; validate(); } Loading @@ -77,6 +82,7 @@ public final class VcnConfig implements Parcelable { new ArraySet<>( PersistableBundleUtils.toList( gatewayConnectionConfigsBundle, VcnGatewayConnectionConfig::new)); mIsTestModeProfile = in.getBoolean(IS_TEST_MODE_PROFILE_KEY); validate(); } Loading @@ -103,6 +109,15 @@ public final class VcnConfig implements Parcelable { return Collections.unmodifiableSet(mGatewayConnectionConfigs); } /** * Returns whether or not this VcnConfig is restricted to test networks. * * @hide */ public boolean isTestModeProfile() { return mIsTestModeProfile; } /** * Serializes this object to a PersistableBundle. * Loading @@ -119,13 +134,14 @@ public final class VcnConfig implements Parcelable { new ArrayList<>(mGatewayConnectionConfigs), VcnGatewayConnectionConfig::toPersistableBundle); result.putPersistableBundle(GATEWAY_CONNECTION_CONFIGS_KEY, gatewayConnectionConfigsBundle); result.putBoolean(IS_TEST_MODE_PROFILE_KEY, mIsTestModeProfile); return result; } @Override public int hashCode() { return Objects.hash(mPackageName, mGatewayConnectionConfigs); return Objects.hash(mPackageName, mGatewayConnectionConfigs, mIsTestModeProfile); } @Override Loading @@ -136,7 +152,8 @@ public final class VcnConfig implements Parcelable { final VcnConfig rhs = (VcnConfig) other; return mPackageName.equals(rhs.mPackageName) && mGatewayConnectionConfigs.equals(rhs.mGatewayConnectionConfigs); && mGatewayConnectionConfigs.equals(rhs.mGatewayConnectionConfigs) && mIsTestModeProfile == rhs.mIsTestModeProfile; } // Parcelable methods Loading Loading @@ -172,6 +189,8 @@ public final class VcnConfig implements Parcelable { @NonNull private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs = new ArraySet<>(); private boolean mIsTestModeProfile = false; public Builder(@NonNull Context context) { Objects.requireNonNull(context, "context was null"); Loading Loading @@ -206,6 +225,22 @@ public final class VcnConfig implements Parcelable { return this; } /** * Restricts this VcnConfig to matching with test networks (only). * * <p>This method is for testing only, and must not be used by apps. Calling {@link * VcnManager#setVcnConfig(ParcelUuid, VcnConfig)} with a VcnConfig where test-network usage * is enabled will require the MANAGE_TEST_NETWORKS permission. * * @return this {@link Builder} instance, for chaining * @hide */ @NonNull public Builder setIsTestModeProfile() { mIsTestModeProfile = true; return this; } /** * Builds and validates the VcnConfig. * Loading @@ -213,7 +248,7 @@ public final class VcnConfig implements Parcelable { */ @NonNull public VcnConfig build() { return new VcnConfig(mPackageName, mGatewayConnectionConfigs); return new VcnConfig(mPackageName, mGatewayConnectionConfigs, mIsTestModeProfile); } } } core/java/android/net/vcn/VcnGatewayConnectionConfig.java +8 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package android.net.vcn; import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE; import static com.android.internal.annotations.VisibleForTesting.Visibility; import android.annotation.IntDef; Loading Loading @@ -438,6 +440,8 @@ public final class VcnGatewayConnectionConfig { * distinguish between VcnGatewayConnectionConfigs configured on a single {@link * VcnConfig}. This will be used as the identifier in VcnStatusCallback invocations. * @param tunnelConnectionParams the IKE tunnel connection configuration * @throws IllegalArgumentException if the provided IkeTunnelConnectionParams is not * configured to support MOBIKE * @see IkeTunnelConnectionParams * @see VcnManager.VcnStatusCallback#onGatewayConnectionError */ Loading @@ -446,6 +450,10 @@ public final class VcnGatewayConnectionConfig { @NonNull IkeTunnelConnectionParams tunnelConnectionParams) { Objects.requireNonNull(gatewayConnectionName, "gatewayConnectionName was null"); Objects.requireNonNull(tunnelConnectionParams, "tunnelConnectionParams was null"); if (!tunnelConnectionParams.getIkeSessionParams().hasIkeOption(IKE_OPTION_MOBIKE)) { throw new IllegalArgumentException( "MOBIKE must be configured for the provided IkeSessionParams"); } mGatewayConnectionName = gatewayConnectionName; mTunnelConnectionParams = tunnelConnectionParams; Loading services/core/java/com/android/server/VcnManagementService.java +16 −5 Original line number Diff line number Diff line Loading @@ -167,7 +167,6 @@ public class VcnManagementService extends IVcnManagementService.Stub { @NonNull private final VcnNetworkProvider mNetworkProvider; @NonNull private final TelephonySubscriptionTrackerCallback mTelephonySubscriptionTrackerCb; @NonNull private final TelephonySubscriptionTracker mTelephonySubscriptionTracker; @NonNull private final VcnContext mVcnContext; @NonNull private final BroadcastReceiver mPkgChangeReceiver; @NonNull Loading Loading @@ -212,7 +211,6 @@ public class VcnManagementService extends IVcnManagementService.Stub { mContext, mLooper, mTelephonySubscriptionTrackerCb); mConfigDiskRwHelper = mDeps.newPersistableBundleLockingReadWriteHelper(VCN_CONFIG_FILE); mVcnContext = mDeps.newVcnContext(mContext, mLooper, mNetworkProvider); mPkgChangeReceiver = new BroadcastReceiver() { @Override Loading Loading @@ -336,8 +334,9 @@ public class VcnManagementService extends IVcnManagementService.Stub { public VcnContext newVcnContext( @NonNull Context context, @NonNull Looper looper, @NonNull VcnNetworkProvider vcnNetworkProvider) { return new VcnContext(context, looper, vcnNetworkProvider); @NonNull VcnNetworkProvider vcnNetworkProvider, boolean getIsInTestMode) { return new VcnContext(context, looper, vcnNetworkProvider, getIsInTestMode); } /** Creates a new Vcn instance using the provided configuration */ Loading Loading @@ -419,6 +418,14 @@ public class VcnManagementService extends IVcnManagementService.Stub { "Carrier privilege required for subscription group to set VCN Config"); } private void enforceManageTestNetworksForTestMode(@NonNull VcnConfig vcnConfig) { if (vcnConfig.isTestModeProfile()) { mContext.enforceCallingPermission( android.Manifest.permission.MANAGE_TEST_NETWORKS, "Test-mode require the MANAGE_TEST_NETWORKS permission"); } } private class VcnSubscriptionTrackerCallback implements TelephonySubscriptionTrackerCallback { /** * Handles subscription group changes, as notified by {@link TelephonySubscriptionTracker} Loading Loading @@ -542,8 +549,11 @@ public class VcnManagementService extends IVcnManagementService.Stub { final VcnCallbackImpl vcnCallback = new VcnCallbackImpl(subscriptionGroup); final VcnContext vcnContext = mDeps.newVcnContext( mContext, mLooper, mNetworkProvider, config.isTestModeProfile()); final Vcn newInstance = mDeps.newVcn(mVcnContext, subscriptionGroup, config, mLastSnapshot, vcnCallback); mDeps.newVcn(vcnContext, subscriptionGroup, config, mLastSnapshot, vcnCallback); mVcns.put(subscriptionGroup, newInstance); // Now that a new VCN has started, notify all registered listeners to refresh their Loading Loading @@ -587,6 +597,7 @@ public class VcnManagementService extends IVcnManagementService.Stub { mContext.getSystemService(AppOpsManager.class) .checkPackage(mDeps.getBinderCallingUid(), config.getProvisioningPackageName()); enforceManageTestNetworksForTestMode(config); enforceCallingUserAndCarrierPrivilege(subscriptionGroup, opPkgName); Binder.withCleanCallingIdentity(() -> { Loading services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java +17 −0 Original line number Diff line number Diff line Loading @@ -158,8 +158,15 @@ public class UnderlyingNetworkTracker { * carrier owned networks may be selected, as the request specifies only subIds in the VCN's * subscription group, while the VCN networks are excluded by virtue of not having subIds set on * the VCN-exposed networks. * * <p>If the VCN that this UnderlyingNetworkTracker belongs to is in test-mode, this will return * a NetworkRequest that only matches Test Networks. */ private NetworkRequest getRouteSelectionRequest() { if (mVcnContext.isInTestMode()) { return getTestNetworkRequest(mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup)); } return getBaseNetworkRequestBuilder() .setSubscriptionIds(mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup)) .build(); Loading Loading @@ -210,6 +217,16 @@ public class UnderlyingNetworkTracker { .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); } /** Builds and returns a NetworkRequest for the given subIds to match Test Networks. */ private NetworkRequest getTestNetworkRequest(@NonNull Set<Integer> subIds) { return getBaseNetworkRequestBuilder() .addTransportType(NetworkCapabilities.TRANSPORT_TEST) .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) .setSubscriptionIds(subIds) .build(); } /** * Update this UnderlyingNetworkTracker's TelephonySubscriptionSnapshot. * Loading services/core/java/com/android/server/vcn/VcnContext.java +8 −1 Original line number Diff line number Diff line Loading @@ -31,14 +31,17 @@ public class VcnContext { @NonNull private final Context mContext; @NonNull private final Looper mLooper; @NonNull private final VcnNetworkProvider mVcnNetworkProvider; private final boolean mIsInTestMode; public VcnContext( @NonNull Context context, @NonNull Looper looper, @NonNull VcnNetworkProvider vcnNetworkProvider) { @NonNull VcnNetworkProvider vcnNetworkProvider, boolean isInTestMode) { mContext = Objects.requireNonNull(context, "Missing context"); mLooper = Objects.requireNonNull(looper, "Missing looper"); mVcnNetworkProvider = Objects.requireNonNull(vcnNetworkProvider, "Missing networkProvider"); mIsInTestMode = isInTestMode; } @NonNull Loading @@ -56,6 +59,10 @@ public class VcnContext { return mVcnNetworkProvider; } public boolean isInTestMode() { return mIsInTestMode; } /** * Verifies that the caller is running on the VcnContext Thread. * Loading Loading
core/java/android/net/vcn/VcnConfig.java +39 −4 Original line number Diff line number Diff line Loading @@ -52,12 +52,17 @@ public final class VcnConfig implements Parcelable { private static final String GATEWAY_CONNECTION_CONFIGS_KEY = "mGatewayConnectionConfigs"; @NonNull private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs; private static final String IS_TEST_MODE_PROFILE_KEY = "mIsTestModeProfile"; private final boolean mIsTestModeProfile; private VcnConfig( @NonNull String packageName, @NonNull Set<VcnGatewayConnectionConfig> gatewayConnectionConfigs) { @NonNull Set<VcnGatewayConnectionConfig> gatewayConnectionConfigs, boolean isTestModeProfile) { mPackageName = packageName; mGatewayConnectionConfigs = Collections.unmodifiableSet(new ArraySet<>(gatewayConnectionConfigs)); mIsTestModeProfile = isTestModeProfile; validate(); } Loading @@ -77,6 +82,7 @@ public final class VcnConfig implements Parcelable { new ArraySet<>( PersistableBundleUtils.toList( gatewayConnectionConfigsBundle, VcnGatewayConnectionConfig::new)); mIsTestModeProfile = in.getBoolean(IS_TEST_MODE_PROFILE_KEY); validate(); } Loading @@ -103,6 +109,15 @@ public final class VcnConfig implements Parcelable { return Collections.unmodifiableSet(mGatewayConnectionConfigs); } /** * Returns whether or not this VcnConfig is restricted to test networks. * * @hide */ public boolean isTestModeProfile() { return mIsTestModeProfile; } /** * Serializes this object to a PersistableBundle. * Loading @@ -119,13 +134,14 @@ public final class VcnConfig implements Parcelable { new ArrayList<>(mGatewayConnectionConfigs), VcnGatewayConnectionConfig::toPersistableBundle); result.putPersistableBundle(GATEWAY_CONNECTION_CONFIGS_KEY, gatewayConnectionConfigsBundle); result.putBoolean(IS_TEST_MODE_PROFILE_KEY, mIsTestModeProfile); return result; } @Override public int hashCode() { return Objects.hash(mPackageName, mGatewayConnectionConfigs); return Objects.hash(mPackageName, mGatewayConnectionConfigs, mIsTestModeProfile); } @Override Loading @@ -136,7 +152,8 @@ public final class VcnConfig implements Parcelable { final VcnConfig rhs = (VcnConfig) other; return mPackageName.equals(rhs.mPackageName) && mGatewayConnectionConfigs.equals(rhs.mGatewayConnectionConfigs); && mGatewayConnectionConfigs.equals(rhs.mGatewayConnectionConfigs) && mIsTestModeProfile == rhs.mIsTestModeProfile; } // Parcelable methods Loading Loading @@ -172,6 +189,8 @@ public final class VcnConfig implements Parcelable { @NonNull private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs = new ArraySet<>(); private boolean mIsTestModeProfile = false; public Builder(@NonNull Context context) { Objects.requireNonNull(context, "context was null"); Loading Loading @@ -206,6 +225,22 @@ public final class VcnConfig implements Parcelable { return this; } /** * Restricts this VcnConfig to matching with test networks (only). * * <p>This method is for testing only, and must not be used by apps. Calling {@link * VcnManager#setVcnConfig(ParcelUuid, VcnConfig)} with a VcnConfig where test-network usage * is enabled will require the MANAGE_TEST_NETWORKS permission. * * @return this {@link Builder} instance, for chaining * @hide */ @NonNull public Builder setIsTestModeProfile() { mIsTestModeProfile = true; return this; } /** * Builds and validates the VcnConfig. * Loading @@ -213,7 +248,7 @@ public final class VcnConfig implements Parcelable { */ @NonNull public VcnConfig build() { return new VcnConfig(mPackageName, mGatewayConnectionConfigs); return new VcnConfig(mPackageName, mGatewayConnectionConfigs, mIsTestModeProfile); } } }
core/java/android/net/vcn/VcnGatewayConnectionConfig.java +8 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package android.net.vcn; import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE; import static com.android.internal.annotations.VisibleForTesting.Visibility; import android.annotation.IntDef; Loading Loading @@ -438,6 +440,8 @@ public final class VcnGatewayConnectionConfig { * distinguish between VcnGatewayConnectionConfigs configured on a single {@link * VcnConfig}. This will be used as the identifier in VcnStatusCallback invocations. * @param tunnelConnectionParams the IKE tunnel connection configuration * @throws IllegalArgumentException if the provided IkeTunnelConnectionParams is not * configured to support MOBIKE * @see IkeTunnelConnectionParams * @see VcnManager.VcnStatusCallback#onGatewayConnectionError */ Loading @@ -446,6 +450,10 @@ public final class VcnGatewayConnectionConfig { @NonNull IkeTunnelConnectionParams tunnelConnectionParams) { Objects.requireNonNull(gatewayConnectionName, "gatewayConnectionName was null"); Objects.requireNonNull(tunnelConnectionParams, "tunnelConnectionParams was null"); if (!tunnelConnectionParams.getIkeSessionParams().hasIkeOption(IKE_OPTION_MOBIKE)) { throw new IllegalArgumentException( "MOBIKE must be configured for the provided IkeSessionParams"); } mGatewayConnectionName = gatewayConnectionName; mTunnelConnectionParams = tunnelConnectionParams; Loading
services/core/java/com/android/server/VcnManagementService.java +16 −5 Original line number Diff line number Diff line Loading @@ -167,7 +167,6 @@ public class VcnManagementService extends IVcnManagementService.Stub { @NonNull private final VcnNetworkProvider mNetworkProvider; @NonNull private final TelephonySubscriptionTrackerCallback mTelephonySubscriptionTrackerCb; @NonNull private final TelephonySubscriptionTracker mTelephonySubscriptionTracker; @NonNull private final VcnContext mVcnContext; @NonNull private final BroadcastReceiver mPkgChangeReceiver; @NonNull Loading Loading @@ -212,7 +211,6 @@ public class VcnManagementService extends IVcnManagementService.Stub { mContext, mLooper, mTelephonySubscriptionTrackerCb); mConfigDiskRwHelper = mDeps.newPersistableBundleLockingReadWriteHelper(VCN_CONFIG_FILE); mVcnContext = mDeps.newVcnContext(mContext, mLooper, mNetworkProvider); mPkgChangeReceiver = new BroadcastReceiver() { @Override Loading Loading @@ -336,8 +334,9 @@ public class VcnManagementService extends IVcnManagementService.Stub { public VcnContext newVcnContext( @NonNull Context context, @NonNull Looper looper, @NonNull VcnNetworkProvider vcnNetworkProvider) { return new VcnContext(context, looper, vcnNetworkProvider); @NonNull VcnNetworkProvider vcnNetworkProvider, boolean getIsInTestMode) { return new VcnContext(context, looper, vcnNetworkProvider, getIsInTestMode); } /** Creates a new Vcn instance using the provided configuration */ Loading Loading @@ -419,6 +418,14 @@ public class VcnManagementService extends IVcnManagementService.Stub { "Carrier privilege required for subscription group to set VCN Config"); } private void enforceManageTestNetworksForTestMode(@NonNull VcnConfig vcnConfig) { if (vcnConfig.isTestModeProfile()) { mContext.enforceCallingPermission( android.Manifest.permission.MANAGE_TEST_NETWORKS, "Test-mode require the MANAGE_TEST_NETWORKS permission"); } } private class VcnSubscriptionTrackerCallback implements TelephonySubscriptionTrackerCallback { /** * Handles subscription group changes, as notified by {@link TelephonySubscriptionTracker} Loading Loading @@ -542,8 +549,11 @@ public class VcnManagementService extends IVcnManagementService.Stub { final VcnCallbackImpl vcnCallback = new VcnCallbackImpl(subscriptionGroup); final VcnContext vcnContext = mDeps.newVcnContext( mContext, mLooper, mNetworkProvider, config.isTestModeProfile()); final Vcn newInstance = mDeps.newVcn(mVcnContext, subscriptionGroup, config, mLastSnapshot, vcnCallback); mDeps.newVcn(vcnContext, subscriptionGroup, config, mLastSnapshot, vcnCallback); mVcns.put(subscriptionGroup, newInstance); // Now that a new VCN has started, notify all registered listeners to refresh their Loading Loading @@ -587,6 +597,7 @@ public class VcnManagementService extends IVcnManagementService.Stub { mContext.getSystemService(AppOpsManager.class) .checkPackage(mDeps.getBinderCallingUid(), config.getProvisioningPackageName()); enforceManageTestNetworksForTestMode(config); enforceCallingUserAndCarrierPrivilege(subscriptionGroup, opPkgName); Binder.withCleanCallingIdentity(() -> { Loading
services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java +17 −0 Original line number Diff line number Diff line Loading @@ -158,8 +158,15 @@ public class UnderlyingNetworkTracker { * carrier owned networks may be selected, as the request specifies only subIds in the VCN's * subscription group, while the VCN networks are excluded by virtue of not having subIds set on * the VCN-exposed networks. * * <p>If the VCN that this UnderlyingNetworkTracker belongs to is in test-mode, this will return * a NetworkRequest that only matches Test Networks. */ private NetworkRequest getRouteSelectionRequest() { if (mVcnContext.isInTestMode()) { return getTestNetworkRequest(mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup)); } return getBaseNetworkRequestBuilder() .setSubscriptionIds(mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup)) .build(); Loading Loading @@ -210,6 +217,16 @@ public class UnderlyingNetworkTracker { .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); } /** Builds and returns a NetworkRequest for the given subIds to match Test Networks. */ private NetworkRequest getTestNetworkRequest(@NonNull Set<Integer> subIds) { return getBaseNetworkRequestBuilder() .addTransportType(NetworkCapabilities.TRANSPORT_TEST) .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) .setSubscriptionIds(subIds) .build(); } /** * Update this UnderlyingNetworkTracker's TelephonySubscriptionSnapshot. * Loading
services/core/java/com/android/server/vcn/VcnContext.java +8 −1 Original line number Diff line number Diff line Loading @@ -31,14 +31,17 @@ public class VcnContext { @NonNull private final Context mContext; @NonNull private final Looper mLooper; @NonNull private final VcnNetworkProvider mVcnNetworkProvider; private final boolean mIsInTestMode; public VcnContext( @NonNull Context context, @NonNull Looper looper, @NonNull VcnNetworkProvider vcnNetworkProvider) { @NonNull VcnNetworkProvider vcnNetworkProvider, boolean isInTestMode) { mContext = Objects.requireNonNull(context, "Missing context"); mLooper = Objects.requireNonNull(looper, "Missing looper"); mVcnNetworkProvider = Objects.requireNonNull(vcnNetworkProvider, "Missing networkProvider"); mIsInTestMode = isInTestMode; } @NonNull Loading @@ -56,6 +59,10 @@ public class VcnContext { return mVcnNetworkProvider; } public boolean isInTestMode() { return mIsInTestMode; } /** * Verifies that the caller is running on the VcnContext Thread. * Loading