mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-28 09:58:30 +01:00
code cleanup: make treads own their queue datastructures, use methods
to stop them, etc. Heading toward making it easier to detect when the BT stack is hosed and user needs to be warned or told to get a better phone.
This commit is contained in:
parent
3bda56420c
commit
ac2ac47aed
1 changed files with 127 additions and 90 deletions
|
@ -121,13 +121,12 @@ public class BTService extends Service {
|
|||
}
|
||||
|
||||
private BluetoothAdapter m_adapter;
|
||||
private LinkedBlockingQueue<BTQueueElem> m_queue;
|
||||
private static HashMap<String,String> s_names =
|
||||
new HashMap<String, String>();
|
||||
private static HashMap<String,int[]> s_devGames;
|
||||
private BTMsgSink m_btMsgSink;
|
||||
private Thread m_listener;
|
||||
private Thread m_sender;
|
||||
private BTListenerThread m_listener;
|
||||
private BTSenderThread m_sender;
|
||||
|
||||
public static boolean BTEnabled()
|
||||
{
|
||||
|
@ -221,7 +220,7 @@ public class BTService extends Service {
|
|||
int cmd = intent.getIntExtra( CMD_STR, -1 );
|
||||
DbgUtils.logf( "BTService.onStartCommand; cmd=%d", cmd );
|
||||
if ( -1 == cmd ) {
|
||||
} else if ( null == m_queue ) {
|
||||
} else if ( null == m_sender ) {
|
||||
DbgUtils.logf( "exiting: m_queue is null" );
|
||||
stopSelf();
|
||||
} else {
|
||||
|
@ -229,10 +228,10 @@ public class BTService extends Service {
|
|||
case -1:
|
||||
break;
|
||||
case PING:
|
||||
m_queue.add( new BTQueueElem( BTCmd.PING ) );
|
||||
m_sender.add( new BTQueueElem( BTCmd.PING ) );
|
||||
break;
|
||||
case SCAN:
|
||||
m_queue.add( new BTQueueElem( BTCmd.SCAN ) );
|
||||
m_sender.add( new BTQueueElem( BTCmd.SCAN ) );
|
||||
break;
|
||||
case INVITE:
|
||||
int gameID = intent.getIntExtra( GAMEID_STR, -1 );
|
||||
|
@ -241,7 +240,7 @@ public class BTService extends Service {
|
|||
int lang = intent.getIntExtra( LANG_STR, -1 );
|
||||
int nPlayersT = intent.getIntExtra( NTO_STR, -1 );
|
||||
int nPlayersH = intent.getIntExtra( NHE_STR, -1 );
|
||||
m_queue.add( new BTQueueElem( BTCmd.INVITE, target, addr,
|
||||
m_sender.add( new BTQueueElem( BTCmd.INVITE, target, addr,
|
||||
gameID, lang,
|
||||
nPlayersT, nPlayersH ) );
|
||||
break;
|
||||
|
@ -251,8 +250,7 @@ public class BTService extends Service {
|
|||
addr = intent.getStringExtra( ADDR_STR );
|
||||
gameID = intent.getIntExtra( GAMEID_STR, -1 );
|
||||
if ( -1 != gameID ) {
|
||||
Assert.assertNotNull( m_queue );
|
||||
m_queue.add( new BTQueueElem( BTCmd.MESG_SEND, buf, target,
|
||||
m_sender.add( new BTQueueElem( BTCmd.MESG_SEND, buf, target,
|
||||
addr, gameID ) );
|
||||
}
|
||||
break;
|
||||
|
@ -281,28 +279,28 @@ public class BTService extends Service {
|
|||
}
|
||||
|
||||
private class BTListenerThread extends Thread {
|
||||
private BluetoothServerSocket m_serverSocket;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
BluetoothServerSocket serverSocket;
|
||||
while ( m_adapter.isEnabled() ) {
|
||||
try {
|
||||
serverSocket = m_adapter.
|
||||
m_serverSocket = m_adapter.
|
||||
listenUsingRfcommWithServiceRecord( XWApp.getAppName(),
|
||||
XWApp.getAppUUID() );
|
||||
} catch ( java.io.IOException ioe ) {
|
||||
DbgUtils.logf( "listenUsingRfcommWithServiceRecord=>%s",
|
||||
ioe.toString() );
|
||||
serverSocket = null;
|
||||
continue;
|
||||
m_serverSocket = null;
|
||||
}
|
||||
|
||||
while ( null != m_serverSocket && m_adapter.isEnabled() ) {
|
||||
|
||||
BluetoothSocket socket = null;
|
||||
DataInputStream inStream = null;
|
||||
int nRead = 0;
|
||||
try {
|
||||
DbgUtils.logf( "run: calling accept(60000)" );
|
||||
socket = serverSocket.accept( 60000 ); // blocks
|
||||
socket = m_serverSocket.accept( 60000 ); // blocks
|
||||
addAddr( socket );
|
||||
DbgUtils.logf( "run: accept() returned" );
|
||||
inStream = new DataInputStream( socket.getInputStream() );
|
||||
|
@ -329,16 +327,27 @@ public class BTService extends Service {
|
|||
DbgUtils.logf( "trying again..." );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( null != serverSocket ) {
|
||||
if ( null != m_serverSocket ) {
|
||||
try {
|
||||
serverSocket.close();
|
||||
m_serverSocket.close();
|
||||
} catch ( java.io.IOException ioe ) {
|
||||
DbgUtils.logf( "close()=>%s", ioe.toString() );
|
||||
}
|
||||
serverSocket = null;
|
||||
m_serverSocket = null;
|
||||
}
|
||||
} // run()
|
||||
|
||||
public void stopListening()
|
||||
{
|
||||
try {
|
||||
m_serverSocket.close();
|
||||
} catch ( java.io.IOException ioe ) {
|
||||
DbgUtils.logf( "close()=>%s", ioe.toString() );
|
||||
}
|
||||
m_serverSocket = null;
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -347,27 +356,28 @@ public class BTService extends Service {
|
|||
Set<BluetoothDevice> pairedDevs = m_adapter.getBondedDevices();
|
||||
DbgUtils.logf( "ping: got %d paired devices", pairedDevs.size() );
|
||||
for ( BluetoothDevice dev : pairedDevs ) {
|
||||
boolean success = false;
|
||||
try {
|
||||
DbgUtils.logf( "PingThread: got socket to device %s",
|
||||
dev.getName() );
|
||||
BluetoothSocket socket =
|
||||
dev.createRfcommSocketToServiceRecord( XWApp.getAppUUID() );
|
||||
if ( null != socket ) {
|
||||
socket.connect();
|
||||
|
||||
DbgUtils.logf( "sendPings: connected" );
|
||||
DataOutputStream os =
|
||||
new DataOutputStream( socket.getOutputStream() );
|
||||
os.writeByte( BTCmd.PING.ordinal() );
|
||||
DbgUtils.logf( "sendPings: wrote" );
|
||||
DataOutputStream os = connect( socket, BTCmd.PING );
|
||||
if ( null != os ) {
|
||||
os.flush();
|
||||
Thread killer = killSocketIn( socket, 10 );
|
||||
|
||||
DataInputStream is =
|
||||
new DataInputStream( socket.getInputStream() );
|
||||
boolean success = BTCmd.PONG == BTCmd.values()[is.readByte()];
|
||||
success = BTCmd.PONG == BTCmd.values()[is.readByte()];
|
||||
killer.interrupt();
|
||||
}
|
||||
socket.close();
|
||||
}
|
||||
} catch ( java.io.IOException ioe ) {
|
||||
DbgUtils.logf( "sendPings: ioe: %s", ioe.toString() );
|
||||
}
|
||||
|
||||
if ( success ) {
|
||||
DbgUtils.logf( "got PONG from %s", dev.getName() );
|
||||
|
@ -377,10 +387,6 @@ public class BTService extends Service {
|
|||
}
|
||||
}
|
||||
}
|
||||
} catch ( java.io.IOException ioe ) {
|
||||
DbgUtils.logf( "sendPings: ioe: %s", ioe.toString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendInvite( BTQueueElem elem )
|
||||
|
@ -391,10 +397,9 @@ public class BTService extends Service {
|
|||
BluetoothSocket socket =
|
||||
dev.createRfcommSocketToServiceRecord( XWApp.getAppUUID() );
|
||||
if ( null != socket ) {
|
||||
socket.connect();
|
||||
DataOutputStream outStream =
|
||||
new DataOutputStream( socket.getOutputStream() );
|
||||
outStream.writeByte( BTCmd.INVITE.ordinal() );
|
||||
boolean success = false;
|
||||
DataOutputStream outStream = connect( socket, BTCmd.INVITE );
|
||||
if ( null != outStream ) {
|
||||
outStream.writeInt( elem.m_gameID );
|
||||
outStream.writeInt( elem.m_lang );
|
||||
outStream.writeInt( elem.m_nPlayersT );
|
||||
|
@ -403,10 +408,11 @@ public class BTService extends Service {
|
|||
|
||||
DataInputStream inStream =
|
||||
new DataInputStream( socket.getInputStream() );
|
||||
boolean success =
|
||||
BTCmd.INVITE_ACCPT == BTCmd.values()[inStream.readByte()];
|
||||
success = BTCmd.INVITE_ACCPT
|
||||
== BTCmd.values()[inStream.readByte()];
|
||||
DbgUtils.logf( "sendInvite(): invite done: success=%b",
|
||||
success );
|
||||
}
|
||||
socket.close();
|
||||
|
||||
BTEvent evt = success ? BTEvent.NEWGAME_SUCCESS
|
||||
|
@ -426,10 +432,8 @@ public class BTService extends Service {
|
|||
BluetoothSocket socket =
|
||||
dev.createRfcommSocketToServiceRecord( XWApp.getAppUUID() );
|
||||
if ( null != socket ) {
|
||||
socket.connect();
|
||||
DataOutputStream outStream =
|
||||
new DataOutputStream( socket.getOutputStream() );
|
||||
outStream.writeByte( BTCmd.MESG_SEND.ordinal() );
|
||||
DataOutputStream outStream = connect( socket, BTCmd.MESG_SEND );
|
||||
if ( null != outStream ) {
|
||||
outStream.writeInt( elem.m_gameID );
|
||||
|
||||
short len = (short)elem.m_msg.length;
|
||||
|
@ -444,6 +448,7 @@ public class BTService extends Service {
|
|||
success =
|
||||
BTCmd.MESG_ACCPT == BTCmd.values()[inStream.readByte()];
|
||||
killer.interrupt();
|
||||
}
|
||||
socket.close();
|
||||
}
|
||||
} catch ( java.io.IOException ioe ) {
|
||||
|
@ -497,6 +502,18 @@ public class BTService extends Service {
|
|||
}
|
||||
|
||||
private class BTSenderThread extends Thread {
|
||||
private LinkedBlockingQueue<BTQueueElem> m_queue;
|
||||
|
||||
public BTSenderThread( LinkedBlockingQueue<BTQueueElem> queue )
|
||||
{
|
||||
m_queue = queue;
|
||||
}
|
||||
|
||||
public void add( BTQueueElem elem )
|
||||
{
|
||||
m_queue.add( elem );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
|
@ -661,15 +678,16 @@ public class BTService extends Service {
|
|||
|
||||
private void startSender()
|
||||
{
|
||||
m_queue = new LinkedBlockingQueue<BTQueueElem>();
|
||||
m_sender = new BTSenderThread();
|
||||
LinkedBlockingQueue<BTQueueElem> queue =
|
||||
new LinkedBlockingQueue<BTQueueElem>();
|
||||
m_sender = new BTSenderThread( queue );
|
||||
m_sender.start();
|
||||
}
|
||||
|
||||
private void stopListener()
|
||||
{
|
||||
DbgUtils.logf( "stopListener..." );
|
||||
m_listener.interrupt();
|
||||
m_listener.stopListening();
|
||||
try {
|
||||
m_listener.join( 100 );
|
||||
} catch ( InterruptedException ie ) {
|
||||
|
@ -692,6 +710,26 @@ public class BTService extends Service {
|
|||
DbgUtils.logf( "stopSender done" );
|
||||
}
|
||||
|
||||
private DataOutputStream connect( BluetoothSocket socket, BTCmd cmd )
|
||||
{
|
||||
DbgUtils.logf( "connecting to %s to send %s",
|
||||
socket.getRemoteDevice().getName(), cmd.toString() );
|
||||
// Docs say always call cancelDiscovery before trying to connect
|
||||
m_adapter.cancelDiscovery();
|
||||
|
||||
DataOutputStream dos;
|
||||
try {
|
||||
socket.connect();
|
||||
dos = new DataOutputStream( socket.getOutputStream() );
|
||||
dos.writeByte( cmd.ordinal() );
|
||||
DbgUtils.logf( "connect successful" );
|
||||
} catch ( java.io.IOException ioe ) {
|
||||
DbgUtils.logf( "connect()=>%s", ioe.toString() );
|
||||
dos = null;
|
||||
}
|
||||
return dos;
|
||||
}
|
||||
|
||||
private Thread killSocketIn( final BluetoothSocket socket, int seconds )
|
||||
{
|
||||
final int millis = seconds * 1000;
|
||||
|
@ -721,8 +759,7 @@ public class BTService extends Service {
|
|||
public int transportSend( byte[] buf, final CommsAddrRec addr, int gameID )
|
||||
{
|
||||
Assert.assertNotNull( addr );
|
||||
Assert.assertNotNull( m_queue );
|
||||
m_queue.add( new BTQueueElem( BTCmd.MESG_SEND, buf,
|
||||
m_sender.add( new BTQueueElem( BTCmd.MESG_SEND, buf,
|
||||
addr.bt_hostName, addr.bt_btAddr,
|
||||
gameID ) );
|
||||
return buf.length;
|
||||
|
|
Loading…
Reference in a new issue