Merge "[DO NOT MERGE] Revert "Remove VCN Carrier Privilege grace period"" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
715e111819
@@ -24,6 +24,7 @@ import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
|
||||
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_INACTIVE;
|
||||
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED;
|
||||
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
|
||||
import static android.telephony.SubscriptionManager.isValidSubscriptionId;
|
||||
|
||||
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
|
||||
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionTrackerCallback;
|
||||
@@ -167,6 +168,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
static final String VCN_CONFIG_FILE =
|
||||
new File(Environment.getDataSystemDirectory(), "vcn/configs.xml").getPath();
|
||||
|
||||
// TODO(b/176956496): Directly use CarrierServiceBindHelper.UNBIND_DELAY_MILLIS
|
||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||
static final long CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS = TimeUnit.SECONDS.toMillis(30);
|
||||
|
||||
/* Binder context for this service */
|
||||
@NonNull private final Context mContext;
|
||||
@NonNull private final Dependencies mDeps;
|
||||
@@ -360,15 +365,12 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
|
||||
/** Notifies the VcnManagementService that external dependencies can be set up. */
|
||||
public void systemReady() {
|
||||
// Always run on the handler thread to ensure consistency.
|
||||
mHandler.post(() -> {
|
||||
mNetworkProvider.register();
|
||||
mContext.getSystemService(ConnectivityManager.class)
|
||||
.registerNetworkCallback(
|
||||
new NetworkRequest.Builder().clearCapabilities().build(),
|
||||
mTrackingNetworkCallback);
|
||||
mTelephonySubscriptionTracker.register();
|
||||
});
|
||||
mNetworkProvider.register();
|
||||
mContext.getSystemService(ConnectivityManager.class)
|
||||
.registerNetworkCallback(
|
||||
new NetworkRequest.Builder().clearCapabilities().build(),
|
||||
mTrackingNetworkCallback);
|
||||
mTelephonySubscriptionTracker.register();
|
||||
}
|
||||
|
||||
private void enforcePrimaryUser() {
|
||||
@@ -509,15 +511,22 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
if (!mVcns.containsKey(subGrp)) {
|
||||
startVcnLocked(subGrp, entry.getValue());
|
||||
}
|
||||
|
||||
// Cancel any scheduled teardowns for active subscriptions
|
||||
mHandler.removeCallbacksAndMessages(mVcns.get(subGrp));
|
||||
}
|
||||
}
|
||||
|
||||
// Schedule teardown of any VCN instances that have lost carrier privileges
|
||||
// Schedule teardown of any VCN instances that have lost carrier privileges (after a
|
||||
// delay)
|
||||
for (Entry<ParcelUuid, Vcn> entry : mVcns.entrySet()) {
|
||||
final ParcelUuid subGrp = entry.getKey();
|
||||
final VcnConfig config = mConfigs.get(subGrp);
|
||||
|
||||
final boolean isActiveSubGrp = isActiveSubGroup(subGrp, snapshot);
|
||||
final boolean isValidActiveDataSubIdNotInVcnSubGrp =
|
||||
isValidSubscriptionId(snapshot.getActiveDataSubscriptionId())
|
||||
&& !isActiveSubGroup(subGrp, snapshot);
|
||||
|
||||
// TODO(b/193687515): Support multiple VCNs active at the same time
|
||||
if (config == null
|
||||
@@ -527,12 +536,31 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
final ParcelUuid uuidToTeardown = subGrp;
|
||||
final Vcn instanceToTeardown = entry.getValue();
|
||||
|
||||
stopVcnLocked(uuidToTeardown);
|
||||
// TODO(b/193687515): Support multiple VCNs active at the same time
|
||||
// If directly switching to a subscription not in the current group,
|
||||
// teardown immediately to prevent other subscription's network from being
|
||||
// outscored by the VCN. Otherwise, teardown after a delay to ensure that
|
||||
// SIM profile switches do not trigger the VCN to cycle.
|
||||
final long teardownDelayMs =
|
||||
isValidActiveDataSubIdNotInVcnSubGrp
|
||||
? 0
|
||||
: CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS;
|
||||
mHandler.postDelayed(() -> {
|
||||
synchronized (mLock) {
|
||||
// Guard against case where this is run after a old instance was
|
||||
// torn down, and a new instance was started. Verify to ensure
|
||||
// correct instance is torn down. This could happen as a result of a
|
||||
// Carrier App manually removing/adding a VcnConfig.
|
||||
if (mVcns.get(uuidToTeardown) == instanceToTeardown) {
|
||||
stopVcnLocked(uuidToTeardown);
|
||||
|
||||
// TODO(b/181789060): invoke asynchronously after Vcn notifies
|
||||
// through VcnCallback
|
||||
notifyAllPermissionedStatusCallbacksLocked(
|
||||
uuidToTeardown, VCN_STATUS_CODE_INACTIVE);
|
||||
// TODO(b/181789060): invoke asynchronously after Vcn notifies
|
||||
// through VcnCallback
|
||||
notifyAllPermissionedStatusCallbacksLocked(
|
||||
uuidToTeardown, VCN_STATUS_CODE_INACTIVE);
|
||||
}
|
||||
}
|
||||
}, instanceToTeardown, teardownDelayMs);
|
||||
} else {
|
||||
// If this VCN's status has not changed, update it with the new snapshot
|
||||
entry.getValue().updateSubscriptionSnapshot(mLastSnapshot);
|
||||
|
||||
@@ -23,6 +23,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
|
||||
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
|
||||
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
|
||||
import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
|
||||
|
||||
@@ -276,7 +277,6 @@ public class VcnManagementServiceTest {
|
||||
@Test
|
||||
public void testSystemReady() throws Exception {
|
||||
mVcnMgmtSvc.systemReady();
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
verify(mConnMgr).registerNetworkProvider(any(VcnNetworkProvider.class));
|
||||
verify(mSubscriptionTracker).register();
|
||||
@@ -494,8 +494,10 @@ public class VcnManagementServiceTest {
|
||||
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
||||
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(null, Collections.emptySet());
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
// Verify teardown after delay
|
||||
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
|
||||
mTestLooper.dispatchAll();
|
||||
verify(vcn).teardownAsynchronously();
|
||||
verify(mMockPolicyListener).onPolicyChanged();
|
||||
}
|
||||
@@ -521,6 +523,92 @@ public class VcnManagementServiceTest {
|
||||
assertEquals(0, mVcnMgmtSvc.getAllVcns().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests an intermediate state where carrier privileges are marked as lost before active data
|
||||
* subId changes during a SIM ejection.
|
||||
*
|
||||
* <p>The expected outcome is that the VCN is torn down after a delay, as opposed to
|
||||
* immediately.
|
||||
*/
|
||||
@Test
|
||||
public void testTelephonyNetworkTrackerCallbackLostCarrierPrivilegesBeforeActiveDataSubChanges()
|
||||
throws Exception {
|
||||
setupActiveSubscription(TEST_UUID_2);
|
||||
|
||||
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
||||
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_2);
|
||||
|
||||
// Simulate privileges lost
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||
TEST_SUBSCRIPTION_ID,
|
||||
TEST_UUID_2,
|
||||
Collections.emptySet(),
|
||||
Collections.emptyMap(),
|
||||
false /* hasCarrierPrivileges */);
|
||||
|
||||
// Verify teardown after delay
|
||||
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
|
||||
mTestLooper.dispatchAll();
|
||||
verify(vcn).teardownAsynchronously();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTelephonyNetworkTrackerCallbackSimSwitchesDoNotKillVcnInstances()
|
||||
throws Exception {
|
||||
setupActiveSubscription(TEST_UUID_2);
|
||||
|
||||
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
||||
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_2);
|
||||
|
||||
// Simulate SIM unloaded
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||
INVALID_SUBSCRIPTION_ID,
|
||||
null /* activeDataSubscriptionGroup */,
|
||||
Collections.emptySet(),
|
||||
Collections.emptyMap(),
|
||||
false /* hasCarrierPrivileges */);
|
||||
|
||||
// Simulate new SIM loaded right during teardown delay.
|
||||
mTestLooper.moveTimeForward(
|
||||
VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS / 2);
|
||||
mTestLooper.dispatchAll();
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(TEST_UUID_2, Collections.singleton(TEST_UUID_2));
|
||||
|
||||
// Verify that even after the full timeout duration, the VCN instance is not torn down
|
||||
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
|
||||
mTestLooper.dispatchAll();
|
||||
verify(vcn, never()).teardownAsynchronously();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTelephonyNetworkTrackerCallbackDoesNotKillNewVcnInstances() throws Exception {
|
||||
setupActiveSubscription(TEST_UUID_2);
|
||||
|
||||
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
||||
final Vcn oldInstance = startAndGetVcnInstance(TEST_UUID_2);
|
||||
|
||||
// Simulate SIM unloaded
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(null, Collections.emptySet());
|
||||
|
||||
// Config cleared, SIM reloaded & config re-added right before teardown delay, staring new
|
||||
// vcnInstance.
|
||||
mTestLooper.moveTimeForward(
|
||||
VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS / 2);
|
||||
mTestLooper.dispatchAll();
|
||||
mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2, TEST_PACKAGE_NAME);
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(TEST_UUID_2, Collections.singleton(TEST_UUID_2));
|
||||
final Vcn newInstance = startAndGetVcnInstance(TEST_UUID_2);
|
||||
|
||||
// Verify that new instance was different, and the old one was torn down
|
||||
assertTrue(oldInstance != newInstance);
|
||||
verify(oldInstance).teardownAsynchronously();
|
||||
|
||||
// Verify that even after the full timeout duration, the new VCN instance is not torn down
|
||||
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
|
||||
mTestLooper.dispatchAll();
|
||||
verify(newInstance, never()).teardownAsynchronously();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPackageChangeListenerRegistered() throws Exception {
|
||||
verify(mMockContext).registerReceiver(any(BroadcastReceiver.class), argThat(filter -> {
|
||||
@@ -910,8 +998,6 @@ public class VcnManagementServiceTest {
|
||||
private void setupSubscriptionAndStartVcn(
|
||||
int subId, ParcelUuid subGrp, boolean isVcnActive, boolean hasCarrierPrivileges) {
|
||||
mVcnMgmtSvc.systemReady();
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||
subGrp,
|
||||
Collections.singleton(subGrp),
|
||||
@@ -1007,7 +1093,6 @@ public class VcnManagementServiceTest {
|
||||
|
||||
private void setupTrackedCarrierWifiNetwork(NetworkCapabilities caps) {
|
||||
mVcnMgmtSvc.systemReady();
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
final ArgumentCaptor<NetworkCallback> captor =
|
||||
ArgumentCaptor.forClass(NetworkCallback.class);
|
||||
@@ -1252,14 +1337,15 @@ public class VcnManagementServiceTest {
|
||||
true /* isActive */,
|
||||
true /* hasCarrierPrivileges */);
|
||||
|
||||
// VCN is currently active. Lose carrier privileges for TEST_PACKAGE so the VCN goes
|
||||
// inactive.
|
||||
// VCN is currently active. Lose carrier privileges for TEST_PACKAGE and hit teardown
|
||||
// timeout so the VCN goes inactive.
|
||||
final TelephonySubscriptionSnapshot snapshot =
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||
TEST_UUID_1,
|
||||
Collections.singleton(TEST_UUID_1),
|
||||
Collections.singletonMap(TEST_SUBSCRIPTION_ID, TEST_UUID_1),
|
||||
false /* hasCarrierPrivileges */);
|
||||
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
// Giving TEST_PACKAGE privileges again will restart the VCN (which will indicate ACTIVE
|
||||
|
||||
Reference in New Issue
Block a user