From d707e7f5ae9bf252d2e8fc5731304a0970b677e8 Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Mon, 30 Nov 2020 12:35:52 +0900 Subject: [PATCH] Do not query CS in NetworkProvider constructor ConnectivityService may not be available in a NetworkProvider constructor, if it is created (but still unused) before ConnectivityService starts. As ConnectivityManager is only necessary in declareNetworkRequestUnfulfillable, which should not be called often, just query ConnectivityManager at that point. This is necessary for VcnManagementService, which is started before ConnectivityService and creates its NetworkProvider in its constructor. Fortunately VcnManagementService does not call declareNetworkRequestUnfulfillable at this point. ConnectivityManager may be migrated to classic service getters that cache "null" when the service was not available the first time it is queried, so no system service must query it before it starts. Bug: 171540887 Test: atest FrameworksNetTests:NetworkProviderTest Change-Id: I8dadcd0e1360a9464192f330493e13aa69dd9fe2 --- core/java/android/net/NetworkProvider.java | 7 +++---- .../common/java/android/net/NetworkProviderTest.kt | 14 +++++++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/core/java/android/net/NetworkProvider.java b/core/java/android/net/NetworkProvider.java index d31218d9b6..726b899fc2 100644 --- a/core/java/android/net/NetworkProvider.java +++ b/core/java/android/net/NetworkProvider.java @@ -70,7 +70,7 @@ public class NetworkProvider { private final Messenger mMessenger; private final String mName; - private final ConnectivityManager mCm; + private final Context mContext; private int mProviderId = ID_NONE; @@ -85,8 +85,6 @@ public class NetworkProvider { */ @SystemApi public NetworkProvider(@NonNull Context context, @NonNull Looper looper, @NonNull String name) { - mCm = ConnectivityManager.from(context); - Handler handler = new Handler(looper) { @Override public void handleMessage(Message m) { @@ -102,6 +100,7 @@ public class NetworkProvider { } } }; + mContext = context; mMessenger = new Messenger(handler); mName = name; } @@ -165,6 +164,6 @@ public class NetworkProvider { @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) { - mCm.declareNetworkRequestUnfulfillable(request); + ConnectivityManager.from(mContext).declareNetworkRequestUnfulfillable(request); } } diff --git a/tests/net/common/java/android/net/NetworkProviderTest.kt b/tests/net/common/java/android/net/NetworkProviderTest.kt index dd3f5bebdb..77e9f12c71 100644 --- a/tests/net/common/java/android/net/NetworkProviderTest.kt +++ b/tests/net/common/java/android/net/NetworkProviderTest.kt @@ -33,6 +33,9 @@ import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mockito.Mockito.doReturn +import org.mockito.Mockito.mock +import org.mockito.Mockito.verifyNoMoreInteractions import java.util.UUID import kotlin.test.assertEquals import kotlin.test.assertNotEquals @@ -87,8 +90,8 @@ class NetworkProviderTest { ) = seenEvents.poll(DEFAULT_TIMEOUT_MS) { it is T && predicate(it) } } - private fun createNetworkProvider(): TestNetworkProvider { - return TestNetworkProvider(context, mHandlerThread.looper) + private fun createNetworkProvider(ctx: Context = context): TestNetworkProvider { + return TestNetworkProvider(ctx, mHandlerThread.looper) } @Test @@ -169,7 +172,12 @@ class NetworkProviderTest { @Test fun testDeclareNetworkRequestUnfulfillable() { - val provider = createNetworkProvider() + val mockContext = mock(Context::class.java) + val provider = createNetworkProvider(mockContext) + // ConnectivityManager not required at creation time + verifyNoMoreInteractions(mockContext) + doReturn(mCm).`when`(mockContext).getSystemService(Context.CONNECTIVITY_SERVICE) + mCm.registerNetworkProvider(provider) val specifier = StringNetworkSpecifier(UUID.randomUUID().toString())