1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.vcn.cts; 18 19 import static android.content.pm.PackageManager.FEATURE_TELEPHONY; 20 import static android.content.pm.PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION; 21 import static android.ipsec.ike.cts.IkeTunUtils.PortPair; 22 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_DNS_EVENTS; 23 import static android.net.ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT; 24 import static android.net.ConnectivitySettingsManager.getCaptivePortalMode; 25 import static android.net.ConnectivitySettingsManager.setCaptivePortalMode; 26 import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS; 27 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 28 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 29 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; 30 import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS; 31 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 32 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 33 import static android.net.NetworkCapabilities.TRANSPORT_TEST; 34 import static android.net.vcn.VcnGatewayConnectionConfig.VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY; 35 import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE; 36 import static android.net.vcn.VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED; 37 import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE; 38 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_ANY; 39 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_FORBIDDEN; 40 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED; 41 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; 42 43 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; 44 45 import static com.android.compatibility.common.util.SystemUtil.runShellCommand; 46 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; 47 import static com.android.compatibility.common.util.TestUtils.waitUntil; 48 import static com.android.internal.util.HexDump.hexStringToByteArray; 49 50 import static org.junit.Assert.assertEquals; 51 import static org.junit.Assert.assertFalse; 52 import static org.junit.Assert.assertNotNull; 53 import static org.junit.Assert.assertNull; 54 import static org.junit.Assert.assertTrue; 55 import static org.junit.Assert.fail; 56 import static org.junit.Assume.assumeTrue; 57 58 import android.annotation.NonNull; 59 import android.annotation.Nullable; 60 import android.content.Context; 61 import android.content.pm.PackageManager; 62 import android.ipsec.ike.cts.IkeTunUtils; 63 import android.net.ConnectivityManager; 64 import android.net.InetAddresses; 65 import android.net.LinkProperties; 66 import android.net.Network; 67 import android.net.NetworkCapabilities; 68 import android.net.NetworkRequest; 69 import android.net.vcn.VcnCellUnderlyingNetworkTemplate; 70 import android.net.vcn.VcnConfig; 71 import android.net.vcn.VcnGatewayConnectionConfig; 72 import android.net.vcn.VcnManager; 73 import android.net.vcn.VcnNetworkPolicyResult; 74 import android.net.vcn.VcnUnderlyingNetworkTemplate; 75 import android.net.vcn.VcnWifiUnderlyingNetworkTemplate; 76 import android.net.vcn.cts.TestNetworkWrapper.VcnTestNetworkCallback; 77 import android.net.vcn.cts.TestNetworkWrapper.VcnTestNetworkCallback.CapabilitiesChangedEvent; 78 import android.os.ParcelUuid; 79 import android.os.PersistableBundle; 80 import android.os.Process; 81 import android.os.SystemClock; 82 import android.os.UserManager; 83 import android.telephony.CarrierConfigManager; 84 import android.telephony.SubscriptionManager; 85 import android.telephony.TelephonyManager; 86 import android.telephony.cts.util.SubscriptionGroupUtils; 87 88 import androidx.test.InstrumentationRegistry; 89 import androidx.test.ext.junit.runners.AndroidJUnit4; 90 91 import com.android.compatibility.common.util.CarrierPrivilegeUtils; 92 93 import org.junit.After; 94 import org.junit.Before; 95 import org.junit.Test; 96 import org.junit.runner.RunWith; 97 98 import java.net.InetAddress; 99 import java.util.ArrayList; 100 import java.util.Arrays; 101 import java.util.Collections; 102 import java.util.HashSet; 103 import java.util.List; 104 import java.util.Objects; 105 import java.util.Set; 106 import java.util.UUID; 107 import java.util.concurrent.BlockingQueue; 108 import java.util.concurrent.CompletableFuture; 109 import java.util.concurrent.Executor; 110 import java.util.concurrent.LinkedBlockingQueue; 111 import java.util.concurrent.TimeUnit; 112 113 @RunWith(AndroidJUnit4.class) 114 public class VcnManagerTest extends VcnTestBase { 115 private static final String TAG = VcnManagerTest.class.getSimpleName(); 116 117 private static final int CALLBACK_TIMEOUT_MS = 5000; 118 private static final long SAFEMODE_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(35); 119 120 private static final int ACTIVE_SUB_ID_TIMEOUT_SECONDS = 60; 121 122 private static final Executor INLINE_EXECUTOR = Runnable::run; 123 124 private static final int TEST_NETWORK_MTU = 1500; 125 126 private static final int VCN_STATUS_CODE_AWAIT_TIMEOUT = -1; 127 128 private static final InetAddress LOCAL_ADDRESS = 129 InetAddresses.parseNumericAddress("198.51.100.1"); 130 private static final InetAddress SECONDARY_LOCAL_ADDRESS = 131 InetAddresses.parseNumericAddress("198.51.100.2"); 132 133 private static final long IKE_DETERMINISTIC_INITIATOR_SPI = 134 Long.parseLong("46B8ECA1E0D72A18", 16); 135 136 private final Context mContext; 137 private final VcnManager mVcnManager; 138 private final SubscriptionManager mSubscriptionManager; 139 private final TelephonyManager mTelephonyManager; 140 private final ConnectivityManager mConnectivityManager; 141 private final CarrierConfigManager mCarrierConfigManager; 142 private final int mOldCaptivePortalMode; 143 VcnManagerTest()144 public VcnManagerTest() { 145 mContext = InstrumentationRegistry.getContext(); 146 mVcnManager = mContext.getSystemService(VcnManager.class); 147 mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class); 148 mTelephonyManager = mContext.getSystemService(TelephonyManager.class); 149 mConnectivityManager = mContext.getSystemService(ConnectivityManager.class); 150 mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class); 151 152 mOldCaptivePortalMode = getCaptivePortalMode(mContext, CAPTIVE_PORTAL_MODE_PROMPT); 153 } 154 155 @Before setUp()156 public void setUp() throws Exception { 157 final boolean hasFeatureTelephony = 158 mContext.getPackageManager().hasSystemFeature(FEATURE_TELEPHONY); 159 final boolean hasFeatureTelSubscription = 160 mContext.getPackageManager().hasSystemFeature(FEATURE_TELEPHONY_SUBSCRIPTION); 161 final boolean hasTelephonyFlag = hasFeatureTelephony || hasFeatureTelSubscription; 162 163 // Before V, only devices with FEATURE_TELEPHONY are required to run the tests. Starting 164 // from V, tests are also required on following cases: 165 // 166 // Device that has a non-null VcnManager even if it has neither of FEATURE_TELEPHONY or 167 // FEATURE_TELEPHONY_SUBSCRIPTION. 168 // 169 // Device that has FEATURE_TELEPHONY_SUBSCRIPTION. This should not be a new requirement 170 // since before V devices with FEATURE_TELEPHONY_SUBSCRIPTION are already enforced to have 171 // FEATURE_TELEPHONY. 172 assumeTrue(hasTelephonyFlag || mVcnManager != null); 173 174 getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(); 175 176 // TODO: b/348715017 Add multi-user support for VCN 177 // Skip the test if it is not running as a main user 178 final UserManager userManager = mContext.getSystemService(UserManager.class); 179 assumeTrue(Objects.equals(userManager.getMainUser(), Process.myUserHandle())); 180 181 // Ensure Internet probing check will be performed on VCN networks 182 setCaptivePortalMode(mContext, CAPTIVE_PORTAL_MODE_PROMPT); 183 184 runShellCommand("cmd connectivity airplane-mode disable"); 185 } 186 187 @After tearDown()188 public void tearDown() throws Exception { 189 setCaptivePortalMode(mContext, mOldCaptivePortalMode); 190 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 191 } 192 buildVcnConfigBase()193 private VcnConfig.Builder buildVcnConfigBase() { 194 return buildVcnConfigBase(new ArrayList<VcnUnderlyingNetworkTemplate>()); 195 } 196 buildVcnConfigBase(List<VcnUnderlyingNetworkTemplate> nwTemplate)197 private VcnConfig.Builder buildVcnConfigBase(List<VcnUnderlyingNetworkTemplate> nwTemplate) { 198 // TODO(b/191371669): remove the exposed MMS capability and use 199 // VcnGatewayConnectionConfigTest.buildVcnGatewayConnectionConfig() instead 200 return new VcnConfig.Builder(mContext) 201 .addGatewayConnectionConfig( 202 VcnGatewayConnectionConfigTest.buildVcnGatewayConnectionConfigBase() 203 .addExposedCapability(NetworkCapabilities.NET_CAPABILITY_MMS) 204 .setVcnUnderlyingNetworkPriorities(nwTemplate) 205 .addGatewayOption( 206 VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY) 207 .build()); 208 } 209 buildVcnConfig()210 private VcnConfig buildVcnConfig() { 211 return buildVcnConfigBase().build(); 212 } 213 buildTestModeVcnConfig()214 private VcnConfig buildTestModeVcnConfig() { 215 return buildVcnConfigBase().setIsTestModeProfile().build(); 216 } 217 verifyAndGetValidDataSubId()218 private int verifyAndGetValidDataSubId() throws Exception { 219 // Wait for an active sub ID to mitigate the cuttlefish test issue where the CTS will 220 // start before a valid data subId is ready. In most cases this should return immediately 221 // without needing to wait. 222 waitUntil( 223 "There must be an active data subscription to complete CTS", 224 ACTIVE_SUB_ID_TIMEOUT_SECONDS, 225 () -> 226 SubscriptionManager.getDefaultDataSubscriptionId() 227 != INVALID_SUBSCRIPTION_ID); 228 return SubscriptionManager.getDefaultDataSubscriptionId(); 229 } 230 231 @Test(expected = SecurityException.class) testSetVcnConfig_noCarrierPrivileges()232 public void testSetVcnConfig_noCarrierPrivileges() throws Exception { 233 mVcnManager.setVcnConfig(new ParcelUuid(UUID.randomUUID()), buildVcnConfig()); 234 } 235 236 @Test testSetVcnConfig_withCarrierPrivileges()237 public void testSetVcnConfig_withCarrierPrivileges() throws Exception { 238 final int dataSubId = verifyAndGetValidDataSubId(); 239 CarrierPrivilegeUtils.withCarrierPrivileges(mContext, dataSubId, () -> { 240 SubscriptionGroupUtils.withEphemeralSubscriptionGroup(mContext, dataSubId, (subGrp) -> { 241 mVcnManager.setVcnConfig(subGrp, buildVcnConfig()); 242 mVcnManager.clearVcnConfig(subGrp); 243 }); 244 }); 245 246 assertFalse(mTelephonyManager.createForSubscriptionId(dataSubId).hasCarrierPrivileges()); 247 } 248 249 @Test(expected = SecurityException.class) testClearVcnConfig_noCarrierPrivileges()250 public void testClearVcnConfig_noCarrierPrivileges() throws Exception { 251 mVcnManager.clearVcnConfig(new ParcelUuid(UUID.randomUUID())); 252 } 253 254 @Test testClearVcnConfig_withCarrierPrivileges()255 public void testClearVcnConfig_withCarrierPrivileges() throws Exception { 256 final int dataSubId = verifyAndGetValidDataSubId(); 257 258 CarrierPrivilegeUtils.withCarrierPrivileges(mContext, dataSubId, () -> { 259 SubscriptionGroupUtils.withEphemeralSubscriptionGroup(mContext, dataSubId, (subGrp) -> { 260 mVcnManager.clearVcnConfig(subGrp); 261 }); 262 }); 263 } 264 265 @Test testGetConfiguredSubscriptionGroups()266 public void testGetConfiguredSubscriptionGroups() throws Exception { 267 final int dataSubId = verifyAndGetValidDataSubId(); 268 CarrierPrivilegeUtils.withCarrierPrivileges(mContext, dataSubId, () -> { 269 SubscriptionGroupUtils.withEphemeralSubscriptionGroup(mContext, dataSubId, (subGrp) -> { 270 mVcnManager.setVcnConfig(subGrp, buildVcnConfig()); 271 assertEquals(Arrays.asList(subGrp), mVcnManager.getConfiguredSubscriptionGroups()); 272 273 mVcnManager.clearVcnConfig(subGrp); 274 }); 275 }); 276 } 277 278 /** Test implementation of VcnNetworkPolicyChangeListener for verification purposes. */ 279 private static class TestVcnNetworkPolicyChangeListener 280 implements VcnManager.VcnNetworkPolicyChangeListener { 281 private final CompletableFuture<Void> mFutureOnPolicyChanged = new CompletableFuture<>(); 282 283 @Override onPolicyChanged()284 public void onPolicyChanged() { 285 mFutureOnPolicyChanged.complete(null /* unused */); 286 } 287 awaitOnPolicyChanged()288 public void awaitOnPolicyChanged() throws Exception { 289 mFutureOnPolicyChanged.get(CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS); 290 } 291 } 292 293 @Test(expected = SecurityException.class) testAddVcnNetworkPolicyChangeListener_noNetworkFactoryPermission()294 public void testAddVcnNetworkPolicyChangeListener_noNetworkFactoryPermission() 295 throws Exception { 296 // Drop shell permission identity to test unpermissioned behavior. 297 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 298 299 final TestVcnNetworkPolicyChangeListener listener = 300 new TestVcnNetworkPolicyChangeListener(); 301 302 try { 303 mVcnManager.addVcnNetworkPolicyChangeListener(INLINE_EXECUTOR, listener); 304 } finally { 305 mVcnManager.removeVcnNetworkPolicyChangeListener(listener); 306 } 307 } 308 309 @Test testRemoveVcnNetworkPolicyChangeListener_noNetworkFactoryPermission()310 public void testRemoveVcnNetworkPolicyChangeListener_noNetworkFactoryPermission() { 311 final TestVcnNetworkPolicyChangeListener listener = 312 new TestVcnNetworkPolicyChangeListener(); 313 314 mVcnManager.removeVcnNetworkPolicyChangeListener(listener); 315 } 316 317 @Test(expected = SecurityException.class) testApplyVcnNetworkPolicy_noNetworkFactoryPermission()318 public void testApplyVcnNetworkPolicy_noNetworkFactoryPermission() throws Exception { 319 // Drop shell permission identity to test unpermissioned behavior. 320 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 321 322 final NetworkCapabilities nc = new NetworkCapabilities.Builder().build(); 323 final LinkProperties lp = new LinkProperties(); 324 325 mVcnManager.applyVcnNetworkPolicy(nc, lp); 326 } 327 328 @Test testApplyVcnNetworkPolicy_manageTestNetworkRequiresTransportTest()329 public void testApplyVcnNetworkPolicy_manageTestNetworkRequiresTransportTest() 330 throws Exception { 331 final NetworkCapabilities nc = 332 new NetworkCapabilities.Builder().addTransportType(TRANSPORT_CELLULAR).build(); 333 final LinkProperties lp = new LinkProperties(); 334 335 runWithShellPermissionIdentity( 336 () -> { 337 try { 338 mVcnManager.applyVcnNetworkPolicy(nc, lp); 339 fail("Expected IllegalStateException for applyVcnNetworkPolicy"); 340 } catch (IllegalStateException e) { 341 } 342 }, 343 android.Manifest.permission.MANAGE_TEST_NETWORKS); 344 } 345 createTestNetworkWrapperForPolicyTest( boolean isRestricted, int subId)346 private TestNetworkWrapper createTestNetworkWrapperForPolicyTest( 347 boolean isRestricted, int subId) throws Exception { 348 final Set<Integer> capabilities = new HashSet<>(); 349 capabilities.add(NET_CAPABILITY_CBS); 350 if (!isRestricted) { 351 capabilities.add(NET_CAPABILITY_NOT_RESTRICTED); 352 } 353 354 return createTestNetworkWrapper(subId, LOCAL_ADDRESS, capabilities); 355 } 356 buildVcnConfigWithTransportTestRestricted()357 private VcnConfig buildVcnConfigWithTransportTestRestricted() { 358 return buildVcnConfigBase() 359 .setIsTestModeProfile() 360 .setRestrictedUnderlyingNetworkTransports(Set.of(TRANSPORT_TEST)) 361 .build(); 362 } 363 364 @Test testApplyVcnNetworkPolicyDuringVcnSetup_onUnrestrictedNetwork()365 public void testApplyVcnNetworkPolicyDuringVcnSetup_onUnrestrictedNetwork() throws Exception { 366 final int subId = verifyAndGetValidDataSubId(); 367 final VcnConfig vcnConfig = buildVcnConfigWithTransportTestRestricted(); 368 369 try (TestNetworkWrapper networkWrapperUnrestricted = 370 createTestNetworkWrapperForPolicyTest(false /* isRestricted */, subId)) { 371 verifyUnderlyingCellAndRunTest( 372 subId, 373 (subGrp, cellNetwork, cellNetworkCb) -> { 374 cellNetworkCb.waitForAvailable(); 375 376 // Attempt VCN setup on an unrestricted network; expect the network to 377 // change to be restricted 378 mVcnManager.setVcnConfig(subGrp, vcnConfig); 379 380 VcnNetworkPolicyResult policyResult = 381 networkWrapperUnrestricted.awaitVcnNetworkPolicyChange(); 382 383 // Expect teardown due to restriction capability change 384 assertTrue(policyResult.isTeardownRequested()); 385 assertFalse( 386 policyResult 387 .getNetworkCapabilities() 388 .hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 389 390 // Verify underlying network is lost 391 networkWrapperUnrestricted.vcnNetworkCallback.waitForLost(); 392 393 mVcnManager.clearVcnConfig(subGrp); 394 }); 395 } 396 } 397 398 @Test testApplyVcnNetworkPolicyDuringVcnSetup_onRestrictedNetwork()399 public void testApplyVcnNetworkPolicyDuringVcnSetup_onRestrictedNetwork() throws Exception { 400 final int subId = verifyAndGetValidDataSubId(); 401 final VcnConfig vcnConfig = buildVcnConfigWithTransportTestRestricted(); 402 403 try (TestNetworkWrapper networkWrapperRestricted = 404 createTestNetworkWrapperForPolicyTest(true /* isRestricted */, subId)) { 405 406 verifyUnderlyingCellAndRunTest( 407 subId, 408 (subGrp, cellNetwork, cellNetworkCb) -> { 409 // Set up VCN on a restricted network 410 final VcnSetupResult vcnSetupResult = 411 setupAndGetVcnNetwork( 412 subGrp, 413 cellNetwork, 414 cellNetworkCb, 415 vcnConfig, 416 networkWrapperRestricted); 417 418 VcnNetworkPolicyResult policyResult = 419 networkWrapperRestricted.awaitVcnNetworkPolicyChange(); 420 421 // Do not expect teardown since the restriction capability does not change 422 assertFalse(policyResult.isTeardownRequested()); 423 assertFalse( 424 policyResult 425 .getNetworkCapabilities() 426 .hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 427 428 clearVcnConfigsAndVerifyNetworkTeardown( 429 subGrp, cellNetworkCb, vcnSetupResult.vcnNetwork); 430 }); 431 } 432 } 433 waitForSafeMode(TestNetworkWrapper networkWrapper)434 private void waitForSafeMode(TestNetworkWrapper networkWrapper) throws Exception { 435 // Once VCN starts, the test network should lose NOT_VCN_MANAGED 436 waitForExpectedUnderlyingNetworkWithCapabilities( 437 networkWrapper, 438 false /* expectNotVcnManaged */, 439 false /* expectNotMetered */, 440 TestNetworkWrapper.NETWORK_CB_TIMEOUT_MS); 441 442 // After VCN has started up, wait for safemode to kick in and expect the 443 // underlying Test Network to regain NOT_VCN_MANAGED. 444 waitForExpectedUnderlyingNetworkWithCapabilities( 445 networkWrapper, 446 true /* expectNotVcnManaged */, 447 false /* expectNotMetered */, 448 SAFEMODE_TIMEOUT_MILLIS); 449 } 450 verifyApplyVcnNetworkPolicyPostVcnSetupChangeNetworkRestriction( boolean isSafeMode, boolean isRestrictedBefore, boolean expectRestrictedAfter)451 private void verifyApplyVcnNetworkPolicyPostVcnSetupChangeNetworkRestriction( 452 boolean isSafeMode, boolean isRestrictedBefore, boolean expectRestrictedAfter) 453 throws Exception { 454 final int subId = verifyAndGetValidDataSubId(); 455 final VcnConfig vcnConfig = buildVcnConfigWithTransportTestRestricted(); 456 457 try (TestNetworkWrapper networkWrapperRestricted = 458 createTestNetworkWrapperForPolicyTest(true /* isRestricted */, subId)) { 459 460 verifyUnderlyingCellAndRunTest( 461 subId, 462 (subGrp, cellNetwork, cellNetworkCb) -> { 463 // Set up VCN on a restricted network 464 final VcnSetupResult vcnSetupResult = 465 setupAndGetVcnNetwork( 466 subGrp, 467 cellNetwork, 468 cellNetworkCb, 469 vcnConfig, 470 networkWrapperRestricted); 471 472 if (isSafeMode) { 473 waitForSafeMode(networkWrapperRestricted); 474 } 475 476 // Bring up another test network and verify its restriction capability 477 // change. 478 try (TestNetworkWrapper testNetworkWrapper = 479 createTestNetworkWrapperForPolicyTest(isRestrictedBefore, subId)) { 480 481 // The requested NetworkCapabilities should have been changed by 482 // VcnManager before the test network was brought up. Verify it by 483 // checking the NetworkCapabilities after the network setup. 484 final NetworkCapabilities nc = 485 mConnectivityManager.getNetworkCapabilities( 486 testNetworkWrapper.tunNetwork); 487 assertEquals( 488 !expectRestrictedAfter, 489 nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); 490 } 491 492 clearVcnConfigsAndVerifyNetworkTeardown( 493 subGrp, cellNetworkCb, vcnSetupResult.vcnNetwork); 494 }); 495 } 496 } 497 498 @Test testApplyVcnNetworkPolicy_activeMode_onRestrictedNetwork()499 public void testApplyVcnNetworkPolicy_activeMode_onRestrictedNetwork() throws Exception { 500 verifyApplyVcnNetworkPolicyPostVcnSetupChangeNetworkRestriction( 501 false /* isSafeMode */, 502 true /* isRestrictedBefore */, 503 true /* expectRestrictedAfter */); 504 } 505 506 @Test testApplyVcnNetworkPolicy_safeMode_onRestrictedNetwork()507 public void testApplyVcnNetworkPolicy_safeMode_onRestrictedNetwork() throws Exception { 508 verifyApplyVcnNetworkPolicyPostVcnSetupChangeNetworkRestriction( 509 true /* isSafeMode */, 510 true /* isRestrictedBefore */, 511 true /* expectRestrictedAfter */); 512 } 513 514 @Test testApplyVcnNetworkPolicy_activeMode_onUnrestrictedNetwork()515 public void testApplyVcnNetworkPolicy_activeMode_onUnrestrictedNetwork() throws Exception { 516 verifyApplyVcnNetworkPolicyPostVcnSetupChangeNetworkRestriction( 517 false /* isSafeMode */, 518 false /* isRestrictedBefore */, 519 true /* expectRestrictedAfter */); 520 } 521 522 @Test testApplyVcnNetworkPolicy_safeMode_onUnrestrictedNetwork()523 public void testApplyVcnNetworkPolicy_safeMode_onUnrestrictedNetwork() throws Exception { 524 verifyApplyVcnNetworkPolicyPostVcnSetupChangeNetworkRestriction( 525 true /* isSafeMode */, 526 false /* isRestrictedBefore */, 527 false /* expectRestrictedAfter */); 528 } 529 530 /** Test implementation of VcnStatusCallback for verification purposes. */ 531 private static class TestVcnStatusCallback extends VcnManager.VcnStatusCallback { 532 private final BlockingQueue<Integer> mOnStatusChangedHistory = new LinkedBlockingQueue<>(); 533 private final BlockingQueue<GatewayConnectionError> mOnGatewayConnectionErrorHistory = 534 new LinkedBlockingQueue<>(); 535 536 @Override onStatusChanged(int statusCode)537 public void onStatusChanged(int statusCode) { 538 mOnStatusChangedHistory.offer(statusCode); 539 } 540 541 @Override onGatewayConnectionError( @onNull String gatewayConnectionName, int errorCode, @Nullable Throwable detail)542 public void onGatewayConnectionError( 543 @NonNull String gatewayConnectionName, int errorCode, @Nullable Throwable detail) { 544 mOnGatewayConnectionErrorHistory.offer( 545 new GatewayConnectionError(gatewayConnectionName, errorCode, detail)); 546 } 547 awaitOnStatusChanged()548 public int awaitOnStatusChanged() throws Exception { 549 final Integer status = 550 mOnStatusChangedHistory.poll(CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS); 551 552 // Null means timeout 553 return status == null ? VCN_STATUS_CODE_AWAIT_TIMEOUT : status; 554 } 555 awaitOnGatewayConnectionError()556 public GatewayConnectionError awaitOnGatewayConnectionError() throws Exception { 557 return mOnGatewayConnectionErrorHistory.poll( 558 CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS); 559 } 560 } 561 verifyVcnStatus(ParcelUuid subGrp, int expectedStatus)562 private void verifyVcnStatus(ParcelUuid subGrp, int expectedStatus) throws Exception { 563 final TestVcnStatusCallback callback = new TestVcnStatusCallback(); 564 mVcnManager.registerVcnStatusCallback(subGrp, INLINE_EXECUTOR, callback); 565 566 assertEquals(expectedStatus, callback.awaitOnStatusChanged()); 567 568 mVcnManager.unregisterVcnStatusCallback(callback); 569 } 570 571 /** Info class for organizing VcnStatusCallback#onGatewayConnectionError response data. */ 572 private static class GatewayConnectionError { 573 @NonNull public final String gatewayConnectionName; 574 public final int errorCode; 575 @Nullable public final Throwable detail; 576 GatewayConnectionError( @onNull String gatewayConnectionName, int errorCode, @Nullable Throwable detail)577 public GatewayConnectionError( 578 @NonNull String gatewayConnectionName, int errorCode, @Nullable Throwable detail) { 579 this.gatewayConnectionName = gatewayConnectionName; 580 this.errorCode = errorCode; 581 this.detail = detail; 582 } 583 } 584 registerVcnStatusCallbackForSubId( @onNull TestVcnStatusCallback callback, int subId)585 private void registerVcnStatusCallbackForSubId( 586 @NonNull TestVcnStatusCallback callback, int subId) throws Exception { 587 CarrierPrivilegeUtils.withCarrierPrivileges(mContext, subId, () -> { 588 SubscriptionGroupUtils.withEphemeralSubscriptionGroup(mContext, subId, (subGrp) -> { 589 mVcnManager.registerVcnStatusCallback(subGrp, INLINE_EXECUTOR, callback); 590 }); 591 }); 592 } 593 594 @Test testRegisterVcnStatusCallback()595 public void testRegisterVcnStatusCallback() throws Exception { 596 final TestVcnStatusCallback callback = new TestVcnStatusCallback(); 597 final int subId = verifyAndGetValidDataSubId(); 598 599 try { 600 registerVcnStatusCallbackForSubId(callback, subId); 601 602 final int statusCode = callback.awaitOnStatusChanged(); 603 assertEquals(VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED, statusCode); 604 } finally { 605 mVcnManager.unregisterVcnStatusCallback(callback); 606 } 607 } 608 609 @Test testRegisterVcnStatusCallback_reuseUnregisteredCallback()610 public void testRegisterVcnStatusCallback_reuseUnregisteredCallback() throws Exception { 611 final TestVcnStatusCallback callback = new TestVcnStatusCallback(); 612 final int subId = verifyAndGetValidDataSubId(); 613 614 try { 615 registerVcnStatusCallbackForSubId(callback, subId); 616 mVcnManager.unregisterVcnStatusCallback(callback); 617 registerVcnStatusCallbackForSubId(callback, subId); 618 } finally { 619 mVcnManager.unregisterVcnStatusCallback(callback); 620 } 621 } 622 623 @Test(expected = IllegalStateException.class) testRegisterVcnStatusCallback_duplicateRegister()624 public void testRegisterVcnStatusCallback_duplicateRegister() throws Exception { 625 final TestVcnStatusCallback callback = new TestVcnStatusCallback(); 626 final int subId = verifyAndGetValidDataSubId(); 627 628 try { 629 registerVcnStatusCallbackForSubId(callback, subId); 630 registerVcnStatusCallbackForSubId(callback, subId); 631 } finally { 632 mVcnManager.unregisterVcnStatusCallback(callback); 633 } 634 } 635 636 @Test testUnregisterVcnStatusCallback()637 public void testUnregisterVcnStatusCallback() throws Exception { 638 final TestVcnStatusCallback callback = new TestVcnStatusCallback(); 639 640 mVcnManager.unregisterVcnStatusCallback(callback); 641 } 642 createTestNetworkWrapper( int subId, InetAddress localAddress, Set<Integer> capabilities)643 private TestNetworkWrapper createTestNetworkWrapper( 644 int subId, InetAddress localAddress, Set<Integer> capabilities) throws Exception { 645 TestNetworkWrapper testNetworkWrapper = 646 new TestNetworkWrapper( 647 mContext, 648 TEST_NETWORK_MTU, 649 capabilities, 650 Collections.singleton(subId), 651 localAddress); 652 assertNotNull("No test network found", testNetworkWrapper.tunNetwork); 653 return testNetworkWrapper; 654 } 655 createTestNetworkWrapper( boolean isMetered, int subId, InetAddress localAddress)656 private TestNetworkWrapper createTestNetworkWrapper( 657 boolean isMetered, int subId, InetAddress localAddress) throws Exception { 658 final Set<Integer> capabilities = new HashSet<>(); 659 capabilities.add(NET_CAPABILITY_CBS); 660 if (!isMetered) { 661 capabilities.add(NET_CAPABILITY_NOT_METERED); 662 } 663 664 return createTestNetworkWrapper(subId, localAddress, capabilities); 665 } 666 667 @Test testVcnManagedNetworkLosesNotVcnManagedCapability()668 public void testVcnManagedNetworkLosesNotVcnManagedCapability() throws Exception { 669 final int subId = verifyAndGetValidDataSubId(); 670 try (TestNetworkWrapper testNetworkWrapper = 671 createTestNetworkWrapper(true /* isMetered */, subId, LOCAL_ADDRESS)) { 672 // Before the VCN starts, the test network should have NOT_VCN_MANAGED 673 waitForExpectedUnderlyingNetworkWithCapabilities( 674 testNetworkWrapper, 675 true /* expectNotVcnManaged */, 676 false /* expectNotMetered */, 677 TestNetworkWrapper.NETWORK_CB_TIMEOUT_MS); 678 679 CarrierPrivilegeUtils.withCarrierPrivilegesForShell(mContext, subId, () -> { 680 SubscriptionGroupUtils.withEphemeralSubscriptionGroup(mContext, subId, (subGrp) -> { 681 mVcnManager.setVcnConfig(subGrp, buildVcnConfig()); 682 683 // Once VCN starts, the test network should lose NOT_VCN_MANAGED 684 waitForExpectedUnderlyingNetworkWithCapabilities( 685 testNetworkWrapper, 686 false /* expectNotVcnManaged */, 687 false /* expectNotMetered */, 688 TestNetworkWrapper.NETWORK_CB_TIMEOUT_MS); 689 690 mVcnManager.clearVcnConfig(subGrp); 691 692 // After the VCN tears down, the test network should have 693 // NOT_VCN_MANAGED again 694 waitForExpectedUnderlyingNetworkWithCapabilities( 695 testNetworkWrapper, 696 true /* expectNotVcnManaged */, 697 false /* expectNotMetered */, 698 TestNetworkWrapper.NETWORK_CB_TIMEOUT_MS); 699 }); 700 }); 701 } 702 } 703 waitForExpectedUnderlyingNetworkWithCapabilities( TestNetworkWrapper testNetworkWrapper, boolean expectNotVcnManaged, boolean expectNotMetered, long timeoutMillis)704 private void waitForExpectedUnderlyingNetworkWithCapabilities( 705 TestNetworkWrapper testNetworkWrapper, 706 boolean expectNotVcnManaged, 707 boolean expectNotMetered, 708 long timeoutMillis) 709 throws Exception { 710 final long start = SystemClock.elapsedRealtime(); 711 712 // Wait for NetworkCapabilities changes until they match the expected capabilities 713 do { 714 final CapabilitiesChangedEvent capabilitiesChangedEvent = 715 testNetworkWrapper.vcnNetworkCallback.waitForOnCapabilitiesChanged( 716 timeoutMillis); 717 assertNotNull("Failed to receive NetworkCapabilities change", capabilitiesChangedEvent); 718 719 final NetworkCapabilities nc = capabilitiesChangedEvent.networkCapabilities; 720 if (testNetworkWrapper.tunNetwork.equals(capabilitiesChangedEvent.network) 721 && nc.hasCapability(NET_CAPABILITY_VALIDATED) 722 && expectNotVcnManaged == nc.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 723 && expectNotMetered == nc.hasCapability(NET_CAPABILITY_NOT_METERED)) { 724 return; 725 } 726 } while (SystemClock.elapsedRealtime() - start < timeoutMillis); 727 728 fail( 729 "Expected update for network=" 730 + testNetworkWrapper.tunNetwork.getNetId() 731 + ". Wanted NOT_VCN_MANAGED=" 732 + expectNotVcnManaged 733 + " NOT_METERED=" 734 + expectNotMetered); 735 } 736 737 private interface VcnTestRunnable { runTest(ParcelUuid subGrp, Network cellNetwork, VcnTestNetworkCallback cellNetworkCb)738 void runTest(ParcelUuid subGrp, Network cellNetwork, VcnTestNetworkCallback cellNetworkCb) 739 throws Exception; 740 } 741 verifyUnderlyingCellAndRunTest(int subId, VcnTestRunnable test)742 private void verifyUnderlyingCellAndRunTest(int subId, VcnTestRunnable test) throws Exception { 743 // Get current cell Network then wait for it to drop (due to losing NOT_VCN_MANAGED) 744 // before waiting for VCN Network. 745 final NetworkRequest cellNetworkReq = 746 new NetworkRequest.Builder() 747 .addTransportType(TRANSPORT_CELLULAR) 748 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 749 .build(); 750 final VcnTestNetworkCallback cellNetworkCb = new VcnTestNetworkCallback(); 751 mConnectivityManager.requestNetwork(cellNetworkReq, cellNetworkCb); 752 final Network cellNetwork = cellNetworkCb.waitForAvailable(); 753 assertNotNull("No cell network found", cellNetwork); 754 755 CarrierPrivilegeUtils.withCarrierPrivilegesForShell(mContext, subId, () -> { 756 SubscriptionGroupUtils.withEphemeralSubscriptionGroup( 757 mContext, 758 subId, 759 (subGrp) -> { 760 test.runTest(subGrp, cellNetwork, cellNetworkCb); 761 } 762 ); 763 }); 764 mConnectivityManager.unregisterNetworkCallback(cellNetworkCb); 765 } 766 767 @Test testSetVcnConfigOnTestNetwork()768 public void testSetVcnConfigOnTestNetwork() throws Exception { 769 final int subId = verifyAndGetValidDataSubId(); 770 771 try (TestNetworkWrapper testNetworkWrapper = 772 createTestNetworkWrapper(true /* isMetered */, subId, LOCAL_ADDRESS)) { 773 verifyUnderlyingCellAndRunTest(subId, (subGrp, cellNetwork, cellNetworkCb) -> { 774 final VcnSetupResult vcnSetupResult = 775 setupAndGetVcnNetwork(subGrp, cellNetwork, cellNetworkCb, testNetworkWrapper); 776 777 clearVcnConfigsAndVerifyNetworkTeardown( 778 subGrp, cellNetworkCb, vcnSetupResult.vcnNetwork); 779 }); 780 } 781 } 782 783 @Test testSetVcnConfigOnTestNetworkAndDumpsys()784 public void testSetVcnConfigOnTestNetworkAndDumpsys() throws Exception { 785 final int subId = verifyAndGetValidDataSubId(); 786 787 try (TestNetworkWrapper testNetworkWrapper = 788 createTestNetworkWrapper(true /* isMetered */, subId, LOCAL_ADDRESS)) { 789 verifyUnderlyingCellAndRunTest(subId, (subGrp, cellNetwork, cellNetworkCb) -> { 790 final VcnSetupResult vcnSetupResult = 791 setupAndGetVcnNetwork(subGrp, cellNetwork, cellNetworkCb, testNetworkWrapper); 792 793 runShellCommand("dumpsys vcn_management"); 794 795 clearVcnConfigsAndVerifyNetworkTeardown( 796 subGrp, cellNetworkCb, vcnSetupResult.vcnNetwork); 797 }); 798 } 799 } 800 801 @Test testSetVcnConfigOnTestNetworkAndHandleDataStall()802 public void testSetVcnConfigOnTestNetworkAndHandleDataStall() throws Exception { 803 final int subId = verifyAndGetValidDataSubId(); 804 805 try (TestNetworkWrapper testNetworkWrapper = 806 createTestNetworkWrapper(true /* isMetered */, subId, LOCAL_ADDRESS)) { 807 verifyUnderlyingCellAndRunTest( 808 subId, 809 (subGrp, cellNetwork, cellNetworkCb) -> { 810 final VcnSetupResult vcnSetupResult = 811 setupAndGetVcnNetwork( 812 subGrp, cellNetwork, cellNetworkCb, testNetworkWrapper); 813 814 mConnectivityManager.simulateDataStall( 815 DETECTION_METHOD_DNS_EVENTS, 816 System.currentTimeMillis(), 817 vcnSetupResult.vcnNetwork, 818 new PersistableBundle() /* extra data stall info; unused */); 819 820 injectAndVerifyIkeMobikePackets(testNetworkWrapper.ikeTunUtils); 821 822 clearVcnConfigsAndVerifyNetworkTeardown( 823 subGrp, cellNetworkCb, vcnSetupResult.vcnNetwork); 824 }); 825 } 826 } 827 createTestNetworkForNetworkSelection( int subId, Set<Integer> capabilities)828 private TestNetworkWrapper createTestNetworkForNetworkSelection( 829 int subId, Set<Integer> capabilities) throws Exception { 830 return createTestNetworkWrapper(subId, LOCAL_ADDRESS, capabilities); 831 } 832 verifyVcnMigratesToPreferredUnderlyingNetwork( VcnConfig vcnConfig, Set<Integer> capSetLessPreferred, Set<Integer> capSetPreferred)833 private void verifyVcnMigratesToPreferredUnderlyingNetwork( 834 VcnConfig vcnConfig, Set<Integer> capSetLessPreferred, Set<Integer> capSetPreferred) 835 throws Exception { 836 final int subId = verifyAndGetValidDataSubId(); 837 838 // Start on a less preferred network. 839 try (TestNetworkWrapper testNetworkWrapperLessPreferred = 840 createTestNetworkForNetworkSelection(subId, capSetLessPreferred)) { 841 verifyUnderlyingCellAndRunTest( 842 subId, 843 (subGrp, cellNetwork, cellNetworkCb) -> { 844 final VcnSetupResult vcnSetupResult = 845 setupAndGetVcnNetwork( 846 subGrp, 847 cellNetwork, 848 cellNetworkCb, 849 vcnConfig, 850 testNetworkWrapperLessPreferred); 851 852 // Then bring up a more preferred network, and expect to switch to it. 853 try (TestNetworkWrapper testNetworkWrapperPreferred = 854 createTestNetworkForNetworkSelection(subId, capSetPreferred)) { 855 injectAndVerifyIkeMobikePackets( 856 testNetworkWrapperPreferred.ikeTunUtils); 857 858 clearVcnConfigsAndVerifyNetworkTeardown( 859 subGrp, cellNetworkCb, vcnSetupResult.vcnNetwork); 860 } 861 }); 862 } 863 } 864 verifyVcnDoesNotSelectLessPreferredUnderlyingNetwork( VcnConfig vcnConfig, Set<Integer> capSetLessPreferred, Set<Integer> capSetPreferred)865 private void verifyVcnDoesNotSelectLessPreferredUnderlyingNetwork( 866 VcnConfig vcnConfig, Set<Integer> capSetLessPreferred, Set<Integer> capSetPreferred) 867 throws Exception { 868 final int subId = verifyAndGetValidDataSubId(); 869 870 // Start on a more preferred network. 871 try (TestNetworkWrapper testNetworkWrapperPreferred = 872 createTestNetworkForNetworkSelection(subId, capSetPreferred)) { 873 verifyUnderlyingCellAndRunTest( 874 subId, 875 (subGrp, cellNetwork, cellNetworkCb) -> { 876 final VcnSetupResult vcnSetupResult = 877 setupAndGetVcnNetwork( 878 subGrp, 879 cellNetwork, 880 cellNetworkCb, 881 vcnConfig, 882 testNetworkWrapperPreferred); 883 884 // Then bring up a less preferred network, and expect the VCN underlying 885 // network does not change. 886 try (TestNetworkWrapper testNetworkWrapperLessPreferred = 887 createTestNetworkForNetworkSelection(subId, capSetLessPreferred)) { 888 injectAndVerifyIkeDpdPackets( 889 testNetworkWrapperPreferred.ikeTunUtils, 890 vcnSetupResult.ikeExchangePortPair); 891 892 clearVcnConfigsAndVerifyNetworkTeardown( 893 subGrp, cellNetworkCb, vcnSetupResult.vcnNetwork); 894 } 895 }); 896 } 897 } 898 verifyVcnMigratesAfterPreferredUnderlyingNetworkDies( VcnConfig vcnConfig, Set<Integer> capSetLessPreferred, Set<Integer> capSetPreferred)899 private void verifyVcnMigratesAfterPreferredUnderlyingNetworkDies( 900 VcnConfig vcnConfig, Set<Integer> capSetLessPreferred, Set<Integer> capSetPreferred) 901 throws Exception { 902 final int subId = verifyAndGetValidDataSubId(); 903 904 // Start on a more preferred network 905 try (TestNetworkWrapper testNetworkWrapperPreferred = 906 createTestNetworkForNetworkSelection(subId, capSetPreferred)) { 907 verifyUnderlyingCellAndRunTest( 908 subId, 909 (subGrp, cellNetwork, cellNetworkCb) -> { 910 final VcnSetupResult vcnSetupResult = 911 setupAndGetVcnNetwork( 912 subGrp, 913 cellNetwork, 914 cellNetworkCb, 915 vcnConfig, 916 testNetworkWrapperPreferred); 917 918 // Bring up a less preferred network 919 try (TestNetworkWrapper testNetworkWrapperLessPreferred = 920 createTestNetworkForNetworkSelection(subId, capSetLessPreferred)) { 921 // Teardown the preferred network 922 testNetworkWrapperPreferred.close(); 923 testNetworkWrapperPreferred.vcnNetworkCallback.waitForLost(); 924 925 // Verify the VCN switches to the remaining less preferred network 926 injectAndVerifyIkeMobikePackets( 927 testNetworkWrapperLessPreferred.ikeTunUtils); 928 929 clearVcnConfigsAndVerifyNetworkTeardown( 930 subGrp, cellNetworkCb, vcnSetupResult.vcnNetwork); 931 } 932 }); 933 } 934 } 935 createCellTemplateBaseBuilder()936 private VcnCellUnderlyingNetworkTemplate.Builder createCellTemplateBaseBuilder() 937 throws Exception { 938 return new VcnCellUnderlyingNetworkTemplate.Builder().setInternet(MATCH_ANY); 939 } 940 createVcnConfigPrefersMetered()941 private VcnConfig createVcnConfigPrefersMetered() throws Exception { 942 final List<VcnUnderlyingNetworkTemplate> nwTemplates = new ArrayList<>(); 943 nwTemplates.add( 944 createCellTemplateBaseBuilder() 945 .setCbs(MATCH_REQUIRED) 946 .setMetered(MATCH_REQUIRED) 947 .build()); 948 nwTemplates.add( 949 createCellTemplateBaseBuilder() 950 .setCbs(MATCH_REQUIRED) 951 .setMetered(MATCH_FORBIDDEN) 952 .build()); 953 return buildVcnConfigBase(nwTemplates).setIsTestModeProfile().build(); 954 } 955 956 @Test testVcnMigratesToPreferredUnderlyingNetwork_preferMetered()957 public void testVcnMigratesToPreferredUnderlyingNetwork_preferMetered() throws Exception { 958 verifyVcnMigratesToPreferredUnderlyingNetwork( 959 createVcnConfigPrefersMetered(), 960 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_CBS), 961 Set.of(NET_CAPABILITY_CBS)); 962 } 963 964 @Test testVcnDoesNotSelectLessPreferredUnderlyingNetwork_preferMetered()965 public void testVcnDoesNotSelectLessPreferredUnderlyingNetwork_preferMetered() 966 throws Exception { 967 verifyVcnDoesNotSelectLessPreferredUnderlyingNetwork( 968 createVcnConfigPrefersMetered(), 969 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_CBS), 970 Set.of(NET_CAPABILITY_CBS)); 971 } 972 973 @Test testVcnMigratesAfterPreferredUnderlyingNetworkDies_preferMetered()974 public void testVcnMigratesAfterPreferredUnderlyingNetworkDies_preferMetered() 975 throws Exception { 976 verifyVcnMigratesAfterPreferredUnderlyingNetworkDies( 977 createVcnConfigPrefersMetered(), 978 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_CBS), 979 Set.of(NET_CAPABILITY_CBS)); 980 } 981 createVcnConfigPrefersCbs()982 private VcnConfig createVcnConfigPrefersCbs() throws Exception { 983 final List<VcnUnderlyingNetworkTemplate> nwTemplates = new ArrayList<>(); 984 nwTemplates.add(createCellTemplateBaseBuilder().setCbs(MATCH_REQUIRED).build()); 985 nwTemplates.add(createCellTemplateBaseBuilder().setRcs(MATCH_REQUIRED).build()); 986 987 return buildVcnConfigBase(nwTemplates).setIsTestModeProfile().build(); 988 } 989 990 @Test testVcnMigratesToPreferredUnderlyingNetwork_preferCbs()991 public void testVcnMigratesToPreferredUnderlyingNetwork_preferCbs() throws Exception { 992 verifyVcnMigratesToPreferredUnderlyingNetwork( 993 createVcnConfigPrefersCbs(), 994 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_RCS), 995 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_CBS)); 996 } 997 998 @Test testVcnDoesNotSelectLessPreferredUnderlyingNetwork_preferCbs()999 public void testVcnDoesNotSelectLessPreferredUnderlyingNetwork_preferCbs() throws Exception { 1000 verifyVcnDoesNotSelectLessPreferredUnderlyingNetwork( 1001 createVcnConfigPrefersCbs(), 1002 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_RCS), 1003 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_CBS)); 1004 } 1005 1006 @Test testVcnMigratesAfterPreferredUnderlyingNetworkDies_preferCbs()1007 public void testVcnMigratesAfterPreferredUnderlyingNetworkDies_preferCbs() throws Exception { 1008 verifyVcnMigratesAfterPreferredUnderlyingNetworkDies( 1009 createVcnConfigPrefersCbs(), 1010 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_RCS), 1011 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_CBS)); 1012 } 1013 createVcnConfigPrefersNonCbs()1014 private VcnConfig createVcnConfigPrefersNonCbs() throws Exception { 1015 final List<VcnUnderlyingNetworkTemplate> nwTemplates = new ArrayList<>(); 1016 nwTemplates.add( 1017 createCellTemplateBaseBuilder() 1018 .setRcs(MATCH_REQUIRED) 1019 .setCbs(MATCH_FORBIDDEN) 1020 .build()); 1021 nwTemplates.add( 1022 createCellTemplateBaseBuilder().setRcs(MATCH_REQUIRED).setCbs(MATCH_ANY).build()); 1023 1024 return buildVcnConfigBase(nwTemplates).setIsTestModeProfile().build(); 1025 } 1026 1027 @Test testVcnMigratesToPreferredUnderlyingNetwork_preferNonCbs()1028 public void testVcnMigratesToPreferredUnderlyingNetwork_preferNonCbs() throws Exception { 1029 verifyVcnMigratesToPreferredUnderlyingNetwork( 1030 createVcnConfigPrefersNonCbs(), 1031 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_RCS, NET_CAPABILITY_CBS), 1032 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_RCS)); 1033 } 1034 1035 @Test testVcnDoesNotSelectLessPreferredUnderlyingNetwork_preferNonCbs()1036 public void testVcnDoesNotSelectLessPreferredUnderlyingNetwork_preferNonCbs() throws Exception { 1037 verifyVcnDoesNotSelectLessPreferredUnderlyingNetwork( 1038 createVcnConfigPrefersNonCbs(), 1039 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_RCS, NET_CAPABILITY_CBS), 1040 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_RCS)); 1041 } 1042 1043 @Test testVcnMigratesAfterPreferredUnderlyingNetworkDies_preferNonCbs()1044 public void testVcnMigratesAfterPreferredUnderlyingNetworkDies_preferNonCbs() throws Exception { 1045 verifyVcnMigratesAfterPreferredUnderlyingNetworkDies( 1046 createVcnConfigPrefersNonCbs(), 1047 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_RCS, NET_CAPABILITY_CBS), 1048 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_RCS)); 1049 } 1050 1051 @Test testSetVcnWithCbsMatchAny_preferCbsNetworkOverUnmatchedNetwork()1052 public void testSetVcnWithCbsMatchAny_preferCbsNetworkOverUnmatchedNetwork() throws Exception { 1053 final List<VcnUnderlyingNetworkTemplate> nwTemplates = new ArrayList<>(); 1054 nwTemplates.add( 1055 createCellTemplateBaseBuilder().setRcs(MATCH_REQUIRED).setCbs(MATCH_ANY).build()); 1056 1057 final VcnConfig vcnConfig = buildVcnConfigBase(nwTemplates).setIsTestModeProfile().build(); 1058 1059 verifyVcnMigratesToPreferredUnderlyingNetwork( 1060 vcnConfig, 1061 Set.of(NET_CAPABILITY_NOT_METERED), 1062 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_RCS, NET_CAPABILITY_CBS)); 1063 } 1064 1065 @Test testSetVcnWithCbsMatchAny_preferNonCbsNetworkOverUnmatchedNetwork()1066 public void testSetVcnWithCbsMatchAny_preferNonCbsNetworkOverUnmatchedNetwork() 1067 throws Exception { 1068 final List<VcnUnderlyingNetworkTemplate> nwTemplates = new ArrayList<>(); 1069 nwTemplates.add( 1070 createCellTemplateBaseBuilder().setRcs(MATCH_REQUIRED).setCbs(MATCH_ANY).build()); 1071 1072 final VcnConfig vcnConfig = buildVcnConfigBase(nwTemplates).setIsTestModeProfile().build(); 1073 1074 verifyVcnMigratesToPreferredUnderlyingNetwork( 1075 vcnConfig, 1076 Set.of(NET_CAPABILITY_NOT_METERED), 1077 Set.of(NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_RCS)); 1078 } 1079 1080 @Test testVcnNoUnderlyingNetworkSelectedFallback()1081 public void testVcnNoUnderlyingNetworkSelectedFallback() throws Exception { 1082 final int subId = verifyAndGetValidDataSubId(); 1083 final List<VcnUnderlyingNetworkTemplate> nwTemplates = new ArrayList<>(); 1084 nwTemplates.add( 1085 new VcnWifiUnderlyingNetworkTemplate.Builder().setMetered(MATCH_REQUIRED).build()); 1086 final VcnConfig vcnConfig = buildVcnConfigBase(nwTemplates).setIsTestModeProfile().build(); 1087 1088 // Bring up a network that does not match any of the configured network templates 1089 try (TestNetworkWrapper testNetworkWrapper = 1090 createTestNetworkWrapper(false /* isMetered */, subId, LOCAL_ADDRESS)) { 1091 verifyUnderlyingCellAndRunTest(subId, (subGrp, cellNetwork, cellNetworkCb) -> { 1092 // Verify the VCN can still be set up on the only one underlying network 1093 final VcnSetupResult vcnSetupResult = 1094 setupAndGetVcnNetwork( 1095 subGrp, 1096 cellNetwork, 1097 cellNetworkCb, 1098 vcnConfig, 1099 testNetworkWrapper); 1100 1101 clearVcnConfigsAndVerifyNetworkTeardown( 1102 subGrp, cellNetworkCb, vcnSetupResult.vcnNetwork); 1103 }); 1104 } 1105 } 1106 1107 private static class VcnSetupResult { 1108 public final Network vcnNetwork; 1109 public final PortPair ikeExchangePortPair; 1110 VcnSetupResult(Network vcnNetwork, PortPair ikeExchangePortPair)1111 VcnSetupResult(Network vcnNetwork, PortPair ikeExchangePortPair) { 1112 this.vcnNetwork = vcnNetwork; 1113 this.ikeExchangePortPair = ikeExchangePortPair; 1114 } 1115 } 1116 setupAndGetVcnNetwork( @onNull ParcelUuid subGrp, @NonNull Network cellNetwork, @NonNull VcnTestNetworkCallback cellNetworkCb, @NonNull VcnConfig testModeVcnConfig, @NonNull TestNetworkWrapper testNetworkWrapper)1117 private VcnSetupResult setupAndGetVcnNetwork( 1118 @NonNull ParcelUuid subGrp, 1119 @NonNull Network cellNetwork, 1120 @NonNull VcnTestNetworkCallback cellNetworkCb, 1121 @NonNull VcnConfig testModeVcnConfig, 1122 @NonNull TestNetworkWrapper testNetworkWrapper) 1123 throws Exception { 1124 cellNetworkCb.waitForAvailable(); 1125 mVcnManager.setVcnConfig(subGrp, testModeVcnConfig); 1126 1127 // Wait until the cell Network is lost (due to losing NOT_VCN_MANAGED) to wait for 1128 // VCN network 1129 final Network lostCellNetwork = cellNetworkCb.waitForLost(); 1130 assertEquals(cellNetwork, lostCellNetwork); 1131 1132 final PortPair ikeExchangePortPair = 1133 injectAndVerifyIkeSessionNegotiationPackets(testNetworkWrapper.ikeTunUtils); 1134 1135 final Network vcnNetwork = cellNetworkCb.waitForAvailable(); 1136 assertNotNull("VCN network did not come up", vcnNetwork); 1137 return new VcnSetupResult(vcnNetwork, ikeExchangePortPair); 1138 } 1139 setupAndGetVcnNetwork( @onNull ParcelUuid subGrp, @NonNull Network cellNetwork, @NonNull VcnTestNetworkCallback cellNetworkCb, @NonNull TestNetworkWrapper testNetworkWrapper)1140 private VcnSetupResult setupAndGetVcnNetwork( 1141 @NonNull ParcelUuid subGrp, 1142 @NonNull Network cellNetwork, 1143 @NonNull VcnTestNetworkCallback cellNetworkCb, 1144 @NonNull TestNetworkWrapper testNetworkWrapper) 1145 throws Exception { 1146 return setupAndGetVcnNetwork( 1147 subGrp, cellNetwork, cellNetworkCb, buildTestModeVcnConfig(), testNetworkWrapper); 1148 } 1149 injectAndVerifyIkeSessionNegotiationPackets(@onNull IkeTunUtils ikeTunUtils)1150 private PortPair injectAndVerifyIkeSessionNegotiationPackets(@NonNull IkeTunUtils ikeTunUtils) 1151 throws Exception { 1152 // Generated by forcing IKE to use Test Mode (RandomnessFactory#mIsTestModeEnabled) and 1153 // capturing IKE packets with a live server. 1154 final String ikeInitResp = 1155 "46b8eca1e0d72a189b9f8e0158e1c0a52120222000000000000001d022000030" 1156 + "0000002c010100040300000c0100000c800e0080030000080300000803000008" 1157 + "02000008000000080400000e28000108000e0000164d3413d855a1642d4d6355" 1158 + "a8ef6666bfaa28a4b5264600c9ffbaef7930bd33af49022926013aae0a48d764" 1159 + "750ccb3987605957e31a2ef0e6838cfa67af989933c2879434081c4e9787f0d4" 1160 + "4da0d7dacca5589702a4537ee4fb18e8db21a948b245260f55212a1c619f61c6" 1161 + "fa1caaff4474082f9714b14ef4bcc7b2b8f43fcb939931119e53b05274faec65" 1162 + "2816c563529e60c1a88183eba9c456ecb644faf57b726b83e3242e08489d95e9" 1163 + "81e59c7ad82cf3cdfb00fe0213c4e65d61e88bbefbd536261027da722a2bbf89" 1164 + "c6378e63ce6fbcef282421e5576bba1b2faa3c4c2d41028f91df7ba165a24a18" 1165 + "fcba4f96db3e5e0eed76dc7c3c432362dd4a82d32900002461cbd03c08819730" 1166 + "f1060ed0c0446f784eb8dd884d3f73f54eb2b0c3071cc4f32900001c00004004" 1167 + "07150f3fd9584dbebb7e88ad256c7bfb9b0bb55a2900001c00004005e3aa3788" 1168 + "7040e38dbb4de8fd435161cce904ec59290000080000402e290000100000402f" 1169 + "00020003000400050000000800004014"; 1170 final String ikeAuthResp = 1171 "46b8eca1e0d72a189b9f8e0158e1c0a52e20232000000001000000fc240000e0" 1172 + "1a666eb2a02b37682436a18fff5e9cef67b9096d6c7887ed235f8b5173c9469e" 1173 + "361621b66849de2dbcabf956b3d055cafafd503530543540e81dac9bf8fb8826" 1174 + "e08bc99e9ed2185d8f1322c8885abe4f98a9832c694da775eaa4ae69f17b8cbf" 1175 + "b009bf82b4bf4012bca489595631c3168cd417f813e7d177d2ceb70766a0773c" 1176 + "8819d8763627ddc9455ae3d5a5a03224020a66c8e58c8073c4a1fcf5d67cfa95" 1177 + "15de86b392a63ff54ff5572302b9ce7725085b05839252794c3680f5d8f34019" 1178 + "fa1930ea045d2a9987850e2049235c7328ef148370b6a3403408b987"; 1179 1180 ikeTunUtils.awaitReqAndInjectResp( 1181 IKE_DETERMINISTIC_INITIATOR_SPI, 1182 0 /* expectedMsgId */, 1183 false /* expectedUseEncap */, 1184 ikeInitResp); 1185 1186 byte[] ikeAuthReqPkt = 1187 ikeTunUtils.awaitReqAndInjectResp( 1188 IKE_DETERMINISTIC_INITIATOR_SPI, 1189 1 /* expectedMsgId */, 1190 true /* expectedUseEncap */, 1191 ikeAuthResp); 1192 1193 return IkeTunUtils.getSrcDestPortPair(ikeAuthReqPkt); 1194 } 1195 clearVcnConfigsAndVerifyNetworkTeardown( @onNull ParcelUuid subGrp, @NonNull VcnTestNetworkCallback cellNetworkCb, @NonNull Network vcnNetwork)1196 private void clearVcnConfigsAndVerifyNetworkTeardown( 1197 @NonNull ParcelUuid subGrp, 1198 @NonNull VcnTestNetworkCallback cellNetworkCb, 1199 @NonNull Network vcnNetwork) 1200 throws Exception { 1201 // Clear the history to remove other networks have been matched to the request 1202 cellNetworkCb.clearLostHistory(); 1203 1204 mVcnManager.clearVcnConfig(subGrp); 1205 1206 // Expect VCN Network to disappear after VcnConfig is cleared. 1207 if (mConnectivityManager.getNetworkCapabilities(vcnNetwork) != null) { 1208 1209 // If not already torn down, wait for teardown. In the event that the underlying network 1210 // has already regained the NOT_VCN_MANAGED bit (before the VCN's NetworkAgent teardown) 1211 // the VCN network MAY be immediately replaced with the underlying Cell, which only 1212 // fires an onAvailable for the new network, as opposed to an onLost() for the VCN 1213 // network. In that case, check that the VCN network has been unregistered. 1214 // 1215 // An alternative approach is to monitor #onAvailable as an indicator of potential 1216 // network loss. However, since #onAvailable can mean either 1) the new network has 1217 // higher priority, or 2) the old network is disconnected, this approach will introduce 1218 // a lot more complexities. 1219 final Network lostVcnNetwork = cellNetworkCb.waitForLost(); 1220 if (lostVcnNetwork != null) { 1221 assertEquals(vcnNetwork, lostVcnNetwork); 1222 } else { 1223 assertNull(mConnectivityManager.getNetworkCapabilities(vcnNetwork)); 1224 } 1225 } // Else already torn down, pass. 1226 } 1227 1228 @Test testVcnMigrationAfterNetworkDies()1229 public void testVcnMigrationAfterNetworkDies() throws Exception { 1230 final int subId = verifyAndGetValidDataSubId(); 1231 1232 try (TestNetworkWrapper testNetworkWrapper = 1233 createTestNetworkWrapper(true /* isMetered */, subId, LOCAL_ADDRESS)) { 1234 verifyUnderlyingCellAndRunTest(subId, (subGrp, cellNetwork, cellNetworkCb) -> { 1235 final VcnSetupResult vcnSetupResult = 1236 setupAndGetVcnNetwork(subGrp, cellNetwork, cellNetworkCb, testNetworkWrapper); 1237 1238 testNetworkWrapper.close(); 1239 testNetworkWrapper.vcnNetworkCallback.waitForLost(); 1240 1241 try (TestNetworkWrapper secondaryTestNetworkWrapper = 1242 createTestNetworkWrapper(true /* isMetered */, subId, LOCAL_ADDRESS)) { 1243 try { 1244 injectAndVerifyIkeMobikePackets(secondaryTestNetworkWrapper.ikeTunUtils); 1245 1246 clearVcnConfigsAndVerifyNetworkTeardown( 1247 subGrp, cellNetworkCb, vcnSetupResult.vcnNetwork); 1248 } finally { 1249 secondaryTestNetworkWrapper.close(); 1250 } 1251 } 1252 }); 1253 } 1254 } 1255 injectAndVerifyIkeMobikePackets(@onNull IkeTunUtils ikeTunUtils)1256 private void injectAndVerifyIkeMobikePackets(@NonNull IkeTunUtils ikeTunUtils) 1257 throws Exception { 1258 // Generated by forcing IKE to use Test Mode (RandomnessFactory#mIsTestModeEnabled) and 1259 // capturing IKE packets with a live server. To force the mobility event, use 1260 // IkeSession#setNetwork with the new desired Network. 1261 final String ikeUpdateSaResp = 1262 "46b8eca1e0d72a189b9f8e0158e1c0a52e202520000000020000007c29000060" 1263 + "a1fd35f112d92d1df19ce734f6edf56ccda1bfd44ef6de428a097e04d5b40b28" 1264 + "3897e42f23dd53e444dc6c676cf9a7d9d73bb3975d663ec351fb5ae4e56a55d8" 1265 + "cbcf376a3b99cc6fd858621cc78b3017d895e4309f09a444028dba85"; 1266 final String ikeCreateChildResp = 1267 "46b8eca1e0d72a189b9f8e0158e1c0a52e20242000000003000000cc210000b0" 1268 + "e6bb78203dbe2189806c5cecef5040b8c4c0253895c7c0acea6483a1f0f72425" 1269 + "77ab46e18d553329d4ae1bd31cf57eec6ec31ceb1f2ed6b1195cac98b4b97a25" 1270 + "115d14c414e44dba8ebbdaf502e43f98a09036bee0ea2a621176300874a3eae8" 1271 + "c988357255b4e5923928d335b0ef62a565333fae6a64c85ac30e7da34ceeade4" 1272 + "1a161bcad0b51f8209ee1fdaf53d50359ad6b986ecd4290c9f69a34c64ddc0eb" 1273 + "73b8f3231f3f4e057404c18d"; 1274 final String ikeDeleteChildResp = 1275 "46b8eca1e0d72a189b9f8e0158e1c0a52e202520000000040000004c2a000030" 1276 + "53d97806d48ce44e0d4e1adf1de36778f77c3823bfaf8186cc71d4dc73497099" 1277 + "a9049e7be8a2013affd56ab7"; 1278 1279 ikeTunUtils.awaitReqAndInjectResp( 1280 IKE_DETERMINISTIC_INITIATOR_SPI, 1281 2 /* expectedMsgId */, 1282 true /* expectedUseEncap */, 1283 ikeUpdateSaResp); 1284 1285 // If Kernel migration enabled, it will be used instead of MOBIKE-rekey 1286 // TODO (b/277939911): Decouple VCN CTS from IKE implementation behavior 1287 if (!mContext.getPackageManager() 1288 .hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNEL_MIGRATION)) { 1289 ikeTunUtils.awaitReqAndInjectResp( 1290 IKE_DETERMINISTIC_INITIATOR_SPI, 1291 3 /* expectedMsgId */, 1292 true /* expectedUseEncap */, 1293 ikeCreateChildResp); 1294 1295 ikeTunUtils.awaitReqAndInjectResp( 1296 IKE_DETERMINISTIC_INITIATOR_SPI, 1297 4 /* expectedMsgId */, 1298 true /* expectedUseEncap */, 1299 ikeDeleteChildResp); 1300 } 1301 } 1302 injectAndVerifyIkeDpdPackets( @onNull IkeTunUtils ikeTunUtils, PortPair localRemotePorts)1303 private void injectAndVerifyIkeDpdPackets( 1304 @NonNull IkeTunUtils ikeTunUtils, PortPair localRemotePorts) throws Exception { 1305 // Generated by forcing IKE to use Test Mode (RandomnessFactory#mIsTestModeEnabled) and 1306 // capturing IKE packets with a live server. 1307 final String ikeDpdRequestHex = 1308 "46b8eca1e0d72a189b9f8e0158e1c0a52E202500000000000000004c00000030" 1309 + "3A31D5FAC230FEA67246B0C1A049A28944C341301979EB7B52FC669274B77D5F" 1310 + "A6CFE8D768CF390536436D08"; 1311 1312 byte[] ikeDpdRequest = 1313 IkeTunUtils.buildIkePacket( 1314 REMOTE_ADDRESS, 1315 LOCAL_ADDRESS, 1316 localRemotePorts.dstPort, 1317 localRemotePorts.srcPort, 1318 true /* useEncap */, 1319 hexStringToByteArray(ikeDpdRequestHex)); 1320 1321 ikeTunUtils.injectPacket(ikeDpdRequest); 1322 ikeTunUtils.awaitResp( 1323 IKE_DETERMINISTIC_INITIATOR_SPI, 1324 0 /* expectedMsgId */, 1325 true /* expectedUseEncap */); 1326 } 1327 verifyVcnSafeModeTimeoutOnTestNetwork(int subId, long timeoutMillis)1328 private void verifyVcnSafeModeTimeoutOnTestNetwork(int subId, long timeoutMillis) 1329 throws Exception { 1330 try (TestNetworkWrapper testNetworkWrapper = 1331 createTestNetworkWrapper(true /* isMetered */, subId, LOCAL_ADDRESS)) { 1332 // Before the VCN starts, the test network should have NOT_VCN_MANAGED 1333 waitForExpectedUnderlyingNetworkWithCapabilities( 1334 testNetworkWrapper, 1335 true /* expectNotVcnManaged */, 1336 false /* expectNotMetered */, 1337 TestNetworkWrapper.NETWORK_CB_TIMEOUT_MS); 1338 verifyUnderlyingCellAndRunTest(subId, (subGrp, cellNetwork, cellNetworkCb) -> { 1339 final VcnSetupResult vcnSetupResult = 1340 setupAndGetVcnNetwork(subGrp, cellNetwork, cellNetworkCb, testNetworkWrapper); 1341 1342 // Once VCN starts, the test network should lose NOT_VCN_MANAGED 1343 waitForExpectedUnderlyingNetworkWithCapabilities( 1344 testNetworkWrapper, 1345 false /* expectNotVcnManaged */, 1346 false /* expectNotMetered */, 1347 TestNetworkWrapper.NETWORK_CB_TIMEOUT_MS); 1348 1349 // After VCN has started up, wait for safemode to kick in and expect the 1350 // underlying Test Network to regain NOT_VCN_MANAGED. 1351 waitForExpectedUnderlyingNetworkWithCapabilities( 1352 testNetworkWrapper, 1353 true /* expectNotVcnManaged */, 1354 false /* expectNotMetered */, 1355 timeoutMillis); 1356 1357 // Verify that VCN Network is also lost in safemode 1358 cellNetworkCb.waitForLostNetwork(vcnSetupResult.vcnNetwork); 1359 1360 verifyVcnStatus(subGrp, VCN_STATUS_CODE_SAFE_MODE); 1361 1362 mVcnManager.clearVcnConfig(subGrp); 1363 }); 1364 } 1365 } 1366 setSafeModeTimeoutForCarrier(int subId, int timeoutSeconds)1367 private void setSafeModeTimeoutForCarrier(int subId, int timeoutSeconds) { 1368 final PersistableBundle carrierConfig = new PersistableBundle(); 1369 carrierConfig.putInt(VcnManager.VCN_SAFE_MODE_TIMEOUT_SECONDS_KEY, timeoutSeconds); 1370 mCarrierConfigManager.overrideConfig(subId, carrierConfig); 1371 } 1372 1373 @Test testVcnSafeModeOnTestNetwork_defaultTimeout()1374 public void testVcnSafeModeOnTestNetwork_defaultTimeout() throws Exception { 1375 final int subId = verifyAndGetValidDataSubId(); 1376 verifyVcnSafeModeTimeoutOnTestNetwork(subId, SAFEMODE_TIMEOUT_MILLIS); 1377 } 1378 1379 @Test testVcnSafeModeOnTestNetwork_overrideTimeout()1380 public void testVcnSafeModeOnTestNetwork_overrideTimeout() throws Exception { 1381 final int subId = verifyAndGetValidDataSubId(); 1382 final int safeModeTimeoutSeconds = 5; 1383 final int gracePeriod = 5; 1384 1385 final PersistableBundle oldCarrierConfig = mCarrierConfigManager.getConfigForSubId(subId); 1386 setSafeModeTimeoutForCarrier(subId, safeModeTimeoutSeconds); 1387 1388 verifyVcnSafeModeTimeoutOnTestNetwork( 1389 subId, TimeUnit.SECONDS.toMillis(safeModeTimeoutSeconds + gracePeriod)); 1390 1391 mCarrierConfigManager.overrideConfig(subId, oldCarrierConfig); 1392 } 1393 verifyEnterSafeModeImmediately(VcnConfig vcnConfig, boolean isSafeModeExpected)1394 private void verifyEnterSafeModeImmediately(VcnConfig vcnConfig, boolean isSafeModeExpected) 1395 throws Exception { 1396 final int subId = verifyAndGetValidDataSubId(); 1397 final TestVcnStatusCallback callback = new TestVcnStatusCallback(); 1398 1399 // Override the safe mode timeout to be zero 1400 final PersistableBundle oldCarrierConfig = mCarrierConfigManager.getConfigForSubId(subId); 1401 setSafeModeTimeoutForCarrier(subId, 0); 1402 1403 try (TestNetworkWrapper testNetworkWrapper = 1404 createTestNetworkWrapper(true /* isMetered */, subId, LOCAL_ADDRESS)) { 1405 verifyUnderlyingCellAndRunTest(subId, (subGrp, cellNetwork, cellNetworkCb) -> { 1406 mVcnManager.registerVcnStatusCallback(subGrp, INLINE_EXECUTOR, callback); 1407 mVcnManager.setVcnConfig(subGrp, vcnConfig); 1408 1409 assertEquals( 1410 VCN_STATUS_CODE_NOT_CONFIGURED, callback.awaitOnStatusChanged()); 1411 assertEquals(VCN_STATUS_CODE_ACTIVE, callback.awaitOnStatusChanged()); 1412 1413 if (isSafeModeExpected) { 1414 assertEquals( 1415 VCN_STATUS_CODE_SAFE_MODE, callback.awaitOnStatusChanged()); 1416 } else { 1417 assertEquals( 1418 VCN_STATUS_CODE_AWAIT_TIMEOUT, callback.awaitOnStatusChanged()); 1419 } 1420 1421 mVcnManager.clearVcnConfig(subGrp); 1422 mVcnManager.unregisterVcnStatusCallback(callback); 1423 }); 1424 } 1425 1426 // Reset Carrier Config 1427 mCarrierConfigManager.overrideConfig(subId, oldCarrierConfig); 1428 } 1429 newVcnConfig(boolean isSafeModeEnabled)1430 private VcnConfig newVcnConfig(boolean isSafeModeEnabled) { 1431 final VcnGatewayConnectionConfig.Builder gatewayConfigBuilder = 1432 VcnGatewayConnectionConfigTest.buildVcnGatewayConnectionConfigBase() 1433 .addExposedCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 1434 1435 if (!isSafeModeEnabled) { 1436 gatewayConfigBuilder.setSafeModeEnabled(false); 1437 } 1438 // Don't call setSafeModeEnabled since enabling safe mode should not be flag gated 1439 1440 return new VcnConfig.Builder(mContext) 1441 .setIsTestModeProfile() 1442 .addGatewayConnectionConfig(gatewayConfigBuilder.build()) 1443 .build(); 1444 } 1445 1446 @Test testEnterSafeModeImmediately_safeModeEnabled()1447 public void testEnterSafeModeImmediately_safeModeEnabled() throws Exception { 1448 verifyEnterSafeModeImmediately( 1449 newVcnConfig(true /* isSafeModeEnabled */), true /* isSafeModeExpected */); 1450 } 1451 1452 @Test testEnterSafeModeImmediately_safeModeDisabled()1453 public void testEnterSafeModeImmediately_safeModeDisabled() throws Exception { 1454 verifyEnterSafeModeImmediately( 1455 newVcnConfig(false /* isSafeModeEnabled */), false /* isSafeModeExpected */); 1456 } 1457 } 1458