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

Commit 7de2e844 authored by Cody Kesting's avatar Cody Kesting
Browse files

Allow system components to request underlying network policies.

This CL updates VcnManager to allow system components with permission
NETWORK_FACTORY to request the current VcnUnderlingNetworkPolicy for a
specific Network's NetworkCapabilities and LinkProperties.

Bug: 175900686
Test: atest FrameworksVcnTests
Change-Id: I16416e619bdb03630582f5660260b0090730e9eb
parent 6a5d57c2
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -16,8 +16,11 @@

package android.net.vcn;

import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
import android.net.vcn.VcnConfig;
import android.net.vcn.VcnUnderlyingNetworkPolicy;
import android.os.ParcelUuid;

/**
@@ -29,4 +32,5 @@ interface IVcnManagementService {

    void addVcnUnderlyingNetworkPolicyListener(in IVcnUnderlyingNetworkPolicyListener listener);
    void removeVcnUnderlyingNetworkPolicyListener(in IVcnUnderlyingNetworkPolicyListener listener);
    VcnUnderlyingNetworkPolicy getUnderlyingNetworkPolicy(in NetworkCapabilities nc, in LinkProperties lp);
}
+34 −1
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.content.Context;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -62,7 +64,7 @@ import java.util.concurrent.Executor;
 * @hide
 */
@SystemService(Context.VCN_MANAGEMENT_SERVICE)
public final class VcnManager {
public class VcnManager {
    @NonNull private static final String TAG = VcnManager.class.getSimpleName();

    /** @hide */
@@ -222,6 +224,37 @@ public final class VcnManager {
        }
    }

    /**
     * Queries the underlying network policy for a network with the given parameters.
     *
     * <p>Prior to a new NetworkAgent being registered, or upon notification that Carrier VCN policy
     * may have changed via {@link VcnUnderlyingNetworkPolicyListener#onPolicyChanged()}, a Network
     * Provider MUST poll for the updated Network policy based on that Network's capabilities and
     * properties.
     *
     * @param networkCapabilities the NetworkCapabilities to be used in determining the Network
     *     policy for this Network.
     * @param linkProperties the LinkProperties to be used in determining the Network policy for
     *     this Network.
     * @throws SecurityException if the caller does not have permission NETWORK_FACTORY
     * @return the VcnUnderlyingNetworkPolicy to be used for this Network.
     * @hide
     */
    @NonNull
    @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
    public VcnUnderlyingNetworkPolicy getUnderlyingNetworkPolicy(
            @NonNull NetworkCapabilities networkCapabilities,
            @NonNull LinkProperties linkProperties) {
        requireNonNull(networkCapabilities, "networkCapabilities must not be null");
        requireNonNull(linkProperties, "linkProperties must not be null");

        try {
            return mService.getUnderlyingNetworkPolicy(networkCapabilities, linkProperties);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Binder wrapper for added VcnUnderlyingNetworkPolicyListeners to receive signals from System
     * Server.
+27 −1
Original line number Diff line number Diff line
@@ -25,9 +25,12 @@ import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.net.vcn.IVcnManagementService;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
import android.net.vcn.VcnConfig;
import android.net.vcn.VcnUnderlyingNetworkPolicy;
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
@@ -527,7 +530,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
            @NonNull IVcnUnderlyingNetworkPolicyListener listener) {
        requireNonNull(listener, "listener was null");

        mContext.enforceCallingPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.NETWORK_FACTORY,
                "Must have permission NETWORK_FACTORY to register a policy listener");

@@ -561,4 +564,27 @@ public class VcnManagementService extends IVcnManagementService.Stub {
            }
        }
    }

    /**
     * Gets the UnderlyingNetworkPolicy as determined by the provided NetworkCapabilities and
     * LinkProperties.
     */
    @NonNull
    @Override
    public VcnUnderlyingNetworkPolicy getUnderlyingNetworkPolicy(
            @NonNull NetworkCapabilities networkCapabilities,
            @NonNull LinkProperties linkProperties) {
        requireNonNull(networkCapabilities, "networkCapabilities was null");
        requireNonNull(linkProperties, "linkProperties was null");

        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.NETWORK_FACTORY,
                "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

        return new VcnUnderlyingNetworkPolicy(false /* isTearDownRequested */, networkCapabilities);
    }
}
+29 −0
Original line number Diff line number Diff line
@@ -18,14 +18,19 @@ package android.net.vcn;

import static androidx.test.InstrumentationRegistry.getContext;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
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.content.Context;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.net.vcn.VcnManager.VcnUnderlyingNetworkPolicyListener;

import org.junit.Before;
@@ -103,4 +108,28 @@ public class VcnManagerTest {
    public void testRemoveVcnUnderlyingNetworkPolicyListenerNullListener() {
        mVcnManager.removeVcnUnderlyingNetworkPolicyListener(null);
    }

    @Test
    public void testGetUnderlyingNetworkPolicy() throws Exception {
        NetworkCapabilities nc = new NetworkCapabilities();
        LinkProperties lp = new LinkProperties();
        when(mMockVcnManagementService.getUnderlyingNetworkPolicy(eq(nc), eq(lp)))
                .thenReturn(new VcnUnderlyingNetworkPolicy(false /* isTearDownRequested */, nc));

        VcnUnderlyingNetworkPolicy policy = mVcnManager.getUnderlyingNetworkPolicy(nc, lp);

        assertFalse(policy.isTeardownRequested());
        assertEquals(nc, policy.getMergedNetworkCapabilities());
        verify(mMockVcnManagementService).getUnderlyingNetworkPolicy(eq(nc), eq(lp));
    }

    @Test(expected = NullPointerException.class)
    public void testGetUnderlyingNetworkPolicyNullNetworkCapabilities() throws Exception {
        mVcnManager.getUnderlyingNetworkPolicy(null, new LinkProperties());
    }

    @Test(expected = NullPointerException.class)
    public void testGetUnderlyingNetworkPolicyNullLinkProperties() throws Exception {
        mVcnManager.getUnderlyingNetworkPolicy(new NetworkCapabilities(), null);
    }
}
+36 −9
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubsc
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;
@@ -41,9 +43,12 @@ import static org.mockito.Mockito.verify;
import android.app.AppOpsManager;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
import android.net.vcn.VcnConfig;
import android.net.vcn.VcnConfigTest;
import android.net.vcn.VcnUnderlyingNetworkPolicy;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
@@ -63,6 +68,7 @@ import com.android.server.vcn.VcnContext;
import com.android.server.vcn.VcnNetworkProvider;
import com.android.server.vcn.util.PersistableBundleUtils;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -192,6 +198,14 @@ public class VcnManagementServiceTest {
        mTestLooper.dispatchAll();
    }

    @Before
    public void setUp() {
        doNothing()
                .when(mMockContext)
                .enforceCallingOrSelfPermission(
                        eq(android.Manifest.permission.NETWORK_FACTORY), any());
    }

    private void setupMockedCarrierPrivilege(boolean isPrivileged) {
        doReturn(Collections.singletonList(TEST_SUBSCRIPTION_INFO))
                .when(mSubMgr)
@@ -455,10 +469,6 @@ public class VcnManagementServiceTest {

    @Test
    public void testAddVcnUnderlyingNetworkPolicyListener() throws Exception {
        doNothing()
                .when(mMockContext)
                .enforceCallingPermission(eq(android.Manifest.permission.NETWORK_FACTORY), any());

        mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);

        verify(mMockIBinder).linkToDeath(any(), anyInt());
@@ -468,17 +478,14 @@ public class VcnManagementServiceTest {
    public void testAddVcnUnderlyingNetworkPolicyListenerInvalidPermission() {
        doThrow(new SecurityException())
                .when(mMockContext)
                .enforceCallingPermission(eq(android.Manifest.permission.NETWORK_FACTORY), any());
                .enforceCallingOrSelfPermission(
                        eq(android.Manifest.permission.NETWORK_FACTORY), any());

        mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
    }

    @Test
    public void testRemoveVcnUnderlyingNetworkPolicyListener() {
        // verify listener added
        doNothing()
                .when(mMockContext)
                .enforceCallingPermission(eq(android.Manifest.permission.NETWORK_FACTORY), any());
        mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);

        mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
@@ -488,4 +495,24 @@ public class VcnManagementServiceTest {
    public void testRemoveVcnUnderlyingNetworkPolicyListenerNeverRegistered() {
        mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
    }

    @Test
    public void testGetUnderlyingNetworkPolicy() throws Exception {
        VcnUnderlyingNetworkPolicy policy =
                mVcnMgmtSvc.getUnderlyingNetworkPolicy(
                        new NetworkCapabilities(), new LinkProperties());

        assertFalse(policy.isTeardownRequested());
        assertNotNull(policy.getMergedNetworkCapabilities());
    }

    @Test(expected = SecurityException.class)
    public void testGetUnderlyingNetworkPolicyInvalidPermission() {
        doThrow(new SecurityException())
                .when(mMockContext)
                .enforceCallingOrSelfPermission(
                        eq(android.Manifest.permission.NETWORK_FACTORY), any());

        mVcnMgmtSvc.getUnderlyingNetworkPolicy(new NetworkCapabilities(), new LinkProperties());
    }
}