From 2f5ae51d3f6f1df99fdeb8abdfd38f345e1b3660 Mon Sep 17 00:00:00 2001 From: Eric House Date: Tue, 29 Dec 2015 07:14:27 -0800 Subject: [PATCH] experimental change toward fixing networking stalls: when the cache thinks the network isn't up, check anyway. Probably needs to be done on a backoff timer so we aren't checking every few milliseconds.... --- .../eehouse/android/xw4/NetStateCache.java | 112 ++++++++++++------ 1 file changed, 74 insertions(+), 38 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetStateCache.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetStateCache.java index dea479421..b3f2091ae 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetStateCache.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetStateCache.java @@ -48,7 +48,7 @@ public class NetStateCache { private static boolean s_netAvail = false; private static boolean s_isWifi; private static PvtBroadcastReceiver s_receiver; - private static final boolean s_onSim = Build.PRODUCT.contains("sdk"); + private static final boolean s_onSDKSim = Build.PRODUCT.contains("sdk"); // not genymotion public static void register( Context context, StateChangedIf proc ) { @@ -69,7 +69,24 @@ public class NetStateCache { public static boolean netAvail( Context context ) { initIfNot( context ); - return s_netAvail || s_onSim; + + // Cache is returning false negatives. Don't trust it. + if ( !s_netAvail ) { + boolean netAvail = getIsConnected( context ); + if ( netAvail ) { + String msg = "netAvail(): second-guessing successful!!!"; + DbgUtils.logf( msg ); + Utils.showToast( context, msg ); + s_netAvail = true; + if ( null != s_receiver ) { + s_receiver.notifyStateChanged( context ); + } + } + } + + boolean result = s_netAvail || s_onSDKSim; + DbgUtils.logf( "netAvail() => %b", result ); + return result; } public static boolean onWifi() @@ -89,6 +106,19 @@ public class NetStateCache { } } + private static boolean getIsConnected( Context context ) + { + boolean result = false; + NetworkInfo ni = ((ConnectivityManager) + context.getSystemService( Context.CONNECTIVITY_SERVICE )) + .getActiveNetworkInfo(); + if ( null != ni && ni.isConnectedOrConnecting() ) { + result = true; + } + DbgUtils.logf( "NetStateCache.getConnected() => %b", result ); + return result; + } + private static void initIfNot( Context context ) { synchronized( s_haveReceiver ) { @@ -130,7 +160,7 @@ public class NetStateCache { } @Override - public void onReceive( final Context context, Intent intent ) + public void onReceive( Context context, Intent intent ) { DbgUtils.assertOnUIThread(); @@ -160,41 +190,7 @@ public class NetStateCache { if ( s_netAvail != netAvail ) { s_netAvail = netAvail; // keep current in case we're asked - - // We want to wait for WAIT_STABLE_MILLIS of inactivity - // before informing listeners. So each time there's a - // change, kill any existing timer then set another, which - // will only fire if we go that long without coming - // through here again. - - if ( null != mNotifyLater ) { - mHandler.removeCallbacks( mNotifyLater ); - mNotifyLater = null; - } - if ( mLastStateSent != s_netAvail ) { - mNotifyLater = new Runnable() { - @Override - public void run() { - Assert.assertTrue( mLastStateSent != s_netAvail ); - mLastStateSent = s_netAvail; - - synchronized( s_ifs ) { - Iterator iter = s_ifs.iterator(); - while ( iter.hasNext() ) { - iter.next().netAvail( s_netAvail ); - } - } - - if ( s_netAvail ) { - CommsConnType typ = CommsConnType - .COMMS_CONN_RELAY; - GameUtils.resendAllIf( context, typ, - false ); - } - } - }; - mHandler.postDelayed( mNotifyLater, WAIT_STABLE_MILLIS ); - } + notifyStateChanged( context ); } else { DbgUtils.logdf( "NetStateCache.PvtBroadcastReceiver.onReceive:" + " no change; doing nothing; s_netAvail=%b", @@ -202,6 +198,46 @@ public class NetStateCache { } } } + + public void notifyStateChanged( final Context context ) + { + // We want to wait for WAIT_STABLE_MILLIS of inactivity + // before informing listeners. So each time there's a + // change, kill any existing timer then set another, which + // will only fire if we go that long without coming + // through here again. + + if ( null != mNotifyLater ) { + mHandler.removeCallbacks( mNotifyLater ); + mNotifyLater = null; + } + if ( mLastStateSent != s_netAvail ) { + mNotifyLater = new Runnable() { + @Override + public void run() { + Assert.assertTrue( mLastStateSent != s_netAvail ); + mLastStateSent = s_netAvail; + + DbgUtils.logf( "NetStateCache.notifyStateChanged(%b)", + s_netAvail ); + + synchronized( s_ifs ) { + Iterator iter = s_ifs.iterator(); + while ( iter.hasNext() ) { + iter.next().netAvail( s_netAvail ); + } + } + + if ( s_netAvail ) { + CommsConnType typ = CommsConnType + .COMMS_CONN_RELAY; + GameUtils.resendAllIf( context, typ, false ); + } + } + }; + mHandler.postDelayed( mNotifyLater, WAIT_STABLE_MILLIS ); + } + } } // class PvtBroadcastReceiver }