Merge "Allow system components to request underlying network policies."

This commit is contained in:
Cody Kesting
2021-01-29 18:58:00 +00:00
committed by Gerrit Code Review
5 changed files with 130 additions and 11 deletions

View File

@@ -16,8 +16,11 @@
package android.net.vcn; package android.net.vcn;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener; import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
import android.net.vcn.VcnConfig; import android.net.vcn.VcnConfig;
import android.net.vcn.VcnUnderlyingNetworkPolicy;
import android.os.ParcelUuid; import android.os.ParcelUuid;
/** /**
@@ -29,4 +32,5 @@ interface IVcnManagementService {
void addVcnUnderlyingNetworkPolicyListener(in IVcnUnderlyingNetworkPolicyListener listener); void addVcnUnderlyingNetworkPolicyListener(in IVcnUnderlyingNetworkPolicyListener listener);
void removeVcnUnderlyingNetworkPolicyListener(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.RequiresPermission;
import android.annotation.SystemService; import android.annotation.SystemService;
import android.content.Context; import android.content.Context;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.os.ParcelUuid; import android.os.ParcelUuid;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceSpecificException; import android.os.ServiceSpecificException;
@@ -62,7 +64,7 @@ import java.util.concurrent.Executor;
* @hide * @hide
*/ */
@SystemService(Context.VCN_MANAGEMENT_SERVICE) @SystemService(Context.VCN_MANAGEMENT_SERVICE)
public final class VcnManager { public class VcnManager {
@NonNull private static final String TAG = VcnManager.class.getSimpleName(); @NonNull private static final String TAG = VcnManager.class.getSimpleName();
/** @hide */ /** @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 * Binder wrapper for added VcnUnderlyingNetworkPolicyListeners to receive signals from System
* Server. * Server.

View File

@@ -25,9 +25,12 @@ import android.annotation.NonNull;
import android.app.AppOpsManager; import android.app.AppOpsManager;
import android.content.Context; import android.content.Context;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.net.vcn.IVcnManagementService; import android.net.vcn.IVcnManagementService;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener; import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
import android.net.vcn.VcnConfig; import android.net.vcn.VcnConfig;
import android.net.vcn.VcnUnderlyingNetworkPolicy;
import android.os.Binder; import android.os.Binder;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
@@ -527,7 +530,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
@NonNull IVcnUnderlyingNetworkPolicyListener listener) { @NonNull IVcnUnderlyingNetworkPolicyListener listener) {
requireNonNull(listener, "listener was null"); requireNonNull(listener, "listener was null");
mContext.enforceCallingPermission( mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.NETWORK_FACTORY, android.Manifest.permission.NETWORK_FACTORY,
"Must have permission NETWORK_FACTORY to register a policy listener"); "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 androidx.test.InstrumentationRegistry.getContext;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.net.vcn.VcnManager.VcnUnderlyingNetworkPolicyListener; import android.net.vcn.VcnManager.VcnUnderlyingNetworkPolicyListener;
import org.junit.Before; import org.junit.Before;
@@ -103,4 +108,28 @@ public class VcnManagerTest {
public void testRemoveVcnUnderlyingNetworkPolicyListenerNullListener() { public void testRemoveVcnUnderlyingNetworkPolicyListenerNullListener() {
mVcnManager.removeVcnUnderlyingNetworkPolicyListener(null); 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 com.android.server.vcn.VcnTestUtils.setupSystemService;
import static org.junit.Assert.assertEquals; 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.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
@@ -41,9 +43,12 @@ import static org.mockito.Mockito.verify;
import android.app.AppOpsManager; import android.app.AppOpsManager;
import android.content.Context; import android.content.Context;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener; import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
import android.net.vcn.VcnConfig; import android.net.vcn.VcnConfig;
import android.net.vcn.VcnConfigTest; import android.net.vcn.VcnConfigTest;
import android.net.vcn.VcnUnderlyingNetworkPolicy;
import android.os.IBinder; import android.os.IBinder;
import android.os.ParcelUuid; import android.os.ParcelUuid;
import android.os.PersistableBundle; 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.VcnNetworkProvider;
import com.android.server.vcn.util.PersistableBundleUtils; import com.android.server.vcn.util.PersistableBundleUtils;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
@@ -192,6 +198,14 @@ public class VcnManagementServiceTest {
mTestLooper.dispatchAll(); mTestLooper.dispatchAll();
} }
@Before
public void setUp() {
doNothing()
.when(mMockContext)
.enforceCallingOrSelfPermission(
eq(android.Manifest.permission.NETWORK_FACTORY), any());
}
private void setupMockedCarrierPrivilege(boolean isPrivileged) { private void setupMockedCarrierPrivilege(boolean isPrivileged) {
doReturn(Collections.singletonList(TEST_SUBSCRIPTION_INFO)) doReturn(Collections.singletonList(TEST_SUBSCRIPTION_INFO))
.when(mSubMgr) .when(mSubMgr)
@@ -455,10 +469,6 @@ public class VcnManagementServiceTest {
@Test @Test
public void testAddVcnUnderlyingNetworkPolicyListener() throws Exception { public void testAddVcnUnderlyingNetworkPolicyListener() throws Exception {
doNothing()
.when(mMockContext)
.enforceCallingPermission(eq(android.Manifest.permission.NETWORK_FACTORY), any());
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener); mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
verify(mMockIBinder).linkToDeath(any(), anyInt()); verify(mMockIBinder).linkToDeath(any(), anyInt());
@@ -468,17 +478,14 @@ public class VcnManagementServiceTest {
public void testAddVcnUnderlyingNetworkPolicyListenerInvalidPermission() { public void testAddVcnUnderlyingNetworkPolicyListenerInvalidPermission() {
doThrow(new SecurityException()) doThrow(new SecurityException())
.when(mMockContext) .when(mMockContext)
.enforceCallingPermission(eq(android.Manifest.permission.NETWORK_FACTORY), any()); .enforceCallingOrSelfPermission(
eq(android.Manifest.permission.NETWORK_FACTORY), any());
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener); mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
} }
@Test @Test
public void testRemoveVcnUnderlyingNetworkPolicyListener() { public void testRemoveVcnUnderlyingNetworkPolicyListener() {
// verify listener added
doNothing()
.when(mMockContext)
.enforceCallingPermission(eq(android.Manifest.permission.NETWORK_FACTORY), any());
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener); mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener); mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
@@ -488,4 +495,24 @@ public class VcnManagementServiceTest {
public void testRemoveVcnUnderlyingNetworkPolicyListenerNeverRegistered() { public void testRemoveVcnUnderlyingNetworkPolicyListenerNeverRegistered() {
mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener); 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());
}
} }