Merge "Implement Policy Listener add/remove in VcnService." am: 59035bd8c7
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1532144 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: If6a3af9de981897cdd843f12d4c012da5929bc58
This commit is contained in:
@@ -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;
|
||||
@@ -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");
|
||||
@@ -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 */);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user