fix confirmation of duplicate game from invite. Along the way

dramatically simplify how new game intents are passed around.
This commit is contained in:
Eric House 2012-11-28 19:17:29 -08:00
parent 6f620ebc44
commit 19333e33ac
7 changed files with 107 additions and 231 deletions

View file

@ -974,8 +974,7 @@ public class BTService extends Service {
private void postNotification( int gameID, int title, String body )
{
Intent intent = new Intent( this, DispatchNotify.class );
intent.putExtra( DispatchNotify.GAMEID_EXTRA, gameID );
Intent intent = GamesList.makeGameIDIntent( this, gameID );
Utils.postNotification( this, intent, R.string.new_btmove_title,
body, gameID );
}

View file

@ -33,175 +33,16 @@ import org.eehouse.android.xw4.jni.GameSummary;
public class DispatchNotify extends Activity {
public static final String RELAYIDS_EXTRA = "relayids";
public static final String GAMEID_EXTRA = "gameid";
public interface HandleRelaysIface {
void handleRelaysIDs( final String[] relayIDs );
void handleInvite( final Uri invite );
void handleGameID( int gameID );
}
private static HashSet<HandleRelaysIface> s_running =
new HashSet<HandleRelaysIface>();
private static HandleRelaysIface s_handler;
@Override
protected void onCreate( Bundle savedInstanceState )
{
boolean mustLaunch = false;
super.onCreate( savedInstanceState );
String[] relayIDs = getIntent().getStringArrayExtra( RELAYIDS_EXTRA );
int gameID = getIntent().getIntExtra( GAMEID_EXTRA, -1 );
Uri data = getIntent().getData();
if ( null != relayIDs ) {
if ( !tryHandle( relayIDs ) ) {
mustLaunch = true;
}
} else if ( -1 != gameID ) {
if ( !tryHandle( gameID ) ) {
mustLaunch = true;
}
} else if ( null != data ) { // relay invite redirected URL case
NetLaunchInfo nli = new NetLaunchInfo( data );
if ( null != nli && nli.isValid() ) {
long rowid = DBUtils.getRowIDForOpen( this, nli );
if ( DBUtils.ROWID_NOTFOUND == rowid ) {
boolean haveDict;
if ( null == nli.dict ) { // can only test for language support
haveDict =
0 < DictLangCache.getHaveLang( this,
nli.lang ).length;
} else {
haveDict =
DictLangCache.haveDict( this, nli.lang, nli.dict );
}
if ( haveDict ) {
if ( !tryHandle( data ) ) {
mustLaunch = true;
}
} else {
Intent intent =
MultiService.makeMissingDictIntent( this, nli );
intent.putExtra( MultiService.OWNER,
MultiService.OWNER_RELAY );
// do we have gameID?
MultiService.
postMissingDictNotification( this, intent,
nli.inviteID
.hashCode() );
}
} else {
DbgUtils.logf( "DispatchNotify: dropping duplicate invite" );
GameSummary summary = DBUtils.getSummary( this, rowid );
if ( null != summary ) {
gameID = summary.gameID;
if ( !tryHandle( gameID ) ) {
mustLaunch = true;
}
}
}
}
}
if ( mustLaunch ) {
DbgUtils.logf( "DispatchNotify: nothing running" );
Intent intent = new Intent( this, GamesList.class );
// This combination of flags will bring an existing
// GamesList instance to the front, killing any children
// it has, or create a new one if none exists. Coupled
// with a "standard" launchMode it seems to work, meaning
// both that the app preserves its stack in normal use
// (you can go to Home with a stack of activities and
// return to the top activity on that stack if you
// relaunch the app) and that when I launch from here the
// stack gets nuked and we don't get a second GamesList
// instance.
intent.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK );
if ( null != relayIDs ) {
intent.putExtra( RELAYIDS_EXTRA, relayIDs );
} else if ( -1 != gameID ) {
intent.putExtra( GAMEID_EXTRA, gameID );
} else if ( null != data ) {
intent.setData( data );
} else {
Assert.fail();
}
startActivity( intent );
if ( null != data ) { // relay invite redirected URL case
GamesList.openGame( this, data );
}
finish();
}
public static void SetRunning( Activity running )
{
if ( running instanceof HandleRelaysIface ) {
s_running.add( (HandleRelaysIface)running );
}
}
public static void ClearRunning( Activity running )
{
if ( running instanceof HandleRelaysIface ) {
s_running.remove( (HandleRelaysIface)running );
}
}
public static void SetRelayIDsHandler( HandleRelaysIface iface )
{
s_handler = iface;
}
private static boolean tryHandle( Uri data )
{
boolean handled = false;
if ( null != s_handler ) {
// This means the GamesList activity is frontmost
s_handler.handleInvite( data );
handled = true;
} else {
for ( HandleRelaysIface iface : s_running ) {
iface.handleInvite( data );
handled = true;
}
}
return handled;
}
public static boolean tryHandle( String[] relayIDs )
{
boolean handled = false;
if ( null != s_handler ) {
// This means the GamesList activity is frontmost
s_handler.handleRelaysIDs( relayIDs );
handled = true;
} else {
for ( HandleRelaysIface iface : s_running ) {
iface.handleRelaysIDs( relayIDs );
handled = true;
}
}
return handled;
}
public static boolean tryHandle( int gameID )
{
boolean handled = false;
if ( null != s_handler ) {
// This means the GamesList activity is frontmost
s_handler.handleGameID( gameID );
handled = true;
} else {
for ( HandleRelaysIface iface : s_running ) {
iface.handleGameID( gameID );
handled = true;
}
}
return handled;
}
} // onCreate
}

View file

@ -51,8 +51,7 @@ import junit.framework.Assert;
import org.eehouse.android.xw4.jni.*;
public class GamesList extends XWListActivity
implements DispatchNotify.HandleRelaysIface,
DBUtils.DBChangeListener,
implements DBUtils.DBChangeListener,
GameListAdapter.LoadItemCB,
DictImportActivity.DownloadFinishedListener {
@ -65,6 +64,9 @@ public class GamesList extends XWListActivity
private static final String SAVE_ROWID = "SAVE_ROWID";
private static final String SAVE_DICTNAMES = "SAVE_DICTNAMES";
private static final String RELAYIDS_EXTRA = "relayids";
private static final String GAMEID_EXTRA = "gameid";
private static final int NEW_NET_GAME_ACTION = 1;
private static final int RESET_GAME_ACTION = 2;
private static final int DELETE_GAME_ACTION = 3;
@ -293,8 +295,7 @@ public class GamesList extends XWListActivity
{
super.onNewIntent( intent );
Assert.assertNotNull( intent );
invalRelayIDs( intent.
getStringArrayExtra( DispatchNotify.RELAYIDS_EXTRA ) );
invalRelayIDs( intent.getStringArrayExtra( RELAYIDS_EXTRA ) );
startFirstHasDict( intent );
startNewNetGame( intent );
startHasGameID( intent );
@ -304,7 +305,6 @@ public class GamesList extends XWListActivity
protected void onStart()
{
super.onStart();
DispatchNotify.SetRelayIDsHandler( this );
boolean hide = CommonPrefs.getHideIntro( this );
int hereOrGone = hide ? View.GONE : View.VISIBLE;
@ -331,7 +331,6 @@ public class GamesList extends XWListActivity
// (TelephonyManager)getSystemService( Context.TELEPHONY_SERVICE );
// mgr.listen( m_phoneStateListener, PhoneStateListener.LISTEN_NONE );
// m_phoneStateListener = null;
DispatchNotify.SetRelayIDsHandler( null );
super.onStop();
}
@ -372,39 +371,6 @@ public class GamesList extends XWListActivity
}
}
// DispatchNotify.HandleRelaysIface interface
public void handleRelaysIDs( final String[] relayIDs )
{
post( new Runnable() {
public void run() {
invalRelayIDs( relayIDs );
startFirstHasDict( relayIDs );
}
} );
}
public void handleInvite( Uri invite )
{
final NetLaunchInfo nli = new NetLaunchInfo( invite );
if ( nli.isValid() ) {
post( new Runnable() {
@Override
public void run() {
startNewNetGame( nli );
}
} );
}
}
public void handleGameID( final int gameID )
{
post( new Runnable() {
public void run() {
startHasGameID( gameID );
}
} );
}
// DBUtils.DBChangeListener interface
public void gameSaved( final long rowid )
{
@ -474,8 +440,9 @@ public class GamesList extends XWListActivity
if ( AlertDialog.BUTTON_POSITIVE == which ) {
switch( id ) {
case NEW_NET_GAME_ACTION:
long rowid = GameUtils.makeNewNetGame( this, m_netLaunchInfo );
GameUtils.launchGame( this, rowid, true );
if ( checkWarnNoDict( m_netLaunchInfo ) ) {
makeNewNetGameIf();
}
break;
case RESET_GAME_ACTION:
GameUtils.resetGame( this, m_rowid );
@ -629,10 +596,13 @@ public class GamesList extends XWListActivity
{
post( new Runnable() {
public void run() {
boolean madeGame = success ? makeNewNetGameIf() : false;
if ( ! madeGame ) {
int id = success ? R.string.download_done
: R.string.download_failed;
Utils.showToast( GamesList.this, id );
}
}
} );
}
@ -698,6 +668,32 @@ public class GamesList extends XWListActivity
return handled;
} // handleMenuItem
private boolean checkWarnNoDict( NetLaunchInfo nli )
{
// check that we have the dict required
boolean haveDict;
if ( null == nli.dict ) { // can only test for language support
String[] dicts = DictLangCache.getHaveLang( this, nli.lang );
haveDict = 0 < dicts.length;
if ( haveDict ) {
// Just pick one -- good enough for the period when
// users aren't using new clients that include the
// dict name.
nli.dict = dicts[0];
}
} else {
haveDict =
DictLangCache.haveDict( this, nli.lang, nli.dict );
}
if ( !haveDict ) {
m_netLaunchInfo = nli;
m_missingDictLang = nli.lang;
m_missingDictName = nli.dict;
showDialog( WARN_NODICT );
}
return haveDict;
}
private boolean checkWarnNoDict( long rowid )
{
String[][] missingNames = new String[1][];
@ -764,8 +760,7 @@ public class GamesList extends XWListActivity
private void startFirstHasDict( Intent intent )
{
if ( null != intent ) {
String[] relayIDs =
intent.getStringArrayExtra( DispatchNotify.RELAYIDS_EXTRA );
String[] relayIDs = intent.getStringArrayExtra( RELAYIDS_EXTRA );
startFirstHasDict( relayIDs );
}
}
@ -775,33 +770,34 @@ public class GamesList extends XWListActivity
startActivity( new Intent( this, NewGameActivity.class ) );
}
private void startNewNetGame( NetLaunchInfo info )
private void startNewNetGame( NetLaunchInfo nli )
{
long rowid = DBUtils.getRowIDForOpen( this, info );
long rowid = DBUtils.getRowIDForOpen( this, nli );
if ( DBUtils.ROWID_NOTFOUND == rowid ) {
rowid = GameUtils.makeNewNetGame( this, info );
GameUtils.launchGame( this, rowid, true );
if ( checkWarnNoDict( nli ) ) {
makeNewNetGame( nli );
}
} else {
String msg = getString( R.string.dup_game_queryf, info.room );
m_netLaunchInfo = info;
String msg = getString( R.string.dup_game_queryf, nli.room );
m_netLaunchInfo = nli;
showConfirmThen( msg, NEW_NET_GAME_ACTION );
}
} // startNewNetGame
private void startNewNetGame( Intent intent )
{
NetLaunchInfo info = null;
NetLaunchInfo nli = null;
if ( MultiService.isMissingDictIntent( intent ) ) {
info = new NetLaunchInfo( intent );
nli = new NetLaunchInfo( intent );
} else {
Uri data = intent.getData();
if ( null != data ) {
info = new NetLaunchInfo( data );
nli = new NetLaunchInfo( data );
}
}
if ( null != info && info.isValid() ) {
startNewNetGame( info );
if ( null != nli && nli.isValid() ) {
startNewNetGame( nli );
}
} // startNewNetGame
@ -815,7 +811,7 @@ public class GamesList extends XWListActivity
private void startHasGameID( Intent intent )
{
int gameID = intent.getIntExtra( DispatchNotify.GAMEID_EXTRA, 0 );
int gameID = intent.getIntExtra( GAMEID_EXTRA, 0 );
if ( 0 != gameID ) {
startHasGameID( gameID );
}
@ -840,10 +836,55 @@ public class GamesList extends XWListActivity
}
}
private boolean makeNewNetGameIf()
{
boolean madeGame = null != m_netLaunchInfo;
if ( madeGame ) {
makeNewNetGame( m_netLaunchInfo );
m_netLaunchInfo = null;
}
return madeGame;
}
private void makeNewNetGame( NetLaunchInfo info )
{
long rowid = GameUtils.makeNewNetGame( this, info );
GameUtils.launchGame( this, rowid, true );
}
public static void onGameDictDownload( Context context, Intent intent )
{
intent.setClass( context, GamesList.class );
context.startActivity( intent );
}
private static Intent makeSelfIntent( Context context )
{
Intent intent = new Intent( context, GamesList.class );
intent.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK );
return intent;
}
public static Intent makeRelayIdsIntent( Context context,
String[] relayIDs )
{
Intent intent = makeSelfIntent( context );
intent.putExtra( RELAYIDS_EXTRA, relayIDs );
return intent;
}
public static Intent makeGameIDIntent( Context context, int gameID )
{
Intent intent = makeSelfIntent( context );
intent.putExtra( GAMEID_EXTRA, gameID );
return intent;
}
public static void openGame( Context context, Uri data )
{
Intent intent = makeSelfIntent( context );
intent.setData( data );
context.startActivity( intent );
}
}

View file

@ -63,8 +63,8 @@ public class RelayService extends Service {
long[] rowids = DBUtils.getRowIDsFor( this, relayID );
if ( null != rowids ) {
for ( long rowid : rowids ) {
Intent intent = new Intent( this, DispatchNotify.class );
intent.putExtra( DispatchNotify.RELAYIDS_EXTRA,
Intent intent =
GamesList.makeRelayIdsIntent( this,
new String[] {relayID} );
String msg = Utils.format( this, R.string.notify_bodyf,
GameUtils.getName( this, rowid ) );

View file

@ -617,8 +617,7 @@ public class SMSService extends Service {
private void postNotification( int gameID, int title, String body )
{
Intent intent = new Intent( this, DispatchNotify.class );
intent.putExtra( DispatchNotify.GAMEID_EXTRA, gameID );
Intent intent = GamesList.makeGameIDIntent( this, gameID );
Utils.postNotification( this, intent, title, body, gameID );
}

View file

@ -48,7 +48,6 @@ public class XWActivity extends Activity
{
DbgUtils.logf( "%s.onStart(this=%H)", getClass().getName(), this );
super.onStart();
DispatchNotify.SetRunning( this );
}
@Override
@ -73,7 +72,6 @@ public class XWActivity extends Activity
protected void onStop()
{
DbgUtils.logf( "%s.onStop(this=%H)", getClass().getName(), this );
DispatchNotify.ClearRunning( this );
super.onStop();
}

View file

@ -45,7 +45,6 @@ public class XWListActivity extends ListActivity
{
DbgUtils.logf( "%s.onStart(this=%H)", getClass().getName(), this );
super.onStart();
DispatchNotify.SetRunning( this );
}
@Override
@ -70,7 +69,6 @@ public class XWListActivity extends ListActivity
protected void onStop()
{
DbgUtils.logf( "%s.onStop(this=%H)", getClass().getName(), this );
DispatchNotify.ClearRunning( this );
super.onStop();
}