Loading services/core/java/com/android/server/VcnManagementService.java +55 −6 Original line number Diff line number Diff line Loading @@ -31,16 +31,19 @@ import android.net.vcn.VcnConfig; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.ParcelUuid; import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.UserHandle; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; import com.android.internal.annotations.GuardedBy; Loading Loading @@ -155,6 +158,11 @@ public class VcnManagementService extends IVcnManagementService.Stub { @NonNull private final PersistableBundleUtils.LockingReadWriteHelper mConfigDiskRwHelper; @GuardedBy("mLock") @NonNull private final Map<IBinder, PolicyListenerBinderDeath> mRegisteredPolicyListeners = new ArrayMap<>(); @VisibleForTesting(visibility = Visibility.PRIVATE) VcnManagementService(@NonNull Context context, @NonNull Dependencies deps) { mContext = requireNonNull(context, "Missing context"); Loading Loading @@ -497,19 +505,60 @@ public class VcnManagementService extends IVcnManagementService.Stub { } } /** Binder death recipient used to remove a registered policy listener. */ private class PolicyListenerBinderDeath implements Binder.DeathRecipient { @NonNull private final IVcnUnderlyingNetworkPolicyListener mListener; PolicyListenerBinderDeath(@NonNull IVcnUnderlyingNetworkPolicyListener listener) { mListener = listener; } @Override public void binderDied() { Log.e(TAG, "app died without removing VcnUnderlyingNetworkPolicyListener"); removeVcnUnderlyingNetworkPolicyListener(mListener); } } /** Adds the provided listener for receiving VcnUnderlyingNetworkPolicy updates. */ @GuardedBy("mLock") @Override public void addVcnUnderlyingNetworkPolicyListener( IVcnUnderlyingNetworkPolicyListener listener) { // TODO(b/175739863): implement policy listener registration throw new UnsupportedOperationException("Not yet implemented"); @NonNull IVcnUnderlyingNetworkPolicyListener listener) { requireNonNull(listener, "listener was null"); mContext.enforceCallingPermission( android.Manifest.permission.NETWORK_FACTORY, "Must have permission NETWORK_FACTORY to register a policy listener"); PolicyListenerBinderDeath listenerBinderDeath = new PolicyListenerBinderDeath(listener); synchronized (mLock) { mRegisteredPolicyListeners.put(listener.asBinder(), listenerBinderDeath); try { listener.asBinder().linkToDeath(listenerBinderDeath, 0 /* flags */); } catch (RemoteException e) { // Remote binder already died - cleanup registered Listener listenerBinderDeath.binderDied(); } } } /** Removes the provided listener from receiving VcnUnderlyingNetworkPolicy updates. */ @GuardedBy("mLock") @Override public void removeVcnUnderlyingNetworkPolicyListener( IVcnUnderlyingNetworkPolicyListener listener) { // TODO(b/175739863): implement policy listener unregistration throw new UnsupportedOperationException("Not yet implemented"); @NonNull IVcnUnderlyingNetworkPolicyListener listener) { requireNonNull(listener, "listener was null"); synchronized (mLock) { PolicyListenerBinderDeath listenerBinderDeath = mRegisteredPolicyListeners.remove(listener.asBinder()); if (listenerBinderDeath != null) { listener.asBinder().unlinkToDeath(listenerBinderDeath, 0 /* flags */); } } } } tests/vcn/java/com/android/server/VcnManagementServiceTest.java +49 −0 Original line number Diff line number Diff line Loading @@ -23,10 +23,15 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.argThat; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; Loading @@ -35,8 +40,10 @@ import static org.mockito.Mockito.verify; import android.app.AppOpsManager; import android.content.Context; import android.net.ConnectivityManager; import android.net.vcn.IVcnUnderlyingNetworkPolicyListener; import android.net.vcn.VcnConfig; import android.net.vcn.VcnConfigTest; import android.os.IBinder; import android.os.ParcelUuid; import android.os.PersistableBundle; import android.os.Process; Loading Loading @@ -126,6 +133,10 @@ public class VcnManagementServiceTest { private final VcnManagementService mVcnMgmtSvc; private final IVcnUnderlyingNetworkPolicyListener mMockPolicyListener = mock(IVcnUnderlyingNetworkPolicyListener.class); private final IBinder mMockIBinder = mock(IBinder.class); public VcnManagementServiceTest() throws Exception { setupSystemService(mConnMgr, Context.CONNECTIVITY_SERVICE, ConnectivityManager.class); setupSystemService(mTelMgr, Context.TELEPHONY_SERVICE, TelephonyManager.class); Loading Loading @@ -169,6 +180,8 @@ public class VcnManagementServiceTest { setupMockedCarrierPrivilege(true); mVcnMgmtSvc = new VcnManagementService(mMockContext, mMockDeps); doReturn(mMockIBinder).when(mMockPolicyListener).asBinder(); // Make sure the profiles are loaded. mTestLooper.dispatchAll(); } Loading Loading @@ -438,4 +451,40 @@ public class VcnManagementServiceTest { mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2); verify(vcnInstance).teardownAsynchronously(); } @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()); } @Test(expected = SecurityException.class) public void testAddVcnUnderlyingNetworkPolicyListenerInvalidPermission() { doThrow(new SecurityException()) .when(mMockContext) .enforceCallingPermission(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); } @Test public void testRemoveVcnUnderlyingNetworkPolicyListenerNeverRegistered() { mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener); } } Loading
services/core/java/com/android/server/VcnManagementService.java +55 −6 Original line number Diff line number Diff line Loading @@ -31,16 +31,19 @@ import android.net.vcn.VcnConfig; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.ParcelUuid; import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.UserHandle; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; import com.android.internal.annotations.GuardedBy; Loading Loading @@ -155,6 +158,11 @@ public class VcnManagementService extends IVcnManagementService.Stub { @NonNull private final PersistableBundleUtils.LockingReadWriteHelper mConfigDiskRwHelper; @GuardedBy("mLock") @NonNull private final Map<IBinder, PolicyListenerBinderDeath> mRegisteredPolicyListeners = new ArrayMap<>(); @VisibleForTesting(visibility = Visibility.PRIVATE) VcnManagementService(@NonNull Context context, @NonNull Dependencies deps) { mContext = requireNonNull(context, "Missing context"); Loading Loading @@ -497,19 +505,60 @@ public class VcnManagementService extends IVcnManagementService.Stub { } } /** Binder death recipient used to remove a registered policy listener. */ private class PolicyListenerBinderDeath implements Binder.DeathRecipient { @NonNull private final IVcnUnderlyingNetworkPolicyListener mListener; PolicyListenerBinderDeath(@NonNull IVcnUnderlyingNetworkPolicyListener listener) { mListener = listener; } @Override public void binderDied() { Log.e(TAG, "app died without removing VcnUnderlyingNetworkPolicyListener"); removeVcnUnderlyingNetworkPolicyListener(mListener); } } /** Adds the provided listener for receiving VcnUnderlyingNetworkPolicy updates. */ @GuardedBy("mLock") @Override public void addVcnUnderlyingNetworkPolicyListener( IVcnUnderlyingNetworkPolicyListener listener) { // TODO(b/175739863): implement policy listener registration throw new UnsupportedOperationException("Not yet implemented"); @NonNull IVcnUnderlyingNetworkPolicyListener listener) { requireNonNull(listener, "listener was null"); mContext.enforceCallingPermission( android.Manifest.permission.NETWORK_FACTORY, "Must have permission NETWORK_FACTORY to register a policy listener"); PolicyListenerBinderDeath listenerBinderDeath = new PolicyListenerBinderDeath(listener); synchronized (mLock) { mRegisteredPolicyListeners.put(listener.asBinder(), listenerBinderDeath); try { listener.asBinder().linkToDeath(listenerBinderDeath, 0 /* flags */); } catch (RemoteException e) { // Remote binder already died - cleanup registered Listener listenerBinderDeath.binderDied(); } } } /** Removes the provided listener from receiving VcnUnderlyingNetworkPolicy updates. */ @GuardedBy("mLock") @Override public void removeVcnUnderlyingNetworkPolicyListener( IVcnUnderlyingNetworkPolicyListener listener) { // TODO(b/175739863): implement policy listener unregistration throw new UnsupportedOperationException("Not yet implemented"); @NonNull IVcnUnderlyingNetworkPolicyListener listener) { requireNonNull(listener, "listener was null"); synchronized (mLock) { PolicyListenerBinderDeath listenerBinderDeath = mRegisteredPolicyListeners.remove(listener.asBinder()); if (listenerBinderDeath != null) { listener.asBinder().unlinkToDeath(listenerBinderDeath, 0 /* flags */); } } } }
tests/vcn/java/com/android/server/VcnManagementServiceTest.java +49 −0 Original line number Diff line number Diff line Loading @@ -23,10 +23,15 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.argThat; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; Loading @@ -35,8 +40,10 @@ import static org.mockito.Mockito.verify; import android.app.AppOpsManager; import android.content.Context; import android.net.ConnectivityManager; import android.net.vcn.IVcnUnderlyingNetworkPolicyListener; import android.net.vcn.VcnConfig; import android.net.vcn.VcnConfigTest; import android.os.IBinder; import android.os.ParcelUuid; import android.os.PersistableBundle; import android.os.Process; Loading Loading @@ -126,6 +133,10 @@ public class VcnManagementServiceTest { private final VcnManagementService mVcnMgmtSvc; private final IVcnUnderlyingNetworkPolicyListener mMockPolicyListener = mock(IVcnUnderlyingNetworkPolicyListener.class); private final IBinder mMockIBinder = mock(IBinder.class); public VcnManagementServiceTest() throws Exception { setupSystemService(mConnMgr, Context.CONNECTIVITY_SERVICE, ConnectivityManager.class); setupSystemService(mTelMgr, Context.TELEPHONY_SERVICE, TelephonyManager.class); Loading Loading @@ -169,6 +180,8 @@ public class VcnManagementServiceTest { setupMockedCarrierPrivilege(true); mVcnMgmtSvc = new VcnManagementService(mMockContext, mMockDeps); doReturn(mMockIBinder).when(mMockPolicyListener).asBinder(); // Make sure the profiles are loaded. mTestLooper.dispatchAll(); } Loading Loading @@ -438,4 +451,40 @@ public class VcnManagementServiceTest { mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2); verify(vcnInstance).teardownAsynchronously(); } @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()); } @Test(expected = SecurityException.class) public void testAddVcnUnderlyingNetworkPolicyListenerInvalidPermission() { doThrow(new SecurityException()) .when(mMockContext) .enforceCallingPermission(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); } @Test public void testRemoveVcnUnderlyingNetworkPolicyListenerNeverRegistered() { mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener); } }