Skip to content

Commit 3a8a004

Browse files
committed
[DO NOT MERGE] Revert "Remove VCN Carrier Privilege grace period"
This reverts commit fb4a590. This change brings back the grace period built in VCN because the carrier privileges grace period is turn off. Bug: 229418673 Test: atest FrameworksVcnTests CtsVcnTestCases Change-Id: I85738c969c2bf78da33beaebe5863432948b7735
1 parent 23ed66f commit 3a8a004

File tree

2 files changed

+137
-23
lines changed

2 files changed

+137
-23
lines changed

services/core/java/com/android/server/VcnManagementService.java

+44-16
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_INACTIVE;
2525
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED;
2626
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
27+
import static android.telephony.SubscriptionManager.isValidSubscriptionId;
2728

2829
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
2930
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionTrackerCallback;
@@ -167,6 +168,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
167168
static final String VCN_CONFIG_FILE =
168169
new File(Environment.getDataSystemDirectory(), "vcn/configs.xml").getPath();
169170

171+
// TODO(b/176956496): Directly use CarrierServiceBindHelper.UNBIND_DELAY_MILLIS
172+
@VisibleForTesting(visibility = Visibility.PRIVATE)
173+
static final long CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS = TimeUnit.SECONDS.toMillis(30);
174+
170175
/* Binder context for this service */
171176
@NonNull private final Context mContext;
172177
@NonNull private final Dependencies mDeps;
@@ -360,15 +365,12 @@ public LocationPermissionChecker newLocationPermissionChecker(@NonNull Context c
360365

361366
/** Notifies the VcnManagementService that external dependencies can be set up. */
362367
public void systemReady() {
363-
// Always run on the handler thread to ensure consistency.
364-
mHandler.post(() -> {
365-
mNetworkProvider.register();
366-
mContext.getSystemService(ConnectivityManager.class)
367-
.registerNetworkCallback(
368-
new NetworkRequest.Builder().clearCapabilities().build(),
369-
mTrackingNetworkCallback);
370-
mTelephonySubscriptionTracker.register();
371-
});
368+
mNetworkProvider.register();
369+
mContext.getSystemService(ConnectivityManager.class)
370+
.registerNetworkCallback(
371+
new NetworkRequest.Builder().clearCapabilities().build(),
372+
mTrackingNetworkCallback);
373+
mTelephonySubscriptionTracker.register();
372374
}
373375

374376
private void enforcePrimaryUser() {
@@ -509,15 +511,22 @@ && isActiveSubGroup(subGrp, snapshot)) {
509511
if (!mVcns.containsKey(subGrp)) {
510512
startVcnLocked(subGrp, entry.getValue());
511513
}
514+
515+
// Cancel any scheduled teardowns for active subscriptions
516+
mHandler.removeCallbacksAndMessages(mVcns.get(subGrp));
512517
}
513518
}
514519

515-
// Schedule teardown of any VCN instances that have lost carrier privileges
520+
// Schedule teardown of any VCN instances that have lost carrier privileges (after a
521+
// delay)
516522
for (Entry<ParcelUuid, Vcn> entry : mVcns.entrySet()) {
517523
final ParcelUuid subGrp = entry.getKey();
518524
final VcnConfig config = mConfigs.get(subGrp);
519525

520526
final boolean isActiveSubGrp = isActiveSubGroup(subGrp, snapshot);
527+
final boolean isValidActiveDataSubIdNotInVcnSubGrp =
528+
isValidSubscriptionId(snapshot.getActiveDataSubscriptionId())
529+
&& !isActiveSubGroup(subGrp, snapshot);
521530

522531
// TODO(b/193687515): Support multiple VCNs active at the same time
523532
if (config == null
@@ -527,12 +536,31 @@ && isActiveSubGroup(subGrp, snapshot)) {
527536
final ParcelUuid uuidToTeardown = subGrp;
528537
final Vcn instanceToTeardown = entry.getValue();
529538

530-
stopVcnLocked(uuidToTeardown);
531-
532-
// TODO(b/181789060): invoke asynchronously after Vcn notifies
533-
// through VcnCallback
534-
notifyAllPermissionedStatusCallbacksLocked(
535-
uuidToTeardown, VCN_STATUS_CODE_INACTIVE);
539+
// TODO(b/193687515): Support multiple VCNs active at the same time
540+
// If directly switching to a subscription not in the current group,
541+
// teardown immediately to prevent other subscription's network from being
542+
// outscored by the VCN. Otherwise, teardown after a delay to ensure that
543+
// SIM profile switches do not trigger the VCN to cycle.
544+
final long teardownDelayMs =
545+
isValidActiveDataSubIdNotInVcnSubGrp
546+
? 0
547+
: CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS;
548+
mHandler.postDelayed(() -> {
549+
synchronized (mLock) {
550+
// Guard against case where this is run after a old instance was
551+
// torn down, and a new instance was started. Verify to ensure
552+
// correct instance is torn down. This could happen as a result of a
553+
// Carrier App manually removing/adding a VcnConfig.
554+
if (mVcns.get(uuidToTeardown) == instanceToTeardown) {
555+
stopVcnLocked(uuidToTeardown);
556+
557+
// TODO(b/181789060): invoke asynchronously after Vcn notifies
558+
// through VcnCallback
559+
notifyAllPermissionedStatusCallbacksLocked(
560+
uuidToTeardown, VCN_STATUS_CODE_INACTIVE);
561+
}
562+
}
563+
}, instanceToTeardown, teardownDelayMs);
536564
} else {
537565
// If this VCN's status has not changed, update it with the new snapshot
538566
entry.getValue().updateSubscriptionSnapshot(mLastSnapshot);

tests/vcn/java/com/android/server/VcnManagementServiceTest.java

+93-7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
2424
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
2525
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
26+
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2627
import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2728
import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
2829

@@ -276,7 +277,6 @@ private void setupMockedCarrierPrivilege(boolean isPrivileged, String pkg) {
276277
@Test
277278
public void testSystemReady() throws Exception {
278279
mVcnMgmtSvc.systemReady();
279-
mTestLooper.dispatchAll();
280280

281281
verify(mConnMgr).registerNetworkProvider(any(VcnNetworkProvider.class));
282282
verify(mSubscriptionTracker).register();
@@ -494,8 +494,10 @@ public void testTelephonyNetworkTrackerCallbackStopsInstances() throws Exception
494494
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
495495

496496
triggerSubscriptionTrackerCbAndGetSnapshot(null, Collections.emptySet());
497-
mTestLooper.dispatchAll();
498497

498+
// Verify teardown after delay
499+
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
500+
mTestLooper.dispatchAll();
499501
verify(vcn).teardownAsynchronously();
500502
verify(mMockPolicyListener).onPolicyChanged();
501503
}
@@ -521,6 +523,92 @@ public void testTelephonyNetworkTrackerCallbackSwitchToNewSubscriptionImmediatel
521523
assertEquals(0, mVcnMgmtSvc.getAllVcns().size());
522524
}
523525

526+
/**
527+
* Tests an intermediate state where carrier privileges are marked as lost before active data
528+
* subId changes during a SIM ejection.
529+
*
530+
* <p>The expected outcome is that the VCN is torn down after a delay, as opposed to
531+
* immediately.
532+
*/
533+
@Test
534+
public void testTelephonyNetworkTrackerCallbackLostCarrierPrivilegesBeforeActiveDataSubChanges()
535+
throws Exception {
536+
setupActiveSubscription(TEST_UUID_2);
537+
538+
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
539+
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_2);
540+
541+
// Simulate privileges lost
542+
triggerSubscriptionTrackerCbAndGetSnapshot(
543+
TEST_SUBSCRIPTION_ID,
544+
TEST_UUID_2,
545+
Collections.emptySet(),
546+
Collections.emptyMap(),
547+
false /* hasCarrierPrivileges */);
548+
549+
// Verify teardown after delay
550+
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
551+
mTestLooper.dispatchAll();
552+
verify(vcn).teardownAsynchronously();
553+
}
554+
555+
@Test
556+
public void testTelephonyNetworkTrackerCallbackSimSwitchesDoNotKillVcnInstances()
557+
throws Exception {
558+
setupActiveSubscription(TEST_UUID_2);
559+
560+
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
561+
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_2);
562+
563+
// Simulate SIM unloaded
564+
triggerSubscriptionTrackerCbAndGetSnapshot(
565+
INVALID_SUBSCRIPTION_ID,
566+
null /* activeDataSubscriptionGroup */,
567+
Collections.emptySet(),
568+
Collections.emptyMap(),
569+
false /* hasCarrierPrivileges */);
570+
571+
// Simulate new SIM loaded right during teardown delay.
572+
mTestLooper.moveTimeForward(
573+
VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS / 2);
574+
mTestLooper.dispatchAll();
575+
triggerSubscriptionTrackerCbAndGetSnapshot(TEST_UUID_2, Collections.singleton(TEST_UUID_2));
576+
577+
// Verify that even after the full timeout duration, the VCN instance is not torn down
578+
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
579+
mTestLooper.dispatchAll();
580+
verify(vcn, never()).teardownAsynchronously();
581+
}
582+
583+
@Test
584+
public void testTelephonyNetworkTrackerCallbackDoesNotKillNewVcnInstances() throws Exception {
585+
setupActiveSubscription(TEST_UUID_2);
586+
587+
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
588+
final Vcn oldInstance = startAndGetVcnInstance(TEST_UUID_2);
589+
590+
// Simulate SIM unloaded
591+
triggerSubscriptionTrackerCbAndGetSnapshot(null, Collections.emptySet());
592+
593+
// Config cleared, SIM reloaded & config re-added right before teardown delay, staring new
594+
// vcnInstance.
595+
mTestLooper.moveTimeForward(
596+
VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS / 2);
597+
mTestLooper.dispatchAll();
598+
mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2, TEST_PACKAGE_NAME);
599+
triggerSubscriptionTrackerCbAndGetSnapshot(TEST_UUID_2, Collections.singleton(TEST_UUID_2));
600+
final Vcn newInstance = startAndGetVcnInstance(TEST_UUID_2);
601+
602+
// Verify that new instance was different, and the old one was torn down
603+
assertTrue(oldInstance != newInstance);
604+
verify(oldInstance).teardownAsynchronously();
605+
606+
// Verify that even after the full timeout duration, the new VCN instance is not torn down
607+
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
608+
mTestLooper.dispatchAll();
609+
verify(newInstance, never()).teardownAsynchronously();
610+
}
611+
524612
@Test
525613
public void testPackageChangeListenerRegistered() throws Exception {
526614
verify(mMockContext).registerReceiver(any(BroadcastReceiver.class), argThat(filter -> {
@@ -910,8 +998,6 @@ private void setupSubscriptionAndStartVcn(int subId, ParcelUuid subGrp, boolean
910998
private void setupSubscriptionAndStartVcn(
911999
int subId, ParcelUuid subGrp, boolean isVcnActive, boolean hasCarrierPrivileges) {
9121000
mVcnMgmtSvc.systemReady();
913-
mTestLooper.dispatchAll();
914-
9151001
triggerSubscriptionTrackerCbAndGetSnapshot(
9161002
subGrp,
9171003
Collections.singleton(subGrp),
@@ -1007,7 +1093,6 @@ public void testGetUnderlyingNetworkPolicyVcnWifi_safeMode() throws Exception {
10071093

10081094
private void setupTrackedCarrierWifiNetwork(NetworkCapabilities caps) {
10091095
mVcnMgmtSvc.systemReady();
1010-
mTestLooper.dispatchAll();
10111096

10121097
final ArgumentCaptor<NetworkCallback> captor =
10131098
ArgumentCaptor.forClass(NetworkCallback.class);
@@ -1252,14 +1337,15 @@ public void testRegisterVcnStatusCallback_VcnInactive() throws Exception {
12521337
true /* isActive */,
12531338
true /* hasCarrierPrivileges */);
12541339

1255-
// VCN is currently active. Lose carrier privileges for TEST_PACKAGE so the VCN goes
1256-
// inactive.
1340+
// VCN is currently active. Lose carrier privileges for TEST_PACKAGE and hit teardown
1341+
// timeout so the VCN goes inactive.
12571342
final TelephonySubscriptionSnapshot snapshot =
12581343
triggerSubscriptionTrackerCbAndGetSnapshot(
12591344
TEST_UUID_1,
12601345
Collections.singleton(TEST_UUID_1),
12611346
Collections.singletonMap(TEST_SUBSCRIPTION_ID, TEST_UUID_1),
12621347
false /* hasCarrierPrivileges */);
1348+
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
12631349
mTestLooper.dispatchAll();
12641350

12651351
// Giving TEST_PACKAGE privileges again will restart the VCN (which will indicate ACTIVE

0 commit comments

Comments
 (0)