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

Commit c3717844 authored by Benedict Wong's avatar Benedict Wong Committed by Jack Yu
Browse files

Honor NOT_RESTRICTED set by VCN policy

This change allows Telephony to honor the VCN's NOT_RESTRICTED policy,
for consistency with Wifi. This makes maintainance of the entire system
simpler.

In addition, this prevents apps that enumerate interfaces and networks,
binding and testing each, resulting in failures when usage of networks
is mutually exclusive (eg, some implementations of modems)

Bug: 202547696
Test: atest DataNetworkTest
Merged-In: I258ac3e203886c98bc201b1f896275893e351c5e
Change-Id: I258ac3e203886c98bc201b1f896275893e351c5e
parent 322b4a97
Loading
Loading
Loading
Loading
+14 −14
Original line number Diff line number Diff line
@@ -1670,7 +1670,9 @@ public class DataNetwork extends StateMachine {
        // Always start with NOT_VCN_MANAGED, then remove if VcnManager indicates this is part of a
        // VCN.
        builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
        if (isVcnManaged(builder.build())) {
        final VcnNetworkPolicyResult vcnPolicy = getVcnPolicy(builder.build());
        if (vcnPolicy != null && !vcnPolicy.getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)) {
            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
        }

@@ -1739,7 +1741,9 @@ public class DataNetwork extends StateMachine {

        // If one of the capabilities are for special use, for example, IMS, CBS, then this
        // network should be restricted, regardless data is enabled or not.
        if (NetworkCapabilitiesUtils.inferRestrictedCapability(builder.build())) {
        if (NetworkCapabilitiesUtils.inferRestrictedCapability(builder.build())
                || (vcnPolicy != null && !vcnPolicy.getNetworkCapabilities()
                        .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED))) {
            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
        }

@@ -2815,18 +2819,14 @@ public class DataNetwork extends StateMachine {
     * Check if the this data network is VCN-managed.
     *
     * @param networkCapabilities The network capabilities of this data network.
     * @return {@code true} if this data network is VCN-managed.
     */
    private boolean isVcnManaged(NetworkCapabilities networkCapabilities) {
        if (mVcnManager == null) return false;
        VcnNetworkPolicyResult policyResult =
                mVcnManager.applyVcnNetworkPolicy(networkCapabilities, getLinkProperties());

        // if the Network does have capability NOT_VCN_MANAGED, return false to indicate it's not
        // VCN-managed
        return !policyResult
                .getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
     * @return The VCN's policy for this DataNetwork.
     */
    private VcnNetworkPolicyResult getVcnPolicy(NetworkCapabilities networkCapabilities) {
        if (mVcnManager == null) {
            return null;
        }

        return mVcnManager.applyVcnNetworkPolicy(networkCapabilities, getLinkProperties());
    }

    /**
+12 −12
Original line number Diff line number Diff line
@@ -1974,9 +1974,15 @@ public class DataConnection extends StateMachine {
        // Always start with NOT_VCN_MANAGED, then remove if VcnManager indicates this is part of a
        // VCN.
        builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
        if (isVcnManaged(builder.build())) {
        final VcnNetworkPolicyResult vcnPolicy = getVcnPolicy(builder.build());
        if (!vcnPolicy.getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)) {
            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
        }
        if (!vcnPolicy.getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
        }

        return builder.build();
    }
@@ -2017,19 +2023,13 @@ public class DataConnection extends StateMachine {
    }

    /**
     * Returns whether the Network represented by this DataConnection is VCN-managed.
     * Check if the this data network is VCN-managed.
     *
     * <p>Determining if the Network is VCN-managed requires polling VcnManager.
     * @param networkCapabilities The network capabilities of this data network.
     * @return The VCN's policy for this DataNetwork.
     */
    private boolean isVcnManaged(NetworkCapabilities networkCapabilities) {
        VcnNetworkPolicyResult policyResult =
                mVcnManager.applyVcnNetworkPolicy(networkCapabilities, getLinkProperties());

        // if the Network does have capability NOT_VCN_MANAGED, return false to indicate it's not
        // VCN-managed
        return !policyResult
                .getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
    private VcnNetworkPolicyResult getVcnPolicy(NetworkCapabilities networkCapabilities) {
        return mVcnManager.applyVcnNetworkPolicy(networkCapabilities, getLinkProperties());
    }

    /** @return {@code true} if validation is required, {@code false} otherwise. */
+87 −4
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
@@ -34,6 +36,8 @@ import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener;
import android.net.vcn.VcnNetworkPolicyResult;
import android.os.AsyncResult;
import android.os.Looper;
import android.os.Message;
@@ -343,6 +347,12 @@ public class DataNetworkTest extends TelephonyTest {
                NetworkCapabilities.NET_CAPABILITY_SUPL)).isTrue();
        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
                NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)).isTrue();
        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
                NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)).isTrue();
        verify(mVcnManager, atLeastOnce()).applyVcnNetworkPolicy(
                argThat(caps -> caps.hasCapability(
                        NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)),
                any());

        verify(mDataNetworkCallback).onConnected(eq(mDataNetworkUT));
    }
@@ -673,6 +683,15 @@ public class DataNetworkTest extends TelephonyTest {

    @Test
    public void testAdminAndOwnerUids() throws Exception {
        doReturn(ADMIN_UID2).when(mCarrierPrivilegesTracker).getCarrierServicePackageUid();
        setupDataNetwork();

        assertThat(mDataNetworkUT.getNetworkCapabilities().getAdministratorUids()).asList()
                .containsExactly(ADMIN_UID1, ADMIN_UID2);
        assertThat(mDataNetworkUT.getNetworkCapabilities().getOwnerUid()).isEqualTo(ADMIN_UID2);
    }

    private void setupDataNetwork() throws Exception {
        DataNetworkController.NetworkRequestList
                networkRequestList = new DataNetworkController.NetworkRequestList();
        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
@@ -680,7 +699,6 @@ public class DataNetworkTest extends TelephonyTest {
                .build(), mPhone));

        setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123);
        doReturn(ADMIN_UID2).when(mCarrierPrivilegesTracker).getCarrierServicePackageUid();

        mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers,
                mInternetDataProfile, networkRequestList,
@@ -694,10 +712,75 @@ public class DataNetworkTest extends TelephonyTest {
        sendServiceStateChangedEvent(ServiceState.STATE_IN_SERVICE,
                ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
        processAllMessages();
    }

        assertThat(mDataNetworkUT.getNetworkCapabilities().getAdministratorUids()).asList()
                .containsExactly(ADMIN_UID1, ADMIN_UID2);
        assertThat(mDataNetworkUT.getNetworkCapabilities().getOwnerUid()).isEqualTo(ADMIN_UID2);
    @Test
    public void testVcnPolicy() throws Exception {
        doAnswer(invocation -> {
            NetworkCapabilities nc = invocation.getArgument(0);
            NetworkCapabilities policyNc = new NetworkCapabilities.Builder(nc)
                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
                    .build();

            return new VcnNetworkPolicyResult(
                    false /* isTearDownRequested */, policyNc);
        }).when(mVcnManager).applyVcnNetworkPolicy(any(), any());

        setupDataNetwork();

        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
                NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)).isFalse();
        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
                NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)).isFalse();
    }

    @Test
    public void testVcnPolicyUpdated() throws Exception {
        setupDataNetwork();

        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
                NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)).isTrue();
        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
                NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)).isTrue();

        doAnswer(invocation -> {
            NetworkCapabilities nc = invocation.getArgument(0);
            NetworkCapabilities policyNc = new NetworkCapabilities.Builder(nc)
                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
                    .build();

            return new VcnNetworkPolicyResult(
                    false /* isTearDownRequested */, policyNc);
        }).when(mVcnManager).applyVcnNetworkPolicy(any(), any());
        triggerVcnNetworkPolicyChanged();

        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
                NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)).isFalse();
    }

    @Test
    public void testVcnPolicyTeardownRequested() throws Exception {
        setupDataNetwork();

        doAnswer(invocation -> {
            NetworkCapabilities nc = invocation.getArgument(0);

            return new VcnNetworkPolicyResult(
                    true /* isTearDownRequested */, nc);
        }).when(mVcnManager).applyVcnNetworkPolicy(any(), any());
        triggerVcnNetworkPolicyChanged();

        assertThat(mDataNetworkUT.isConnected()).isFalse();
    }

    private void triggerVcnNetworkPolicyChanged() {
        ArgumentCaptor<VcnNetworkPolicyChangeListener> captor =
                ArgumentCaptor.forClass(VcnNetworkPolicyChangeListener.class);

        verify(mVcnManager).addVcnNetworkPolicyChangeListener(any(), captor.capture());
        captor.getValue().onPolicyChanged();
        processAllMessages();
    }

    @Test
+45 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.net.LinkProperties;
import android.net.NattKeepalivePacketData;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.vcn.VcnNetworkPolicyResult;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.HandlerThread;
@@ -783,6 +784,50 @@ public class DataConnectionTest extends TelephonyTest {
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
    }

    @Test
    @SmallTest
    public void testVcnNetworkCapability() throws Exception {
        mContextFixture.getCarrierConfigBundle().putStringArray(
                CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                new String[] { "default" });
        doReturn(mApn2).when(mApnContext).getApnSetting();

        doAnswer(invocation -> {
            NetworkCapabilities nc = invocation.getArgument(0);
            NetworkCapabilities policyNc = new NetworkCapabilities.Builder(nc)
                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
                    .build();

            return new VcnNetworkPolicyResult(
                    false /* isTearDownRequested */, policyNc);
        }).when(mVcnManager).applyVcnNetworkPolicy(any(), any());
        connectEvent(true);

        assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED));
        assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED));

        disconnectEvent();

        doAnswer(invocation -> {
            NetworkCapabilities nc = invocation.getArgument(0);
            NetworkCapabilities policyNc = new NetworkCapabilities.Builder(nc)
                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
                    .build();

            return new VcnNetworkPolicyResult(
                    false /* isTearDownRequested */, policyNc);
        }).when(mVcnManager).applyVcnNetworkPolicy(any(), any());
        connectEvent(true);

        assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED));
        assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED));
    }

    @Test
    @SmallTest
    public void testEnterpriseNetworkCapability() throws Exception {