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
This commit is contained in:
Cody Kesting
2020-12-17 13:57:41 -08:00
parent 6a5d57c2ee
commit 7de2e8443c
5 changed files with 130 additions and 11 deletions

View File

@@ -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);
}

View File

@@ -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.

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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());
}
}