From ca4bf6edc3bf1080de3897617ffeb299119965ee Mon Sep 17 00:00:00 2001 From: Hugo Benichi Date: Fri, 3 Feb 2017 15:55:42 +0900 Subject: [PATCH] ConnectivityManager: no double NetworkCallback registration Test: new test in ConnectivityManagerTest Bug: 20701525 Change-Id: I205333d31d43e6e6c7fe704ce63b458065f345ce --- .../java/android/net/ConnectivityManager.java | 9 ++- .../android/net/ConnectivityManagerTest.java | 57 +++++++++++++++++-- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 30afdc2768..397e683d42 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -2884,11 +2884,14 @@ public class ConnectivityManager { if (callback == null) { throw new IllegalArgumentException("null NetworkCallback"); } - if (need == null && action != REQUEST) { + if ((need == null) && (action != REQUEST)) { throw new IllegalArgumentException("null NetworkCapabilities"); } - // TODO: throw an exception if callback.networkRequest is not null. - // http://b/20701525 + final int targetSdk = mContext.getApplicationInfo().targetSdkVersion; + if ((targetSdk > VERSION_CODES.N_MR1) && (callback.networkRequest != null)) { + // http://b/20701525 + throw new IllegalArgumentException("NetworkCallback already registered"); + } final NetworkRequest request; try { synchronized(sCallbacks) { diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java index b984bbfdda..684a101ed4 100644 --- a/tests/net/java/android/net/ConnectivityManagerTest.java +++ b/tests/net/java/android/net/ConnectivityManagerTest.java @@ -36,21 +36,36 @@ 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; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.when; -import android.net.ConnectivityManager; -import android.net.NetworkCapabilities; - +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.os.Build.VERSION_CODES; +import android.net.ConnectivityManager.NetworkCallback; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; -import org.junit.runner.RunWith; +import org.junit.Before; import org.junit.Test; - - +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) @SmallTest public class ConnectivityManagerTest { + + @Mock Context mCtx; + @Mock IConnectivityManager mService; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + static NetworkCapabilities verifyNetworkCapabilities( int legacyType, int transportType, int... capabilities) { final NetworkCapabilities nc = ConnectivityManager.networkCapabilitiesForType(legacyType); @@ -173,4 +188,34 @@ public class ConnectivityManagerTest { verifyUnrestrictedNetworkCapabilities( ConnectivityManager.TYPE_ETHERNET, TRANSPORT_ETHERNET); } + + @Test + public void testNoDoubleCallbackRegistration() throws Exception { + ConnectivityManager manager = new ConnectivityManager(mCtx, mService); + NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); + NetworkCallback callback = new ConnectivityManager.NetworkCallback(); + ApplicationInfo info = new ApplicationInfo(); + info.targetSdkVersion = VERSION_CODES.N_MR1 + 1; + + when(mCtx.getApplicationInfo()).thenReturn(info); + when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt())).thenReturn(request); + + manager.requestNetwork(request, callback); + + // Callback is already registered, reregistration should fail. + Class wantException = IllegalArgumentException.class; + expectThrowable(() -> manager.requestNetwork(request, callback), wantException); + } + + static void expectThrowable(Runnable block, Class throwableType) { + try { + block.run(); + } catch (Throwable t) { + if (t.getClass().equals(throwableType)) { + return; + } + fail("expected exception of type " + throwableType + ", but was " + t.getClass()); + } + fail("expected exception of type " + throwableType); + } }