Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6047b6ba authored by Benedict Wong's avatar Benedict Wong Committed by Automerger Merge Worker
Browse files

Merge "Match underlying networks based on interface name" am: d7f30280 am: b8935449

parents aa6e3c62 b8935449
Loading
Loading
Loading
Loading
+26 −10
Original line number Diff line number Diff line
@@ -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;
        }

+54 −10
Original line number Diff line number Diff line
@@ -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)