move network state listener into own class so it can live longer than

a single game (keeping network state across games launches) and be
used by other network clients later.
This commit is contained in:
Andy2 2011-01-06 08:08:16 -08:00
parent d832ba6795
commit 99c26cc0e9
2 changed files with 142 additions and 48 deletions

View file

@ -30,14 +30,7 @@ import java.net.InetSocketAddress;
import java.util.Vector;
import java.util.Iterator;
import junit.framework.Assert;
import android.telephony.SmsManager;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.app.PendingIntent;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
@ -46,7 +39,8 @@ import org.eehouse.android.xw4.jni.*;
import org.eehouse.android.xw4.jni.JNIThread.*;
import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
public class CommsTransport implements TransportProcs {
public class CommsTransport implements TransportProcs,
NetStateCache.StateChangedIf {
public static final int DIALOG = 0;
public static final int DIALOG_RETRY = 1;
@ -84,8 +78,6 @@ public class CommsTransport implements TransportProcs {
private ByteBuffer m_bytesIn;
private Context m_context;
private BroadcastReceiver m_receiver;
private boolean m_netAvail = true;
// assembling inbound packet
private byte[] m_packetIn;
@ -100,7 +92,7 @@ public class CommsTransport implements TransportProcs {
m_buffersOut = new Vector<ByteBuffer>();
m_bytesIn = ByteBuffer.allocate( 2048 );
buildNetAvailReceiver();
NetStateCache.register( context, this );
}
public class CommsThread extends Thread {
@ -238,9 +230,15 @@ public class CommsTransport implements TransportProcs {
public void waitToStop()
{
waitToStopImpl();
if ( null != m_receiver ) {
m_context.unregisterReceiver( m_receiver );
m_receiver = null;
NetStateCache.unregister( m_context, this );
}
// NetStateCache.StateChangedIf interface
public void netAvail( boolean nowAvailable )
{
if ( !nowAvailable ) {
waitToStopImpl();
m_jniThread.handle( JNICmd.CMD_TRANSFAIL );
}
}
@ -332,39 +330,6 @@ public class CommsTransport implements TransportProcs {
}
}
private class CommsBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive( Context context, Intent intent )
{
if ( intent.getAction().
equals( ConnectivityManager.CONNECTIVITY_ACTION)) {
NetworkInfo ni = (NetworkInfo)intent.
getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
boolean netAvail = NetworkInfo.State.CONNECTED == ni.getState();
boolean netAvailDet = NetworkInfo.DetailedState.CONNECTED ==
ni.getDetailedState();
Utils.logf( "CommsTransport::onReceive: netAvail=%s;netAvailDet=%s",
netAvail?"true":"false", netAvailDet?"true":"false" );
m_netAvail = netAvail;
if ( !netAvail ) {
waitToStopImpl();
m_jniThread.handle( JNICmd.CMD_TRANSFAIL );
}
}
}
}
private void buildNetAvailReceiver()
{
m_receiver = new CommsBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction( ConnectivityManager.CONNECTIVITY_ACTION );
Intent intent = m_context.registerReceiver( m_receiver, filter );
}
private void waitToStopImpl()
{
m_done = true; // this is in a race!
@ -398,7 +363,7 @@ public class CommsTransport implements TransportProcs {
switch ( m_addr.conType ) {
case COMMS_CONN_RELAY:
if ( m_netAvail ) {
if ( NetStateCache.netAvail( m_context ) ) {
putOut( buf ); // add to queue
if ( null == m_thread ) {
m_thread = new CommsThread();

View file

@ -0,0 +1,129 @@
/* -*- compile-command: "cd ../../../../../; ant install"; -*- */
/*
* Copyright 2010 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.NetworkInfo;
import android.net.ConnectivityManager;
import java.util.HashSet;
import java.util.Iterator;
import junit.framework.Assert;
public class NetStateCache {
public interface StateChangedIf {
public void netAvail( boolean nowAvailable );
}
private static Boolean s_haveReceiver = new Boolean( false );
private static HashSet<StateChangedIf> s_ifs;
private static boolean s_netAvail = false;
private static CommsBroadcastReceiver s_receiver;
public static void register( Context context, StateChangedIf proc )
{
initIfNot( context );
synchronized( s_ifs ) {
s_ifs.add( proc );
}
}
public static void unregister( Context context, StateChangedIf proc )
{
initIfNot( context );
synchronized( s_ifs ) {
s_ifs.remove( proc );
}
}
public static boolean netAvail( Context context )
{
initIfNot( context );
return s_netAvail;
}
private static void initIfNot( Context context )
{
synchronized( s_haveReceiver ) {
if ( !s_haveReceiver ) {
// First figure out the current net state. Note that
// this doesn't seem to work on the emulator.
ConnectivityManager connMgr = (ConnectivityManager)
context.getSystemService( Context.CONNECTIVITY_SERVICE );
NetworkInfo ni = connMgr.getActiveNetworkInfo();
s_netAvail = null != ni &&
NetworkInfo.State.CONNECTED == ni.getState();
s_receiver = new CommsBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction( ConnectivityManager.CONNECTIVITY_ACTION );
Intent intent = context.registerReceiver( s_receiver, filter );
s_ifs = new HashSet<StateChangedIf>();
s_haveReceiver = true;
}
}
}
private static class CommsBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive( Context context, Intent intent )
{
if ( intent.getAction().
equals( ConnectivityManager.CONNECTIVITY_ACTION)) {
NetworkInfo ni = (NetworkInfo)intent.
getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
Utils.logf( "CommsTransport::onReceive: %s",
ni.getState().toString() );
boolean netAvail;
switch ( ni.getState() ) {
case CONNECTED:
netAvail = true;
break;
case DISCONNECTED:
netAvail = false;
break;
default:
// ignore everything else
netAvail = s_netAvail;
break;
}
if ( s_netAvail != netAvail ) {
Iterator<StateChangedIf> iter = s_ifs.iterator();
while ( iter.hasNext() ) {
StateChangedIf proc = iter.next();
proc.netAvail( netAvail );
}
s_netAvail = netAvail;
}
}
}
} // class CommsBroadcastReceiver
}