diff options
author | Eric Gribkoff <ericgribkoff@google.com> | 2018-06-30 09:24:47 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-30 09:24:47 -0700 |
commit | 27a1c900a9dd63be89d5bafbad314c071b26a849 (patch) | |
tree | 6f0bc96b7cd581685feaa192c9fc0d1e0a86f3d2 /android | |
parent | 8c52e138eeb9c040ca6197643db496749d65b580 (diff) | |
download | grpc-grpc-java-27a1c900a9dd63be89d5bafbad314c071b26a849.tar.gz |
android: initialize listener with isConnected=false (#4606)
Diffstat (limited to 'android')
-rw-r--r-- | android/src/main/java/io/grpc/android/AndroidChannelBuilder.java | 40 | ||||
-rw-r--r-- | android/src/test/java/io/grpc/android/AndroidChannelBuilderTest.java | 10 |
2 files changed, 23 insertions, 27 deletions
diff --git a/android/src/main/java/io/grpc/android/AndroidChannelBuilder.java b/android/src/main/java/io/grpc/android/AndroidChannelBuilder.java index 3a824e23f..4223e1577 100644 --- a/android/src/main/java/io/grpc/android/AndroidChannelBuilder.java +++ b/android/src/main/java/io/grpc/android/AndroidChannelBuilder.java @@ -187,7 +187,15 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi if (context != null) { connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - configureNetworkMonitoring(); + try { + configureNetworkMonitoring(); + } catch (SecurityException e) { + Log.w( + LOG_TAG, + "Failed to configure network monitoring. Does app have ACCESS_NETWORK_STATE" + + " permission?", + e); + } } else { connectivityManager = null; } @@ -195,29 +203,10 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi @GuardedBy("lock") private void configureNetworkMonitoring() { - // Eagerly check current network state to verify app has required permissions - NetworkInfo currentNetwork; - try { - currentNetwork = connectivityManager.getActiveNetworkInfo(); - } catch (SecurityException e) { - Log.w( - LOG_TAG, - "Failed to configure network monitoring. Does app have ACCESS_NETWORK_STATE" - + " permission?", - e); - return; - } - // Android N added the registerDefaultNetworkCallback API to listen to changes in the device's // default network. For earlier Android API levels, use the BroadcastReceiver API. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && connectivityManager != null) { - // The connection status may change before registration of the listener is complete, but - // this will at worst result in invoking resetConnectBackoff() instead of enterIdle() (or - // vice versa) on the first network change. - boolean isConnected = currentNetwork != null && currentNetwork.isConnected(); - - final DefaultNetworkCallback defaultNetworkCallback = - new DefaultNetworkCallback(isConnected); + final DefaultNetworkCallback defaultNetworkCallback = new DefaultNetworkCallback(); connectivityManager.registerDefaultNetworkCallback(defaultNetworkCallback); unregisterRunnable = new Runnable() { @@ -313,12 +302,13 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi /** Respond to changes in the default network. Only used on API levels 24+. */ @TargetApi(Build.VERSION_CODES.N) private class DefaultNetworkCallback extends ConnectivityManager.NetworkCallback { + // Registering a listener may immediate invoke onAvailable/onLost: the API docs do not specify + // if the methods are always invoked once, then again on any change, or only on change. When + // onAvailable() is invoked immediately without an actual network change, it's preferable to + // (spuriously) resetConnectBackoff() rather than enterIdle(), as the former is a no-op if the + // channel has already moved to CONNECTING. private boolean isConnected = false; - private DefaultNetworkCallback(boolean isConnected) { - this.isConnected = isConnected; - } - @Override public void onAvailable(Network network) { if (isConnected) { diff --git a/android/src/test/java/io/grpc/android/AndroidChannelBuilderTest.java b/android/src/test/java/io/grpc/android/AndroidChannelBuilderTest.java index 0477c34a0..db6be27ea 100644 --- a/android/src/test/java/io/grpc/android/AndroidChannelBuilderTest.java +++ b/android/src/test/java/io/grpc/android/AndroidChannelBuilderTest.java @@ -256,15 +256,21 @@ public final class AndroidChannelBuilderTest { @Test @Config(sdk = 24) - public void newChannelWithConnection_entersIdleOnConnectionChange_api24() { + public void newChannelWithConnection_entersIdleOnSecondConnectionChange_api24() { shadowConnectivityManager.setActiveNetworkInfo(MOBILE_CONNECTED); TestChannel delegateChannel = new TestChannel(); ManagedChannel androidChannel = new AndroidChannelBuilder.AndroidChannel( delegateChannel, RuntimeEnvironment.application.getApplicationContext()); + // The first onAvailable() may just signal that the device was connected when the callback is + // registered, rather than indicating a changed network, so we do not enter idle. shadowConnectivityManager.setActiveNetworkInfo(WIFI_CONNECTED); - assertThat(delegateChannel.resetCount).isEqualTo(0); + assertThat(delegateChannel.resetCount).isEqualTo(1); + assertThat(delegateChannel.enterIdleCount).isEqualTo(0); + + shadowConnectivityManager.setActiveNetworkInfo(MOBILE_CONNECTED); + assertThat(delegateChannel.resetCount).isEqualTo(1); assertThat(delegateChannel.enterIdleCount).isEqualTo(1); androidChannel.shutdown(); |