diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java index f788c796d..ebfe349ee 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java @@ -1105,6 +1105,18 @@ public class BoardActivity extends XWActivity { == Configuration.ORIENTATION_LANDSCAPE; m_toolbar.orientChanged( isLandscape ); populateToolbar(); + + + switch( DBUtils.getHasMsgs( m_path ) ) { + case MSG_LEVEL_CHAT: + startChatActivity(); + // FALLTHRU + case MSG_LEVEL_TURN: + // clear it if non-NONE + DBUtils.setHasMsgs( m_path, + GameSummary.MsgLevel.MSG_LEVEL_NONE ); + break; + } } } // loadGame diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ChatActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ChatActivity.java index e61fe4285..5a9904fd1 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ChatActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ChatActivity.java @@ -51,17 +51,19 @@ public class ChatActivity extends XWActivity implements View.OnClickListener { } DBUtils.HistoryPair[] pairs = DBUtils.getChatHistory( this, m_path ); - LinearLayout layout = (LinearLayout)findViewById( R.id.chat_history ); - LayoutInflater factory = LayoutInflater.from( this ); + if ( null != pairs ) { + LinearLayout layout = (LinearLayout)findViewById( R.id.chat_history ); + LayoutInflater factory = LayoutInflater.from( this ); - for ( DBUtils.HistoryPair pair : pairs ) { - TextView view = - (TextView)factory.inflate( pair.sourceLocal - ? R.layout.chat_history_local - : R.layout.chat_history_remote, - null ); - view.setText( pair.msg ); - layout.addView( view ); + for ( DBUtils.HistoryPair pair : pairs ) { + TextView view = + (TextView)factory.inflate( pair.sourceLocal + ? R.layout.chat_history_local + : R.layout.chat_history_remote, + null ); + view.setText( pair.msg ); + layout.addView( view ); + } } ((Button)findViewById( R.id.send_button )).setOnClickListener( this ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBHelper.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBHelper.java index 595bba6a0..8899e5c1a 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBHelper.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBHelper.java @@ -124,11 +124,11 @@ public class DBHelper extends SQLiteOpenHelper { onCreateObits(db); } else if ( newVersion == 7 && oldVersion == 6 ) { db.execSQL( "ALTER TABLE " + TABLE_NAME_SUM + - " ADD COLUMN " + TURN + "INTEGER;" ); + " ADD COLUMN " + TURN + " INTEGER;" ); db.execSQL( "ALTER TABLE " + TABLE_NAME_SUM + - " ADD COLUMN " + GIFLAGS + "INTEGER;" ); + " ADD COLUMN " + GIFLAGS + " INTEGER;" ); db.execSQL( "ALTER TABLE " + TABLE_NAME_SUM + - " ADD COLUMN " + CHAT_HISTORY + "TEXT;" ); + " ADD COLUMN " + CHAT_HISTORY + " TEXT;" ); } else { db.execSQL( "DROP TABLE " + TABLE_NAME_SUM + ";" ); if ( oldVersion >= 6 ) { diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java index 07e965e31..0bb1464c3 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java @@ -152,7 +152,8 @@ public class DBUtils { col = cursor.getColumnIndex( DBHelper.HASMSGS ); if ( col >= 0 ) { - summary.msgsPending = 0 != cursor.getInt( col ); + summary.pendingMsgLevel = + GameSummary.MsgLevel.values()[cursor.getInt( col )]; } } cursor.close(); @@ -164,7 +165,7 @@ public class DBUtils { saveSummary( context, file, summary ); } return summary; - } + } // getSummary public static void saveSummary( Context context, String path, GameSummary summary ) @@ -187,7 +188,6 @@ public class DBUtils { values.put( DBHelper.DICTLANG, summary.dictLang ); values.put( DBHelper.DICTNAME, summary.dictName ); values.put( DBHelper.GAME_OVER, summary.gameOver ); - values.put( DBHelper.HASMSGS, 0 ); if ( null != summary.scores ) { StringBuffer sb = new StringBuffer(); @@ -237,14 +237,15 @@ public class DBUtils { return result; } - public static void setHasMsgs( String relayID ) + // 0 means none; 1 just moves; 2 chat + public static void setHasMsgs( String path, GameSummary.MsgLevel level ) { synchronized( s_dbHelper ) { SQLiteDatabase db = s_dbHelper.getWritableDatabase(); - String selection = DBHelper.RELAYID + "=\'" + relayID + "\'"; + String selection = DBHelper.FILE_NAME + "=\"" + path + "\""; ContentValues values = new ContentValues(); - values.put( DBHelper.HASMSGS, 1 ); + values.put( DBHelper.HASMSGS, level.ordinal() ); int result = db.update( DBHelper.TABLE_NAME_SUM, values, selection, null ); @@ -253,6 +254,26 @@ public class DBUtils { } } + public static GameSummary.MsgLevel getHasMsgs( String path ) + { + GameSummary.MsgLevel result = GameSummary.MsgLevel.MSG_LEVEL_NONE; + synchronized( s_dbHelper ) { + SQLiteDatabase db = s_dbHelper.getReadableDatabase(); + String selection = DBHelper.FILE_NAME + "=\"" + path + "\""; + String[] columns = { DBHelper.HASMSGS }; + Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns, + selection, null, null, null, null ); + if ( 1 == cursor.getCount() && cursor.moveToFirst() ) { + int level = cursor.getInt( cursor + .getColumnIndex(DBHelper.HASMSGS)); + result = GameSummary.MsgLevel.values()[level]; + } + cursor.close(); + db.close(); + } + return result; + } + public static String getPathFor( Context context, String relayID ) { String result = null; @@ -482,13 +503,17 @@ public class DBUtils { public static HistoryPair[] getChatHistory( Context context, String path ) { + HistoryPair[] result = null; final String localPrefix = context.getString( R.string.chat_local_id ); - String[] msgs = getChatHistoryStr( context, path ).split( "\n" ); - HistoryPair[] result = new HistoryPair[msgs.length]; - for ( int ii = 0; ii < result.length; ++ii ) { - String msg = msgs[ii]; - boolean isLocal = msg.startsWith( localPrefix ); - result[ii] = new HistoryPair( msg, isLocal ); + String history = getChatHistoryStr( context, path ); + if ( null != history ) { + String[] msgs = history.split( "\n" ); + result = new HistoryPair[msgs.length]; + for ( int ii = 0; ii < result.length; ++ii ) { + String msg = msgs[ii]; + boolean isLocal = msg.startsWith( localPrefix ); + result[ii] = new HistoryPair( msg, isLocal ); + } } return result; } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java index f1047334e..370b12df2 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java @@ -107,8 +107,9 @@ public class GameListAdapter extends XWListAdapter { } View marker = layout.findViewById( R.id.msg_marker ); - marker.setVisibility( summary.msgsPending? - View.VISIBLE : View.GONE ); + marker.setVisibility( summary.pendingMsgLevel + == GameSummary.MsgLevel.MSG_LEVEL_NONE + ? View.GONE : View.VISIBLE ); m_viewsCache.put( path, layout ); } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java index 983da3a93..4609f24d9 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java @@ -94,9 +94,26 @@ public class GameUtils { private static GameSummary summarizeAndClose( Context context, String path, int gamePtr, CurGameInfo gi ) + { + return summarizeAndClose( context, path, gamePtr, gi, null ); + } + + private static GameSummary summarizeAndClose( Context context, + String path, + int gamePtr, CurGameInfo gi, + FeedUtilsImpl feedImpl ) { GameSummary summary = new GameSummary( gi ); XwJNI.game_summarize( gamePtr, summary ); + + if ( null != feedImpl ) { + if ( feedImpl.m_gotChat ) { + summary.pendingMsgLevel = GameSummary.MsgLevel.MSG_LEVEL_CHAT; + } else if ( feedImpl.m_gotMsg ) { + summary.pendingMsgLevel = GameSummary.MsgLevel.MSG_LEVEL_TURN; + } + } + DBUtils.saveSummary( context, path, summary ); XwJNI.game_dispose( gamePtr ); @@ -381,15 +398,23 @@ public class GameUtils { private static class FeedUtilsImpl extends UtilCtxtImpl { private Context m_context; private String m_path; + public boolean m_gotMsg; + public boolean m_gotChat; public FeedUtilsImpl( Context context, String path ) { m_context = context; m_path = path; + m_gotMsg = false; } public void showChat( String msg ) { DBUtils.appendChatHistory( m_context, m_path, msg, false ); + m_gotChat = true; + } + public void turnChanged() + { + m_gotMsg = true; } } @@ -401,9 +426,8 @@ public class GameUtils { if ( null != path ) { int gamePtr = XwJNI.initJNI(); CurGameInfo gi = new CurGameInfo( context ); - loadMakeGame( context, gamePtr, gi, - new FeedUtilsImpl(context, path), - path ); + FeedUtilsImpl feedImpl = new FeedUtilsImpl( context, path ); + loadMakeGame( context, gamePtr, gi, feedImpl, path ); for ( byte[] msg : msgs ) { draw = XwJNI.game_receiveMessage( gamePtr, msg ) || draw; @@ -412,7 +436,14 @@ public class GameUtils { // update gi to reflect changes due to messages XwJNI.game_getGi( gamePtr, gi ); saveGame( context, gamePtr, gi, path, false ); - summarizeAndClose( context, path, gamePtr, gi ); + summarizeAndClose( context, path, gamePtr, gi, feedImpl ); + if ( feedImpl.m_gotChat ) { + DBUtils.setHasMsgs( path, GameSummary.MsgLevel.MSG_LEVEL_CHAT ); + draw = true; + } else if ( feedImpl.m_gotMsg ) { + DBUtils.setHasMsgs( path, GameSummary.MsgLevel.MSG_LEVEL_TURN ); + draw = true; + } } Utils.logf( "feedMessages=>%s", draw?"true":"false" ); return draw; 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 11bbafb60..2f23bc424 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetStateCache.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetStateCache.java @@ -28,6 +28,7 @@ import android.net.NetworkInfo; import android.net.ConnectivityManager; import java.util.HashSet; import java.util.Iterator; +import android.os.Build; import junit.framework.Assert; public class NetStateCache { @@ -40,6 +41,7 @@ public class NetStateCache { private static HashSet s_ifs; private static boolean s_netAvail = false; private static CommsBroadcastReceiver s_receiver; + private static final boolean s_onSim = Build.PRODUCT.contains("sdk"); public static void register( Context context, StateChangedIf proc ) { @@ -60,7 +62,7 @@ public class NetStateCache { public static boolean netAvail( Context context ) { initIfNot( context ); - return s_netAvail; + return s_netAvail || s_onSim; } private static void initIfNot( Context context ) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetUtils.java index 5afe6c6d2..e90882e3f 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetUtils.java @@ -195,7 +195,6 @@ public class NetUtils { if ( null != msgs[ii] ) { if( GameUtils.feedMessages( context, ids[ii], msgs[ii] ) ) { - DBUtils.setHasMsgs( ids[ii] ); idsWMsgs.add( ids[ii] ); } } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/GameSummary.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/GameSummary.java index f0f1ce9f1..2dfd96032 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/GameSummary.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/GameSummary.java @@ -29,6 +29,8 @@ import org.eehouse.android.xw4.R; * in CurGameInfo */ public class GameSummary { + public enum MsgLevel { MSG_LEVEL_NONE, MSG_LEVEL_TURN, MSG_LEVEL_CHAT }; + public int nMoves; public int turn; public int giFlags; @@ -42,19 +44,23 @@ public class GameSummary { public String roomName; public String relayID; public int seed; - public boolean msgsPending; + public MsgLevel pendingMsgLevel; public long modtime; public int dictLang; public String dictName; public CurGameInfo.DeviceRole serverRole; + private CurGameInfo m_gi; - public GameSummary(){} + public GameSummary(){ + pendingMsgLevel = MsgLevel.MSG_LEVEL_NONE; + } public GameSummary( CurGameInfo gi ) { + super(); nPlayers = gi.nPlayers; dictLang = gi.dictLang; dictName = gi.dictName; diff --git a/xwords4/common/server.c b/xwords4/common/server.c index 195594eca..d22be358b 100644 --- a/xwords4/common/server.c +++ b/xwords4/common/server.c @@ -809,48 +809,47 @@ postponeRobotMove( ServerCtxt* server ) static void showPrevScore( ServerCtxt* server ) { - XW_UtilCtxt* util = server->vol.util; - XWStreamCtxt* stream; - const XP_UCHAR* str; - CurGameInfo* gi = server->vol.gi; - XP_U16 nPlayers = gi->nPlayers; - XP_U16 prevTurn; - XP_U16 strCode; - LocalPlayer* lp; + if ( server->nv.showRobotScores ) { /* this can be changed between turns */ + XW_UtilCtxt* util = server->vol.util; + XWStreamCtxt* stream; + const XP_UCHAR* str; + CurGameInfo* gi = server->vol.gi; + XP_U16 nPlayers = gi->nPlayers; + XP_U16 prevTurn; + XP_U16 strCode; + LocalPlayer* lp; - XP_ASSERT( server->nv.showRobotScores ); + prevTurn = (server->nv.currentTurn + nPlayers - 1) % nPlayers; + lp = &gi->players[prevTurn]; - prevTurn = (server->nv.currentTurn + nPlayers - 1) % nPlayers; - lp = &gi->players[prevTurn]; + if ( LP_IS_LOCAL(lp) ) { + XP_ASSERT( LP_IS_ROBOT(lp) ); + strCode = STR_ROBOT_MOVED; + } else { + strCode = STR_REMOTE_MOVED; + } - if ( LP_IS_LOCAL(lp) ) { - XP_ASSERT( LP_IS_ROBOT(lp) ); - strCode = STR_ROBOT_MOVED; - } else { - strCode = STR_REMOTE_MOVED; + stream = mkServerStream( server ); + + str = util_getUserString( util, strCode ); + stream_catString( stream, str ); + + if ( !!server->nv.prevMoveStream ) { + XWStreamCtxt* prevStream = server->nv.prevMoveStream; + XP_U16 len = stream_getSize( prevStream ); + XP_UCHAR* buf = XP_MALLOC( server->mpool, len ); + + stream_getBytes( prevStream, buf, len ); + stream_destroy( prevStream ); + server->nv.prevMoveStream = NULL; + + stream_putBytes( stream, buf, len ); + XP_FREE( server->mpool, buf ); + } + + (void)util_userQuery( util, QUERY_ROBOT_MOVE, stream ); + stream_destroy( stream ); } - - stream = mkServerStream( server ); - - str = util_getUserString( util, strCode ); - stream_catString( stream, str ); - - if ( !!server->nv.prevMoveStream ) { - XWStreamCtxt* prevStream = server->nv.prevMoveStream; - XP_U16 len = stream_getSize( prevStream ); - XP_UCHAR* buf = XP_MALLOC( server->mpool, len ); - - stream_getBytes( prevStream, buf, len ); - stream_destroy( prevStream ); - server->nv.prevMoveStream = NULL; - - stream_putBytes( stream, buf, len ); - XP_FREE( server->mpool, buf ); - } - - (void)util_userQuery( util, QUERY_ROBOT_MOVE, stream ); - stream_destroy( stream ); - SETSTATE( server, server->vol.stateAfterShow ); } /* showPrevScore */