mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-29 08:34:37 +01:00
Merge branch 'android_branch' into android_groups
This commit is contained in:
commit
d33f44ea24
8 changed files with 134 additions and 168 deletions
|
@ -22,7 +22,7 @@
|
|||
to come from a domain that you own or have control over. -->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.eehouse.android.xw4"
|
||||
android:versionCode="49"
|
||||
android:versionCode="50"
|
||||
android:versionName="@string/app_version"
|
||||
>
|
||||
|
||||
|
|
|
@ -5,24 +5,17 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<b>Crosswords 4.4 beta 57 release</b>
|
||||
<b>Crosswords 4.4 beta 58 release</b>
|
||||
|
||||
<h3>New with this release</h3>
|
||||
<ul>
|
||||
<li>Include new game information as an attachment in email invites
|
||||
for use on devices that don't dispatch URLs correctly in received
|
||||
email (e.g. some by HTC) </li>
|
||||
<li>Show final scores alert whenever a finished game is opened -- to
|
||||
make it more clear that it's finished</li>
|
||||
<li>Fix flickering in main screen (games list)</li>
|
||||
<li>Add option, off by default, to keep rack tiles square even when
|
||||
the screen is large enough that they can be taller</li>
|
||||
<li>Allow grouping of games in collapsible user-defined categores:
|
||||
"Games with Kati", "Finished games", etc.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Next up</h3>
|
||||
<ul>
|
||||
<li>Allow grouping of games in collapsible user-defined categores: "Games with
|
||||
Kati", "Finished games", etc.</li>
|
||||
<li>Improve communication with relay</li>
|
||||
</ul>
|
||||
|
||||
<p>(The full changelog
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<string name="app_version">4.4 beta 57</string>
|
||||
<string name="app_version">4.4 beta 58</string>
|
||||
</resources>
|
||||
|
|
|
@ -1739,8 +1739,9 @@ public class BoardActivity extends XWActivity
|
|||
}
|
||||
}
|
||||
};
|
||||
m_jniThread = new JNIThread( m_jniGamePtr, m_gi, m_view,
|
||||
m_gameLock, this, handler );
|
||||
m_jniThread =
|
||||
new JNIThread( m_jniGamePtr, stream, m_gi,
|
||||
m_view, m_gameLock, this, handler );
|
||||
// see http://stackoverflow.com/questions/680180/where-to-stop-\
|
||||
// destroy-threads-in-android-service-class
|
||||
m_jniThread.setDaemon( true );
|
||||
|
|
|
@ -21,21 +21,14 @@
|
|||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.content.Context;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import javax.net.SocketFactory;
|
||||
|
||||
public class NetUtils {
|
||||
|
||||
private static final int MAX_SEND = 1024;
|
||||
private static final int MAX_BUF = MAX_SEND - 2;
|
||||
|
||||
public static final byte PROTOCOL_VERSION = 0;
|
||||
// from xwrelay.h
|
||||
public static byte PRX_PUB_ROOMS = 1;
|
||||
|
@ -194,76 +187,6 @@ public class NetUtils {
|
|||
return msgs;
|
||||
} // queryRelay
|
||||
|
||||
public static void sendToRelay( Context context,
|
||||
HashMap<String,ArrayList<byte[]>> msgHash )
|
||||
{
|
||||
// format: total msg lenth: 2
|
||||
// number-of-relayIDs: 2
|
||||
// for-each-relayid: relayid + '\n': varies
|
||||
// message count: 1
|
||||
// for-each-message: length: 2
|
||||
// message: varies
|
||||
|
||||
if ( null != msgHash ) {
|
||||
try {
|
||||
// Build up a buffer containing everything but the total
|
||||
// message length and number of relayIDs in the message.
|
||||
ByteArrayOutputStream store =
|
||||
new ByteArrayOutputStream( MAX_BUF ); // mem
|
||||
DataOutputStream outBuf = new DataOutputStream( store );
|
||||
int msgLen = 4; // relayID count + protocol stuff
|
||||
int nRelayIDs = 0;
|
||||
|
||||
Iterator<String> iter = msgHash.keySet().iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
String relayID = iter.next();
|
||||
int thisLen = 1 + relayID.length(); // string and '\n'
|
||||
thisLen += 2; // message count
|
||||
|
||||
ArrayList<byte[]> msgs = msgHash.get( relayID );
|
||||
for ( byte[] msg : msgs ) {
|
||||
thisLen += 2 + msg.length;
|
||||
}
|
||||
|
||||
if ( msgLen + thisLen > MAX_BUF ) {
|
||||
// Need to deal with this case by sending multiple
|
||||
// packets. It WILL happen.
|
||||
break;
|
||||
}
|
||||
// got space; now write it
|
||||
++nRelayIDs;
|
||||
outBuf.writeBytes( relayID );
|
||||
outBuf.write( '\n' );
|
||||
outBuf.writeShort( msgs.size() );
|
||||
for ( byte[] msg : msgs ) {
|
||||
outBuf.writeShort( msg.length );
|
||||
outBuf.write( msg );
|
||||
}
|
||||
msgLen += thisLen;
|
||||
}
|
||||
|
||||
// Now open a real socket, write size and proto, and
|
||||
// copy in the formatted buffer
|
||||
Socket socket = makeProxySocket( context, 8000 );
|
||||
if ( null != socket ) {
|
||||
DataOutputStream outStream =
|
||||
new DataOutputStream( socket.getOutputStream() );
|
||||
outStream.writeShort( msgLen );
|
||||
outStream.writeByte( NetUtils.PROTOCOL_VERSION );
|
||||
outStream.writeByte( NetUtils.PRX_PUT_MSGS );
|
||||
outStream.writeShort( nRelayIDs );
|
||||
outStream.write( store.toByteArray() );
|
||||
outStream.flush();
|
||||
socket.close();
|
||||
}
|
||||
} catch ( java.io.IOException ioe ) {
|
||||
DbgUtils.loge( ioe );
|
||||
}
|
||||
} else {
|
||||
DbgUtils.logf( "sendToRelay: null msgs" );
|
||||
}
|
||||
} // sendToRelay
|
||||
|
||||
private static int sumStrings( final String[] strs )
|
||||
{
|
||||
int len = 0;
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
/* -*- compile-command: "cd ../../../../../; ant install"; -*- */
|
||||
/*
|
||||
* Copyright 2009-2010 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.Context;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eehouse.android.xw4.jni.*;
|
||||
|
||||
public class RelayMsgSink extends MultiMsgSink {
|
||||
|
||||
private HashMap<String,ArrayList<byte[]>> m_msgLists = null;
|
||||
|
||||
public void send( Context context )
|
||||
{
|
||||
NetUtils.sendToRelay( context, m_msgLists );
|
||||
}
|
||||
|
||||
/***** TransportProcs interface *****/
|
||||
|
||||
public boolean relayNoConnProc( byte[] buf, String relayID )
|
||||
{
|
||||
if ( null == m_msgLists ) {
|
||||
m_msgLists = new HashMap<String,ArrayList<byte[]>>();
|
||||
}
|
||||
|
||||
ArrayList<byte[]> list = m_msgLists.get( relayID );
|
||||
if ( list == null ) {
|
||||
list = new ArrayList<byte[]>();
|
||||
m_msgLists.put( relayID, list );
|
||||
}
|
||||
list.add( buf );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -24,18 +24,18 @@ import android.app.Service;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import javax.net.SocketFactory;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.io.InputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.eehouse.android.xw4.jni.GameSummary;
|
||||
|
||||
public class RelayService extends Service {
|
||||
private static final int MAX_SEND = 1024;
|
||||
private static final int MAX_BUF = MAX_SEND - 2;
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
|
@ -114,4 +114,102 @@ public class RelayService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
private static void sendToRelay( Context context,
|
||||
HashMap<String,ArrayList<byte[]>> msgHash )
|
||||
{
|
||||
// format: total msg lenth: 2
|
||||
// number-of-relayIDs: 2
|
||||
// for-each-relayid: relayid + '\n': varies
|
||||
// message count: 1
|
||||
// for-each-message: length: 2
|
||||
// message: varies
|
||||
|
||||
if ( null != msgHash ) {
|
||||
try {
|
||||
// Build up a buffer containing everything but the total
|
||||
// message length and number of relayIDs in the message.
|
||||
ByteArrayOutputStream store =
|
||||
new ByteArrayOutputStream( MAX_BUF ); // mem
|
||||
DataOutputStream outBuf = new DataOutputStream( store );
|
||||
int msgLen = 4; // relayID count + protocol stuff
|
||||
int nRelayIDs = 0;
|
||||
|
||||
Iterator<String> iter = msgHash.keySet().iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
String relayID = iter.next();
|
||||
int thisLen = 1 + relayID.length(); // string and '\n'
|
||||
thisLen += 2; // message count
|
||||
|
||||
ArrayList<byte[]> msgs = msgHash.get( relayID );
|
||||
for ( byte[] msg : msgs ) {
|
||||
thisLen += 2 + msg.length;
|
||||
}
|
||||
|
||||
if ( msgLen + thisLen > MAX_BUF ) {
|
||||
// Need to deal with this case by sending multiple
|
||||
// packets. It WILL happen.
|
||||
break;
|
||||
}
|
||||
// got space; now write it
|
||||
++nRelayIDs;
|
||||
outBuf.writeBytes( relayID );
|
||||
outBuf.write( '\n' );
|
||||
outBuf.writeShort( msgs.size() );
|
||||
for ( byte[] msg : msgs ) {
|
||||
outBuf.writeShort( msg.length );
|
||||
outBuf.write( msg );
|
||||
}
|
||||
msgLen += thisLen;
|
||||
}
|
||||
|
||||
// Now open a real socket, write size and proto, and
|
||||
// copy in the formatted buffer
|
||||
Socket socket = NetUtils.makeProxySocket( context, 8000 );
|
||||
if ( null != socket ) {
|
||||
DataOutputStream outStream =
|
||||
new DataOutputStream( socket.getOutputStream() );
|
||||
outStream.writeShort( msgLen );
|
||||
outStream.writeByte( NetUtils.PROTOCOL_VERSION );
|
||||
outStream.writeByte( NetUtils.PRX_PUT_MSGS );
|
||||
outStream.writeShort( nRelayIDs );
|
||||
outStream.write( store.toByteArray() );
|
||||
outStream.flush();
|
||||
socket.close();
|
||||
}
|
||||
} catch ( java.io.IOException ioe ) {
|
||||
DbgUtils.loge( ioe );
|
||||
}
|
||||
} else {
|
||||
DbgUtils.logf( "sendToRelay: null msgs" );
|
||||
}
|
||||
} // sendToRelay
|
||||
|
||||
private class RelayMsgSink extends MultiMsgSink {
|
||||
|
||||
private HashMap<String,ArrayList<byte[]>> m_msgLists = null;
|
||||
|
||||
public void send( Context context )
|
||||
{
|
||||
sendToRelay( context, m_msgLists );
|
||||
}
|
||||
|
||||
/***** TransportProcs interface *****/
|
||||
|
||||
public boolean relayNoConnProc( byte[] buf, String relayID )
|
||||
{
|
||||
if ( null == m_msgLists ) {
|
||||
m_msgLists = new HashMap<String,ArrayList<byte[]>>();
|
||||
}
|
||||
|
||||
ArrayList<byte[]> list = m_msgLists.get( relayID );
|
||||
if ( list == null ) {
|
||||
list = new ArrayList<byte[]>();
|
||||
m_msgLists.put( relayID, list );
|
||||
}
|
||||
list.add( buf );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,13 +22,14 @@
|
|||
package org.eehouse.android.xw4.jni;
|
||||
|
||||
import android.content.Context;
|
||||
import java.lang.InterruptedException;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.Iterator;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import java.lang.InterruptedException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.eehouse.android.xw4.R;
|
||||
import org.eehouse.android.xw4.DbgUtils;
|
||||
|
@ -122,6 +123,7 @@ public class JNIThread extends Thread {
|
|||
private boolean m_stopped = false;
|
||||
private boolean m_saveOnStop = false;
|
||||
private int m_jniGamePtr;
|
||||
private byte[] m_gameAtStart;
|
||||
private GameLock m_lock;
|
||||
private Context m_context;
|
||||
private CurGameInfo m_gi;
|
||||
|
@ -143,10 +145,12 @@ public class JNIThread extends Thread {
|
|||
Object[] m_args;
|
||||
}
|
||||
|
||||
public JNIThread( int gamePtr, CurGameInfo gi, SyncedDraw drawer,
|
||||
GameLock lock, Context context, Handler handler )
|
||||
public JNIThread( int gamePtr, byte[] gameAtStart, CurGameInfo gi,
|
||||
SyncedDraw drawer, GameLock lock, Context context,
|
||||
Handler handler )
|
||||
{
|
||||
m_jniGamePtr = gamePtr;
|
||||
m_gameAtStart = gameAtStart;
|
||||
m_gi = gi;
|
||||
m_drawer = drawer;
|
||||
m_lock = lock;
|
||||
|
@ -286,13 +290,17 @@ public class JNIThread extends Thread {
|
|||
if ( null != m_newDict ) {
|
||||
m_gi.dictName = m_newDict;
|
||||
}
|
||||
GameSummary summary = new GameSummary( m_context, m_gi );
|
||||
XwJNI.game_summarize( m_jniGamePtr, summary );
|
||||
byte[] state = XwJNI.game_saveToStream( m_jniGamePtr, m_gi );
|
||||
GameUtils.saveGame( m_context, state, m_lock, false );
|
||||
DBUtils.saveSummary( m_context, m_lock, summary );
|
||||
// There'd better be no way for saveGame above to fail!
|
||||
XwJNI.game_saveSucceeded( m_jniGamePtr );
|
||||
if ( Arrays.equals( m_gameAtStart, state ) ) {
|
||||
DbgUtils.logf( "no change in game; can skip saving" );
|
||||
} else {
|
||||
GameSummary summary = new GameSummary( m_context, m_gi );
|
||||
XwJNI.game_summarize( m_jniGamePtr, summary );
|
||||
DBUtils.saveGame( m_context, m_lock, state, false );
|
||||
DBUtils.saveSummary( m_context, m_lock, summary );
|
||||
// There'd better be no way for saveGame above to fail!
|
||||
XwJNI.game_saveSucceeded( m_jniGamePtr );
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
|
|
Loading…
Add table
Reference in a new issue