diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTService.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTService.java index 37f225d83..3d2f21d87 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTService.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTService.java @@ -55,6 +55,7 @@ import org.eehouse.android.xw4.jni.LastMoveInfo; import org.eehouse.android.xw4.jni.XwJNI; import org.eehouse.android.xw4.jni.JNIThread; import org.eehouse.android.xw4.loc.LocUtils; +import org.eehouse.android.xw4.XWService.ReceiveResult; import junit.framework.Assert; @@ -574,47 +575,20 @@ public class BTService extends XWService { BluetoothDevice host = socket.getRemoteDevice(); addAddr( host ); - // check if still here - long[] rowids = DBUtils.getRowIDsFor( BTService.this, - gameID ); - boolean haveGame = null != rowids && 0 < rowids.length; - BTCmd result = haveGame ? - BTCmd.MESG_ACCPT : BTCmd.MESG_GAMEGONE; + CommsAddrRec addr = new CommsAddrRec( host.getName(), + host.getAddress() ); + ReceiveResult rslt + = BTService.this.receiveMessage( BTService.this, gameID, + m_btMsgSink, buffer, addr ); + + BTCmd result = rslt == ReceiveResult.GAME_GONE ? + BTCmd.MESG_GAMEGONE : BTCmd.MESG_ACCPT; DataOutputStream os = new DataOutputStream( socket.getOutputStream() ); os.writeByte( result.ordinal() ); os.flush(); socket.close(); - - CommsAddrRec addr = new CommsAddrRec( host.getName(), - host.getAddress() ); - - boolean[] isLocalP = new boolean[1]; - for ( long rowid : rowids ) { - JNIThread jniThread = JNIThread.getRetained( rowid, false ); - boolean consumed = false; - if ( null != jniThread ) { - consumed = true; - jniThread.receive( buffer, addr ).release(); - } else if ( haveGame ) { - GameUtils.BackMoveResult bmr = - new GameUtils.BackMoveResult(); - if ( GameUtils.feedMessage( BTService.this, rowid, - buffer, addr, - m_btMsgSink, bmr, - isLocalP ) ) { - consumed = true; - GameUtils.postMoveNotification( BTService.this, - rowid, bmr, - isLocalP[0] ); - } - } - if ( !consumed ) { - DbgUtils.logf( "nobody took msg for gameID %X", - gameID ); - } - } } else { DbgUtils.logf( "receiveMessages: read only %d of %d bytes", nRead, len ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiMsgSink.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiMsgSink.java index a68675c36..45504cfd5 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiMsgSink.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiMsgSink.java @@ -50,7 +50,7 @@ public class MultiMsgSink implements TransportProcs { // rowID is used as token to identify game on relay. Anything that // uniquely identifies a game on a device would work public long getRowID() { return m_rowid; }; - public void setRowID( long rowID ) { m_rowid = rowID; }; + public MultiMsgSink setRowID( long rowID ) { m_rowid = rowID; return this; }; // These will be overridden by e.g. BTService which for sendViaBluetooth() // can just insert a message into its queue diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayService.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayService.java index 490b88657..bc56f81f5 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayService.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayService.java @@ -317,6 +317,12 @@ public class RelayService extends XWService return intent; } + @Override + protected MultiMsgSink getSink( long rowid ) + { + return new RelayMsgSink().setRowID( rowid ); + } + @Override public void onCreate() { @@ -400,7 +406,7 @@ public class RelayService extends XWService String relayID = intent.getStringExtra( RELAY_ID ); sendNoConnMessage( rowid, relayID, msg ); } else { - feedMessage( rowid, msg ); + receiveMessage( this, rowid, null, msg, s_addr ); } break; case INVITE: @@ -996,28 +1002,6 @@ public class RelayService extends XWService return devid; } - private void feedMessage( long rowid, byte[] msg ) - { - DbgUtils.logdf( "RelayService::feedMessage: %d bytes for rowid %d", - msg.length, rowid ); - JNIThread jniThread = JNIThread.getRetained( rowid, false ); - if ( null != jniThread ) { - jniThread.receive( msg, s_addr ).release(); - DbgUtils.logdf( "RelayService.feedMessage(): jniThread.receive() ate it" ); - } else { - RelayMsgSink sink = new RelayMsgSink(); - sink.setRowID( rowid ); - BackMoveResult bmr = new BackMoveResult(); - boolean[] isLocalP = new boolean[1]; - if ( GameUtils.feedMessage( this, rowid, msg, s_addr, - sink, bmr, isLocalP ) ) { - GameUtils.postMoveNotification( this, rowid, bmr, isLocalP[0] ); - } else { - DbgUtils.logdf( "feedMessage(): background dropped it" ); - } - } - } - private void fetchAndProcess() { long[][] rowIDss = new long[1][]; @@ -1041,45 +1025,14 @@ public class RelayService extends XWService boolean[] isLocalP = new boolean[1]; for ( int ii = 0; ii < nameCount; ++ii ) { byte[][] forOne = msgs[ii]; - - // if game has messages, open it and feed 'em to it. if ( null != forOne ) { - BackMoveResult bmr = new BackMoveResult(); long rowid = rowIDs[ii]; sink.setRowID( rowid ); - // since BoardDelegate.feedMessages can't know: - isLocalP[0] = false; - boolean delivered = true; - - JNIThread jniThread = JNIThread.getRetained( rowid, false ); - if ( null != jniThread ) { - for ( byte[] msg : forOne ) { - jniThread.receive( msg, s_addr ); - } - jniThread.release(); - } else if ( GameUtils.feedMessages( this, rowid, forOne, s_addr, - sink, bmr, isLocalP ) ) { - } else { - delivered = false; - } - - if ( delivered ) { - idsWMsgs.add( relayIDs[ii] ); - bmrs.add( bmr ); - isLocals.add( isLocalP[0] ); - } else { - DbgUtils.logf( "RelayService.process(): message for %s (rowid %d)" - + " not consumed", relayIDs[ii], rowid ); + for ( byte[] msg : forOne ) { + receiveMessage( this, rowid, sink, msg, s_addr ); } } } - if ( 0 < idsWMsgs.size() ) { - String[] tmp = new String[idsWMsgs.size()]; - idsWMsgs.toArray( tmp ); - BackMoveResult[] bmrsa = new BackMoveResult[bmrs.size()]; - bmrs.toArray( bmrsa ); - setupNotifications( tmp, bmrsa, isLocals ); - } sink.send( this ); } } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSService.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSService.java index d390705f3..a69d4c1d0 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSService.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSService.java @@ -55,6 +55,7 @@ import java.util.Set; import junit.framework.Assert; +import org.eehouse.android.xw4.XWService.ReceiveResult; import org.eehouse.android.xw4.GameUtils.BackMoveResult; import org.eehouse.android.xw4.MultiService.DictFetchOwner; import org.eehouse.android.xw4.MultiService.MultiEvent; @@ -288,6 +289,12 @@ public class SMSService extends XWService { return s_showToasts; } + @Override // abstract + protected MultiMsgSink getSink( long rowid ) + { + return new SMSMsgSink( this ); + } + @Override public void onCreate() { @@ -704,25 +711,9 @@ public class SMSService extends XWService { private void feedMessage( int gameID, byte[] msg, CommsAddrRec addr ) { - long[] rowids = DBUtils.getRowIDsFor( this, gameID ); - if ( null == rowids || 0 == rowids.length ) { + ReceiveResult rslt = receiveMessage( this, gameID, null, msg, addr ); + if ( ReceiveResult.GAME_GONE == rslt ) { sendDiedPacket( addr.sms_phone, gameID ); - } else { - boolean[] isLocalP = new boolean[1]; - for ( long rowid : rowids ) { - JNIThread jniThread = JNIThread.getRetained( rowid, false ); - if ( null != jniThread ) { - jniThread.receive( msg, addr ).release(); - } else { - SMSMsgSink sink = new SMSMsgSink( this ); - BackMoveResult bmr = new BackMoveResult(); - if ( GameUtils.feedMessage( this, rowid, msg, addr, - sink, bmr, isLocalP ) ) { - GameUtils.postMoveNotification( this, rowid, bmr, - isLocalP[0] ); - } - } - } } } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWService.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWService.java index a686cf579..d1146b626 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWService.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWService.java @@ -21,17 +21,23 @@ package org.eehouse.android.xw4; import android.app.Service; +import android.content.Context; import android.content.Intent; import android.os.IBinder; import java.util.HashSet; import java.util.Set; +import junit.framework.Assert; + import org.eehouse.android.xw4.MultiService.MultiEvent; +import org.eehouse.android.xw4.jni.CommsAddrRec; +import org.eehouse.android.xw4.jni.JNIThread; import org.eehouse.android.xw4.jni.UtilCtxt; import org.eehouse.android.xw4.jni.UtilCtxtImpl; -public class XWService extends Service { +class XWService extends Service { + public static enum ReceiveResult { OK, GAME_GONE, UNCONSUMED }; protected static MultiService s_srcMgr = null; private static Set s_seen = new HashSet(); @@ -85,4 +91,56 @@ public class XWService extends Service { } return m_utilCtxt; } + + // Meant to be overridden + protected MultiMsgSink getSink( long rowid ) { Assert.fail(); return null; } + + protected ReceiveResult receiveMessage( Context context, int gameID, + MultiMsgSink sink, byte[] msg, + CommsAddrRec addr ) + { + ReceiveResult result; + long[] rowids = DBUtils.getRowIDsFor( context, gameID ); + if ( null == rowids || 0 == rowids.length ) { + result = ReceiveResult.GAME_GONE; + } else { + result = ReceiveResult.UNCONSUMED; + for ( long rowid : rowids ) { + if ( receiveMessage( context, rowid, sink, msg, addr ) ) { + result = ReceiveResult.OK; + } + } + } + return result; + } + + protected boolean receiveMessage( Context context, long rowid, + MultiMsgSink sink, byte[] msg, + CommsAddrRec addr ) + { + boolean allConsumed = true; + boolean[] isLocalP = new boolean[1]; + JNIThread jniThread = JNIThread.getRetained( rowid, false ); + boolean consumed = false; + if ( null != jniThread ) { + consumed = true; + jniThread.receive( msg, addr ).release(); + } else { + GameUtils.BackMoveResult bmr = + new GameUtils.BackMoveResult(); + if ( null == sink ) { + sink = getSink( rowid ); + } + if ( GameUtils.feedMessage( context, rowid, msg, addr, + sink, bmr, isLocalP ) ) { + consumed = true; + GameUtils.postMoveNotification( context, rowid, bmr, + isLocalP[0] ); + } + } + if ( allConsumed && !consumed ) { + allConsumed = false; + } + return allConsumed; + } }