mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-15 15:41:24 +01:00
snapshot: invite sent by NFC connects two devices using relay with BT
ability passed too (though not yet used.)
This commit is contained in:
parent
7a1cd06486
commit
93f0b626af
21 changed files with 1433 additions and 1210 deletions
File diff suppressed because it is too large
Load diff
|
@ -84,7 +84,7 @@
|
|||
<string name="key_udp_interval">key_udp_interval</string>
|
||||
|
||||
<string name="key_notagain_sync">key_notagain_sync</string>
|
||||
<string name="key_notagain_sms_ready">key_notagain_sms_ready</string>
|
||||
<!-- <string name="key_notagain_sms_ready">key_notagain_sms_ready</string> -->
|
||||
<string name="key_notagain_newselect">key_notagain_newselect</string>
|
||||
<string name="key_notagain_backclears">key_notagain_backclears</string>
|
||||
<string name="key_notagain_chat">key_notagain_chat</string>
|
||||
|
|
|
@ -1149,19 +1149,24 @@
|
|||
<!-- The invitation process begins with this query. The choice is
|
||||
between html and plaintext formatting but I also provide some
|
||||
explanation/guidance. -->
|
||||
<string name="sms_or_email">Send invitation using SMS (texting) or
|
||||
via email?</string>
|
||||
<string name="nfc_or_email">Send invitation using NFC (Android
|
||||
beaming – NEW) or via email?</string>
|
||||
<string name="nfc_or_sms_or_email">Send invitation using SMS
|
||||
(texting) or NFC (\"Android beaming\" – NEW) or via email?</string>
|
||||
<string name="invite_choice_sms">SMS (texting)</string>
|
||||
<string name="invite_choice_email">Email</string>
|
||||
<string name="invite_choice_bt">Bluetooth</string>
|
||||
<string name="invite_choice_nfc">NFC (\"Android beaming\")</string>
|
||||
<string name="invite_choice_title">How would you like to send this invitation?</string>
|
||||
<!-- <string name="sms_or_email">Send invitation using SMS (texting) or -->
|
||||
<!-- via email?</string> -->
|
||||
<!-- <string name="nfc_or_email">Send invitation using NFC (Android -->
|
||||
<!-- beaming – NEW) or via email?</string> -->
|
||||
<!-- <string name="nfc_or_sms_or_email">Send invitation using SMS -->
|
||||
<!-- (texting) or NFC (\"Android beaming\" – NEW) or via email?</string> -->
|
||||
|
||||
<!-- When an invitation is sent, the user gets to choose between
|
||||
plaintext and html formatting. These two strings are shown in the
|
||||
two buttons in the dialog. -->
|
||||
<string name="button_text">SMS/Text</string>
|
||||
<string name="button_html">Email</string>
|
||||
<string name="button_nfc">NFC</string>
|
||||
<!-- <string name="button_text">SMS/Text</string> -->
|
||||
<!-- <string name="button_html">Email</string> -->
|
||||
<!-- <string name="button_nfc">NFC</string> -->
|
||||
|
||||
<!-- This is the subject line of the email/text sent to invite
|
||||
someone to join a game. -->
|
||||
|
@ -2152,10 +2157,10 @@
|
|||
|
||||
<string name="sms_ready_text">Tap the receiving device now</string>
|
||||
|
||||
<string name="not_again_sms_ready">You have NFC enabled. That
|
||||
means that any time a board that\'s missing a player is open, you
|
||||
can tap a nearby person\'s device to invite him/her to
|
||||
play – if he/she is also using NFC.</string>
|
||||
<!-- <string name="not_again_sms_ready">You have NFC enabled. That -->
|
||||
<!-- means that any time a board that\'s missing a player is open, you -->
|
||||
<!-- can tap a nearby person\'s device to invite him/her to -->
|
||||
<!-- play – if he/she is also using NFC.</string> -->
|
||||
|
||||
<string name="pct_suffix">\u0020pct.</string>
|
||||
|
||||
|
|
|
@ -981,18 +981,23 @@
|
|||
<!-- The invitation process begins with this query. The choice is
|
||||
between html and plaintext formatting but I also provide some
|
||||
explanation/guidance. -->
|
||||
<string name="sms_or_email">Dnes noitativni gnisu SMS )gnitxet( ro
|
||||
aiv ?liame</string>
|
||||
<string name="nfc_or_email">Dnes noitativni gnisu CFN dIordna(
|
||||
gnimaeb – )WEn ro aiv ?liame</string>
|
||||
<string name="nfc_or_sms_or_email">Dnes noitativni gnisu SMS
|
||||
)gnitxet( ro CFN (\"Diordna gnimaeb\" – )WEn ro aiv ?liame</string>
|
||||
<string name="invite_choice_sms">SMS )gnitxet(</string>
|
||||
<string name="invite_choice_email">Liame</string>
|
||||
<string name="invite_choice_bt">Htooteulb</string>
|
||||
<string name="invite_choice_nfc">CFN (\"Diordna gnimaeb\")</string>
|
||||
<string name="invite_choice_title">Woh dluow uoy ekil ot dnes siht ?noitativni</string>
|
||||
<!-- <string name="sms_or_email">Send invitation using SMS (texting) or -->
|
||||
<!-- via email?</string> -->
|
||||
<!-- <string name="nfc_or_email">Send invitation using NFC (Android -->
|
||||
<!-- beaming – NEW) or via email?</string> -->
|
||||
<!-- <string name="nfc_or_sms_or_email">Send invitation using SMS -->
|
||||
<!-- (texting) or NFC (\"Android beaming\" – NEW) or via email?</string> -->
|
||||
<!-- When an invitation is sent, the user gets to choose between
|
||||
plaintext and html formatting. These two strings are shown in the
|
||||
two buttons in the dialog. -->
|
||||
<string name="button_text">TXEt/sms</string>
|
||||
<string name="button_html">Liame</string>
|
||||
<string name="button_nfc">CFN</string>
|
||||
<!-- <string name="button_text">SMS/Text</string> -->
|
||||
<!-- <string name="button_html">Email</string> -->
|
||||
<!-- <string name="button_nfc">NFC</string> -->
|
||||
<!-- This is the subject line of the email/text sent to invite
|
||||
someone to join a game. -->
|
||||
<string name="invite_subject_fmt">Tel\'s yalp Sdrowssorc mOor( %1$s)</string>
|
||||
|
@ -1845,10 +1850,10 @@
|
|||
<string name="no_hide_titlebar">Siht gnittes si derongi no secived
|
||||
ekil sruoy taht dneped no eht \"Noitca rab.\"</string>
|
||||
<string name="sms_ready_text">Pat eht gniviecer ecived won</string>
|
||||
<string name="not_again_sms_ready">Uoy evah CFN delbane. Taht
|
||||
snaem taht yna emit a draob taht\'s gnissim a reyalp si ,nepo uoy
|
||||
nac pat a ybraen nosrep\'s ecived ot etivni reh/mih ot
|
||||
yalp – fi ehs/eh si osla gnisu CFN.</string>
|
||||
<!-- <string name="not_again_sms_ready">You have NFC enabled. That -->
|
||||
<!-- means that any time a board that\'s missing a player is open, you -->
|
||||
<!-- can tap a nearby person\'s device to invite him/her to -->
|
||||
<!-- play – if he/she is also using NFC.</string> -->
|
||||
<string name="pct_suffix">\u0020tcp.</string>
|
||||
<string name="menu_rateme">Etar Sdrowssorc</string>
|
||||
<string name="no_market">Elgoog Yalp ppa ton dnuof</string>
|
||||
|
|
|
@ -981,18 +981,23 @@
|
|||
<!-- The invitation process begins with this query. The choice is
|
||||
between html and plaintext formatting but I also provide some
|
||||
explanation/guidance. -->
|
||||
<string name="sms_or_email">SEND INVITATION USING SMS (TEXTING) OR
|
||||
VIA EMAIL?</string>
|
||||
<string name="nfc_or_email">SEND INVITATION USING NFC (ANDROID
|
||||
BEAMING – NEW) OR VIA EMAIL?</string>
|
||||
<string name="nfc_or_sms_or_email">SEND INVITATION USING SMS
|
||||
(TEXTING) OR NFC (\"ANDROID BEAMING\" – NEW) OR VIA EMAIL?</string>
|
||||
<string name="invite_choice_sms">SMS (TEXTING)</string>
|
||||
<string name="invite_choice_email">EMAIL</string>
|
||||
<string name="invite_choice_bt">BLUETOOTH</string>
|
||||
<string name="invite_choice_nfc">NFC (\"ANDROID BEAMING\")</string>
|
||||
<string name="invite_choice_title">HOW WOULD YOU LIKE TO SEND THIS INVITATION?</string>
|
||||
<!-- <string name="sms_or_email">Send invitation using SMS (texting) or -->
|
||||
<!-- via email?</string> -->
|
||||
<!-- <string name="nfc_or_email">Send invitation using NFC (Android -->
|
||||
<!-- beaming – NEW) or via email?</string> -->
|
||||
<!-- <string name="nfc_or_sms_or_email">Send invitation using SMS -->
|
||||
<!-- (texting) or NFC (\"Android beaming\" – NEW) or via email?</string> -->
|
||||
<!-- When an invitation is sent, the user gets to choose between
|
||||
plaintext and html formatting. These two strings are shown in the
|
||||
two buttons in the dialog. -->
|
||||
<string name="button_text">SMS/TEXT</string>
|
||||
<string name="button_html">EMAIL</string>
|
||||
<string name="button_nfc">NFC</string>
|
||||
<!-- <string name="button_text">SMS/Text</string> -->
|
||||
<!-- <string name="button_html">Email</string> -->
|
||||
<!-- <string name="button_nfc">NFC</string> -->
|
||||
<!-- This is the subject line of the email/text sent to invite
|
||||
someone to join a game. -->
|
||||
<string name="invite_subject_fmt">LET\'S PLAY CROSSWORDS (ROOM %1$s)</string>
|
||||
|
@ -1845,10 +1850,10 @@
|
|||
<string name="no_hide_titlebar">THIS SETTING IS IGNORED ON DEVICES
|
||||
LIKE YOURS THAT DEPEND ON THE \"ACTION BAR.\"</string>
|
||||
<string name="sms_ready_text">TAP THE RECEIVING DEVICE NOW</string>
|
||||
<string name="not_again_sms_ready">YOU HAVE NFC ENABLED. THAT
|
||||
MEANS THAT ANY TIME A BOARD THAT\'S MISSING A PLAYER IS OPEN, YOU
|
||||
CAN TAP A NEARBY PERSON\'S DEVICE TO INVITE HIM/HER TO
|
||||
PLAY – IF HE/SHE IS ALSO USING NFC.</string>
|
||||
<!-- <string name="not_again_sms_ready">You have NFC enabled. That -->
|
||||
<!-- means that any time a board that\'s missing a player is open, you -->
|
||||
<!-- can tap a nearby person\'s device to invite him/her to -->
|
||||
<!-- play – if he/she is also using NFC.</string> -->
|
||||
<string name="pct_suffix">\u0020PCT.</string>
|
||||
<string name="menu_rateme">RATE CROSSWORDS</string>
|
||||
<string name="no_market">GOOGLE PLAY APP NOT FOUND</string>
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
/* -*- compile-command: "find-and-ant.sh debug install"; -*- */
|
||||
/*
|
||||
* Copyright 2009-2011 by Eric House (xwords@eehouse.org). All
|
||||
* rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class AbsLaunchInfo {
|
||||
private static final String VALID = "abslaunchinfo_valid";
|
||||
|
||||
protected String dict;
|
||||
protected int lang;
|
||||
protected int nPlayersT;
|
||||
|
||||
private boolean m_valid;
|
||||
|
||||
protected AbsLaunchInfo() {}
|
||||
|
||||
protected JSONObject init( String data ) throws JSONException
|
||||
{
|
||||
JSONObject json = new JSONObject( data );
|
||||
lang = json.getInt( MultiService.LANG );
|
||||
dict = json.getString( MultiService.DICT );
|
||||
nPlayersT = json.getInt( MultiService.NPLAYERST );
|
||||
return json;
|
||||
}
|
||||
|
||||
protected void init( Intent intent )
|
||||
{
|
||||
Bundle bundle = intent.getExtras();
|
||||
init( bundle );
|
||||
}
|
||||
|
||||
protected void init( Bundle bundle )
|
||||
{
|
||||
lang = bundle.getInt( MultiService.LANG );
|
||||
dict = bundle.getString( MultiService.DICT );
|
||||
nPlayersT = bundle.getInt( MultiService.NPLAYERST );
|
||||
m_valid = bundle.getBoolean( VALID );
|
||||
}
|
||||
|
||||
protected void putSelf( Bundle bundle )
|
||||
{
|
||||
bundle.putInt( MultiService.LANG, lang );
|
||||
bundle.putString( MultiService.DICT, dict );
|
||||
bundle.putInt( MultiService.NPLAYERST, nPlayersT );
|
||||
bundle.putBoolean( VALID, m_valid );
|
||||
}
|
||||
|
||||
protected static JSONObject makeLaunchJSONObject( int lang, String dict,
|
||||
int nPlayersT )
|
||||
throws JSONException
|
||||
{
|
||||
return new JSONObject()
|
||||
.put( MultiService.LANG, lang )
|
||||
.put( MultiService.DICT, dict )
|
||||
.put( MultiService.NPLAYERST, nPlayersT )
|
||||
;
|
||||
}
|
||||
|
||||
protected boolean isValid() { return m_valid; }
|
||||
protected void setValid( boolean valid ) { m_valid = valid; }
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
/* -*- compile-command: "find-and-ant.sh debug install"; -*- */
|
||||
/*
|
||||
* Copyright 2009-2011 by Eric House (xwords@eehouse.org). All
|
||||
* rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eehouse.android.xw4.jni.CommsAddrRec;
|
||||
|
||||
public class BTLaunchInfo extends AbsLaunchInfo {
|
||||
|
||||
protected String btName;
|
||||
protected String btAddress;
|
||||
protected int gameID;
|
||||
|
||||
public BTLaunchInfo( String data )
|
||||
{
|
||||
try {
|
||||
JSONObject json = init( data );
|
||||
gameID = json.getInt( MultiService.GAMEID );
|
||||
btName = json.getString( MultiService.BT_NAME );
|
||||
btAddress = json.getString( MultiService.BT_ADDRESS );
|
||||
setValid( true );
|
||||
} catch ( JSONException ex ) {
|
||||
DbgUtils.loge( ex );
|
||||
}
|
||||
}
|
||||
|
||||
public static String makeLaunchJSON( String curJson, int gameID, int lang,
|
||||
String dict, int nPlayersT )
|
||||
{
|
||||
Assert.assertNull( curJson );
|
||||
String result = null;
|
||||
BluetoothAdapter adapter = XWApp.BTSUPPORTED
|
||||
? BluetoothAdapter.getDefaultAdapter() : null;
|
||||
if ( null != adapter ) {
|
||||
String name = adapter.getName();
|
||||
String address = adapter.getAddress();
|
||||
|
||||
try {
|
||||
result = makeLaunchJSONObject( lang, dict, nPlayersT )
|
||||
.put( MultiService.GAMEID, gameID )
|
||||
.put( MultiService.BT_NAME, name )
|
||||
.put( MultiService.BT_ADDRESS, address )
|
||||
.toString();
|
||||
} catch ( org.json.JSONException jse ) {
|
||||
DbgUtils.loge( jse );
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public BTLaunchInfo( Intent intent )
|
||||
{
|
||||
init( intent );
|
||||
btName = intent.getStringExtra( MultiService.BT_NAME );
|
||||
btAddress = intent.getStringExtra( MultiService.BT_ADDRESS );
|
||||
gameID = intent.getIntExtra( MultiService.GAMEID, 0 );
|
||||
setValid( null != btAddress && 0 != gameID );
|
||||
}
|
||||
|
||||
|
||||
public static void putExtras( Intent intent, int gameID,
|
||||
String btName, String btAddr )
|
||||
{
|
||||
intent.putExtra( MultiService.GAMEID, gameID );
|
||||
intent.putExtra( MultiService.BT_NAME, btName );
|
||||
intent.putExtra( MultiService.BT_ADDRESS, btAddr );
|
||||
|
||||
intent.putExtra( MultiService.OWNER, MultiService.OWNER_BT );
|
||||
}
|
||||
|
||||
public CommsAddrRec getAddrRec()
|
||||
{
|
||||
return new CommsAddrRec( btName, btAddress );
|
||||
}
|
||||
}
|
|
@ -125,11 +125,13 @@ public class BTService extends XWService {
|
|||
}
|
||||
public BTQueueElem( BTCmd cmd, byte[] buf, String btAddr, int gameID ) {
|
||||
this( cmd );
|
||||
Assert.assertTrue( null != btAddr && 0 < btAddr.length() );
|
||||
m_msg = buf; m_btAddr = btAddr;
|
||||
m_gameID = gameID;
|
||||
}
|
||||
public BTQueueElem( BTCmd cmd, String btAddr, int gameID ) {
|
||||
this( cmd );
|
||||
Assert.assertTrue( null != btAddr && 0 < btAddr.length() );
|
||||
m_btAddr = btAddr;
|
||||
m_gameID = gameID;
|
||||
}
|
||||
|
@ -157,6 +159,13 @@ public class BTService extends XWService {
|
|||
return null != adapter && adapter.isEnabled();
|
||||
}
|
||||
|
||||
public static String[] getBTNameAndAddress()
|
||||
{
|
||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
return null == adapter ? null
|
||||
: new String[] { adapter.getName(), adapter.getAddress() };
|
||||
}
|
||||
|
||||
public static int getPairedCount( Activity activity )
|
||||
{
|
||||
int result = 0;
|
||||
|
@ -242,7 +251,7 @@ public class BTService extends XWService {
|
|||
context.startService( intent );
|
||||
}
|
||||
|
||||
public static void gotGameViaNFC( Context context, BTLaunchInfo bli )
|
||||
public static void gotGameViaNFC( Context context, NetLaunchInfo bli )
|
||||
{
|
||||
Intent intent = getIntentTo( context, NFCINVITE );
|
||||
intent.putExtra( GAMEID_STR, bli.gameID );
|
||||
|
@ -258,12 +267,18 @@ public class BTService extends XWService {
|
|||
public static int enqueueFor( Context context, byte[] buf,
|
||||
String targetAddr, int gameID )
|
||||
{
|
||||
Intent intent = getIntentTo( context, SEND );
|
||||
intent.putExtra( MSG_STR, buf );
|
||||
intent.putExtra( ADDR_STR, targetAddr );
|
||||
intent.putExtra( GAMEID_STR, gameID );
|
||||
context.startService( intent );
|
||||
return buf.length;
|
||||
int nSent = -1;
|
||||
if ( null != targetAddr && 0 < targetAddr.length() ) {
|
||||
Intent intent = getIntentTo( context, SEND );
|
||||
intent.putExtra( MSG_STR, buf );
|
||||
intent.putExtra( ADDR_STR, targetAddr );
|
||||
intent.putExtra( GAMEID_STR, gameID );
|
||||
context.startService( intent );
|
||||
nSent = buf.length;
|
||||
} else {
|
||||
DbgUtils.logf( "BTService.enqueueFor(): targetAddr is null" );
|
||||
}
|
||||
return nSent;
|
||||
}
|
||||
|
||||
public static void gameDied( Context context, int gameID )
|
||||
|
@ -1015,7 +1030,8 @@ public class BTService extends XWService {
|
|||
Intent intent = MultiService
|
||||
.makeMissingDictIntent( context, gameName, lang, dict,
|
||||
nPlayersT, nPlayersH );
|
||||
BTLaunchInfo.putExtras( intent, gameID, btName, btAddr );
|
||||
Assert.fail();
|
||||
// NetLaunchInfo.putExtras( intent, gameID, btName, btAddr );
|
||||
MultiService.postMissingDictNotification( context, intent,
|
||||
gameID );
|
||||
result = BTCmd.INVITE_ACCPT; // ???
|
||||
|
|
|
@ -51,6 +51,7 @@ import java.util.concurrent.Semaphore;
|
|||
import junit.framework.Assert;
|
||||
|
||||
import org.eehouse.android.xw4.DlgDelegate.Action;
|
||||
import org.eehouse.android.xw4.DlgDelegate.DlgClickNotify.InviteMeans;
|
||||
import org.eehouse.android.xw4.jni.*;
|
||||
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
|
||||
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet;
|
||||
|
@ -106,6 +107,7 @@ public class BoardDelegate extends DelegateBase
|
|||
private String[] m_texts;
|
||||
private CommsConnTypeSet m_connTypes = null;
|
||||
private String[] m_missingDevs;
|
||||
private InviteMeans m_missingMeans = null;
|
||||
private boolean m_progressShown = false;
|
||||
private String m_curTiles;
|
||||
private boolean m_canUndoTiles;
|
||||
|
@ -450,7 +452,7 @@ public class BoardDelegate extends DelegateBase
|
|||
.create();
|
||||
break;
|
||||
case DLG_INVITE:
|
||||
if ( null != m_room ) {
|
||||
if ( true || null != m_room ) {
|
||||
lstnr = new DialogInterface.OnClickListener() {
|
||||
public void onClick( DialogInterface dialog,
|
||||
int item ) {
|
||||
|
@ -462,6 +464,8 @@ public class BoardDelegate extends DelegateBase
|
|||
.setPositiveButton( R.string.button_yes, lstnr )
|
||||
.setNegativeButton( R.string.button_no, null )
|
||||
.create();
|
||||
} else {
|
||||
DbgUtils.showf( m_activity, "can't invite for relay: room name not set" );
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -481,7 +485,7 @@ public class BoardDelegate extends DelegateBase
|
|||
protected void prepareDialog( DlgID dlgID, Dialog dialog )
|
||||
{
|
||||
switch( dlgID ) {
|
||||
case DLG_INVITE:
|
||||
case DLG_INVITE: // here
|
||||
AlertDialog ad = (AlertDialog)dialog;
|
||||
String message =
|
||||
getString( R.string.invite_msg_fmt, m_nMissing );
|
||||
|
@ -621,11 +625,13 @@ public class BoardDelegate extends DelegateBase
|
|||
// onActivityResult is called immediately *before*
|
||||
// onResume -- meaning m_gi etc are still null.
|
||||
m_missingDevs = data.getStringArrayExtra( BTInviteDelegate.DEVS );
|
||||
m_missingMeans = InviteMeans.BLUETOOTH;
|
||||
break;
|
||||
case SMS_INVITE_RESULT:
|
||||
// onActivityResult is called immediately *before*
|
||||
// onResume -- meaning m_gi etc are still null.
|
||||
m_missingDevs = data.getStringArrayExtra( SMSInviteDelegate.DEVS );
|
||||
m_missingMeans = InviteMeans.SMS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -905,24 +911,7 @@ public class BoardDelegate extends DelegateBase
|
|||
@Override
|
||||
public void dlgButtonClicked( Action action, int which, Object[] params )
|
||||
{
|
||||
if ( Action.LAUNCH_INVITE_ACTION == action ) {
|
||||
if ( DlgDelegate.DISMISS_BUTTON != which ) {
|
||||
if ( DlgDelegate.NFC_BTN == which ) {
|
||||
if ( NFCUtils.nfcAvail( m_activity )[1] ) {
|
||||
showNotAgainDlgThen( R.string.not_again_sms_ready,
|
||||
R.string.key_notagain_sms_ready );
|
||||
} else {
|
||||
showDialog( DlgID.ENABLE_NFC );
|
||||
}
|
||||
} else {
|
||||
String inviteID = GameUtils.formatGameID( m_gi.gameID );
|
||||
GameUtils.launchInviteActivity( m_activity, which, m_room,
|
||||
inviteID, m_gi.dictLang,
|
||||
m_gi.dictName,
|
||||
m_gi.nPlayers );
|
||||
}
|
||||
}
|
||||
} else if ( AlertDialog.BUTTON_POSITIVE == which ) {
|
||||
if ( AlertDialog.BUTTON_POSITIVE == which ) {
|
||||
JNICmd cmd = JNICmd.CMD_NONE;
|
||||
switch ( action ) {
|
||||
case UNDO_LAST_ACTION:
|
||||
|
@ -1001,6 +990,34 @@ public class BoardDelegate extends DelegateBase
|
|||
}
|
||||
} // dlgButtonClicked
|
||||
|
||||
public void inviteChoiceMade( Action action, InviteMeans means,
|
||||
Object[] params )
|
||||
{
|
||||
if ( action == Action.LAUNCH_INVITE_ACTION ) {
|
||||
switch( means ) {
|
||||
case NFC:
|
||||
if ( ! NFCUtils.nfcAvail( m_activity )[1] ) {
|
||||
showDialog( DlgID.ENABLE_NFC );
|
||||
}
|
||||
break;
|
||||
case BLUETOOTH:
|
||||
BTInviteDelegate.launchForResult( m_activity, m_nMissing,
|
||||
BT_INVITE_RESULT );
|
||||
break;
|
||||
case SMS:
|
||||
SMSInviteDelegate.launchForResult( m_activity, m_nMissing,
|
||||
SMS_INVITE_RESULT );
|
||||
break;
|
||||
case EMAIL:
|
||||
NetLaunchInfo nli = new NetLaunchInfo( m_summary, m_gi );
|
||||
GameUtils.launchEmailInviteActivity( m_activity, nli );
|
||||
break;
|
||||
default:
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// View.OnClickListener interface
|
||||
//////////////////////////////////////////////////
|
||||
|
@ -1167,31 +1184,34 @@ public class BoardDelegate extends DelegateBase
|
|||
public String makeNFCMessage()
|
||||
{
|
||||
String data = null;
|
||||
for ( Iterator<CommsConnType> iter = m_connTypes.iterator();
|
||||
iter.hasNext(); ) {
|
||||
CommsConnType typ = iter.next();
|
||||
switch ( typ ) {
|
||||
case COMMS_CONN_RELAY:
|
||||
if ( 0 < m_nMissing ) { // Isn't there a better test??
|
||||
if ( 0 < m_nMissing ) { // Isn't there a better test??
|
||||
NetLaunchInfo nli = new NetLaunchInfo( m_gi.gameID, m_gi.dictLang,
|
||||
m_gi.dictName, m_gi.nPlayers );
|
||||
for ( Iterator<CommsConnType> iter = m_connTypes.iterator();
|
||||
iter.hasNext(); ) {
|
||||
CommsConnType typ = iter.next();
|
||||
switch ( typ ) {
|
||||
case COMMS_CONN_RELAY:
|
||||
String room = m_summary.roomName;
|
||||
String inviteID = String.format( "%X", m_gi.gameID );
|
||||
Assert.assertNotNull( room );
|
||||
data = NetLaunchInfo.makeLaunchJSON( data, room, inviteID, m_gi.dictLang,
|
||||
m_gi.dictName, m_gi.nPlayers );
|
||||
removeDialog( DlgID.DLG_INVITE );
|
||||
String inviteID = String.format( "%X", m_gi.gameID );
|
||||
nli.addRelayInfo( room, inviteID );
|
||||
break;
|
||||
case COMMS_CONN_BT:
|
||||
nli.addBTInfo();
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
nli.addSMSInfo();
|
||||
break;
|
||||
default:
|
||||
DbgUtils.logf( "Not doing NFC join for conn type %s",
|
||||
typ.toString() );
|
||||
}
|
||||
break;
|
||||
case COMMS_CONN_BT:
|
||||
if ( 0 < m_nMissing ) {
|
||||
data = BTLaunchInfo.makeLaunchJSON( data, m_gi.gameID, m_gi.dictLang,
|
||||
m_gi.dictName, m_gi.nPlayers );
|
||||
removeDialog( DlgID.CONFIRM_THEN );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DbgUtils.logf( "Not doing NFC join for conn type %s",
|
||||
typ.toString() );
|
||||
}
|
||||
data = nli.makeLaunchJSON();
|
||||
}
|
||||
if ( null != data ) {
|
||||
removeDialog( DlgID.CONFIRM_THEN );
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
@ -1314,6 +1334,7 @@ public class BoardDelegate extends DelegateBase
|
|||
private void handleConndMessage( String room, int devOrder, // <- hostID
|
||||
boolean allHere, int nMissing )
|
||||
{
|
||||
DbgUtils.logf( "BoardDelegate.handleConndMessage(): nMissing = %d", nMissing );
|
||||
int naMsg = 0;
|
||||
int naKey = 0;
|
||||
String toastStr = null;
|
||||
|
@ -1652,26 +1673,30 @@ public class BoardDelegate extends DelegateBase
|
|||
{
|
||||
m_connTypes = connTypes;
|
||||
Assert.assertTrue( isServer || 0 == nMissing );
|
||||
DbgUtils.logf( "BoardDelegate.informMissing(isServer=%b, nMissing = %d)",
|
||||
isServer, nMissing );
|
||||
m_nMissing = nMissing; // will be 0 unless isServer is true
|
||||
|
||||
Action action = null;
|
||||
if ( 0 < nMissing && isServer && !m_haveInvited ) {
|
||||
for ( Iterator<CommsConnType> iter = connTypes.iterator();
|
||||
null == action && iter.hasNext(); ) {
|
||||
CommsConnType connType = iter.next();
|
||||
switch( connType ) {
|
||||
case COMMS_CONN_BT:
|
||||
action = Action.BT_PICK_ACTION;
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
action = Action.SMS_PICK_ACTION;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( null != action ) {
|
||||
nonRelayInvite( action );
|
||||
// showInviteChoicesThen( Action.LAUNCH_INVITE_ACTION );
|
||||
showDialog( DlgID.DLG_INVITE );
|
||||
// for ( Iterator<CommsConnType> iter = connTypes.iterator();
|
||||
// null == action && iter.hasNext(); ) {
|
||||
// CommsConnType connType = iter.next();
|
||||
// switch( connType ) {
|
||||
// case COMMS_CONN_BT:
|
||||
// action = Action.BT_PICK_ACTION;
|
||||
// break;
|
||||
// case COMMS_CONN_SMS:
|
||||
// action = Action.SMS_PICK_ACTION;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
// if ( null != action ) {
|
||||
// nonRelayInvite( action );
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1779,25 +1804,32 @@ public class BoardDelegate extends DelegateBase
|
|||
} // class BoardUtilCtxt
|
||||
|
||||
private void inviteForMissing() {
|
||||
outer:
|
||||
DbgUtils.logf( "BoardDelegate.inviteForMissing()" );
|
||||
boolean done = false;
|
||||
for ( Iterator<CommsConnType> iter = m_connTypes.iterator();
|
||||
iter.hasNext(); ) {
|
||||
switch( iter.next() ) {
|
||||
!done && iter.hasNext(); ) {
|
||||
CommsConnType typ = iter.next();
|
||||
DbgUtils.logf( "BoardDelegate.inviteForMissing(): got %s", typ.toString() );
|
||||
switch( typ ) {
|
||||
case COMMS_CONN_BT:
|
||||
nonRelayInvite( Action.BT_PICK_ACTION );
|
||||
break outer;
|
||||
done = true;
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
nonRelayInvite( Action.SMS_PICK_ACTION );
|
||||
break outer;
|
||||
done = true;
|
||||
break;
|
||||
case COMMS_CONN_RELAY:
|
||||
showDialog( DlgID.DLG_INVITE );
|
||||
break outer;
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void nonRelayInvite( final Action action )
|
||||
{
|
||||
DbgUtils.logf( "BoardDelegate.nonRelayInvite()" );
|
||||
m_haveInvited = true;
|
||||
post( new Runnable() {
|
||||
public void run() {
|
||||
|
@ -1835,6 +1867,7 @@ public class BoardDelegate extends DelegateBase
|
|||
byte[] stream = GameUtils.savedGame( m_activity, m_gameLock );
|
||||
m_gi = new CurGameInfo( m_activity );
|
||||
XwJNI.gi_from_stream( m_gi, stream );
|
||||
DbgUtils.logf( "BoardDelegate:after loadGame: gi.nPlayers: %d", m_gi.nPlayers );
|
||||
String langName = m_gi.langName();
|
||||
|
||||
setThis( this );
|
||||
|
@ -1859,10 +1892,12 @@ public class BoardDelegate extends DelegateBase
|
|||
dictNames, pairs.m_bytes,
|
||||
pairs.m_paths, langName );
|
||||
}
|
||||
|
||||
m_summary = new GameSummary( m_activity, m_gi );
|
||||
XwJNI.game_summarize( m_jniGamePtr, m_summary );
|
||||
|
||||
DbgUtils.logf( "BoardDelegate:after makeFromStream: room name: %s",
|
||||
m_summary.roomName );
|
||||
|
||||
Handler handler = new Handler() {
|
||||
public void handleMessage( Message msg ) {
|
||||
switch( msg.what ) {
|
||||
|
@ -2207,17 +2242,18 @@ public class BoardDelegate extends DelegateBase
|
|||
{
|
||||
if ( XWApp.BTSUPPORTED || XWApp.SMSSUPPORTED ) {
|
||||
if ( null != m_missingDevs ) {
|
||||
Assert.assertNotNull( m_missingMeans );
|
||||
String gameName = GameUtils.getName( m_activity, m_rowid );
|
||||
m_invitesPending = m_missingDevs.length;
|
||||
for ( String dev : m_missingDevs ) {
|
||||
if ( m_connTypes.contains( CommsConnType.COMMS_CONN_BT ) ) {
|
||||
switch ( m_missingMeans ) {
|
||||
case BLUETOOTH:
|
||||
String progMsg = BTService.nameForAddr( dev );
|
||||
progMsg = getString( R.string.invite_progress_fmt, progMsg );
|
||||
m_progressShown = true;
|
||||
startProgress( R.string.invite_progress_title, progMsg,
|
||||
new DialogInterface.OnCancelListener() {
|
||||
public void
|
||||
onCancel( DialogInterface dlg )
|
||||
public void onCancel( DialogInterface dlg )
|
||||
{
|
||||
m_progressShown = false;
|
||||
}
|
||||
|
@ -2227,14 +2263,17 @@ public class BoardDelegate extends DelegateBase
|
|||
gameName, m_gi.dictLang,
|
||||
m_gi.dictName, m_gi.nPlayers,
|
||||
1 );
|
||||
} else if ( m_connTypes.contains( CommsConnType.COMMS_CONN_SMS ) ) {
|
||||
break;
|
||||
case SMS:
|
||||
SMSService.inviteRemote( m_activity, dev, m_gi.gameID,
|
||||
gameName, m_gi.dictLang,
|
||||
m_gi.dictName, m_gi.nPlayers,
|
||||
1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_missingDevs = null;
|
||||
m_missingMeans = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -667,7 +667,7 @@ public class DBUtils {
|
|||
|
||||
// Return creation time of newest game matching this nli, or null
|
||||
// if none found.
|
||||
public static Date getMostRecentCreate( Context context, BTLaunchInfo bli )
|
||||
public static Date getMostRecentCreate( Context context, NetLaunchInfo bli )
|
||||
{
|
||||
Date result = null;
|
||||
String[] selectionArgs = new String[] {
|
||||
|
@ -686,37 +686,38 @@ public class DBUtils {
|
|||
cursor.close();
|
||||
db.close();
|
||||
}
|
||||
DbgUtils.logf( "getMostRecentCreate() => %H", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return creation time of newest game matching this nli, or null
|
||||
// if none found.
|
||||
public static Date getMostRecentCreate( Context context, NetLaunchInfo nli )
|
||||
{
|
||||
Date result = null;
|
||||
String[] selectionArgs = new String[] {
|
||||
DBHelper.ROOMNAME, nli.room,
|
||||
DBHelper.INVITEID, nli.inviteID,
|
||||
DBHelper.DICTLANG, String.format( "%d", nli.lang ),
|
||||
DBHelper.NUM_PLAYERS, String.format( "%d", nli.nPlayersT )
|
||||
};
|
||||
// public static Date getMostRecentCreate( Context context, NetLaunchInfo nli )
|
||||
// {
|
||||
// Date result = null;
|
||||
// String[] selectionArgs = new String[] {
|
||||
// DBHelper.ROOMNAME, nli.room,
|
||||
// DBHelper.INVITEID, nli.inviteID,
|
||||
// DBHelper.DICTLANG, String.format( "%d", nli.lang ),
|
||||
// DBHelper.NUM_PLAYERS, String.format( "%d", nli.nPlayersT )
|
||||
// };
|
||||
|
||||
initDB( context );
|
||||
synchronized( s_dbHelper ) {
|
||||
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
Cursor cursor = db.rawQuery( "SELECT " + DBHelper.CREATE_TIME +
|
||||
" FROM " + DBHelper.TABLE_NAME_SUM +
|
||||
" WHERE ?=? AND ?=? AND ?=? AND ?=?",
|
||||
selectionArgs );
|
||||
if ( cursor.moveToNext() ) {
|
||||
int indx = cursor.getColumnIndex( DBHelper.CREATE_TIME );
|
||||
result = new Date( cursor.getLong( indx ) );
|
||||
}
|
||||
cursor.close();
|
||||
db.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// initDB( context );
|
||||
// synchronized( s_dbHelper ) {
|
||||
// SQLiteDatabase db = s_dbHelper.getReadableDatabase();
|
||||
// Cursor cursor = db.rawQuery( "SELECT " + DBHelper.CREATE_TIME +
|
||||
// " FROM " + DBHelper.TABLE_NAME_SUM +
|
||||
// " WHERE ?=? AND ?=? AND ?=? AND ?=?",
|
||||
// selectionArgs );
|
||||
// if ( cursor.moveToNext() ) {
|
||||
// int indx = cursor.getColumnIndex( DBHelper.CREATE_TIME );
|
||||
// result = new Date( cursor.getLong( indx ) );
|
||||
// }
|
||||
// cursor.close();
|
||||
// db.close();
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
public static Date getMostRecentCreate( Context context, Uri data )
|
||||
{
|
||||
|
@ -2134,7 +2135,7 @@ public class DBUtils {
|
|||
}
|
||||
|
||||
private static final int BIT_VECTOR_MASK = 0x8000;
|
||||
private static CommsConnTypeSet intToConnTypeSet( int asInt )
|
||||
public static CommsConnTypeSet intToConnTypeSet( int asInt )
|
||||
{
|
||||
DbgUtils.logf( "intToConnTypeSet(in: %s)", asInt );
|
||||
CommsConnTypeSet result = new CommsConnTypeSet();
|
||||
|
@ -2155,7 +2156,7 @@ public class DBUtils {
|
|||
return result;
|
||||
}
|
||||
|
||||
private static int connTypeSetToInt( CommsConnTypeSet set )
|
||||
public static int connTypeSetToInt( CommsConnTypeSet set )
|
||||
{
|
||||
DbgUtils.logf( "connTypeSetToInt(setSize: %d)", set.size() );
|
||||
int result = BIT_VECTOR_MASK;
|
||||
|
|
|
@ -38,10 +38,11 @@ import android.widget.TextView;
|
|||
import org.eehouse.android.xw4.DlgDelegate.Action;
|
||||
import org.eehouse.android.xw4.loc.LocUtils;
|
||||
import org.eehouse.android.xw4.MultiService.MultiEvent;
|
||||
import org.eehouse.android.xw4.DlgDelegate.DlgClickNotify;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class DelegateBase implements DlgDelegate.DlgClickNotify,
|
||||
public class DelegateBase implements DlgClickNotify,
|
||||
DlgDelegate.HasDlgDelegate,
|
||||
MultiService.MultiEventListener {
|
||||
|
||||
|
@ -484,4 +485,10 @@ public class DelegateBase implements DlgDelegate.DlgClickNotify,
|
|||
{
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
public void inviteChoiceMade( Action action, DlgClickNotify.InviteMeans means, Object[] params )
|
||||
{
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import android.os.Handler;
|
|||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
@ -112,7 +113,11 @@ public class DlgDelegate {
|
|||
private static final String STATE_KEYF = "STATE_%d";
|
||||
|
||||
public interface DlgClickNotify {
|
||||
public static enum InviteMeans {
|
||||
SMS, EMAIL, NFC, BLUETOOTH,
|
||||
};
|
||||
void dlgButtonClicked( Action action, int button, Object[] params );
|
||||
void inviteChoiceMade( Action action, InviteMeans means, Object[] params );
|
||||
}
|
||||
public interface HasDlgDelegate {
|
||||
void showOKOnlyDialog( int msgID );
|
||||
|
@ -313,7 +318,8 @@ public class DlgDelegate {
|
|||
public void showInviteChoicesThen( final Action action )
|
||||
{
|
||||
if ( Utils.deviceSupportsSMS( m_activity )
|
||||
|| NFCUtils.nfcAvail( m_activity )[0] ) {
|
||||
|| NFCUtils.nfcAvail( m_activity )[0]
|
||||
|| BTService.BTAvailable() ) {
|
||||
DlgState state = new DlgState( DlgID.INVITE_CHOICES_THEN, action );
|
||||
addState( state );
|
||||
showDialog( DlgID.INVITE_CHOICES_THEN );
|
||||
|
@ -516,32 +522,50 @@ public class DlgDelegate {
|
|||
return setCallbackDismissListener( dialog, state, dlgID );
|
||||
}
|
||||
|
||||
private Dialog createInviteChoicesDialog( DlgState state, DlgID dlgID )
|
||||
private Dialog createInviteChoicesDialog( final DlgState state, DlgID dlgID )
|
||||
{
|
||||
OnClickListener lstnr = mkCallbackClickListener( state );
|
||||
final ArrayList<DlgClickNotify.InviteMeans> means =
|
||||
new ArrayList<DlgClickNotify.InviteMeans>();
|
||||
ArrayList<String> items = new ArrayList<String>();
|
||||
if ( Utils.deviceSupportsSMS( m_activity ) ) {
|
||||
items.add( getString( R.string.invite_choice_sms ) );
|
||||
means.add( DlgClickNotify.InviteMeans.SMS );
|
||||
}
|
||||
items.add( getString( R.string.invite_choice_email ) );
|
||||
means.add( DlgClickNotify.InviteMeans.EMAIL );
|
||||
if ( BTService.BTAvailable() ) {
|
||||
items.add( getString( R.string.invite_choice_bt ) );
|
||||
means.add( DlgClickNotify.InviteMeans.BLUETOOTH );
|
||||
}
|
||||
if ( NFCUtils.nfcAvail( m_activity )[0] ) {
|
||||
items.add( getString( R.string.invite_choice_nfc ) );
|
||||
means.add( DlgClickNotify.InviteMeans.NFC );
|
||||
}
|
||||
|
||||
boolean haveSMS = Utils.deviceSupportsSMS( m_activity );
|
||||
boolean haveNFC = NFCUtils.nfcAvail( m_activity )[0];
|
||||
int msgID;
|
||||
if ( haveSMS && haveNFC ) {
|
||||
msgID = R.string.nfc_or_sms_or_email;
|
||||
} else if ( haveSMS ) {
|
||||
msgID = R.string.sms_or_email;
|
||||
} else {
|
||||
msgID = R.string.nfc_or_email;
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = LocUtils.makeAlertBuilder( m_activity );
|
||||
builder.setTitle( R.string.query_title );
|
||||
builder.setMessage( msgID );
|
||||
builder.setNegativeButton( R.string.button_html, lstnr );
|
||||
final int[] sel = { -1 };
|
||||
OnClickListener selChanged = new OnClickListener() {
|
||||
public void onClick( DialogInterface dlg, int view ) {
|
||||
sel[0] = view;
|
||||
}
|
||||
};
|
||||
OnClickListener okClicked = new OnClickListener() {
|
||||
public void onClick( DialogInterface dlg, int view ) {
|
||||
Assert.assertTrue( Action.SKIP_CALLBACK != state.m_action );
|
||||
int indx = sel[0];
|
||||
if ( 0 <= indx ) {
|
||||
m_clickCallback.inviteChoiceMade( state.m_action,
|
||||
means.get(indx),
|
||||
state.m_params );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if ( haveSMS ) {
|
||||
builder.setPositiveButton( R.string.button_text, lstnr );
|
||||
}
|
||||
if ( haveNFC ) {
|
||||
builder.setNeutralButton( R.string.button_nfc, lstnr );
|
||||
}
|
||||
AlertDialog.Builder builder = LocUtils.makeAlertBuilder( m_activity )
|
||||
.setTitle( R.string.invite_choice_title )
|
||||
.setSingleChoiceItems( items.toArray( new String[items.size()] ),
|
||||
sel[0], selChanged )
|
||||
.setPositiveButton( R.string.button_ok, okClicked )
|
||||
.setNegativeButton( R.string.button_cancel, null );
|
||||
|
||||
return setCallbackDismissListener( builder.create(), state, dlgID );
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
|
|||
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet;
|
||||
import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
|
||||
import org.eehouse.android.xw4.jni.LastMoveInfo;
|
||||
import org.eehouse.android.xw4.DlgDelegate.DlgClickNotify.InviteMeans;
|
||||
|
||||
public class GameUtils {
|
||||
|
||||
|
@ -451,6 +452,17 @@ public class GameUtils {
|
|||
return rowid;
|
||||
}
|
||||
|
||||
public static long makeNewMultiGame( Context context, NetLaunchInfo nli )
|
||||
{
|
||||
DbgUtils.logf( "makeNewMultiGame(nli=%s)", nli.toString() );
|
||||
CommsAddrRec addr = nli.makeAddrRec( context );
|
||||
|
||||
return makeNewMultiGame( context, null, DBUtils.GROUPID_UNSPEC, addr,
|
||||
new int[] {nli.lang}, new String[] { nli.dict },
|
||||
nli.nPlayersT, 1, nli.inviteID,
|
||||
nli.gameID, false );
|
||||
}
|
||||
|
||||
private static long makeNewMultiGame( Context context, long groupID,
|
||||
CommsAddrRec addr,
|
||||
int[] lang, String[] dict,
|
||||
|
@ -507,9 +519,10 @@ public class GameUtils {
|
|||
int relayPort = XWPrefs.getDefaultRelayPort( context );
|
||||
CommsAddrRec addr = new CommsAddrRec( relayName, relayPort );
|
||||
addr.ip_relay_invite = room;
|
||||
addr.conTypes.add( CommsConnType.COMMS_CONN_BT );
|
||||
|
||||
return makeNewMultiGame( context, groupID, addr, lang, dict,
|
||||
nPlayersT, nPlayersH, inviteID, 0, false );
|
||||
nPlayersT, nPlayersH, inviteID, 0, true );
|
||||
}
|
||||
|
||||
public static long makeNewRelayGame( Context context, long groupID,
|
||||
|
@ -555,11 +568,13 @@ public class GameUtils {
|
|||
lang, dict, nPlayersT, nPlayersH );
|
||||
}
|
||||
|
||||
public static long makeNewBTGame( Context context, BTLaunchInfo bli )
|
||||
public static long makeNewBTGame( Context context, NetLaunchInfo nli )
|
||||
{
|
||||
return makeNewBTGame( context, null, DBUtils.GROUPID_UNSPEC, bli.gameID,
|
||||
bli.getAddrRec(), bli.lang, bli.dict,
|
||||
bli.nPlayersT, 1 );
|
||||
Assert.fail();
|
||||
return -1;
|
||||
// return makeNewBTGame( context, null, DBUtils.GROUPID_UNSPEC, nli.gameID,
|
||||
// nli.btAddress, nli.lang, nli.dict,
|
||||
// nli.nPlayersT, 1 );
|
||||
}
|
||||
|
||||
public static long makeNewBTGame( Context context, MultiMsgSink sink,
|
||||
|
@ -567,17 +582,19 @@ public class GameUtils {
|
|||
int lang, String dict,
|
||||
int nPlayersT, int nPlayersH )
|
||||
{
|
||||
long rowid = -1;
|
||||
int[] langa = { lang };
|
||||
String[] dicta = { dict };
|
||||
boolean isHost = null == addr;
|
||||
if ( isHost ) {
|
||||
addr = new CommsAddrRec( null, null );
|
||||
}
|
||||
String inviteID = GameUtils.formatGameID( gameID );
|
||||
return makeNewMultiGame( context, sink, groupID, addr, langa, dicta,
|
||||
nPlayersT, nPlayersH, inviteID, gameID,
|
||||
isHost );
|
||||
Assert.fail();
|
||||
return -1;
|
||||
// long rowid = -1;
|
||||
// int[] langa = { lang };
|
||||
// String[] dicta = { dict };
|
||||
// boolean isHost = null == addr;
|
||||
// if ( isHost ) {
|
||||
// addr = new CommsAddrRec( null, null );
|
||||
// }
|
||||
// String inviteID = GameUtils.formatGameID( gameID );
|
||||
// return makeNewMultiGame( context, sink, groupID, addr, langa, dicta,
|
||||
// nPlayersT, nPlayersH, inviteID, gameID,
|
||||
// isHost );
|
||||
}
|
||||
|
||||
public static long makeNewSMSGame( Context context, int gameID,
|
||||
|
@ -607,70 +624,116 @@ public class GameUtils {
|
|||
isHost );
|
||||
}
|
||||
|
||||
public static void launchInviteActivity( Activity activity, int chosen,
|
||||
String room, String inviteID,
|
||||
int lang, String dict,
|
||||
int nPlayers )
|
||||
public static void launchEmailInviteActivity( Activity activity, NetLaunchInfo nli )
|
||||
{
|
||||
Assert.assertNotNull( inviteID );
|
||||
DbgUtils.logf( "launchEmailInviteActivity: nli=%s", nli.makeLaunchJSON() );
|
||||
Uri gameUri = nli.makeLaunchUri( activity );
|
||||
DbgUtils.logf( "launchEmailInviteActivity: uri=%s", gameUri );
|
||||
|
||||
if ( DlgDelegate.NFC_BTN == chosen ) {
|
||||
Utils.showToast( activity, R.string.sms_ready_text );
|
||||
} else {
|
||||
Uri gameUri = NetLaunchInfo.makeLaunchUri( activity, room, inviteID,
|
||||
lang, dict, nPlayers );
|
||||
String msgString = null == gameUri ? null : gameUri.toString();
|
||||
String msgString = null == gameUri ? null : gameUri.toString();
|
||||
if ( null != msgString ) {
|
||||
int choiceID;
|
||||
String message = LocUtils.getString( activity, R.string.invite_htm_fmt, msgString );
|
||||
|
||||
if ( null != msgString ) {
|
||||
boolean choseEmail = DlgDelegate.EMAIL_BTN == chosen;
|
||||
Intent intent = new Intent();
|
||||
intent.setAction( Intent.ACTION_SEND );
|
||||
String subject =
|
||||
LocUtils.getString( activity, R.string.invite_subject_fmt,
|
||||
nli.room );
|
||||
intent.putExtra( Intent.EXTRA_SUBJECT, subject );
|
||||
intent.putExtra( Intent.EXTRA_TEXT, Html.fromHtml(message) );
|
||||
|
||||
int fmtId = choseEmail? R.string.invite_htm_fmt : R.string.invite_txt_fmt;
|
||||
int choiceID;
|
||||
String message = LocUtils.getString( activity, fmtId, msgString );
|
||||
|
||||
Intent intent = new Intent();
|
||||
if ( choseEmail ) {
|
||||
intent.setAction( Intent.ACTION_SEND );
|
||||
String subject =
|
||||
LocUtils.getString( activity, R.string.invite_subject_fmt,
|
||||
room );
|
||||
intent.putExtra( Intent.EXTRA_SUBJECT, subject );
|
||||
intent.putExtra( Intent.EXTRA_TEXT, Html.fromHtml(message) );
|
||||
|
||||
File attach = null;
|
||||
File tmpdir = XWApp.ATTACH_SUPPORTED ?
|
||||
DictUtils.getDownloadDir( activity ) : null;
|
||||
if ( null != tmpdir ) { // no attachment
|
||||
attach = makeJsonFor( tmpdir, room, inviteID, lang,
|
||||
dict, nPlayers );
|
||||
}
|
||||
|
||||
if ( null == attach ) { // no attachment
|
||||
intent.setType( "message/rfc822");
|
||||
} else {
|
||||
String mime = LocUtils.getString( activity, R.string.invite_mime );
|
||||
intent.setType( mime );
|
||||
Uri uri = Uri.fromFile( attach );
|
||||
intent.putExtra( Intent.EXTRA_STREAM, uri );
|
||||
}
|
||||
|
||||
choiceID = R.string.invite_chooser_email;
|
||||
} else {
|
||||
intent.setAction( Intent.ACTION_VIEW );
|
||||
intent.setType( "vnd.android-dir/mms-sms" );
|
||||
intent.putExtra( "sms_body", message );
|
||||
choiceID = R.string.invite_chooser_sms;
|
||||
}
|
||||
|
||||
String choiceType = LocUtils.getString( activity, choiceID );
|
||||
String chooserMsg =
|
||||
LocUtils.getString( activity, R.string.invite_chooser_fmt,
|
||||
choiceType );
|
||||
activity.startActivity( Intent.createChooser( intent, chooserMsg ) );
|
||||
File attach = null;
|
||||
File tmpdir = XWApp.ATTACH_SUPPORTED ?
|
||||
DictUtils.getDownloadDir( activity ) : null;
|
||||
if ( null != tmpdir ) { // no attachment
|
||||
attach = makeJsonFor( tmpdir, nli );
|
||||
}
|
||||
|
||||
if ( null == attach ) { // no attachment
|
||||
intent.setType( "message/rfc822");
|
||||
} else {
|
||||
String mime = LocUtils.getString( activity, R.string.invite_mime );
|
||||
intent.setType( mime );
|
||||
Uri uri = Uri.fromFile( attach );
|
||||
intent.putExtra( Intent.EXTRA_STREAM, uri );
|
||||
}
|
||||
|
||||
String choiceType = LocUtils.getString( activity, R.string.invite_chooser_email );
|
||||
String chooserMsg =
|
||||
LocUtils.getString( activity, R.string.invite_chooser_fmt,
|
||||
choiceType );
|
||||
activity.startActivity( Intent.createChooser( intent, chooserMsg ) );
|
||||
}
|
||||
}
|
||||
|
||||
// public static void launchInviteActivity( Activity activity,
|
||||
// InviteMeans means,
|
||||
// String room, String inviteID,
|
||||
// int lang, String dict,
|
||||
// int nPlayers )
|
||||
// {
|
||||
// Assert.assertNotNull( inviteID );
|
||||
|
||||
// if ( InviteMeans.NFC == means ) {
|
||||
// Utils.showToast( activity, R.string.sms_ready_text );
|
||||
// } else {
|
||||
// // NetLaunchInfo nli = new NetLaunchInfo( 0, lang, dict, nPlayers );
|
||||
|
||||
// Uri gameUri = NetLaunchInfo.makeLaunchUri( activity, room, inviteID,
|
||||
// lang, dict, nPlayers );
|
||||
// String msgString = null == gameUri ? null : gameUri.toString();
|
||||
|
||||
// if ( null != msgString ) {
|
||||
// boolean choseEmail = InviteMeans.EMAIL == means;
|
||||
|
||||
// int fmtId = choseEmail? R.string.invite_htm_fmt : R.string.invite_txt_fmt;
|
||||
// int choiceID;
|
||||
// String message = LocUtils.getString( activity, fmtId, msgString );
|
||||
|
||||
// Intent intent = new Intent();
|
||||
// if ( choseEmail ) {
|
||||
// intent.setAction( Intent.ACTION_SEND );
|
||||
// String subject =
|
||||
// LocUtils.getString( activity, R.string.invite_subject_fmt,
|
||||
// room );
|
||||
// intent.putExtra( Intent.EXTRA_SUBJECT, subject );
|
||||
// intent.putExtra( Intent.EXTRA_TEXT, Html.fromHtml(message) );
|
||||
|
||||
// File attach = null;
|
||||
// File tmpdir = XWApp.ATTACH_SUPPORTED ?
|
||||
// DictUtils.getDownloadDir( activity ) : null;
|
||||
// if ( null != tmpdir ) { // no attachment
|
||||
// attach = makeJsonFor( tmpdir, room, inviteID, lang,
|
||||
// dict, nPlayers );
|
||||
// }
|
||||
|
||||
// if ( null == attach ) { // no attachment
|
||||
// intent.setType( "message/rfc822");
|
||||
// } else {
|
||||
// String mime = LocUtils.getString( activity, R.string.invite_mime );
|
||||
// intent.setType( mime );
|
||||
// Uri uri = Uri.fromFile( attach );
|
||||
// intent.putExtra( Intent.EXTRA_STREAM, uri );
|
||||
// }
|
||||
|
||||
// choiceID = R.string.invite_chooser_email;
|
||||
// } else {
|
||||
// intent.setAction( Intent.ACTION_VIEW );
|
||||
// intent.setType( "vnd.android-dir/mms-sms" );
|
||||
// intent.putExtra( "sms_body", message );
|
||||
// choiceID = R.string.invite_chooser_sms;
|
||||
// }
|
||||
|
||||
// String choiceType = LocUtils.getString( activity, choiceID );
|
||||
// String chooserMsg =
|
||||
// LocUtils.getString( activity, R.string.invite_chooser_fmt,
|
||||
// choiceType );
|
||||
// activity.startActivity( Intent.createChooser( intent, chooserMsg ) );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public static String[] dictNames( Context context, long rowid,
|
||||
int[] missingLang )
|
||||
{
|
||||
|
@ -822,6 +885,7 @@ public class GameUtils {
|
|||
XwJNI.comms_resendAll( gamePtr, false, false );
|
||||
|
||||
for ( byte[] msg : msgs ) {
|
||||
Assert.assertNotNull( ret );
|
||||
draw = XwJNI.game_receiveMessage( gamePtr, msg, ret )
|
||||
|| draw;
|
||||
}
|
||||
|
@ -1049,22 +1113,14 @@ public class GameUtils {
|
|||
}
|
||||
}
|
||||
|
||||
private static File makeJsonFor( File dir, String room, String inviteID,
|
||||
int lang, String dict, int nPlayers )
|
||||
private static File makeJsonFor( File dir, NetLaunchInfo nli )
|
||||
{
|
||||
File result = null;
|
||||
if ( XWApp.ATTACH_SUPPORTED ) {
|
||||
JSONObject json = new JSONObject();
|
||||
try {
|
||||
json.put( MultiService.ROOM, room );
|
||||
json.put( MultiService.INVITEID, inviteID );
|
||||
json.put( MultiService.LANG, lang );
|
||||
json.put( MultiService.DICT, dict );
|
||||
json.put( MultiService.NPLAYERST, nPlayers );
|
||||
byte[] data = json.toString().getBytes();
|
||||
byte[] data = nli.makeLaunchJSON().getBytes();
|
||||
|
||||
File file = new File( dir,
|
||||
String.format("invite_%s", room ) );
|
||||
File file = new File( dir, String.format("invite_%d", nli.gameID ));
|
||||
try {
|
||||
FileOutputStream fos = new FileOutputStream( file );
|
||||
fos.write( data, 0, data.length );
|
||||
fos.close();
|
||||
|
|
|
@ -555,7 +555,7 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
private long[] m_rowids;
|
||||
private long m_groupid;
|
||||
private String m_nameField;
|
||||
private AbsLaunchInfo m_netLaunchInfo;
|
||||
private NetLaunchInfo m_netLaunchInfo;
|
||||
private GameNamer m_namer;
|
||||
private Set<Long> m_launchedGames;
|
||||
private boolean m_menuPrepared;
|
||||
|
@ -1460,7 +1460,7 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
}
|
||||
}
|
||||
|
||||
private boolean checkWarnNoDict( AbsLaunchInfo nli )
|
||||
private boolean checkWarnNoDict( NetLaunchInfo nli )
|
||||
{
|
||||
// check that we have the dict required
|
||||
boolean haveDict;
|
||||
|
@ -1590,26 +1590,21 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
NewGameDelegate.startActivity( m_activity, groupID );
|
||||
}
|
||||
|
||||
private void startNewNetGame( AbsLaunchInfo ali )
|
||||
private void startNewNetGame( NetLaunchInfo nli )
|
||||
{
|
||||
Assert.assertTrue( nli.isValid() );
|
||||
Date create = null;
|
||||
if ( ali instanceof NetLaunchInfo ) {
|
||||
create = DBUtils.getMostRecentCreate( m_activity,
|
||||
(NetLaunchInfo)ali );
|
||||
} else if ( ali instanceof BTLaunchInfo ) {
|
||||
create = DBUtils.getMostRecentCreate( m_activity,
|
||||
(BTLaunchInfo)ali );
|
||||
}
|
||||
create = DBUtils.getMostRecentCreate( m_activity, nli );
|
||||
|
||||
if ( null == create ) {
|
||||
if ( checkWarnNoDict( ali ) ) {
|
||||
makeNewNetGame( ali );
|
||||
if ( checkWarnNoDict( nli ) ) {
|
||||
makeNewNetGame( nli );
|
||||
}
|
||||
} else if ( XWPrefs.getSecondInviteAllowed( m_activity ) ) {
|
||||
String msg = getString( R.string.dup_game_query_fmt,
|
||||
create.toString() );
|
||||
m_netLaunchInfo = ali;
|
||||
showConfirmThen( msg, Action.NEW_NET_GAME, ali );
|
||||
m_netLaunchInfo = nli;
|
||||
showConfirmThen( msg, Action.NEW_NET_GAME, nli );
|
||||
} else {
|
||||
showOKOnlyDialog( R.string.dropped_dupe );
|
||||
}
|
||||
|
@ -1617,20 +1612,17 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
|
||||
private void startNewNetGame( Intent intent )
|
||||
{
|
||||
AbsLaunchInfo ali = null;
|
||||
NetLaunchInfo nli = null;
|
||||
if ( MultiService.isMissingDictIntent( intent ) ) {
|
||||
ali = new NetLaunchInfo( intent );
|
||||
if ( !ali.isValid() ) {
|
||||
ali = new BTLaunchInfo( intent );
|
||||
}
|
||||
nli = new NetLaunchInfo( intent );
|
||||
} else {
|
||||
Uri data = intent.getData();
|
||||
if ( null != data ) {
|
||||
ali = new NetLaunchInfo( m_activity, data );
|
||||
nli = new NetLaunchInfo( m_activity, data );
|
||||
}
|
||||
}
|
||||
if ( null != ali && ali.isValid() ) {
|
||||
startNewNetGame( ali );
|
||||
if ( null != nli && nli.isValid() ) {
|
||||
startNewNetGame( nli );
|
||||
}
|
||||
} // startNewNetGame
|
||||
|
||||
|
@ -1672,18 +1664,10 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
{
|
||||
String data = NFCUtils.getFromIntent( intent );
|
||||
if ( null != data ) {
|
||||
do {
|
||||
NetLaunchInfo nli = new NetLaunchInfo( data );
|
||||
if ( nli.isValid() ) {
|
||||
startNewNetGame( nli );
|
||||
break;
|
||||
}
|
||||
BTLaunchInfo bli = new BTLaunchInfo( data );
|
||||
if ( bli.isValid() && checkWarnNoDict( bli ) ) {
|
||||
BTService.gotGameViaNFC( m_activity, bli );
|
||||
break;
|
||||
}
|
||||
} while ( false );
|
||||
NetLaunchInfo nli = new NetLaunchInfo( data );
|
||||
if ( nli.isValid() ) {
|
||||
startNewNetGame( nli );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1749,11 +1733,7 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
{
|
||||
boolean madeGame = null != m_netLaunchInfo;
|
||||
if ( madeGame ) {
|
||||
if ( m_netLaunchInfo instanceof NetLaunchInfo ) {
|
||||
makeNewNetGame( (NetLaunchInfo)m_netLaunchInfo );
|
||||
} else if ( m_netLaunchInfo instanceof BTLaunchInfo ) {
|
||||
makeNewBTGame( (BTLaunchInfo)m_netLaunchInfo );
|
||||
}
|
||||
makeNewNetGame( m_netLaunchInfo );
|
||||
m_netLaunchInfo = null;
|
||||
}
|
||||
return madeGame;
|
||||
|
@ -1842,20 +1822,14 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
launchGame( rowid, false );
|
||||
}
|
||||
|
||||
private void makeNewNetGame( AbsLaunchInfo ali )
|
||||
private void makeNewNetGame( NetLaunchInfo nli )
|
||||
{
|
||||
long rowid = DBUtils.ROWID_NOTFOUND;
|
||||
if ( ali instanceof NetLaunchInfo ) {
|
||||
rowid = GameUtils.makeNewRelayGame( m_activity, (NetLaunchInfo)ali );
|
||||
} else if ( ali instanceof BTLaunchInfo ) {
|
||||
rowid = GameUtils.makeNewBTGame( m_activity, (BTLaunchInfo)ali );
|
||||
} else {
|
||||
Assert.fail();
|
||||
}
|
||||
rowid = GameUtils.makeNewMultiGame( m_activity, nli );
|
||||
launchGame( rowid, true );
|
||||
}
|
||||
|
||||
private void makeNewBTGame( BTLaunchInfo nli )
|
||||
private void makeNewBTGame( NetLaunchInfo nli )
|
||||
{
|
||||
long rowid = GameUtils.makeNewBTGame( m_activity, nli );
|
||||
launchGame( rowid, true );
|
||||
|
|
|
@ -27,46 +27,95 @@ import android.net.Uri;
|
|||
import android.os.Bundle;
|
||||
import java.net.URLEncoder;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONException;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eehouse.android.xw4.loc.LocUtils;
|
||||
import org.eehouse.android.xw4.jni.CommsAddrRec;
|
||||
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
|
||||
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet;
|
||||
import org.eehouse.android.xw4.jni.GameSummary;
|
||||
import org.eehouse.android.xw4.jni.CurGameInfo;
|
||||
|
||||
public class NetLaunchInfo extends AbsLaunchInfo {
|
||||
protected String room;
|
||||
protected String inviteID;
|
||||
public class NetLaunchInfo {
|
||||
private static final String ADDRS_KEY = "ADDRS";
|
||||
|
||||
protected String dict;
|
||||
protected int lang;
|
||||
protected int nPlayersT;
|
||||
protected String room; // relay
|
||||
protected String inviteID; // relay
|
||||
protected String btName;
|
||||
protected String btAddress;
|
||||
protected String phone; // SMS
|
||||
protected boolean isGSM; // SMS
|
||||
protected String osVers; // SMS
|
||||
|
||||
protected int gameID;
|
||||
|
||||
private CommsConnTypeSet m_addrs;
|
||||
private JSONObject m_json;
|
||||
private boolean m_valid;
|
||||
|
||||
public NetLaunchInfo()
|
||||
{
|
||||
m_addrs = new CommsConnTypeSet();
|
||||
}
|
||||
|
||||
public NetLaunchInfo( String data )
|
||||
{
|
||||
try {
|
||||
JSONObject json = init( data );
|
||||
room = json.getString( MultiService.ROOM );
|
||||
inviteID = json.getString( MultiService.INVITEID );
|
||||
setValid( true );
|
||||
} catch ( JSONException jse ) {
|
||||
// Don't bother logging; it's just not a valid object of this type
|
||||
}
|
||||
}
|
||||
m_json = new JSONObject( data );
|
||||
|
||||
public void putSelf( Bundle bundle )
|
||||
{
|
||||
super.putSelf( bundle );
|
||||
bundle.putString( MultiService.ROOM, room );
|
||||
bundle.putString( MultiService.INVITEID, inviteID );
|
||||
int flags = m_json.getInt(ADDRS_KEY);
|
||||
m_addrs = DBUtils.intToConnTypeSet( flags );
|
||||
|
||||
lang = m_json.optInt( MultiService.LANG, -1 );
|
||||
dict = m_json.optString( MultiService.DICT );
|
||||
nPlayersT = m_json.optInt( MultiService.NPLAYERST, -1 );
|
||||
gameID = m_json.optInt( MultiService.GAMEID, -1 );
|
||||
|
||||
for ( CommsConnType typ : m_addrs.getTypes() ) {
|
||||
switch ( typ ) {
|
||||
case COMMS_CONN_BT:
|
||||
btAddress = m_json.optString( MultiService.BT_ADDRESS );
|
||||
btName = m_json.optString( MultiService.BT_NAME );
|
||||
break;
|
||||
case COMMS_CONN_RELAY:
|
||||
room = m_json.optString( MultiService.ROOM );
|
||||
inviteID = m_json.optString( MultiService.INVITEID );
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
phone = m_json.optString( "phn" );
|
||||
isGSM = m_json.optBoolean( "gsm", false );
|
||||
osVers = m_json.optString( "os" );
|
||||
break;
|
||||
default:
|
||||
DbgUtils.logf( "Unexpected typ %s", typ.toString() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
calcValid();
|
||||
} catch ( JSONException jse ) {
|
||||
DbgUtils.loge( jse );
|
||||
}
|
||||
}
|
||||
|
||||
public NetLaunchInfo( Bundle bundle )
|
||||
{
|
||||
init( bundle );
|
||||
room = bundle.getString( MultiService.ROOM );
|
||||
inviteID = bundle.getString( MultiService.INVITEID );
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
public NetLaunchInfo( Context context, Uri data )
|
||||
{
|
||||
setValid( false );
|
||||
this();
|
||||
m_valid = false;
|
||||
if ( null != data ) {
|
||||
String scheme = data.getScheme();
|
||||
try {
|
||||
|
@ -78,7 +127,7 @@ public class NetLaunchInfo extends AbsLaunchInfo {
|
|||
byte[] buf = new byte[len];
|
||||
is.read( buf );
|
||||
|
||||
JSONObject json = init( new String( buf ) );
|
||||
JSONObject json = new JSONObject( new String( buf ) );
|
||||
room = json.getString( MultiService.ROOM );
|
||||
inviteID = json.getString( MultiService.INVITEID );
|
||||
} else {
|
||||
|
@ -90,22 +139,139 @@ public class NetLaunchInfo extends AbsLaunchInfo {
|
|||
String np = data.getQueryParameter( "np" );
|
||||
nPlayersT = Integer.decode( np );
|
||||
}
|
||||
setValid( true );
|
||||
calcValid();
|
||||
} catch ( Exception e ) {
|
||||
DbgUtils.logf( "unable to parse \"%s\"", data.toString() );
|
||||
}
|
||||
}
|
||||
calcValid();
|
||||
}
|
||||
|
||||
public NetLaunchInfo( Intent intent )
|
||||
{
|
||||
init( intent );
|
||||
room = intent.getStringExtra( MultiService.ROOM );
|
||||
inviteID = intent.getStringExtra( MultiService.INVITEID );
|
||||
boolean valid = null != room
|
||||
&& -1 != lang
|
||||
&& -1 != nPlayersT;
|
||||
setValid( valid );
|
||||
lang = intent.getIntExtra( MultiService.LANG, -1 );
|
||||
dict = intent.getStringExtra( MultiService.DICT );
|
||||
nPlayersT = intent.getIntExtra( MultiService.NPLAYERST, -1 );
|
||||
gameID = intent.getIntExtra( MultiService.GAMEID, -1 );
|
||||
btName = intent.getStringExtra( MultiService.BT_NAME );
|
||||
btAddress = intent.getStringExtra( MultiService.BT_ADDRESS );
|
||||
m_addrs = DBUtils.intToConnTypeSet( intent.getIntExtra( ADDRS_KEY, -1 ) );
|
||||
|
||||
calcValid();
|
||||
}
|
||||
|
||||
public NetLaunchInfo( int gamID, int dictLang, String dictName, int nPlayers )
|
||||
{
|
||||
this();
|
||||
dict = dictName;
|
||||
lang = dictLang;
|
||||
nPlayersT = nPlayers;
|
||||
gameID = gamID;
|
||||
}
|
||||
|
||||
public NetLaunchInfo( GameSummary summary, CurGameInfo gi )
|
||||
{
|
||||
this( gi.gameID, gi.dictLang, gi.dictName, gi.nPlayers );
|
||||
|
||||
for ( CommsConnType typ : summary.conTypes.getTypes() ) {
|
||||
DbgUtils.logf( "NetLaunchInfo(): got type %s", typ.toString() );
|
||||
switch( typ ) {
|
||||
case COMMS_CONN_BT:
|
||||
addBTInfo();
|
||||
break;
|
||||
case COMMS_CONN_RELAY:
|
||||
addRelayInfo( summary.roomName, summary.relayID );
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
addSMSInfo();
|
||||
break;
|
||||
default:
|
||||
Assert.fail();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void putSelf( Bundle bundle )
|
||||
{
|
||||
bundle.putString( MultiService.ROOM, room );
|
||||
bundle.putString( MultiService.INVITEID, inviteID );
|
||||
bundle.putInt( MultiService.LANG, lang );
|
||||
bundle.putString( MultiService.DICT, dict );
|
||||
bundle.putInt( MultiService.NPLAYERST, nPlayersT );
|
||||
bundle.putInt( MultiService.GAMEID, gameID );
|
||||
bundle.putString( MultiService.BT_NAME, btName );
|
||||
bundle.putString( MultiService.BT_ADDRESS, btAddress );
|
||||
|
||||
int flags = DBUtils.connTypeSetToInt( m_addrs );
|
||||
bundle.putInt( ADDRS_KEY, flags );
|
||||
}
|
||||
|
||||
public String makeLaunchJSON()
|
||||
{
|
||||
String result = null;
|
||||
try {
|
||||
result = new JSONObject()
|
||||
.put( MultiService.LANG, lang )
|
||||
.put( MultiService.DICT, dict )
|
||||
.put( MultiService.NPLAYERST, nPlayersT )
|
||||
.put( MultiService.ROOM, room )
|
||||
.put( MultiService.INVITEID, inviteID )
|
||||
.put( MultiService.GAMEID, gameID )
|
||||
.put( MultiService.BT_NAME, btName )
|
||||
.put( MultiService.BT_ADDRESS, btAddress )
|
||||
.put( ADDRS_KEY, DBUtils.connTypeSetToInt( m_addrs ) )
|
||||
.toString();
|
||||
} catch ( org.json.JSONException jse ) {
|
||||
DbgUtils.loge( jse );
|
||||
}
|
||||
DbgUtils.logf( "makeLaunchJSON() => %s", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
public CommsAddrRec makeAddrRec( Context context )
|
||||
{
|
||||
CommsAddrRec result = new CommsAddrRec();
|
||||
for ( CommsConnType typ : m_addrs.getTypes() ) {
|
||||
result.conTypes.add( typ );
|
||||
if ( CommsConnType.COMMS_CONN_RELAY == typ ) {
|
||||
String relayName = XWPrefs.getDefaultRelayHost( context );
|
||||
int relayPort = XWPrefs.getDefaultRelayPort( context );
|
||||
result.setRelayParams( relayName, relayPort, room );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Uri makeLaunchUri( Context context )
|
||||
{
|
||||
Uri.Builder ub = new Uri.Builder()
|
||||
.scheme( "http" )
|
||||
.path( String.format( "//%s%s",
|
||||
LocUtils.getString(context, R.string.invite_host),
|
||||
LocUtils.getString(context, R.string.invite_prefix) ) )
|
||||
.appendQueryParameter( "lang", String.format("%d", lang ) )
|
||||
.appendQueryParameter( "np", String.format( "%d", nPlayersT ) )
|
||||
.appendQueryParameter( "gid", String.format( "%d", nPlayersT ) );
|
||||
if ( null != dict ) {
|
||||
ub.appendQueryParameter( "wl", dict );
|
||||
}
|
||||
|
||||
if ( m_addrs.contains( CommsConnType.COMMS_CONN_RELAY ) ) {
|
||||
ub.appendQueryParameter( "room", room );
|
||||
ub.appendQueryParameter( "id", inviteID );
|
||||
}
|
||||
if ( m_addrs.contains( CommsConnType.COMMS_CONN_BT ) ) {
|
||||
ub.appendQueryParameter( "bta", btAddress );
|
||||
ub.appendQueryParameter( "btn", btName );
|
||||
}
|
||||
if ( m_addrs.contains( CommsConnType.COMMS_CONN_SMS ) ) {
|
||||
ub.appendQueryParameter( "phn", phone );
|
||||
}
|
||||
return ub.build();
|
||||
}
|
||||
|
||||
public static Uri makeLaunchUri( Context context, String room,
|
||||
|
@ -127,19 +293,100 @@ public class NetLaunchInfo extends AbsLaunchInfo {
|
|||
return ub.build();
|
||||
}
|
||||
|
||||
public static String makeLaunchJSON( String curJson, String room, String inviteID,
|
||||
int lang, String dict, int nPlayersT )
|
||||
// public static String makeLaunchJSON( String curJson, String room, String inviteID,
|
||||
// int lang, String dict, int nPlayersT )
|
||||
// {
|
||||
// Assert.assertNull( curJson );
|
||||
// String result = null;
|
||||
// try {
|
||||
// result = new JSONObject()
|
||||
// .put( MultiService.LANG, lang )
|
||||
// .put( MultiService.DICT, dict )
|
||||
// .put( MultiService.NPLAYERST, nPlayersT )
|
||||
// .put( MultiService.ROOM, room )
|
||||
// .put( MultiService.INVITEID, inviteID )
|
||||
// .put( MultiService.GAMEID, gameID )
|
||||
// .put( MultiService.BT_NAME, name )
|
||||
// .put( MultiService.BT_ADDRESS, address )
|
||||
// .put( ADDRS_KEY, DBUtils.connTypeSetToInt( m_addrs ) )
|
||||
// .toString();
|
||||
// } catch ( org.json.JSONException jse ) {
|
||||
// DbgUtils.loge( jse );
|
||||
// }
|
||||
// DbgUtils.logf( "makeLaunchJSON() => %s", result );
|
||||
// return result;
|
||||
// }
|
||||
|
||||
public void addRelayInfo( String aRoom, String anInviteID )
|
||||
{
|
||||
Assert.assertNull( curJson );
|
||||
String result = null;
|
||||
try {
|
||||
result = makeLaunchJSONObject( lang, dict, nPlayersT )
|
||||
.put( MultiService.ROOM, room )
|
||||
.put( MultiService.INVITEID, inviteID )
|
||||
.toString();
|
||||
} catch ( org.json.JSONException jse ) {
|
||||
DbgUtils.loge( jse );
|
||||
room = aRoom;
|
||||
inviteID = anInviteID;
|
||||
m_addrs.add( CommsConnType.COMMS_CONN_RELAY );
|
||||
}
|
||||
|
||||
public void addBTInfo()
|
||||
{
|
||||
String[] got = BTService.getBTNameAndAddress();
|
||||
if ( null != got ) {
|
||||
btName = got[0];
|
||||
btAddress = got[1];
|
||||
m_addrs.add( CommsConnType.COMMS_CONN_BT );
|
||||
} else {
|
||||
DbgUtils.logf( "addBTInfo(): no BT info available" );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void addSMSInfo()
|
||||
{
|
||||
// look up own phone number, which will require new permission
|
||||
Assert.fail();
|
||||
phone = "123-456-7890";
|
||||
m_addrs.add( CommsConnType.COMMS_CONN_SMS );
|
||||
}
|
||||
|
||||
public boolean isValid()
|
||||
{
|
||||
DbgUtils.logf( "NetLaunchInfo(%s).isValid() => %b", toString(), m_valid );
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return makeLaunchJSON();
|
||||
}
|
||||
|
||||
public static void putExtras( Intent intent, int gameID, String btAddr )
|
||||
{
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
private boolean hasCommon()
|
||||
{
|
||||
return null != dict
|
||||
&& 0 < lang
|
||||
&& 0 < nPlayersT
|
||||
&& 0 != gameID;
|
||||
}
|
||||
|
||||
private void calcValid()
|
||||
{
|
||||
boolean valid = hasCommon();
|
||||
for ( Iterator<CommsConnType> iter = m_addrs.iterator();
|
||||
valid && iter.hasNext(); ) {
|
||||
switch ( iter.next() ) {
|
||||
case COMMS_CONN_RELAY:
|
||||
valid = null != room && null != inviteID;
|
||||
break;
|
||||
case COMMS_CONN_BT:
|
||||
valid = null != btAddress && 0 != gameID;
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
Assert.fail();
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_valid = valid;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ import org.eehouse.android.xw4.jni.CurGameInfo;
|
|||
import org.eehouse.android.xw4.jni.CommonPrefs;
|
||||
import org.eehouse.android.xw4.jni.CommsAddrRec;
|
||||
import org.eehouse.android.xw4.jni.XwJNI;
|
||||
import org.eehouse.android.xw4.DlgDelegate.DlgClickNotify.InviteMeans;
|
||||
import org.eehouse.android.xw4.DlgDelegate.Action;
|
||||
|
||||
public class NewGameDelegate extends DelegateBase {
|
||||
|
||||
|
@ -151,13 +153,12 @@ public class NewGameDelegate extends DelegateBase {
|
|||
|
||||
// DlgDelegate.DlgClickNotify interface
|
||||
@Override
|
||||
public void dlgButtonClicked( DlgDelegate.Action action, int which, Object[] params )
|
||||
public void inviteChoiceMade( Action action, InviteMeans means,
|
||||
Object[] params )
|
||||
{
|
||||
switch( action ) {
|
||||
case NEW_GAME_ACTION:
|
||||
if ( DlgDelegate.DISMISS_BUTTON != which ) {
|
||||
makeNewGame( true, true, which );
|
||||
}
|
||||
makeNewGame( true, true, means );
|
||||
break;
|
||||
default:
|
||||
Assert.fail();
|
||||
|
@ -297,14 +298,14 @@ public class NewGameDelegate extends DelegateBase {
|
|||
// Let 'em cancel before we make the game
|
||||
showInviteChoicesThen( DlgDelegate.Action.NEW_GAME_ACTION );
|
||||
} else {
|
||||
makeNewGame( networked, launch, DlgDelegate.SMS_BTN );
|
||||
makeNewGame( networked, launch, InviteMeans.SMS );
|
||||
}
|
||||
}
|
||||
|
||||
private void makeNewGame( boolean networked, boolean launch,
|
||||
int inviteHow )
|
||||
InviteMeans inviteHow )
|
||||
{
|
||||
boolean viaNFC = DlgDelegate.NFC_BTN == inviteHow;
|
||||
boolean viaNFC = InviteMeans.NFC == inviteHow;
|
||||
if ( viaNFC && !NFCUtils.nfcAvail( m_activity )[1] ) {
|
||||
showDialog( DlgID.ENABLE_NFC );
|
||||
} else {
|
||||
|
@ -329,9 +330,10 @@ public class NewGameDelegate extends DelegateBase {
|
|||
if ( launch ) {
|
||||
GameUtils.launchGame( m_activity, m_newRowID, networked );
|
||||
if ( networked ) {
|
||||
GameUtils.launchInviteActivity( m_activity, inviteHow, room,
|
||||
inviteID, lang[0], dict[0],
|
||||
nPlayers );
|
||||
Assert.fail();
|
||||
// GameUtils.launchInviteActivity( m_activity, inviteHow, room,
|
||||
// inviteID, lang[0], dict[0],
|
||||
// nPlayers );
|
||||
}
|
||||
finish();
|
||||
} else {
|
||||
|
|
|
@ -1263,7 +1263,7 @@ public class RelayService extends XWService
|
|||
try {
|
||||
m_packetID = nextPacketID( m_cmd );
|
||||
DataOutputStream out = new DataOutputStream( bas );
|
||||
DbgUtils.logf( "Building packet with cmd %s",
|
||||
DbgUtils.logf( "RelayService.makeHeader(): building packet with cmd %s",
|
||||
m_cmd.toString() );
|
||||
out.writeByte( XWPDevProto.XWPDEV_PROTO_VERSION_1.ordinal() );
|
||||
un2vli( m_packetID, out );
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.net.InetAddress;
|
|||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
|
@ -98,10 +97,7 @@ public class CommsAddrRec {
|
|||
public CommsAddrRec( String host, int port )
|
||||
{
|
||||
this( CommsConnType.COMMS_CONN_RELAY );
|
||||
ip_relay_hostName = host;
|
||||
ip_relay_port = port;
|
||||
ip_relay_seeksPublicRoom = false;
|
||||
ip_relay_advertiseRoom = false;
|
||||
setRelayParams( host, port );
|
||||
}
|
||||
|
||||
public CommsAddrRec( String btHost, String btAddr )
|
||||
|
@ -122,6 +118,20 @@ public class CommsAddrRec {
|
|||
this.copyFrom( src );
|
||||
}
|
||||
|
||||
public void setRelayParams( String host, int port, String room )
|
||||
{
|
||||
setRelayParams( host, port );
|
||||
ip_relay_invite = room;
|
||||
}
|
||||
|
||||
public void setRelayParams( String host, int port )
|
||||
{
|
||||
ip_relay_hostName = host;
|
||||
ip_relay_port = port;
|
||||
ip_relay_seeksPublicRoom = false;
|
||||
ip_relay_advertiseRoom = false;
|
||||
}
|
||||
|
||||
public boolean changesMatter( final CommsAddrRec other )
|
||||
{
|
||||
boolean matter = ! conTypes.equals( other.conTypes );
|
||||
|
|
|
@ -61,7 +61,7 @@ public class GameSummary {
|
|||
public int pendingMsgLevel;
|
||||
public long modtime;
|
||||
public int gameID;
|
||||
public String[] remoteDevs; // BTAddr or phone number
|
||||
public String[] remoteDevs; // BTAddrs and phone numbers
|
||||
|
||||
public int dictLang;
|
||||
public DeviceRole serverRole;
|
||||
|
|
|
@ -390,9 +390,9 @@ public class JNIThread extends Thread {
|
|||
break;
|
||||
|
||||
case CMD_RECEIVE:
|
||||
CommsAddrRec ret = (CommsAddrRec)args[1];
|
||||
draw = XwJNI.game_receiveMessage( m_jniGamePtr,
|
||||
(byte[])args[0],
|
||||
(CommsAddrRec)args[1]);
|
||||
(byte[])args[0], ret );
|
||||
handle( JNICmd.CMD_DO );
|
||||
if ( draw ) {
|
||||
handle( JNICmd.CMD_SAVE );
|
||||
|
|
|
@ -1707,7 +1707,7 @@ preProcess( CommsCtxt* comms, XWStreamCtxt* stream,
|
|||
case COMMS_CONN_RELAY:
|
||||
consumed = relayPreProcess( comms, stream, senderID );
|
||||
if ( !consumed ) {
|
||||
*usingRelay = addr_hasType( &comms->addr, COMMS_CONN_RELAY );
|
||||
*usingRelay = XP_TRUE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
@ -1919,7 +1919,8 @@ comms_checkIncomingStream( CommsCtxt* comms, XWStreamCtxt* stream,
|
|||
XWHostID senderID = 0; /* unset; default for non-relay cases */
|
||||
XP_Bool usingRelay = XP_FALSE;
|
||||
|
||||
XP_ASSERT( retAddr == NULL || addr_getType( &comms->addr ) == addr_getType( retAddr ) );
|
||||
XP_ASSERT( retAddr == NULL ||
|
||||
(0 != (comms->addr._conTypes & retAddr->_conTypes)) );
|
||||
#ifdef COMMS_CHECKSUM
|
||||
XP_U16 initialLen = stream_getSize( stream );
|
||||
#endif
|
||||
|
@ -2024,15 +2025,18 @@ XP_Bool
|
|||
comms_isConnected( const CommsCtxt* const comms )
|
||||
{
|
||||
XP_Bool result = XP_FALSE;
|
||||
switch ( addr_getType( &comms->addr ) ) {
|
||||
case COMMS_CONN_RELAY:
|
||||
result = 0 != comms->rr.connName[0];
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
case COMMS_CONN_BT:
|
||||
result = comms->connID != 0;
|
||||
default:
|
||||
break;
|
||||
CommsConnType typ;
|
||||
for ( XP_U32 st = 0; !result && addr_iter( &comms->addr, &typ, &st ); ) {
|
||||
switch ( typ ) {
|
||||
case COMMS_CONN_RELAY:
|
||||
result = 0 != comms->rr.connName[0];
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
case COMMS_CONN_BT:
|
||||
result = comms->connID != 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue