From 92029b2443c2cb453607f03896df2ab804a43547 Mon Sep 17 00:00:00 2001 From: Eric House Date: Thu, 22 Dec 2016 08:57:54 -0800 Subject: [PATCH 01/47] fix to build with CURSES_ONLY flag --- xwords4/linux/.gitignore | 1 + xwords4/linux/Makefile | 3 +++ xwords4/linux/gamesdb.c | 6 ++++++ xwords4/linux/gamesdb.h | 2 ++ xwords4/linux/gtkdraw.h | 3 +++ xwords4/linux/main.h | 2 ++ xwords4/linux/xptypes.h | 2 +- 7 files changed, 18 insertions(+), 1 deletion(-) diff --git a/xwords4/linux/.gitignore b/xwords4/linux/.gitignore index f7e2e8722..3f284af16 100644 --- a/xwords4/linux/.gitignore +++ b/xwords4/linux/.gitignore @@ -1,5 +1,6 @@ /core.* obj_linux_memdbg +obj_linux_memdbg_curses *.xwg obj_linux_rel log_*_*.txt diff --git a/xwords4/linux/Makefile b/xwords4/linux/Makefile index a88bbe5e8..8b5499b5c 100644 --- a/xwords4/linux/Makefile +++ b/xwords4/linux/Makefile @@ -246,6 +246,9 @@ ifneq (,$(findstring DPLATFORM_GTK,$(DEFINES))) POINTER_SUPPORT = -DPOINTER_SUPPORT endif +CFLAGS += `pkg-config --cflags glib-2.0` +LIBS += `pkg-config --libs glib-2.0` + CFLAGS += $(POINTER_SUPPORT) ifneq (,$(findstring DPLATFORM_NCURSES,$(DEFINES))) diff --git a/xwords4/linux/gamesdb.c b/xwords4/linux/gamesdb.c index 0b6d34914..6b599e2bc 100644 --- a/xwords4/linux/gamesdb.c +++ b/xwords4/linux/gamesdb.c @@ -170,6 +170,7 @@ writeToDB( XWStreamCtxt* stream, void* closure ) (*cGlobals->onSave)( cGlobals->onSaveClosure, selRow, newGame ); } +#ifdef PLATFORM_GTK static void addSnapshot( CommonGlobals* cGlobals ) { @@ -191,6 +192,9 @@ addSnapshot( CommonGlobals* cGlobals ) LOG_RETURN_VOID(); } +#else +# define addSnapshot( cGlobals ) +#endif void summarize( CommonGlobals* cGlobals ) @@ -330,6 +334,7 @@ getGameInfo( sqlite3* pDb, sqlite3_int64 rowid, GameInfo* gib ) gib->lastMoveTime = sqlite3_column_int( ppStmt, 10 ); snprintf( gib->name, sizeof(gib->name), "Game %lld", rowid ); +#ifdef PLATFORM_GTK /* Load the snapshot */ GdkPixbuf* snap = NULL; const XP_U8* ptr = sqlite3_column_blob( ppStmt, 11 ); @@ -342,6 +347,7 @@ getGameInfo( sqlite3* pDb, sqlite3_int64 rowid, GameInfo* gib ) g_object_unref( istr ); } gib->snap = snap; +#endif } sqlite3_finalize( ppStmt ); diff --git a/xwords4/linux/gamesdb.h b/xwords4/linux/gamesdb.h index d314a8df8..b7744cdc8 100644 --- a/xwords4/linux/gamesdb.h +++ b/xwords4/linux/gamesdb.h @@ -31,7 +31,9 @@ typedef struct _GameInfo { XP_UCHAR name[128]; XP_UCHAR room[128]; XP_UCHAR conn[128]; +#ifdef PLATFORM_GTK GdkPixbuf* snap; +#endif XP_U32 gameID; XP_S16 nMoves; XP_Bool gameOver; diff --git a/xwords4/linux/gtkdraw.h b/xwords4/linux/gtkdraw.h index b55fea161..b51d46c60 100644 --- a/xwords4/linux/gtkdraw.h +++ b/xwords4/linux/gtkdraw.h @@ -17,6 +17,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifdef PLATFORM_GTK + #ifndef _GTKDRAW_H_ #define _GTKDRAW_H_ @@ -31,3 +33,4 @@ void removeSurface( GtkDrawCtx* dctx ); void getImage( GtkDrawCtx* dctx, XWStreamCtxt* stream ); #endif +#endif diff --git a/xwords4/linux/main.h b/xwords4/linux/main.h index 6e6fff9f4..13bb45c6a 100644 --- a/xwords4/linux/main.h +++ b/xwords4/linux/main.h @@ -240,6 +240,7 @@ typedef struct _SourceData { void* procClosure; } SourceData; +#ifdef PLATFORM_GTK typedef struct _GtkAppGlobals { GArray* selRows; LaunchParams* params; @@ -253,5 +254,6 @@ typedef struct _GtkAppGlobals { /* save window position */ GdkEventConfigure lastConfigure; } GtkAppGlobals; +#endif #endif diff --git a/xwords4/linux/xptypes.h b/xwords4/linux/xptypes.h index 9d6caa954..921bea5aa 100644 --- a/xwords4/linux/xptypes.h +++ b/xwords4/linux/xptypes.h @@ -28,8 +28,8 @@ #include #include +#include #ifdef PLATFORM_GTK -# include # include # include #endif From f9f872695d4dcb4a3c40f79de0a3f2f7bf9000a8 Mon Sep 17 00:00:00 2001 From: Eric House Date: Sat, 24 Dec 2016 12:51:39 -0800 Subject: [PATCH 02/47] improve checkbox handling in invite dialogs Use an array of actual objects rather than indices, and add an equals() method, so checkbox status can survive changes in the set of available items and even be reproduced when the objects backing them change (as happens after a new BT scan finishes.) --- .../XWords4/res/layout/two_strs_item.xml | 4 +- .../eehouse/android/xw4/BTInviteDelegate.java | 36 ++++++----- .../eehouse/android/xw4/InviteDelegate.java | 61 ++++++++++++++----- .../android/xw4/RelayInviteDelegate.java | 6 ++ .../android/xw4/SMSInviteDelegate.java | 21 +++++-- .../org/eehouse/android/xw4/TwoStrsItem.java | 8 ++- 6 files changed, 98 insertions(+), 38 deletions(-) diff --git a/xwords4/android/XWords4/res/layout/two_strs_item.xml b/xwords4/android/XWords4/res/layout/two_strs_item.xml index 5373f1efa..56ad6e2e7 100644 --- a/xwords4/android/XWords4/res/layout/two_strs_item.xml +++ b/xwords4/android/XWords4/res/layout/two_strs_item.xml @@ -3,8 +3,8 @@ diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java index 1efa3894e..74298c986 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java @@ -1,6 +1,6 @@ /* -*- compile-command: "find-and-ant.sh debug install"; -*- */ /* - * Copyright 2009-2015 by Eric House (xwords@eehouse.org). All rights + * Copyright 2009 - 2016 by Eric House (xwords@eehouse.org). All rights * reserved. * * This program is free software; you can redistribute it and/or @@ -40,6 +40,7 @@ import junit.framework.Assert; import org.eehouse.android.xw4.DBUtils.SentInvitesInfo; import org.eehouse.android.xw4.DlgDelegate.Action; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -52,6 +53,7 @@ public class BTInviteDelegate extends InviteDelegate { R.id.button_clear, }; private Activity m_activity; + private TwoStringPair[] m_pairs; public static void launchForResult( Activity activity, int nMissing, SentInvitesInfo info, @@ -94,7 +96,8 @@ public class BTInviteDelegate extends InviteDelegate { scan(); break; case R.id.button_clear: - Utils.notImpl( m_activity ); + removeSelected(); + clearChecked(); break; } } @@ -109,13 +112,13 @@ public class BTInviteDelegate extends InviteDelegate { public void run() { synchronized( BTInviteDelegate.this ) { - TwoStringPair[] pairs = null; + m_pairs = null; if ( 0 < args.length ) { - pairs = TwoStringPair.make( (String[])(args[0]), - (String[])(args[1]) ); + m_pairs = TwoStringPair.make( (String[])(args[0]), + (String[])(args[1]) ); } - updateListAdapter( pairs ); + updateListAdapter( m_pairs ); tryEnable(); } } @@ -131,7 +134,7 @@ public class BTInviteDelegate extends InviteDelegate { { TwoStrsItem item = (TwoStrsItem)child; // change class name! TwoStringPair pair = (TwoStringPair)data; - ((TwoStrsItem)child).setStrings( pair.str2, pair.str1 ); + ((TwoStrsItem)child).setStrings( pair.str2, null/*pair.str1*/ ); } @Override @@ -158,14 +161,17 @@ public class BTInviteDelegate extends InviteDelegate { } // @Override - // protected void clearSelected( Integer[] itemIndices ) - // { - // // String[][] selected = new String[1][]; - // // listSelected( selected, null ); - // // BTService.clearDevices( m_activity, selected[0] ); - - // // super.clearSelected( itemIndices ); - // } + private void removeSelected() + { + Set checked = getChecked(); + String[] devs = new String[checked.size()]; + Iterator iter = checked.iterator(); + for ( int ii = 0; iter.hasNext(); ++ii ) { + TwoStringPair pair = (TwoStringPair)iter.next(); + devs[ii] = pair.str1; + } + BTService.clearDevices( m_activity, devs ); + } // DlgDelegate.DlgClickNotify interface @Override diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java index 5d76d8260..d8e060532 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java @@ -50,6 +50,7 @@ abstract class InviteDelegate extends ListDelegateBase private static final String TAG = InviteDelegate.class.getSimpleName(); protected interface InviterItem { + boolean equals(InviterItem item); } protected static class TwoStringPair implements InviterItem { @@ -68,6 +69,19 @@ abstract class InviteDelegate extends ListDelegateBase } return pairs; } + + public boolean equals( InviterItem item ) + { + boolean result = false; + if ( null != item ) { + TwoStringPair pair = (TwoStringPair)item; + result = str1.equals( pair.str1 ) + && ((null == str2 && null == pair.str2) + || str2.equals( pair.str2 ) ); + DbgUtils.logd( TAG, "%s.equals(%s) => %b", str1, pair.str1, result ); + } + return result; + } } // Children implement ... @@ -90,7 +104,7 @@ abstract class InviteDelegate extends ListDelegateBase private boolean m_showAddrs; private InviteItemsAdapter m_adapter; protected Map m_counts; - protected Set m_checked; + protected Set m_checked; private boolean m_setChecked; // private LinearLayout[] m_items; @@ -102,7 +116,7 @@ abstract class InviteDelegate extends ListDelegateBase m_nMissing = intent.getIntExtra( INTENT_KEY_NMISSING, -1 ); m_lastDev = intent.getStringExtra( INTENT_KEY_LASTDEV ); m_counts = new HashMap(); - m_checked = new HashSet(); + m_checked = new HashSet(); } protected void init( String descTxt, int emptyMsgId ) @@ -150,7 +164,7 @@ abstract class InviteDelegate extends ListDelegateBase protected void updateListAdapter( int itemId, InviterItem[] items ) { - // m_items = items; + updateChecked( items ); m_adapter = new InviteItemsAdapter( itemId, items ); setListAdapter( m_adapter ); } @@ -193,8 +207,8 @@ abstract class InviteDelegate extends ListDelegateBase int ii = 0; InviterItem[] result = new InviterItem[m_checked.size()]; InviterItem[] src = getAdapter().getItems(); - for ( int checked : m_checked ) { - result[ii++] = src[checked]; + for ( InviterItem checked : m_checked ) { + result[ii++] = checked; } return result; } @@ -223,20 +237,40 @@ abstract class InviteDelegate extends ListDelegateBase m_inviteButton.setEnabled( count > 0 && count <= m_nMissing ); } - final Set getChecked() { return m_checked; } + final Set getChecked() { return m_checked; } protected void clearChecked() { m_checked.clear(); } + // Figure which previously-checked items belong in the new set. + private void updateChecked( InviterItem[] newItems ) + { + Set old = new HashSet(); + old.addAll( m_checked ); + int oldSize = old.size(); + m_checked.clear(); + + for ( Iterator iter = old.iterator(); iter.hasNext(); ) { + InviterItem oldItem = iter.next(); + for ( InviterItem item : newItems ) { + if ( item.equals( oldItem ) ) { + m_checked.add( item ); + break; + } + } + } + } + // protected void scan() {} // callbacks made by InviteItemsAdapter protected void onItemChecked( int index, boolean checked ) { DbgUtils.logd( TAG, "onItemChecked(%d, %b)", index, checked ); + InviterItem item = m_adapter.getItems()[index]; if ( checked ) { - m_checked.add( index ); + m_checked.add( item ); } else { - m_checked.remove( index ); + m_checked.remove( item ); } } @@ -245,11 +279,6 @@ abstract class InviteDelegate extends ListDelegateBase return m_adapter; } - private Integer[] makeCheckedArray() - { - return m_checked.toArray( new Integer[m_checked.size()] ); - } - private class InviteItemsAdapter extends XWListAdapter { private InviterItem[] m_items; private int m_itemId; @@ -318,9 +347,9 @@ abstract class InviteDelegate extends ListDelegateBase m_setChecked = false; } if ( isChecked ) { - m_checked.add( position ); + m_checked.add( item ); } else { - m_checked.remove( position ); + m_checked.remove( item ); // // User's now making changes; don't check new views // m_setChecked = false; } @@ -331,7 +360,7 @@ abstract class InviteDelegate extends ListDelegateBase }; box.setOnCheckedChangeListener( listener ); - if ( m_setChecked || m_checked.contains( position ) ) { + if ( m_setChecked || m_checked.contains( item ) ) { box.setChecked( true ); } else if ( null != m_lastDev && m_lastDev.equals( item ) ) { m_lastDev = null; diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayInviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayInviteDelegate.java index b6d303136..740135682 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayInviteDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayInviteDelegate.java @@ -448,6 +448,12 @@ public class RelayInviteDelegate extends InviteDelegate { m_nPlayers = 1; m_opponent = opponent; } + + public boolean equals( InviterItem item ) + { + return item != null + && ((DevIDRec)item).m_devID == m_devID; + } } // private class RelayDevsAdapter extends XWListAdapter { diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java index b71226a7f..8dab4bd25 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java @@ -30,6 +30,7 @@ import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract; +import android.telephony.PhoneNumberUtils; import android.text.method.DialerKeyListener; import android.view.View; import android.widget.Button; @@ -335,10 +336,11 @@ public class SMSInviteDelegate extends InviteDelegate private void clearSelectedImpl() { - Set checked = getChecked(); - for ( int ii = m_phoneRecs.size() - 1; ii >= 0; --ii ) { - if ( checked.contains( ii ) ) { - m_phoneRecs.remove( ii ); + Set checked = getChecked(); + Iterator iter = m_phoneRecs.iterator(); + for ( ; iter.hasNext(); ) { + if ( checked.contains( iter.next() ) ) { + iter.remove(); } } clearChecked(); @@ -371,6 +373,17 @@ public class SMSInviteDelegate extends InviteDelegate this( null, phone ); } + public boolean equals( InviterItem item ) + { + boolean result = false; + if ( null != item && item instanceof PhoneRec ) { + PhoneRec rec = (PhoneRec)item; + result = m_name.equals(rec.m_name) + && PhoneNumberUtils.compare( m_phone, rec.m_phone ); + } + return result; + } + private PhoneRec( String name, String phone ) { m_phone = phone; diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/TwoStrsItem.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/TwoStrsItem.java index e30bbe59f..4ecfac31b 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/TwoStrsItem.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/TwoStrsItem.java @@ -22,6 +22,7 @@ package org.eehouse.android.xw4; import android.content.Context; import android.util.AttributeSet; +import android.view.View; import android.widget.CheckBox; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.LinearLayout; @@ -39,8 +40,13 @@ public class TwoStrsItem extends LinearLayout { { TextView tv = (TextView)findViewById( R.id.text1 ); tv.setText( str1 ); + tv = (TextView)findViewById( R.id.text2 ); - tv.setText( str2 ); + if ( null == str2 ) { + tv.setVisibility( View.GONE ); + } else { + tv.setText( str2 ); + } } public String getStr1() From 84e8f0927cfe7fa7172f6bef187cabb833accfcc Mon Sep 17 00:00:00 2001 From: Eric House Date: Mon, 26 Dec 2016 15:21:10 -0800 Subject: [PATCH 03/47] invitations cleanup: layout and reinvite Fix a layout to be centered when one string not displayed. Fix to pre-check by default the most recent device choice when re-inviting. --- .../XWords4/res/layout/inviter_item_frame.xml | 1 + .../org/eehouse/android/xw4/BTInviteDelegate.java | 10 ---------- .../org/eehouse/android/xw4/InviteDelegate.java | 14 +++++++++++--- .../eehouse/android/xw4/RelayInviteDelegate.java | 8 ++------ .../org/eehouse/android/xw4/SMSInviteDelegate.java | 11 ++--------- 5 files changed, 16 insertions(+), 28 deletions(-) diff --git a/xwords4/android/XWords4/res/layout/inviter_item_frame.xml b/xwords4/android/XWords4/res/layout/inviter_item_frame.xml index d1e9cdd75..9a05b6aca 100644 --- a/xwords4/android/XWords4/res/layout/inviter_item_frame.xml +++ b/xwords4/android/XWords4/res/layout/inviter_item_frame.xml @@ -22,6 +22,7 @@ diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java index 74298c986..66d6e14c7 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java @@ -137,16 +137,6 @@ public class BTInviteDelegate extends InviteDelegate { ((TwoStrsItem)child).setStrings( pair.str2, null/*pair.str1*/ ); } - @Override - protected void listSelected( InviterItem[] selected, String[] devs ) - { - for ( int ii = 0; ii < selected.length; ++ii ) { - TwoStringPair rec = (TwoStringPair)selected[ii]; - devs[ii] = rec.str1; - DbgUtils.logd( TAG, "selecting address %s", devs[ii] ); - } - } - private void scan() { int count = BTService.getPairedCount( m_activity ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java index d8e060532..01167ea3a 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java @@ -51,6 +51,7 @@ abstract class InviteDelegate extends ListDelegateBase protected interface InviterItem { boolean equals(InviterItem item); + String getDev(); // the string that identifies this item in results } protected static class TwoStringPair implements InviterItem { @@ -70,6 +71,8 @@ abstract class InviteDelegate extends ListDelegateBase return pairs; } + public String getDev() { return str1; } + public boolean equals( InviterItem item ) { boolean result = false; @@ -86,7 +89,6 @@ abstract class InviteDelegate extends ListDelegateBase // Children implement ... abstract void onChildAdded( View child, InviterItem item ); - abstract void listSelected( InviterItem[] selected, String[] devs ); public static final String DEVS = "DEVS"; public static final String COUNTS = "COUNTS"; @@ -169,6 +171,13 @@ abstract class InviteDelegate extends ListDelegateBase setListAdapter( m_adapter ); } + protected void listSelected( InviterItem[] selected, String[] devs ) + { + for ( int ii = 0; ii < selected.length; ++ii ) { + devs[ii] = selected[ii].getDev(); + } + } + protected void onBarButtonClicked( int id ) { Assert.fail(); // subclass must implement @@ -362,11 +371,10 @@ abstract class InviteDelegate extends ListDelegateBase if ( m_setChecked || m_checked.contains( item ) ) { box.setChecked( true ); - } else if ( null != m_lastDev && m_lastDev.equals( item ) ) { + } else if ( null != m_lastDev && m_lastDev.equals(item.getDev()) ) { m_lastDev = null; box.setChecked( true ); } - // m_items[position] = layout; return layout; } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayInviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayInviteDelegate.java index 740135682..fcff039ca 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayInviteDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayInviteDelegate.java @@ -207,12 +207,6 @@ public class RelayInviteDelegate extends InviteDelegate { Assert.fail(); } - @Override - public void listSelected( InviterItem[] selected, String[] devsP ) - { - Assert.fail(); - } - // We want to present user with list of previous opponents and devices. We // can easily get list of relayIDs. The relay, if reachable, can convert // that to a (likely shorter) list of devices. Then for each deviceID, @@ -449,6 +443,8 @@ public class RelayInviteDelegate extends InviteDelegate { m_opponent = opponent; } + public String getDev() { return m_devID; } + public boolean equals( InviterItem item ) { return item != null diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java index 8dab4bd25..40b39a8c6 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java @@ -179,15 +179,6 @@ public class SMSInviteDelegate extends InviteDelegate return dialog; } - @Override - protected void listSelected( InviterItem[] selected, String[] devs ) - { - for ( int ii = 0; ii < selected.length; ++ii ) { - PhoneRec rec = (PhoneRec)selected[ii]; - devs[ii] = rec.m_phone; - } - } - @Override protected void onChildAdded( View child, InviterItem data ) { @@ -373,6 +364,8 @@ public class SMSInviteDelegate extends InviteDelegate this( null, phone ); } + public String getDev() { return m_phone; } + public boolean equals( InviterItem item ) { boolean result = false; From f989212926ce463eb7b4cd06521e1df85950e7a4 Mon Sep 17 00:00:00 2001 From: Eric House Date: Mon, 26 Dec 2016 16:06:44 -0800 Subject: [PATCH 04/47] close pending game's board when invite cancelled Add cancelled notification to invite choices dialog. Look for that in board delegate and close the game. Makes the inviting experience more consistent, the goal being that you never look at a game that's missing players without some intervening dialog preventing you from trying to play. --- .../src/org/eehouse/android/xw4/BoardDelegate.java | 5 ++++- .../XWords4/src/org/eehouse/android/xw4/DlgDelegate.java | 9 ++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java index b4af54e64..9e107a56c 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java @@ -1031,7 +1031,10 @@ public class BoardDelegate extends DelegateBase DbgUtils.logd( TAG, "BoardDelegate.dlgButtonClicked(%s, %b)", action.toString(), positive ); - if ( Action.ENABLE_RELAY_DO_OR == action ) { + if ( Action.LAUNCH_INVITE_ACTION == action ) { + Assert.assertFalse( positive ); + finish(); + } else if ( Action.ENABLE_RELAY_DO_OR == action ) { handled = true; if ( positive ) { RelayService.setEnabled( m_activity, true ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DlgDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DlgDelegate.java index c461230d0..4f0f0ae62 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DlgDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DlgDelegate.java @@ -802,13 +802,20 @@ public class DlgDelegate { } } }; + OnClickListener cancelClicked = new OnClickListener() { + public void onClick( DialogInterface dlg, int view ) { + m_clickCallback.dlgButtonClicked( state.m_action, + AlertDialog.BUTTON_NEGATIVE, + state.m_params ); + } + }; AlertDialog.Builder builder = LocUtils.makeAlertBuilder( m_activity ) .setTitle( R.string.invite_choice_title ) .setSingleChoiceItems( items.toArray( new String[items.size()] ), sel[0], selChanged ) .setPositiveButton( android.R.string.ok, okClicked ) - .setNegativeButton( android.R.string.cancel, null ); + .setNegativeButton( android.R.string.cancel, cancelClicked ); return setCallbackDismissListener( builder.create(), state, dlgID ); } From 216dc757ad6865a771c7ea86ee5e577e13fd8bd6 Mon Sep 17 00:00:00 2001 From: Eric House Date: Tue, 27 Dec 2016 11:17:03 -0800 Subject: [PATCH 05/47] up version strings and changelog for release --- xwords4/android/XWords4/AndroidManifest.xml | 2 +- xwords4/android/XWords4/assets/changes.html | 24 +++++++++---------- .../android/XWords4/res/values/app_name.xml | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/xwords4/android/XWords4/AndroidManifest.xml b/xwords4/android/XWords4/AndroidManifest.xml index 968208162..bd9e90e7d 100644 --- a/xwords4/android/XWords4/AndroidManifest.xml +++ b/xwords4/android/XWords4/AndroidManifest.xml @@ -7,7 +7,7 @@ to come from a domain that you own or have control over. --> diff --git a/xwords4/android/XWords4/assets/changes.html b/xwords4/android/XWords4/assets/changes.html index 22cc807d7..e401ec59a 100644 --- a/xwords4/android/XWords4/assets/changes.html +++ b/xwords4/android/XWords4/assets/changes.html @@ -13,10 +13,11 @@ -

Crosswords 4.4.114 release

+

Crosswords 4.4.115 release

-

This release fixes a drawing problem on Android Nougat version - only.

+

This release uses the new permissions process introduced with + "Marshmallow": Crosswords only asks for permissions when they're + required.

Please take @@ -26,11 +27,12 @@

New with this release

    -
  • Fix (or work around) board drawing weirdness introduced with - Nougat. It showed most often when using the hint - feature.
  • -
  • Fix a couple of crashes reported via the Play Store -- - thanks!
  • +
  • Request permissions when they're needed, e.g. ask to send + SMS messages when you choose to play a game that way.
  • +
  • Other permissions required are for access to Storage and to contacts.
  • +
  • Rework the invitations dialogs. (No new features, but please report any bugs!)
  • +
  • New two-color icon for notifications (required by the newer + Android that supports run-time permissions

(The full changelog @@ -38,10 +40,8 @@

Next up

    -
  • Support WiFi Direct (currently working sporadically)
  • -
  • Take advantage of Marshmallow's new permissions model (where - the app only asks for permission, e.g. to send SMS, when it - needs it.) +
  • Continue work to support WiFi Direct (currently working + sporadically)

Please let me know diff --git a/xwords4/android/XWords4/res/values/app_name.xml b/xwords4/android/XWords4/res/values/app_name.xml index b8ef95b5b..d09ebdb08 100644 --- a/xwords4/android/XWords4/res/values/app_name.xml +++ b/xwords4/android/XWords4/res/values/app_name.xml @@ -1,5 +1,5 @@ - 4.4.114 + 4.4.115 From 57c71f4c8200f7f38c1727f42db24e2b63560032 Mon Sep 17 00:00:00 2001 From: Eric House Date: Tue, 27 Dec 2016 11:46:15 -0800 Subject: [PATCH 06/47] invitations: disable remove when nothing checked Subclass needs to do this one: overrides tryEnable() to handle its button-bar buttons. --- .../eehouse/android/xw4/BTInviteDelegate.java | 25 ++++++++--------- .../android/xw4/SMSInviteDelegate.java | 28 ++++++++----------- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java index 66d6e14c7..6ae8cd3ee 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTInviteDelegate.java @@ -25,26 +25,14 @@ import android.app.AlertDialog; import android.content.Intent; import android.os.Bundle; import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView.OnItemSelectedListener; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.LinearLayout; -import android.widget.Spinner; -import android.widget.TextView; +import android.widget.Button; import junit.framework.Assert; import org.eehouse.android.xw4.DBUtils.SentInvitesInfo; import org.eehouse.android.xw4.DlgDelegate.Action; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; -import java.util.Map; import java.util.Set; public class BTInviteDelegate extends InviteDelegate { @@ -137,6 +125,17 @@ public class BTInviteDelegate extends InviteDelegate { ((TwoStrsItem)child).setStrings( pair.str2, null/*pair.str1*/ ); } + @Override + protected void tryEnable() + { + super.tryEnable(); + + Button button = (Button)findViewById( R.id.button_clear ); + if ( null != button ) { // may not be there yet + button.setEnabled( 0 < getChecked().size() ); + } + } + private void scan() { int count = BTService.getPairedCount( m_activity ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java index 40b39a8c6..3928547d0 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java @@ -34,11 +34,6 @@ import android.telephony.PhoneNumberUtils; import android.text.method.DialerKeyListener; import android.view.View; import android.widget.Button; -import android.widget.CompoundButton; -import android.widget.FrameLayout; -import android.widget.ImageButton; -import android.widget.Spinner; -import android.widget.TextView; import junit.framework.Assert; @@ -49,14 +44,12 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; -import java.util.Map; import java.util.Set; import org.json.JSONObject; import org.json.JSONException; -public class SMSInviteDelegate extends InviteDelegate - implements View.OnClickListener { +public class SMSInviteDelegate extends InviteDelegate { private static final String TAG = SMSInviteDelegate.class.getSimpleName(); private static int[] BUTTONIDS = { R.id.button_add, @@ -68,7 +61,6 @@ public class SMSInviteDelegate extends InviteDelegate private static final String SAVE_NUMBER = "SAVE_NUMBER"; private ArrayList m_phoneRecs; - private ImageButton m_addButton; private boolean m_immobileConfirmed; private Activity m_activity; @@ -186,6 +178,17 @@ public class SMSInviteDelegate extends InviteDelegate ((TwoStrsItem)child).setStrings( rec.m_name, rec.m_phone ); } + @Override + protected void tryEnable() + { + super.tryEnable(); + + Button button = (Button)findViewById( R.id.button_clear ); + if ( null != button ) { // may not be there yet + button.setEnabled( 0 < getChecked().size() ); + } + } + // DlgDelegate.DlgClickNotify interface @Override public void dlgButtonClicked( Action action, int which, @@ -283,13 +286,6 @@ public class SMSInviteDelegate extends InviteDelegate return rec1.m_name.compareTo(rec2.m_name); } }); - // String[] phones = new String[m_phoneRecs.size()]; - // String[] names = new String[m_phoneRecs.size()]; - // for ( int ii = 0; ii < m_phoneRecs.size(); ++ii ) { - // PhoneRec rec = m_phoneRecs.get( ii ); - // phones[ii] = rec.m_phone; - // names[ii] = rec.m_name; - // } updateListAdapter( m_phoneRecs.toArray( new PhoneRec[m_phoneRecs.size()] ) ); tryEnable(); From 0fc528a0742ba11b3ab85e978c6845800a787c01 Mon Sep 17 00:00:00 2001 From: Eric House Date: Tue, 27 Dec 2016 13:22:37 -0800 Subject: [PATCH 07/47] cleanup up logging --- .../XWords4/src/org/eehouse/android/xw4/BoardView.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java index b35969c77..710e0e04e 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java @@ -109,7 +109,7 @@ public class BoardView extends View implements BoardHandler, SyncedDraw { } else if ( XwJNI.board_containsPt( m_jniGamePtr, xx, yy ) ) { handle( JNIThread.JNICmd.CMD_PEN_DOWN, xx, yy ); } else { - DbgUtils.logd( TAG, "BoardView.onTouchEvent(): in white space" ); + DbgUtils.logd( TAG, "onTouchEvent(): in white space" ); } break; case MotionEvent.ACTION_MOVE: @@ -160,7 +160,7 @@ public class BoardView extends View implements BoardHandler, SyncedDraw { if ( BoardContainer.getIsPortrait() != (m_dims.height > m_dims.width) ) { // square possible; will break above! Assert.assertTrue( m_dims.height != m_dims.width ); - DbgUtils.logd( TAG, "BoardView.onMeasure: discarding m_dims" ); + DbgUtils.logd( TAG, "onMeasure: discarding m_dims" ); if ( ++m_dimsTossCount < 4 ) { m_dims = null; m_layoutWidth = m_layoutHeight = 0; @@ -187,7 +187,7 @@ public class BoardView extends View implements BoardHandler, SyncedDraw { width = minWidth; } setMeasuredDimension( width, height ); - DbgUtils.logd( TAG, "BoardView.onMeasure: calling setMeasuredDimension( width=%d, height=%d )", + DbgUtils.logd( TAG, "onMeasure: calling setMeasuredDimension( width=%d, height=%d )", width, height ); } @@ -214,7 +214,7 @@ public class BoardView extends View implements BoardHandler, SyncedDraw { ConnStatusHandler.draw( m_context, canvas, getResources(), m_connTypes, m_isSolo ); } else { - DbgUtils.logd( TAG, "BoardView.onDraw(): board not laid out yet" ); + DbgUtils.logd( TAG, "onDraw(): board not laid out yet" ); } } } From 497567ac2d249c3e09f90fa1c965dd4810a94da2 Mon Sep 17 00:00:00 2001 From: Eric House Date: Tue, 27 Dec 2016 13:23:39 -0800 Subject: [PATCH 08/47] check items newly imported from contacts I figure if you just brought it in it's probably to send an invitation to it, and this is how it worked before the refactoring anyway. --- .../src/org/eehouse/android/xw4/InviteDelegate.java | 10 +++------- .../src/org/eehouse/android/xw4/SMSInviteDelegate.java | 7 +++++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java index 01167ea3a..0d346f3e2 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/InviteDelegate.java @@ -269,13 +269,9 @@ abstract class InviteDelegate extends ListDelegateBase } } - // protected void scan() {} - // callbacks made by InviteItemsAdapter - protected void onItemChecked( int index, boolean checked ) + protected void onItemChecked( InviterItem item, boolean checked ) { - DbgUtils.logd( TAG, "onItemChecked(%d, %b)", index, checked ); - InviterItem item = m_adapter.getItems()[index]; if ( checked ) { m_checked.add( item ); } else { @@ -283,7 +279,7 @@ abstract class InviteDelegate extends ListDelegateBase } } - protected InviteItemsAdapter getAdapter() + private InviteItemsAdapter getAdapter() { return m_adapter; } @@ -362,7 +358,7 @@ abstract class InviteDelegate extends ListDelegateBase // // User's now making changes; don't check new views // m_setChecked = false; } - onItemChecked( position, isChecked ); + onItemChecked( item, isChecked ); tryEnable(); } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java index 3928547d0..4537f68d9 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java @@ -210,8 +210,11 @@ public class SMSInviteDelegate extends InviteDelegate { case POST_WARNING_ACTION: DbgUtils.printStack( TAG ); if ( isPositive ) { // ??? - m_phoneRecs.add( new PhoneRec( (String)params[1], - (String)params[0] ) ); + PhoneRec rec = new PhoneRec( (String)params[1], + (String)params[0] ); + m_phoneRecs.add( rec ); + clearChecked(); + onItemChecked( rec, true ); saveAndRebuild(); } break; From 531f30aae806b2e5ae012fdd9a40590b8ed7bc69 Mon Sep 17 00:00:00 2001 From: Eric House Date: Wed, 28 Dec 2016 13:52:04 -0800 Subject: [PATCH 09/47] cleanup: use import more for new class --- .../org/eehouse/android/xw4/BoardDelegate.java | 13 +++++++------ .../eehouse/android/xw4/GamesListDelegate.java | 17 +++++++++-------- .../src/org/eehouse/android/xw4/Perms23.java | 2 +- .../eehouse/android/xw4/SMSInviteDelegate.java | 10 +++------- .../src/org/eehouse/android/xw4/Utils.java | 7 ++++--- 5 files changed, 24 insertions(+), 25 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java index 9e107a56c..3b57e360e 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java @@ -54,6 +54,7 @@ import junit.framework.Assert; import org.eehouse.android.xw4.DBUtils.SentInvitesInfo; import org.eehouse.android.xw4.DlgDelegate.Action; import org.eehouse.android.xw4.DlgDelegate.ActionPair; +import org.eehouse.android.xw4.Perms23.Perm; import org.eehouse.android.xw4.Toolbar.Buttons; import org.eehouse.android.xw4.jni.CommonPrefs; import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType; @@ -725,12 +726,12 @@ public class BoardDelegate extends DelegateBase boolean showRationale ) { Perms23.Builder builder = - new Perms23.Builder( Perms23.Perm.READ_PHONE_STATE ); + new Perms23.Builder( Perm.READ_PHONE_STATE ); if ( showRationale ) { builder.setOnShowRationale( new Perms23.OnShowRationale() { @Override - public void onShouldShowRationale( Set perms ) + public void onShouldShowRationale( Set perms ) { makeOkOnlyBuilder( R.string.phone_state_rationale ) .setAction( Action.RETRY_PHONE_STATE_ACTION ) @@ -742,7 +743,7 @@ public class BoardDelegate extends DelegateBase builder.asyncQuery( m_activity, new Perms23.PermCbck() { @Override - public void onPermissionResult( Map perms ) { // Do the work regardless of result; just won't have @@ -2229,13 +2230,13 @@ public class BoardDelegate extends DelegateBase && null == m_permCbck ) { // already asked? m_permCbck = new Perms23.PermCbck() { @Override - public void onPermissionResult( Map perms ) { ActionPair pair = new ActionPair( Action.DROP_SMS_ACTION, R.string.remove_sms ); - if ( ! perms.get(Perms23.Perm.SEND_SMS) ) { + if ( ! perms.get(Perm.SEND_SMS) ) { makeNotAgainBuilder( R.string.not_again_missing_perms, R.string.key_notagain_missing_perms ) .setActionPair( pair ) @@ -2243,7 +2244,7 @@ public class BoardDelegate extends DelegateBase } } }; - new Perms23.Builder(Perms23.Perm.SEND_SMS) + new Perms23.Builder(Perm.SEND_SMS) .asyncQuery( m_activity, m_permCbck ); } } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesListDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesListDelegate.java index 1b0a3c31f..3c7a0d503 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesListDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesListDelegate.java @@ -53,6 +53,7 @@ import org.eehouse.android.xw4.DlgDelegate.ActionPair; import org.eehouse.android.xw4.DlgDelegate.NAKey; import org.eehouse.android.xw4.DwnldDelegate.DownloadFinishedListener; import org.eehouse.android.xw4.DwnldDelegate.OnGotLcDictListener; +import org.eehouse.android.xw4.Perms23.Perm; import org.eehouse.android.xw4.jni.CommonPrefs; import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet; import org.eehouse.android.xw4.jni.CommsAddrRec; @@ -1560,14 +1561,14 @@ public class GamesListDelegate extends ListDelegateBase break; case R.id.games_menu_loaddb: - new Perms23.Builder( Perms23.Perm.STORAGE ) + new Perms23.Builder( Perm.STORAGE ) .asyncQuery( m_activity, new Perms23.PermCbck() { @Override - public void onPermissionResult( Map granted ) { - Assert.assertTrue( granted.containsKey(Perms23.Perm.STORAGE) ); - if ( granted.get(Perms23.Perm.STORAGE) ) { + Assert.assertTrue( granted.containsKey(Perm.STORAGE) ); + if ( granted.get(Perm.STORAGE) ) { DBUtils.loadDB( m_activity ); XWPrefs.clearGroupPositions( m_activity ); mkListAdapter(); @@ -1576,13 +1577,13 @@ public class GamesListDelegate extends ListDelegateBase } ); break; case R.id.games_menu_storedb: - new Perms23.Builder( Perms23.Perm.STORAGE ) + new Perms23.Builder( Perm.STORAGE ) .asyncQuery( m_activity, new Perms23.PermCbck() { @Override - public void onPermissionResult( Map granted ) + public void onPermissionResult( Map granted ) { - Assert.assertTrue( granted.containsKey( Perms23.Perm.STORAGE ) ); - if ( granted.get( Perms23.Perm.STORAGE ) ) { + Assert.assertTrue( granted.containsKey( Perm.STORAGE ) ); + if ( granted.get( Perm.STORAGE ) ) { DBUtils.saveDB( m_activity ); showToast( R.string.db_store_done ); } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Perms23.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Perms23.java index e5036ed65..2ae3f07c0 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Perms23.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Perms23.java @@ -61,7 +61,7 @@ public class Perms23 { void onPermissionResult( Map perms ); } public interface OnShowRationale { - void onShouldShowRationale( Set perms ); + void onShouldShowRationale( Set perms ); } public static class Builder { diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java index 4537f68d9..aa00d6de3 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSInviteDelegate.java @@ -39,6 +39,7 @@ import junit.framework.Assert; import org.eehouse.android.xw4.DBUtils.SentInvitesInfo; import org.eehouse.android.xw4.DlgDelegate.Action; +import org.eehouse.android.xw4.Perms23.Perm; import java.util.ArrayList; import java.util.Collections; @@ -57,9 +58,6 @@ public class SMSInviteDelegate extends InviteDelegate { R.id.button_clear, }; - private static final String SAVE_NAME = "SAVE_NAME"; - private static final String SAVE_NUMBER = "SAVE_NUMBER"; - private ArrayList m_phoneRecs; private boolean m_immobileConfirmed; private Activity m_activity; @@ -91,8 +89,6 @@ public class SMSInviteDelegate extends InviteDelegate { super.init( msg, R.string.empty_sms_inviter ); addButtonBar( R.layout.sms_buttons, BUTTONIDS ); - // getBundledData( savedInstanceState ); - getSavedState(); rebuildList( true ); @@ -339,11 +335,11 @@ public class SMSInviteDelegate extends InviteDelegate { private void askContactsPermission( boolean showRationale ) { - Perms23.Builder builder = new Perms23.Builder( Perms23.Perm.READ_CONTACTS ); + Perms23.Builder builder = new Perms23.Builder( Perm.READ_CONTACTS ); if ( showRationale ) { builder.setOnShowRationale( new Perms23.OnShowRationale() { @Override - public void onShouldShowRationale( Set perms ) + public void onShouldShowRationale( Set perms ) { makeOkOnlyBuilder( R.string.contacts_rationale ) .setAction( Action.RETRY_CONTACTS_ACTION ) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java index 4b6d08e14..319285f3e 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java @@ -63,6 +63,7 @@ import java.util.Random; import junit.framework.Assert; +import org.eehouse.android.xw4.Perms23.Perm; import org.eehouse.android.xw4.jni.CommonPrefs; import org.eehouse.android.xw4.loc.LocUtils; @@ -113,7 +114,7 @@ public class Utils { public static boolean isGSMPhone( Context context ) { boolean result = false; - if ( Perms23.havePermission( Perms23.Perm.READ_PHONE_STATE ) ) { + if ( Perms23.havePermission( Perm.READ_PHONE_STATE ) ) { SMSService.SMSPhoneInfo info = SMSService.getPhoneInfo( context ); result = info.isPhone && info.isGSM; } @@ -129,7 +130,7 @@ public class Utils { public static boolean deviceSupportsSMS( Context context ) { boolean result = false; - if ( Perms23.havePermission( Perms23.Perm.READ_PHONE_STATE ) ) { + if ( Perms23.havePermission( Perm.READ_PHONE_STATE ) ) { TelephonyManager tm = (TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE ); result = null != tm; @@ -283,7 +284,7 @@ public class Utils { synchronized ( s_phonesHash ) { if ( s_phonesHash.containsKey( phone ) ) { name = s_phonesHash.get( phone ); - } else if ( Perms23.havePermission( Perms23.Perm.READ_CONTACTS ) ) { + } else if ( Perms23.havePermission( Perm.READ_CONTACTS ) ) { try { ContentResolver contentResolver = context .getContentResolver(); From c0784fe8b71c62ee915144125ca7e4713121d767 Mon Sep 17 00:00:00 2001 From: Eric House Date: Thu, 29 Dec 2016 17:17:27 -0800 Subject: [PATCH 10/47] fix crash on Android 2.3 Channel wasn't a thing back then. Catch the ClassNotFound exception and set the same boolean as when permissions aren't available (in manifest), which means nothing else tries to run. --- .../org/eehouse/android/xw4/WiDirService.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/WiDirService.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/WiDirService.java index ba882029d..6913e391e 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/WiDirService.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/WiDirService.java @@ -181,18 +181,20 @@ public class WiDirService extends XWService { public static void init( Context context ) { DbgUtils.logd( TAG, "init()" ); - ChannelListener listener = new ChannelListener() { - @Override - public void onChannelDisconnected() { - DbgUtils.logd( TAG, "onChannelDisconnected()"); - } - }; try { + ChannelListener listener = new ChannelListener() { + @Override + public void onChannelDisconnected() { + DbgUtils.logd( TAG, "onChannelDisconnected()"); + } + }; sChannel = getMgr().initialize( context, Looper.getMainLooper(), listener ); s_discoverer = new ServiceDiscoverer( sChannel ); sHavePermission = true; - } catch ( SecurityException se ) { + } catch ( NoClassDefFoundError ndf ) { // old os version + sHavePermission = false; + } catch ( SecurityException se ) { // perm not in manifest sHavePermission = false; } } From 4cdc917cf513c61aea2fd684d9c89231e4c76302 Mon Sep 17 00:00:00 2001 From: Eric House Date: Thu, 29 Dec 2016 17:27:33 -0800 Subject: [PATCH 11/47] tweak changelog --- xwords4/android/XWords4/assets/changes.html | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/xwords4/android/XWords4/assets/changes.html b/xwords4/android/XWords4/assets/changes.html index e401ec59a..731325a3a 100644 --- a/xwords4/android/XWords4/assets/changes.html +++ b/xwords4/android/XWords4/assets/changes.html @@ -16,8 +16,8 @@

Crosswords 4.4.115 release

This release uses the new permissions process introduced with - "Marshmallow": Crosswords only asks for permissions when they're - required.

+ Android "Marshmallow": Crosswords only asks for permissions when + they're required.

Please take @@ -28,9 +28,12 @@

New with this release

  • Request permissions when they're needed, e.g. ask to send - SMS messages when you choose to play a game that way.
  • -
  • Other permissions required are for access to Storage and to contacts.
  • -
  • Rework the invitations dialogs. (No new features, but please report any bugs!)
  • + SMS messages when you configure a game to communicate using + SMS. +
  • Other permissions required are for access to storage and to + contacts.
  • +
  • Rework the invitations dialogs. (No new features, but please + report any bugs!)
  • New two-color icon for notifications (required by the newer Android that supports run-time permissions
From 74d1967f239c6020ad4b532cccbbc1b0c067b5c5 Mon Sep 17 00:00:00 2001 From: Eric House Date: Thu, 29 Dec 2016 18:21:33 -0800 Subject: [PATCH 12/47] cleanup from code review Mostly removing TAG where isn't being used in the file, but other tweaks too, none of which changes executed code. --- xwords4/android/XWords4/assets/changes.html | 15 ++++++++------ .../XWords4/res/layout/relay_buttons.xml | 2 -- .../eehouse/android/xw4/BTInviteActivity.java | 1 - .../eehouse/android/xw4/BTInviteDelegate.java | 6 +++--- .../eehouse/android/xw4/BoardActivity.java | 1 - .../org/eehouse/android/xw4/BoardFrag.java | 1 - .../org/eehouse/android/xw4/ChatActivity.java | 1 - .../src/org/eehouse/android/xw4/ChatFrag.java | 1 - .../android/xw4/ConnViaViewLayout.java | 1 - .../android/xw4/DictBrowseActivity.java | 1 - .../eehouse/android/xw4/DictBrowseFrag.java | 1 - .../android/xw4/DictListPreference.java | 1 - .../eehouse/android/xw4/DictsActivity.java | 1 - .../org/eehouse/android/xw4/DictsFrag.java | 1 - .../eehouse/android/xw4/DispatchNotify.java | 1 - .../src/org/eehouse/android/xw4/DlgState.java | 1 - .../eehouse/android/xw4/DwnldActivity.java | 1 - .../android/xw4/EditColorPreference.java | 1 - .../android/xw4/ExpiringLinearLayout.java | 1 - .../android/xw4/GameConfigActivity.java | 1 - .../eehouse/android/xw4/GameConfigFrag.java | 1 - .../org/eehouse/android/xw4/GameNamer.java | 1 - .../eehouse/android/xw4/GamesListFrag.java | 1 - .../eehouse/android/xw4/InviteDelegate.java | 12 +++-------- .../android/xw4/LangListPreference.java | 1 - .../eehouse/android/xw4/ListDelegateBase.java | 1 - .../org/eehouse/android/xw4/NotAgainView.java | 1 - .../src/org/eehouse/android/xw4/Perms23.java | 5 ++--- .../android/xw4/RelayCheckBoxPreference.java | 1 - .../android/xw4/RelayInviteActivity.java | 1 - .../eehouse/android/xw4/RelayReceiver.java | 1 - .../android/xw4/SMSCheckBoxPreference.java | 1 - .../android/xw4/SMSInviteActivity.java | 1 - .../android/xw4/SMSInviteDelegate.java | 20 ++++++++----------- .../android/xw4/StudyListActivity.java | 1 - .../eehouse/android/xw4/StudyListFrag.java | 1 - .../org/eehouse/android/xw4/ThumbCanvas.java | 1 - .../org/eehouse/android/xw4/TwoStrsItem.java | 1 - .../src/org/eehouse/android/xw4/Utils.java | 7 ------- .../android/xw4/WiDirInviteActivity.java | 1 - .../android/xw4/XWConnAddrPreference.java | 1 - .../android/xw4/XWDevIDPreference.java | 1 - .../android/xw4/XWEditTextPreference.java | 1 - .../eehouse/android/xw4/XWListPreference.java | 1 - .../android/xw4/XWSumListPreference.java | 1 - .../android/xw4/XWThumbListPreference.java | 1 - .../eehouse/android/xw4/jni/CommonPrefs.java | 1 - .../eehouse/android/xw4/loc/LocActivity.java | 1 - .../android/xw4/loc/LocItemEditActivity.java | 1 - .../android/xw4/loc/LocItemEditDelegate.java | 1 - .../eehouse/android/xw4/loc/LocListItem.java | 1 - .../xw4/loc/XlatingSpinnerAdapter.java | 1 - 52 files changed, 25 insertions(+), 87 deletions(-) diff --git a/xwords4/android/XWords4/assets/changes.html b/xwords4/android/XWords4/assets/changes.html index 731325a3a..643714a59 100644 --- a/xwords4/android/XWords4/assets/changes.html +++ b/xwords4/android/XWords4/assets/changes.html @@ -28,14 +28,17 @@

New with this release

  • Request permissions when they're needed, e.g. ask to send - SMS messages when you configure a game to communicate using - SMS.
  • + SMS messages when you configure a game to communicate using + SMS
  • Other permissions required are for access to storage and to - contacts.
  • -
  • Rework the invitations dialogs. (No new features, but please - report any bugs!)
  • + contacts +
  • Use less battery by being smarter about how often to check + the relay for moves (This will mostly impact those + installing from F-Droid.)
  • New two-color icon for notifications (required by the newer - Android that supports run-time permissions
  • + Android that supports run-time permissions) +
  • Allow board "squares" to be wider than tall if it + fills the screen better

(The full changelog diff --git a/xwords4/android/XWords4/res/layout/relay_buttons.xml b/xwords4/android/XWords4/res/layout/relay_buttons.xml index 81cca3230..ed401fc3e 100644 --- a/xwords4/android/XWords4/res/layout/relay_buttons.xml +++ b/xwords4/android/XWords4/res/layout/relay_buttons.xml @@ -17,8 +17,6 @@ android:clickable="false" /> - add_self_button -