Implement Network policy in VcnManagementService.
This CL implements #getUnderlyingNetworkPolicy() for VcnManagementService. Specifically, it takes the provided NetworkCapabilities and checks for a corresponding VCN. If one exists, a VcnUnderlyingNetworkPolicy will be returned with a copy of the original NetworkCapabilities without the capability NOT_VCN_MANAGED and with the unwanted capability NOT_VCN_MANAGED. Any NetworkCapabilities without a corresponding VCN will be returned a VcnUnderlyingNetworkPolicy with the original NetworkCapabilities intact. Bug: 175914059 Test: atest FrameworksVcnTests Change-Id: Icdffc4f586f58a0e5b6290d5c6449e2bbed5cab0
This commit is contained in:
@@ -27,10 +27,12 @@ import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.TelephonyNetworkSpecifier;
|
||||
import android.net.vcn.IVcnManagementService;
|
||||
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
|
||||
import android.net.vcn.VcnConfig;
|
||||
import android.net.vcn.VcnUnderlyingNetworkPolicy;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
@@ -291,6 +293,12 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
@NonNull VcnConfig config) {
|
||||
return new Vcn(vcnContext, subscriptionGroup, config);
|
||||
}
|
||||
|
||||
/** Gets the subId indicated by the given {@link WifiInfo}. */
|
||||
public int getSubIdForWifiInfo(@NonNull WifiInfo wifiInfo) {
|
||||
// TODO(b/178501049): use the subId indicated by WifiInfo#getSubscriptionId
|
||||
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
}
|
||||
}
|
||||
|
||||
/** Notifies the VcnManagementService that external dependencies can be set up. */
|
||||
@@ -582,8 +590,36 @@ public class VcnManagementService extends IVcnManagementService.Stub {
|
||||
"Must have permission NETWORK_FACTORY or be the SystemServer to get underlying"
|
||||
+ " Network policies");
|
||||
|
||||
// TODO(b/175914059): implement policy generation once VcnManagementService is able to
|
||||
// determine policies
|
||||
// Defensive copy in case this call is in-process and the given NetworkCapabilities mutates
|
||||
networkCapabilities = new NetworkCapabilities(networkCapabilities);
|
||||
|
||||
int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|
||||
&& networkCapabilities.getNetworkSpecifier() instanceof TelephonyNetworkSpecifier) {
|
||||
TelephonyNetworkSpecifier telephonyNetworkSpecifier =
|
||||
(TelephonyNetworkSpecifier) networkCapabilities.getNetworkSpecifier();
|
||||
subId = telephonyNetworkSpecifier.getSubscriptionId();
|
||||
} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
|
||||
&& networkCapabilities.getTransportInfo() instanceof WifiInfo) {
|
||||
WifiInfo wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();
|
||||
subId = mDeps.getSubIdForWifiInfo(wifiInfo);
|
||||
}
|
||||
|
||||
boolean isVcnManagedNetwork = false;
|
||||
if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
synchronized (mLock) {
|
||||
ParcelUuid subGroup = mLastSnapshot.getGroupForSubId(subId);
|
||||
|
||||
// TODO(b/178140910): only mark the Network as VCN-managed if not in safe mode
|
||||
if (mVcns.containsKey(subGroup)) {
|
||||
isVcnManagedNetwork = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isVcnManagedNetwork) {
|
||||
networkCapabilities.removeCapability(
|
||||
NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
|
||||
}
|
||||
|
||||
return new VcnUnderlyingNetworkPolicy(false /* isTearDownRequested */, networkCapabilities);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import static com.android.server.vcn.VcnTestUtils.setupSystemService;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
@@ -30,6 +29,7 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyBoolean;
|
||||
import static org.mockito.Mockito.argThat;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
@@ -39,16 +39,20 @@ import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkCapabilities.Transport;
|
||||
import android.net.TelephonyNetworkSpecifier;
|
||||
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
|
||||
import android.net.vcn.VcnConfig;
|
||||
import android.net.vcn.VcnConfigTest;
|
||||
import android.net.vcn.VcnUnderlyingNetworkPolicy;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.os.IBinder;
|
||||
import android.os.ParcelUuid;
|
||||
import android.os.PersistableBundle;
|
||||
@@ -253,7 +257,14 @@ public class VcnManagementServiceTest {
|
||||
verify(mConfigReadWriteHelper).readFromDisk();
|
||||
}
|
||||
|
||||
private void triggerSubscriptionTrackerCallback(Set<ParcelUuid> activeSubscriptionGroups) {
|
||||
private TelephonySubscriptionSnapshot triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||
Set<ParcelUuid> activeSubscriptionGroups) {
|
||||
return triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||
activeSubscriptionGroups, Collections.emptyMap());
|
||||
}
|
||||
|
||||
private TelephonySubscriptionSnapshot triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||
Set<ParcelUuid> activeSubscriptionGroups, Map<Integer, ParcelUuid> subIdToGroupMap) {
|
||||
final TelephonySubscriptionSnapshot snapshot = mock(TelephonySubscriptionSnapshot.class);
|
||||
doReturn(activeSubscriptionGroups).when(snapshot).getActiveSubscriptionGroups();
|
||||
|
||||
@@ -267,8 +278,14 @@ public class VcnManagementServiceTest {
|
||||
argThat(val -> activeSubscriptionGroups.contains(val)),
|
||||
eq(TEST_PACKAGE_NAME));
|
||||
|
||||
doAnswer(invocation -> {
|
||||
return subIdToGroupMap.get(invocation.getArgument(0));
|
||||
}).when(snapshot).getGroupForSubId(anyInt());
|
||||
|
||||
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
||||
cb.onNewSnapshot(snapshot);
|
||||
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
private TelephonySubscriptionTrackerCallback getTelephonySubscriptionTrackerCallback() {
|
||||
@@ -287,7 +304,7 @@ public class VcnManagementServiceTest {
|
||||
|
||||
@Test
|
||||
public void testTelephonyNetworkTrackerCallbackStartsInstances() throws Exception {
|
||||
triggerSubscriptionTrackerCallback(Collections.singleton(TEST_UUID_1));
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_1));
|
||||
verify(mMockDeps).newVcn(eq(mVcnContext), eq(TEST_UUID_1), eq(TEST_VCN_CONFIG));
|
||||
}
|
||||
|
||||
@@ -296,7 +313,7 @@ public class VcnManagementServiceTest {
|
||||
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
|
||||
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_2);
|
||||
|
||||
triggerSubscriptionTrackerCallback(Collections.emptySet());
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.emptySet());
|
||||
|
||||
// Verify teardown after delay
|
||||
mTestLooper.moveTimeForward(VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
|
||||
@@ -311,13 +328,13 @@ public class VcnManagementServiceTest {
|
||||
final Vcn vcn = startAndGetVcnInstance(TEST_UUID_2);
|
||||
|
||||
// Simulate SIM unloaded
|
||||
triggerSubscriptionTrackerCallback(Collections.emptySet());
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.emptySet());
|
||||
|
||||
// Simulate new SIM loaded right during teardown delay.
|
||||
mTestLooper.moveTimeForward(
|
||||
VcnManagementService.CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS / 2);
|
||||
mTestLooper.dispatchAll();
|
||||
triggerSubscriptionTrackerCallback(Collections.singleton(TEST_UUID_2));
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(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);
|
||||
@@ -331,7 +348,7 @@ public class VcnManagementServiceTest {
|
||||
final Vcn oldInstance = startAndGetVcnInstance(TEST_UUID_2);
|
||||
|
||||
// Simulate SIM unloaded
|
||||
triggerSubscriptionTrackerCallback(Collections.emptySet());
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.emptySet());
|
||||
|
||||
// Config cleared, SIM reloaded & config re-added right before teardown delay, staring new
|
||||
// vcnInstance.
|
||||
@@ -496,14 +513,73 @@ public class VcnManagementServiceTest {
|
||||
mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
|
||||
}
|
||||
|
||||
private void setUpVcnSubscription(int subId, ParcelUuid subGroup) {
|
||||
mVcnMgmtSvc.setVcnConfig(subGroup, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(
|
||||
Collections.singleton(subGroup), Collections.singletonMap(subId, subGroup));
|
||||
}
|
||||
|
||||
private void verifyMergedNetworkCapabilities(
|
||||
NetworkCapabilities mergedCapabilities, @Transport int transportType) {
|
||||
assertTrue(mergedCapabilities.hasTransport(transportType));
|
||||
assertFalse(
|
||||
mergedCapabilities.hasCapability(
|
||||
NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicy() throws Exception {
|
||||
public void testGetUnderlyingNetworkPolicyTransportCell() throws Exception {
|
||||
setUpVcnSubscription(TEST_SUBSCRIPTION_ID, TEST_UUID_2);
|
||||
|
||||
NetworkCapabilities nc =
|
||||
new NetworkCapabilities.Builder()
|
||||
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
|
||||
.setNetworkSpecifier(new TelephonyNetworkSpecifier(TEST_SUBSCRIPTION_ID))
|
||||
.build();
|
||||
|
||||
VcnUnderlyingNetworkPolicy policy =
|
||||
mVcnMgmtSvc.getUnderlyingNetworkPolicy(
|
||||
new NetworkCapabilities(), new LinkProperties());
|
||||
mVcnMgmtSvc.getUnderlyingNetworkPolicy(nc, new LinkProperties());
|
||||
|
||||
assertFalse(policy.isTeardownRequested());
|
||||
assertNotNull(policy.getMergedNetworkCapabilities());
|
||||
verifyMergedNetworkCapabilities(
|
||||
policy.getMergedNetworkCapabilities(), NetworkCapabilities.TRANSPORT_CELLULAR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicyTransportWifi() throws Exception {
|
||||
setUpVcnSubscription(TEST_SUBSCRIPTION_ID, TEST_UUID_2);
|
||||
|
||||
WifiInfo wifiInfo = mock(WifiInfo.class);
|
||||
when(wifiInfo.makeCopy(anyBoolean())).thenReturn(wifiInfo);
|
||||
when(mMockDeps.getSubIdForWifiInfo(eq(wifiInfo))).thenReturn(TEST_SUBSCRIPTION_ID);
|
||||
NetworkCapabilities nc =
|
||||
new NetworkCapabilities.Builder()
|
||||
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
||||
.setTransportInfo(wifiInfo)
|
||||
.build();
|
||||
|
||||
VcnUnderlyingNetworkPolicy policy =
|
||||
mVcnMgmtSvc.getUnderlyingNetworkPolicy(nc, new LinkProperties());
|
||||
|
||||
assertFalse(policy.isTeardownRequested());
|
||||
verifyMergedNetworkCapabilities(
|
||||
policy.getMergedNetworkCapabilities(), NetworkCapabilities.TRANSPORT_WIFI);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnderlyingNetworkPolicyNonVcnNetwork() throws Exception {
|
||||
NetworkCapabilities nc =
|
||||
new NetworkCapabilities.Builder()
|
||||
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
|
||||
.setNetworkSpecifier(new TelephonyNetworkSpecifier(TEST_SUBSCRIPTION_ID))
|
||||
.build();
|
||||
|
||||
VcnUnderlyingNetworkPolicy policy =
|
||||
mVcnMgmtSvc.getUnderlyingNetworkPolicy(nc, new LinkProperties());
|
||||
|
||||
assertFalse(policy.isTeardownRequested());
|
||||
assertEquals(nc, policy.getMergedNetworkCapabilities());
|
||||
}
|
||||
|
||||
@Test(expected = SecurityException.class)
|
||||
|
||||
Reference in New Issue
Block a user