mirror of https://github.com/grpc/grpc-java.git
android: initialize listener with isConnected=false (#4606)
This commit is contained in:
parent
8c52e138ee
commit
27a1c900a9
|
|
@ -187,7 +187,15 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
connectivityManager =
|
connectivityManager =
|
||||||
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
try {
|
||||||
configureNetworkMonitoring();
|
configureNetworkMonitoring();
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
Log.w(
|
||||||
|
LOG_TAG,
|
||||||
|
"Failed to configure network monitoring. Does app have ACCESS_NETWORK_STATE"
|
||||||
|
+ " permission?",
|
||||||
|
e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
connectivityManager = null;
|
connectivityManager = null;
|
||||||
}
|
}
|
||||||
|
|
@ -195,29 +203,10 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi
|
||||||
|
|
||||||
@GuardedBy("lock")
|
@GuardedBy("lock")
|
||||||
private void configureNetworkMonitoring() {
|
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
|
// 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.
|
// default network. For earlier Android API levels, use the BroadcastReceiver API.
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && connectivityManager != null) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && connectivityManager != null) {
|
||||||
// The connection status may change before registration of the listener is complete, but
|
final DefaultNetworkCallback defaultNetworkCallback = new DefaultNetworkCallback();
|
||||||
// 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);
|
|
||||||
connectivityManager.registerDefaultNetworkCallback(defaultNetworkCallback);
|
connectivityManager.registerDefaultNetworkCallback(defaultNetworkCallback);
|
||||||
unregisterRunnable =
|
unregisterRunnable =
|
||||||
new Runnable() {
|
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+. */
|
/** Respond to changes in the default network. Only used on API levels 24+. */
|
||||||
@TargetApi(Build.VERSION_CODES.N)
|
@TargetApi(Build.VERSION_CODES.N)
|
||||||
private class DefaultNetworkCallback extends ConnectivityManager.NetworkCallback {
|
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 boolean isConnected = false;
|
||||||
|
|
||||||
private DefaultNetworkCallback(boolean isConnected) {
|
|
||||||
this.isConnected = isConnected;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAvailable(Network network) {
|
public void onAvailable(Network network) {
|
||||||
if (isConnected) {
|
if (isConnected) {
|
||||||
|
|
|
||||||
|
|
@ -256,15 +256,21 @@ public final class AndroidChannelBuilderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Config(sdk = 24)
|
@Config(sdk = 24)
|
||||||
public void newChannelWithConnection_entersIdleOnConnectionChange_api24() {
|
public void newChannelWithConnection_entersIdleOnSecondConnectionChange_api24() {
|
||||||
shadowConnectivityManager.setActiveNetworkInfo(MOBILE_CONNECTED);
|
shadowConnectivityManager.setActiveNetworkInfo(MOBILE_CONNECTED);
|
||||||
TestChannel delegateChannel = new TestChannel();
|
TestChannel delegateChannel = new TestChannel();
|
||||||
ManagedChannel androidChannel =
|
ManagedChannel androidChannel =
|
||||||
new AndroidChannelBuilder.AndroidChannel(
|
new AndroidChannelBuilder.AndroidChannel(
|
||||||
delegateChannel, RuntimeEnvironment.application.getApplicationContext());
|
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);
|
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);
|
assertThat(delegateChannel.enterIdleCount).isEqualTo(1);
|
||||||
|
|
||||||
androidChannel.shutdown();
|
androidChannel.shutdown();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue