diff options
5 files changed, 130 insertions, 11 deletions
diff --git a/core/java/android/net/vcn/IVcnManagementService.aidl b/core/java/android/net/vcn/IVcnManagementService.aidl index 80ac64b87d4d..4f293eeb3c3b 100644 --- a/core/java/android/net/vcn/IVcnManagementService.aidl +++ b/core/java/android/net/vcn/IVcnManagementService.aidl @@ -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); } diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java index 2d0a6d74cb86..33beb6a9d188 100644 --- a/core/java/android/net/vcn/VcnManager.java +++ b/core/java/android/net/vcn/VcnManager.java @@ -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 */ @@ -223,6 +225,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. * diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java index 76db0192cb00..8562b0d9cb82 100644 --- a/services/core/java/com/android/server/VcnManagementService.java +++ b/services/core/java/com/android/server/VcnManagementService.java @@ -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); + } } diff --git a/tests/vcn/java/android/net/vcn/VcnManagerTest.java b/tests/vcn/java/android/net/vcn/VcnManagerTest.java index 9c6b7194af35..f9db408462b7 100644 --- a/tests/vcn/java/android/net/vcn/VcnManagerTest.java +++ b/tests/vcn/java/android/net/vcn/VcnManagerTest.java @@ -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); + } } diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java index f0cdde33f822..e26bf19488d0 100644 --- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java +++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java @@ -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()); + } } |