diff --git a/xwords4/android/.gitignore b/xwords4/android/.gitignore index c2958256c..c3599faaa 100644 --- a/xwords4/android/.gitignore +++ b/xwords4/android/.gitignore @@ -3,3 +3,5 @@ local.properties .idea app/src/main/assets/build-info.txt +obj-* +libs-* diff --git a/xwords4/android/app/build.gradle b/xwords4/android/app/build.gradle index 5ffd333d6..62d5771a4 100644 --- a/xwords4/android/app/build.gradle +++ b/xwords4/android/app/build.gradle @@ -1,6 +1,6 @@ def INITIAL_CLIENT_VERS = 8 -def VERSION_CODE_BASE = 119 -def VERSION_NAME = '4.4.123' +def VERSION_CODE_BASE = 121 +def VERSION_NAME = '4.4.125' def FABRIC_API_KEY = System.getenv("FABRIC_API_KEY") boolean forFDroid = hasProperty('forFDroid') diff --git a/xwords4/android/app/src/main/AndroidManifest.xml b/xwords4/android/app/src/main/AndroidManifest.xml index c198ca706..bc49a4b99 100644 --- a/xwords4/android/app/src/main/AndroidManifest.xml +++ b/xwords4/android/app/src/main/AndroidManifest.xml @@ -6,8 +6,6 @@ - - - -

CrossWords 4.4.123 release

+

CrossWords 4.4.125 release

-

This is a quick bug-fix release.

+

This release fixes a problem inviting to new networked games, and + with title bars on some Samsung devices.

Please take @@ -25,8 +26,10 @@

New with this release

    -
  • Fix crash when invitation requires a wordlist you don't have
  • -
  • Include latest Portuguese translations
  • +
  • Fix delays bringing up the Invite dialog for new games
  • +
  • Explicitly specify application "theme" to fix a Samsung + "upgrade" turning the titlebar white and so making menu + icons disappear

(The full changelog diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java index d5460275f..78e963232 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java @@ -126,6 +126,7 @@ public class BoardDelegate extends DelegateBase private boolean m_overNotShown; private boolean m_dropOnDismiss; private DBAlert m_inviteAlert; + private boolean m_haveStartedShowing; public class TimerRunnable implements Runnable { private int m_why; @@ -2225,6 +2226,7 @@ public class BoardDelegate extends DelegateBase // Assert.assertFalse( BuildConfig.DEBUG ); } m_inviteAlert = null; + m_haveStartedShowing = false; } } @@ -2304,9 +2306,14 @@ public class BoardDelegate extends DelegateBase showDialogFragment( dlgID, dlgTitle, txt ); } + // This is failing sometimes, and so the null == m_inviteAlert test means + // we never post it. BUT on a lot of devices without the test we wind up + // trying over and over to put the thing up. private void showInviteAlertIf() { - if ( /* null == m_inviteAlert && */m_mySIS.nMissing > 0 && !isFinishing() ) { + DbgUtils.assertOnUIThread(); + if ( ! m_haveStartedShowing && null == m_inviteAlert + && m_mySIS.nMissing > 0 && !isFinishing() ) { InviteAlertState ias = new InviteAlertState(); ias.summary = m_summary; ias.gi = m_gi; @@ -2315,6 +2322,7 @@ public class BoardDelegate extends DelegateBase ias.rowid = m_rowid; ias.nMissing = m_mySIS.nMissing; showDialogFragment( DlgID.DLG_INVITE, ias ); + m_haveStartedShowing = true; } } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/ConnStatusHandler.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/ConnStatusHandler.java index bfcac0c2a..c2d0b9795 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/ConnStatusHandler.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/ConnStatusHandler.java @@ -84,14 +84,24 @@ public class ConnStatusHandler { public String newerStr( Context context ) { - s_time.set( successNewer? lastSuccess : lastFailure ); - return format( context, s_time ); + String result = null; + long time = successNewer? lastSuccess : lastFailure; + if ( time > 0 ) { + s_time.set( time ); + result = format( context, s_time ); + } + return result; } public String olderStr( Context context ) { - s_time.set( successNewer? lastFailure : lastSuccess ); - return format( context, s_time ); + String result = null; + long time = successNewer? lastFailure : lastSuccess; + if ( time > 0 ) { + s_time.set( time ); + result = format( context, s_time ); + } + return result; } public void update( boolean success ) @@ -175,13 +185,20 @@ public class ConnStatusHandler { String did = addDebugInfo( context, typ ); sb.append( String.format( "\n\n*** %s %s***\n", typ.longName( context ), did ) ); + + // For sends we list failures too. SuccessRecord record = recordFor( typ, false ); tmp = LocUtils.getString( context, record.successNewer? R.string.connstat_succ : R.string.connstat_unsucc ); - sb.append( LocUtils - .getString( context, R.string.connstat_lastsend_fmt, - tmp, record.newerStr( context ) ) ); + + String timeStr = record.newerStr( context ); + if ( null != timeStr ) { + sb.append( LocUtils + .getString( context, R.string.connstat_lastsend_fmt, + tmp, timeStr ) ) + .append( "\n" ); + } int fmtId = 0; if ( record.successNewer ) { @@ -193,11 +210,12 @@ public class ConnStatusHandler { fmtId = R.string.connstat_lastother_unsucc_fmt; } } - if ( 0 != fmtId ) { - sb.append( LocUtils.getString( context, fmtId, - record.olderStr( context ))); + timeStr = record.olderStr( context ); + if ( 0 != fmtId && null != timeStr ) { + sb.append( LocUtils.getString( context, fmtId, timeStr )) + .append( "\n" ); } - sb.append( "\n\n" ); + sb.append( "\n" ); record = recordFor( typ, true ); if ( record.haveSuccess() ) { diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java index f54ee142e..5b9f4da1b 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java @@ -290,7 +290,7 @@ public class DelegateBase implements DlgClickNotify, if ( main.inDPMode() ) { if ( !m_finishCalled ) { m_finishCalled = true; - main.finishFragment(); + main.finishFragment( (XWFragment)m_delegator ); } handled = true; } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgDelegate.java index 5d0e31166..265e4b7d6 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgDelegate.java @@ -32,6 +32,8 @@ import android.os.Bundle; import android.os.Handler; import android.view.View; +import java.io.Serializable; + import junit.framework.Assert; import org.eehouse.android.xw4.DBUtils.SentInvitesInfo; @@ -126,13 +128,29 @@ public class DlgDelegate { SET_GOT_LANGDICT, } - public static class ActionPair { + public static class ActionPair implements Serializable { public ActionPair( Action act, int str ) { buttonStr = str; action = act; } public int buttonStr; public Action action; - public Object[] params; // null for now + + @Override + public boolean equals( Object obj ) + { + boolean result; + if ( BuildConfig.DEBUG ) { + result = null != obj && obj instanceof ActionPair; + if ( result ) { + ActionPair other = (ActionPair)obj; + result = buttonStr == other.buttonStr + && action == other.action; + } + } else { + result = super.equals( obj ); + } + return result; + } } public abstract class DlgDelegateBuilder { diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgState.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgState.java index 82dd9a65f..e3ce8f217 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgState.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgState.java @@ -164,6 +164,7 @@ public class DlgState implements Parcelable { out.writeInt( m_titleId ); out.writeString( m_msg ); out.writeSerializable( m_params ); + out.writeSerializable( m_pair ); } private void testCanParcelize() @@ -197,6 +198,7 @@ public class DlgState implements Parcelable { int titleId = in.readInt(); String msg = in.readString(); Object[] params = (Object[])in.readSerializable(); + ActionPair pair = (ActionPair)in.readSerializable(); DlgState state = new DlgState(id) .setMsg( msg ) .setPosButton( posButton ) @@ -206,6 +208,7 @@ public class DlgState implements Parcelable { .setOnNA( onNA ) .setTitle(titleId) .setParams(params) + .setActionPair(pair) ; return state; } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java index cd004bf1a..e98aecd9f 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java @@ -24,19 +24,20 @@ import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; -import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; +import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; +import android.view.ContextMenu; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.AdapterView; import android.widget.AdapterView.OnItemLongClickListener; +import android.widget.AdapterView; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; @@ -1926,8 +1927,19 @@ public class GamesListDelegate extends ListDelegateBase { m_mySIS.nextIsSolo = solo; - int count = m_adapter.getCount(); - boolean skipOffer = 6 > count || XWPrefs.getHideNewgameButtons( m_activity ); + boolean skipOffer = XWPrefs.getHideNewgameButtons( m_activity ); + if ( ! skipOffer ) { + // If the API's availble, offer to hide buttons as soon as there + // are enough games that the list is scrollable. Otherwise fall + // back to there being at least four games. + if ( Build.VERSION.SDK_INT >= 19 ) { + ListView list = getListView(); + skipOffer = !list.canScrollList( 1 ) && !list.canScrollList( -1 ); + } else { + skipOffer = 4 > m_adapter.getCount(); + } + } + if ( skipOffer ) { handleNewGame( solo ); } else { diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MainActivity.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MainActivity.java index ccd43ad95..d4142fc47 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MainActivity.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MainActivity.java @@ -298,11 +298,12 @@ public class MainActivity extends XWActivity resultCode, data ); } - protected void finishFragment() + protected void finishFragment( XWFragment fragment ) { - // Assert.assertTrue( fragment instanceof XWFragment ); // Log.d( TAG, "finishFragment()" ); - getSupportFragmentManager().popBackStack/*Immediate*/(); + int ID = fragment.getCommitID(); + getSupportFragmentManager() + .popBackStack( ID, FragmentManager.POP_BACK_STACK_INCLUSIVE ); } ////////////////////////////////////////////////////////////////////// @@ -453,14 +454,14 @@ public class MainActivity extends XWActivity return frag; } - private void addFragmentImpl( Fragment fragment, Bundle bundle, + private void addFragmentImpl( XWFragment fragment, Bundle bundle, String parentName ) { fragment.setArguments( bundle ); addFragmentImpl( fragment, parentName ); } - private void addFragmentImpl( final Fragment fragment, + private void addFragmentImpl( final XWFragment fragment, final String parentName ) { if ( m_safeToCommit ) { @@ -497,7 +498,7 @@ public class MainActivity extends XWActivity } } - private void safeAddFragment( Fragment fragment, String parentName ) + private void safeAddFragment( XWFragment fragment, String parentName ) { Assert.assertTrue( m_safeToCommit ); String newName = fragment.getClass().getSimpleName(); @@ -505,10 +506,11 @@ public class MainActivity extends XWActivity popUnneeded( fm, newName, parentName ); - fm.beginTransaction() + int ID = fm.beginTransaction() .add( R.id.main_container, fragment, newName ) .addToBackStack( newName ) .commit(); + fragment.setCommitID( ID ); // Don't do this. It causes an exception if e.g. from fragment.start() // I wind up launching another fragment and calling into this code // again. If I need executePendingTransactions() I'm doing something diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayInviteDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayInviteDelegate.java index 44d92c058..f8b043aba 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayInviteDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayInviteDelegate.java @@ -75,6 +75,7 @@ public class RelayInviteDelegate extends InviteDelegate { // private RelayDevsAdapter m_adapter; private boolean m_immobileConfirmed; private Activity m_activity; + private String m_devIDStr; public static void launchForResult( Activity activity, int nMissing, RequestCode requestCode ) @@ -101,6 +102,8 @@ public class RelayInviteDelegate extends InviteDelegate { super.init( msg, R.string.empty_relay_inviter ); addButtonBar( R.layout.relay_buttons, BUTTONIDS ); + m_devIDStr = String.format( "%d", DevID.getRelayDevIDInt(m_activity) ); + // getBundledData( savedInstanceState ); // m_addButton = (ImageButton)findViewById( R.id.manual_add_button ); @@ -437,6 +440,21 @@ public class RelayInviteDelegate extends InviteDelegate { // } // } // addPhoneNumbers + private void addSelf() + { + boolean hasSelf = false; + for ( DevIDRec rec : m_devIDRecs ) { + if ( rec.m_devID.equals( m_devIDStr ) ) { + hasSelf = true; + break; + } + } + if ( !hasSelf ) { + DevIDRec rec = new DevIDRec( "me", m_devIDStr ); + m_devIDRecs.add( rec ); + } + } + private void rebuildList( boolean checkIfAll ) { Collections.sort( m_devIDRecs, new Comparator() { @@ -444,15 +462,9 @@ public class RelayInviteDelegate extends InviteDelegate { return rec1.m_opponent.compareTo(rec2.m_opponent); } }); + + addSelf(); updateListAdapter( m_devIDRecs.toArray( new DevIDRec[m_devIDRecs.size()] ) ); - // m_adapter = new RelayDevsAdapter(); - // setListAdapter( m_adapter ); - // if ( checkIfAll && m_devIDRecs.size() <= m_nMissing ) { - // Iterator iter = m_devIDRecs.iterator(); - // while ( iter.hasNext() ) { - // iter.next().m_isChecked = true; - // } - // } tryEnable(); } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/UpdateCheckReceiver.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/UpdateCheckReceiver.java index 572c8178e..1dbd678bc 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/UpdateCheckReceiver.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/UpdateCheckReceiver.java @@ -177,7 +177,7 @@ public class UpdateCheckReceiver extends BroadcastReceiver { params.put( k_STRINGSHASH, BuildConfig.STRINGS_HASH ); params.put( k_NAME, packageName ); params.put( k_AVERS, versionCode ); - Log.d( TAG, "current update: %s", params.toString() ); + // Log.d( TAG, "current update: %s", params.toString() ); new UpdateQueryTask( context, params, fromUI, pm, packageName, dals ).execute(); } catch ( org.json.JSONException jse ) { @@ -278,6 +278,7 @@ public class UpdateCheckReceiver extends BroadcastReceiver { { boolean gotOne = false; try { + // Log.d( TAG, "makeNotificationsIf(response=%s)", jstr ); JSONObject jobj = new JSONObject( jstr ); if ( null != jobj ) { diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/Utils.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/Utils.java index b4d98e644..e76107259 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/Utils.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/Utils.java @@ -511,8 +511,7 @@ public class Utils { new ObjectInputStream( new ByteArrayInputStream(bytes) ); result = ois.readObject(); } catch ( Exception ex ) { - Log.ex( TAG, ex ); - Assert.assertFalse( BuildConfig.DEBUG ); + Log.d( TAG, ex.getMessage() ); } return result; } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWFragment.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWFragment.java index eeec3d7da..db4b076c7 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWFragment.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWFragment.java @@ -41,10 +41,12 @@ import junit.framework.Assert; abstract class XWFragment extends Fragment implements Delegator { private static final String TAG = XWFragment.class.getSimpleName(); private static final String PARENT_NAME = "PARENT_NAME"; + private static final String COMMIT_ID = "COMMIT_ID"; private DelegateBase m_dlgt; private String m_parentName; private boolean m_hasOptionsMenu = false; + private int m_commitID; private static Set sActiveFrags = new HashSet(); public static XWFragment findOwnsView( View view ) @@ -75,6 +77,9 @@ abstract class XWFragment extends Fragment implements Delegator { return m_parentName; } + public void setCommitID( int id ) { m_commitID = id; } + public int getCommitID() { return m_commitID; } + protected void onCreate( DelegateBase dlgt, Bundle sis, boolean hasOptionsMenu ) { m_hasOptionsMenu = hasOptionsMenu; @@ -87,6 +92,7 @@ abstract class XWFragment extends Fragment implements Delegator { Log.d( TAG, "%s.onSaveInstanceState() called", getClass().getSimpleName() ); Assert.assertNotNull( m_parentName ); outState.putString( PARENT_NAME, m_parentName ); + outState.putInt( COMMIT_ID, m_commitID ); m_dlgt.onSaveInstanceState( outState ); super.onSaveInstanceState( outState ); } @@ -98,6 +104,7 @@ abstract class XWFragment extends Fragment implements Delegator { if ( null != sis ) { m_parentName = sis.getString( PARENT_NAME ); Assert.assertNotNull( m_parentName ); + m_commitID = sis.getInt( COMMIT_ID ); } Assert.assertNull( m_dlgt ); m_dlgt = dlgt; diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java index 57cba9739..49a83d74d 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java @@ -749,10 +749,11 @@ public class JNIThread extends Thread { public void handle( JNICmd cmd, Object... args ) { - m_queue.add( new QueueElem( cmd, true, args ) ); if ( m_stopped && ! JNICmd.CMD_NONE.equals(cmd) ) { - Log.w( TAG, "adding %s to stopped thread!!!", cmd.toString() ); + Log.w( TAG, "NOT adding %s to stopped thread!!!", cmd.toString() ); DbgUtils.printStack( TAG ); + } else { + m_queue.add( new QueueElem( cmd, true, args ) ); } } diff --git a/xwords4/android/app/src/main/res/values/styles.xml b/xwords4/android/app/src/main/res/values/styles.xml index 48152edba..8ffaf87a8 100644 --- a/xwords4/android/app/src/main/res/values/styles.xml +++ b/xwords4/android/app/src/main/res/values/styles.xml @@ -1,5 +1,7 @@ +