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 9f9f5089a..e45f64e3e 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java @@ -816,9 +816,8 @@ public class BoardActivity extends XWActivity if ( DlgDelegate.DISMISS_BUTTON != which ) { GameUtils.launchInviteActivity( BoardActivity.this, DlgDelegate.EMAIL_BTN == which, - m_room, null, - m_gi.dictLang, - m_gi.nPlayers ); + m_room, null, m_gi.dictLang, + m_gi.dictName, m_gi.nPlayers ); } } else if ( AlertDialog.BUTTON_POSITIVE == which ) { JNICmd cmd = JNICmd.CMD_NONE; 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 8403f65e5..8b9473d5f 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java @@ -556,7 +556,7 @@ public class DBUtils { DBHelper.ROOMNAME, nli.room, DBHelper.INVITEID, nli.inviteID, DBHelper.DICTLANG, nli.lang, - DBHelper.NUM_PLAYERS, nli.nPlayers ); + DBHelper.NUM_PLAYERS, nli.nPlayersT ); Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns, selection, null, null, null, null ); if ( 1 == cursor.getCount() && cursor.moveToFirst() ) { @@ -572,7 +572,7 @@ public class DBUtils { { long rowid = ROWID_NOTFOUND; NetLaunchInfo nli = new NetLaunchInfo( data ); - if ( null != nli ) { + if ( null != nli && nli.isValid() ) { rowid = getRowIDForOpen( context, nli ); } return rowid; diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DispatchNotify.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DispatchNotify.java index a82d1addc..57d674d62 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DispatchNotify.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DispatchNotify.java @@ -64,11 +64,30 @@ public class DispatchNotify extends Activity { if ( !tryHandle( gameID ) ) { mustLaunch = true; } - } else if ( null != data ) { - long rowid = DBUtils.getRowIDForOpen( this, data ); + } else if ( null != data ) { // relay invite redirected URL case + NetLaunchInfo nli = new NetLaunchInfo( data ); + long rowid = DBUtils.getRowIDForOpen( this, nli ); if ( DBUtils.ROWID_NOTFOUND == rowid ) { - if ( !tryHandle( data ) ) { - mustLaunch = true; + 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" ); 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 b956c73c3..29414613c 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java @@ -408,7 +408,7 @@ public class GameUtils { } private static long makeNewMultiGame( Context context, CommsAddrRec addr, - int[] lang, String dict, + int[] lang, String[] dict, int nPlayersT, int nPlayersH, String inviteID, int gameID, boolean isHost ) @@ -416,8 +416,9 @@ public class GameUtils { long rowid = -1; CurGameInfo gi = new CurGameInfo( context, true ); - gi.setLang( lang[0], dict ); + gi.setLang( lang[0], dict[0] ); lang[0] = gi.dictLang; + dict[0] = gi.dictName; gi.setNPlayers( nPlayersT, nPlayersH ); gi.juggle(); if ( 0 != gameID ) { @@ -442,7 +443,8 @@ public class GameUtils { public static long makeNewNetGame( Context context, String room, String inviteID, int[] lang, - int nPlayersT, int nPlayersH ) + String[] dict, int nPlayersT, + int nPlayersH ) { long rowid = -1; String relayName = XWPrefs.getDefaultRelayHost( context ); @@ -450,21 +452,24 @@ public class GameUtils { CommsAddrRec addr = new CommsAddrRec( relayName, relayPort ); addr.ip_relay_invite = room; - return makeNewMultiGame( context, addr, lang, null, nPlayersT, + return makeNewMultiGame( context, addr, lang, dict, nPlayersT, nPlayersH, inviteID, 0, false ); } public static long makeNewNetGame( Context context, String room, - String inviteID, int lang, int nPlayers ) + String inviteID, int lang, String dict, + int nPlayers ) { int[] langarr = { lang }; - return makeNewNetGame( context, room, inviteID, langarr, nPlayers, 1 ); + String[] dictArr = { dict }; + return makeNewNetGame( context, room, inviteID, langarr, dictArr, + nPlayers, 1 ); } public static long makeNewNetGame( Context context, NetLaunchInfo info ) { return makeNewNetGame( context, info.room, info.inviteID, info.lang, - info.nPlayers ); + info.dict, info.nPlayersT ); } public static long makeNewBTGame( Context context, int gameID, @@ -488,11 +493,12 @@ public class GameUtils { { long rowid = -1; int[] langa = { lang }; + String[] dicta = { dict }; boolean isHost = null == addr; if ( isHost ) { addr = new CommsAddrRec(CommsAddrRec.CommsConnType.COMMS_CONN_SMS); } - return makeNewMultiGame( context, addr, langa, dict, nPlayersT, + return makeNewMultiGame( context, addr, langa, dicta, nPlayersT, nPlayersH, null, gameID, isHost ); } @@ -515,13 +521,14 @@ public class GameUtils { public static void launchInviteActivity( Context context, boolean choseEmail, String room, String inviteID, - int lang, int nPlayers ) + int lang, String dict, + int nPlayers ) { if ( null == inviteID ) { inviteID = makeRandomID(); } Uri gameUri = NetLaunchInfo.makeLaunchUri( context, room, inviteID, - lang, nPlayers ); + lang, dict, nPlayers ); if ( null != gameUri ) { int fmtId = choseEmail? R.string.invite_htmf : R.string.invite_txtf; diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java index ae2413beb..b9975a6e6 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java @@ -790,13 +790,18 @@ public class GamesList extends XWListActivity private void startNewNetGame( Intent intent ) { - Uri data = intent.getData(); - if ( null != data ) { - NetLaunchInfo info = new NetLaunchInfo( data ); - if ( info.isValid() ) { - startNewNetGame( info ); + NetLaunchInfo info = null; + if ( MultiService.isMissingDictIntent( intent ) ) { + info = new NetLaunchInfo( intent ); + } else { + Uri data = intent.getData(); + if ( null != data ) { + info = new NetLaunchInfo( data ); } } + if ( null != info && info.isValid() ) { + startNewNetGame( info ); + } } // startNewNetGame private void startHasGameID( int gameID ) @@ -833,4 +838,11 @@ public class GamesList extends XWListActivity onContentChanged(); } } + + public static void onGameDictDownload( Context context, Intent intent ) + { + intent.setClass( context, GamesList.class ); + context.startActivity( intent ); + } + } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiService.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiService.java index 8c06598b0..58c620d2b 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiService.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiService.java @@ -31,6 +31,8 @@ public class MultiService { public static final String LANG = "LANG"; public static final String DICT = "DICT"; public static final String GAMEID = "GAMEID"; + public static final String INVITEID = "INVITEID"; // relay only + public static final String ROOM = "ROOM"; public static final String GAMENAME = "GAMENAME"; public static final String NPLAYERST = "NPLAYERST"; public static final String NPLAYERSH = "NPLAYERSH"; @@ -38,6 +40,7 @@ public class MultiService { public static final String OWNER = "OWNER"; public static final int OWNER_SMS = 1; + public static final int OWNER_RELAY = 2; private BTEventListener m_li; @@ -84,11 +87,39 @@ public class MultiService { } } + public static void fillInviteIntent( Intent intent, String gameName, + int lang, String dict, + int nPlayersT, int nPlayersH ) + { + intent.putExtra( GAMENAME, gameName ); + intent.putExtra( LANG, lang ); + intent.putExtra( DICT, dict ); + intent.putExtra( NPLAYERST, nPlayersT ); // both of these used + intent.putExtra( NPLAYERSH, nPlayersH ); + } + + public static Intent makeMissingDictIntent( Context context, String gameName, + int lang, String dict, + int nPlayersT, int nPlayersH ) + { + Intent intent = new Intent( context, DictsActivity.class ); + fillInviteIntent( intent, gameName, lang, dict, nPlayersT, nPlayersH ); + return intent; + } + + public static Intent makeMissingDictIntent( Context context, NetLaunchInfo nli ) + { + Intent intent = makeMissingDictIntent( context, null, nli.lang, nli.dict, + nli.nPlayersT, 1 ); + intent.putExtra( ROOM, nli.room ); + return intent; + } + public static boolean isMissingDictIntent( Intent intent ) { return intent.hasExtra( LANG ) - && intent.hasExtra( DICT ) - && intent.hasExtra( GAMEID ) + // && intent.hasExtra( DICT ) + && (intent.hasExtra( GAMEID ) || intent.hasExtra( ROOM )) && intent.hasExtra( GAMENAME ) && intent.hasExtra( NPLAYERST ) && intent.hasExtra( NPLAYERSH ); @@ -112,6 +143,13 @@ public class MultiService { .create(); } + public static void postMissingDictNotification( Context content, + Intent intent, int id ) + { + Utils.postNotification( content, intent, R.string.missing_dict_title, + R.string.missing_dict_detail, id ); + } + // resend the intent, but only if the dict it names is here. (If // it's not, we may need to try again later, e.g. because our cue // was a focus gain.) @@ -123,11 +161,15 @@ public class MultiService { String dict = intent.getStringExtra( DICT ); downloaded = DictLangCache.haveDict( context, lang, dict ); if ( downloaded ) { - int owner = intent.getIntExtra( OWNER, -1 ); - if ( owner == OWNER_SMS ) { + switch ( intent.getIntExtra( OWNER, -1 ) ) { + case OWNER_SMS: SMSService.onGameDictDownload( context, intent ); - } else { - DbgUtils.logf( "unexpected OWNER: %d", owner ); + break; + case OWNER_RELAY: + GamesList.onGameDictDownload( context, intent ); + break; + default: + DbgUtils.logf( "unexpected OWNER" ); } } } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetLaunchInfo.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetLaunchInfo.java index d73370d79..53a9c61ab 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetLaunchInfo.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetLaunchInfo.java @@ -21,8 +21,9 @@ package org.eehouse.android.xw4; import android.content.Context; -import android.net.Uri; +import android.content.Intent; import android.net.Uri.Builder; +import android.net.Uri; import android.os.Bundle; import java.net.URLEncoder; @@ -30,11 +31,13 @@ import java.net.URLEncoder; public class NetLaunchInfo { public String room; public String inviteID; + public String dict; public int lang; - public int nPlayers; + public int nPlayersT; private static final String LANG = "netlaunchinfo_lang"; private static final String ROOM = "netlaunchinfo_room"; + private static final String DICT = "netlaunchinfo_dict"; private static final String INVITEID = "netlaunchinfo_inviteid"; private static final String NPLAYERS = "netlaunchinfo_nplayers"; private static final String VALID = "netlaunchinfo_valid"; @@ -46,7 +49,8 @@ public class NetLaunchInfo { bundle.putInt( LANG, lang ); bundle.putString( ROOM, room ); bundle.putString( INVITEID, inviteID ); - bundle.putInt( NPLAYERS, nPlayers ); + bundle.putString( DICT, dict ); + bundle.putInt( NPLAYERS, nPlayersT ); bundle.putBoolean( VALID, m_valid ); } @@ -54,8 +58,9 @@ public class NetLaunchInfo { { lang = bundle.getInt( LANG ); room = bundle.getString( ROOM ); + dict = bundle.getString( DICT ); inviteID = bundle.getString( INVITEID ); - nPlayers = bundle.getInt( NPLAYERS ); + nPlayersT = bundle.getInt( NPLAYERS ); m_valid = bundle.getBoolean( VALID ); } @@ -66,10 +71,11 @@ public class NetLaunchInfo { try { room = data.getQueryParameter( "room" ); inviteID = data.getQueryParameter( "id" ); + dict = data.getQueryParameter( "wl" ); String langStr = data.getQueryParameter( "lang" ); lang = Integer.decode( langStr ); String np = data.getQueryParameter( "np" ); - nPlayers = Integer.decode( np ); + nPlayersT = Integer.decode( np ); m_valid = true; } catch ( Exception e ) { DbgUtils.logf( "unable to parse \"%s\"", data.toString() ); @@ -77,8 +83,21 @@ public class NetLaunchInfo { } } + public NetLaunchInfo( Intent intent ) + { + room = intent.getStringExtra( MultiService.ROOM ); + inviteID = intent.getStringExtra( MultiService.INVITEID ); + lang = intent.getIntExtra( MultiService.LANG, -1 ); + dict = intent.getStringExtra( MultiService.DICT ); + nPlayersT = intent.getIntExtra( MultiService.NPLAYERST, -1 ); + m_valid = null != room + && -1 != lang + && -1 != nPlayersT; + } + public static Uri makeLaunchUri( Context context, String room, - String inviteID, int lang, int nPlayers ) + String inviteID, int lang, + String dict, int nPlayersT ) { Builder ub = new Builder(); ub.scheme( "http" ); @@ -86,9 +105,12 @@ public class NetLaunchInfo { XWPrefs.getDefaultRedirHost( context ) ) ); ub.appendQueryParameter( "lang", String.format("%d", lang ) ); - ub.appendQueryParameter( "np", String.format( "%d", nPlayers ) ); + ub.appendQueryParameter( "np", String.format( "%d", nPlayersT ) ); ub.appendQueryParameter( "room", room ); ub.appendQueryParameter( "id", inviteID ); + if ( null != dict ) { + ub.appendQueryParameter( "wl", dict ); + } return ub.build(); } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameActivity.java index 3cfee37c9..039aaa23d 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameActivity.java @@ -318,13 +318,14 @@ public class NewGameActivity extends XWActivity { String inviteID = null; long rowid; int[] lang = {0}; + String[] dict = {null}; final int nPlayers = 2; // hard-coded for no-configure case if ( networked ) { room = GameUtils.makeRandomID(); inviteID = GameUtils.makeRandomID(); rowid = GameUtils.makeNewNetGame( this, room, inviteID, lang, - nPlayers, 1 ); + dict, nPlayers, 1 ); } else { rowid = GameUtils.saveNew( this, new CurGameInfo( this ) ); } @@ -333,7 +334,8 @@ public class NewGameActivity extends XWActivity { GameUtils.launchGame( this, rowid, networked ); if ( networked ) { GameUtils.launchInviteActivity( this, choseEmail, room, - inviteID, lang[0], nPlayers ); + inviteID, lang[0], dict[0], + nPlayers ); } } else { GameUtils.doConfig( this, rowid, GameConfig.class ); 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 6121e7196..18cbd8c88 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSService.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSService.java @@ -424,17 +424,15 @@ public class SMSService extends Service { makeForInvite( phone, gameID, gameName, lang, dict, nPlayersT, nPlayersH ); } else { - Intent intent = new Intent( this, DictsActivity.class ); - fillInviteIntent( intent, phone, gameID, gameName, lang, dict, - nPlayersT, nPlayersH ); + Intent intent = MultiService + .makeMissingDictIntent( this, gameName, lang, dict, + nPlayersT, nPlayersH ); + intent.putExtra( PHONE, phone ); intent.putExtra( MultiService.OWNER, MultiService.OWNER_SMS ); intent.putExtra( MultiService.INVITER, Utils.phoneToContact( this, phone, true ) ); - Utils.postNotification( this, intent, - R.string.missing_dict_title, - R.string.missing_dict_detail, - gameID ); + MultiService.postMissingDictNotification( this, intent, gameID ); } break; case DATA: @@ -591,11 +589,8 @@ public class SMSService extends Service { { intent.putExtra( PHONE, phone ); intent.putExtra( MultiService.GAMEID, gameID ); - intent.putExtra( MultiService.GAMENAME, gameName ); - intent.putExtra( MultiService.LANG, lang ); - intent.putExtra( MultiService.DICT, dict ); - intent.putExtra( MultiService.NPLAYERST, nPlayersT ); - intent.putExtra( MultiService.NPLAYERSH, nPlayersH ); + MultiService.fillInviteIntent( intent, gameName, lang, dict, + nPlayersT, nPlayersH ); } private void feedMessage( int gameID, byte[] msg, CommsAddrRec addr )