Merge "Match underlying networks based on interface name" am: d7f3028003 am: b893544993

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2507856

Change-Id: Ibd3d14da4129b8dd510a60fbc27d30853fddde00
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Benedict Wong
2023-03-27 19:02:56 +00:00
committed by Automerger Merge Worker
2 changed files with 80 additions and 20 deletions

View File

@@ -1104,7 +1104,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
final NetworkCapabilities result = ncBuilder.build();
final VcnUnderlyingNetworkPolicy policy = new VcnUnderlyingNetworkPolicy(
mTrackingNetworkCallback
.requiresRestartForImmutableCapabilityChanges(result),
.requiresRestartForImmutableCapabilityChanges(result, linkProperties),
result);
logVdbg("getUnderlyingNetworkPolicy() called for caps: " + networkCapabilities
@@ -1354,19 +1354,29 @@ public class VcnManagementService extends IVcnManagementService.Stub {
* without requiring a Network restart.
*/
private class TrackingNetworkCallback extends ConnectivityManager.NetworkCallback {
private final Object mLockObject = new Object();
private final Map<Network, NetworkCapabilities> mCaps = new ArrayMap<>();
private final Map<Network, LinkProperties> mLinkProperties = new ArrayMap<>();
@Override
public void onCapabilitiesChanged(Network network, NetworkCapabilities caps) {
synchronized (mCaps) {
synchronized (mLockObject) {
mCaps.put(network, caps);
}
}
@Override
public void onLinkPropertiesChanged(Network network, LinkProperties lp) {
synchronized (mLockObject) {
mLinkProperties.put(network, lp);
}
}
@Override
public void onLost(Network network) {
synchronized (mCaps) {
synchronized (mLockObject) {
mCaps.remove(network);
mLinkProperties.remove(network);
}
}
@@ -1393,22 +1403,28 @@ public class VcnManagementService extends IVcnManagementService.Stub {
return true;
}
private boolean requiresRestartForImmutableCapabilityChanges(NetworkCapabilities caps) {
private boolean requiresRestartForImmutableCapabilityChanges(
NetworkCapabilities caps, LinkProperties lp) {
if (caps.getSubscriptionIds() == null) {
return false;
}
synchronized (mCaps) {
for (NetworkCapabilities existing : mCaps.values()) {
if (caps.getSubscriptionIds().equals(existing.getSubscriptionIds())
&& hasSameTransportsAndCapabilities(caps, existing)) {
// Restart if any immutable capabilities have changed
return existing.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
synchronized (mLockObject) {
// Search for an existing network (using interfce names)
// TODO: Get network from NetworkFactory (if exists) for this match.
for (Entry<Network, LinkProperties> lpEntry : mLinkProperties.entrySet()) {
if (lp.getInterfaceName() != null
&& !lp.getInterfaceName().isEmpty()
&& Objects.equals(
lp.getInterfaceName(), lpEntry.getValue().getInterfaceName())) {
return mCaps.get(lpEntry.getKey())
.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
!= caps.hasCapability(NET_CAPABILITY_NOT_RESTRICTED);
}
}
}
// If no network found, by definition does not need restart.
return false;
}

View File

@@ -17,7 +17,9 @@
package com.android.server;
import static android.net.ConnectivityManager.NetworkCallback;
import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
@@ -67,7 +69,6 @@ import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
import android.net.Uri;
import android.net.vcn.IVcnStatusCallback;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
@@ -128,6 +129,15 @@ public class VcnManagementServiceTest {
private static final VcnConfig TEST_VCN_CONFIG;
private static final VcnConfig TEST_VCN_CONFIG_PKG_2;
private static final int TEST_UID = Process.FIRST_APPLICATION_UID;
private static final String TEST_IFACE_NAME = "TEST_IFACE";
private static final String TEST_IFACE_NAME_2 = "TEST_IFACE2";
private static final LinkProperties TEST_LP_1 = new LinkProperties();
private static final LinkProperties TEST_LP_2 = new LinkProperties();
static {
TEST_LP_1.setInterfaceName(TEST_IFACE_NAME);
TEST_LP_2.setInterfaceName(TEST_IFACE_NAME_2);
}
static {
final Context mockConfigContext = mock(Context.class);
@@ -1034,8 +1044,7 @@ public class VcnManagementServiceTest {
setupSubscriptionAndStartVcn(subId, subGrp, isVcnActive);
return mVcnMgmtSvc.getUnderlyingNetworkPolicy(
getNetworkCapabilitiesBuilderForTransport(subId, transport).build(),
new LinkProperties());
getNetworkCapabilitiesBuilderForTransport(subId, transport).build(), TEST_LP_1);
}
private void checkGetRestrictedTransportsFromCarrierConfig(
@@ -1260,7 +1269,7 @@ public class VcnManagementServiceTest {
false /* expectRestricted */);
}
private void setupTrackedCarrierWifiNetwork(NetworkCapabilities caps) {
private void setupTrackedNetwork(NetworkCapabilities caps, LinkProperties lp) {
mVcnMgmtSvc.systemReady();
final ArgumentCaptor<NetworkCallback> captor =
@@ -1269,7 +1278,10 @@ public class VcnManagementServiceTest {
.registerNetworkCallback(
eq(new NetworkRequest.Builder().clearCapabilities().build()),
captor.capture());
captor.getValue().onCapabilitiesChanged(mock(Network.class, CALLS_REAL_METHODS), caps);
Network mockNetwork = mock(Network.class, CALLS_REAL_METHODS);
captor.getValue().onCapabilitiesChanged(mockNetwork, caps);
captor.getValue().onLinkPropertiesChanged(mockNetwork, lp);
}
@Test
@@ -1279,7 +1291,7 @@ public class VcnManagementServiceTest {
getNetworkCapabilitiesBuilderForTransport(TEST_SUBSCRIPTION_ID, TRANSPORT_WIFI)
.removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
.build();
setupTrackedCarrierWifiNetwork(existingNetworkCaps);
setupTrackedNetwork(existingNetworkCaps, TEST_LP_1);
// Trigger test without VCN instance alive; expect restart due to change of NOT_RESTRICTED
// immutable capability
@@ -1288,7 +1300,7 @@ public class VcnManagementServiceTest {
getNetworkCapabilitiesBuilderForTransport(
TEST_SUBSCRIPTION_ID, TRANSPORT_WIFI)
.build(),
new LinkProperties());
TEST_LP_1);
assertTrue(policy.isTeardownRequested());
}
@@ -1298,7 +1310,7 @@ public class VcnManagementServiceTest {
final NetworkCapabilities existingNetworkCaps =
getNetworkCapabilitiesBuilderForTransport(TEST_SUBSCRIPTION_ID, TRANSPORT_WIFI)
.build();
setupTrackedCarrierWifiNetwork(existingNetworkCaps);
setupTrackedNetwork(existingNetworkCaps, TEST_LP_1);
final VcnUnderlyingNetworkPolicy policy =
startVcnAndGetPolicyForTransport(
@@ -1315,7 +1327,7 @@ public class VcnManagementServiceTest {
.addCapability(NET_CAPABILITY_NOT_RESTRICTED)
.removeCapability(NET_CAPABILITY_IMS)
.build();
setupTrackedCarrierWifiNetwork(existingNetworkCaps);
setupTrackedNetwork(existingNetworkCaps, TEST_LP_1);
final VcnUnderlyingNetworkPolicy policy =
mVcnMgmtSvc.getUnderlyingNetworkPolicy(
@@ -1336,7 +1348,7 @@ public class VcnManagementServiceTest {
new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
.setNetworkSpecifier(new TelephonyNetworkSpecifier(TEST_SUBSCRIPTION_ID_2))
.setSubscriptionIds(Collections.singleton(TEST_SUBSCRIPTION_ID_2))
.build();
VcnUnderlyingNetworkPolicy policy =
@@ -1346,6 +1358,38 @@ public class VcnManagementServiceTest {
assertEquals(nc, policy.getMergedNetworkCapabilities());
}
/**
* Checks that networks with similar capabilities do not clobber each other.
*
* <p>In previous iterations, the VcnMgmtSvc used capability-matching to check if a network
* undergoing policy checks were the same as an existing networks. However, this meant that if
* there were newly added capabilities that the VCN did not check, two networks differing only
* by that capability would restart each other constantly.
*/
@Test
public void testGetUnderlyingNetworkPolicySimilarNetworks() throws Exception {
NetworkCapabilities nc1 =
new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
.addCapability(NET_CAPABILITY_INTERNET)
.setSubscriptionIds(Collections.singleton(TEST_SUBSCRIPTION_ID_2))
.build();
NetworkCapabilities nc2 =
new NetworkCapabilities.Builder(nc1)
.addCapability(NET_CAPABILITY_ENTERPRISE)
.removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
.build();
setupTrackedNetwork(nc1, TEST_LP_1);
VcnUnderlyingNetworkPolicy policy = mVcnMgmtSvc.getUnderlyingNetworkPolicy(nc2, TEST_LP_2);
assertFalse(policy.isTeardownRequested());
assertEquals(nc2, policy.getMergedNetworkCapabilities());
}
@Test(expected = SecurityException.class)
public void testGetUnderlyingNetworkPolicyInvalidPermission() {
doReturn(PackageManager.PERMISSION_DENIED)