fix crash rematching SMS without PHONE permission

You need PHONE permission to start and play an SMS game but not to have
started it in response to an invitation. But to rematch you need it. So
ask, including offering a rationale that differs depending on whether
there's a way for the game to communicate once SMS is removed.
This commit is contained in:
Eric House 2016-12-31 15:05:39 -08:00
parent a24b3396b3
commit 503ea46ca5
10 changed files with 192 additions and 78 deletions

View file

@ -1988,8 +1988,8 @@ XLATE-ME
*/
public static final int connstat_unsucc=0x7f050237;
public static final int contact_not_found=0x7f05035c;
public static final int contacts_rationale=0x7f05035a;
public static final int contact_not_found=0x7f05035f;
public static final int contacts_rationale=0x7f05035d;
/** title of dialog brought up in response to the
board_menu_game_counts menu. The dialog lists all tiles in
the language being used for the game together with how many
@ -5046,6 +5046,13 @@ XLATE-ME
*/
public static final int phone_label=0x7f050223;
public static final int phone_lookup_rationale=0x7f05035a;
/** Case where SMS is the only way the game can communicate
*/
public static final int phone_lookup_rationale_drop=0x7f05035b;
/** Case where SMS is NOT the only way the game can communicate
*/
public static final int phone_lookup_rationale_others=0x7f05035c;
public static final int phone_state_rationale=0x7f050359;
/** Don't warn, but simply force to skip turn (give 0 points)
when user attempts to play word not in the wordlist.
@ -5803,7 +5810,7 @@ XLATE-ME
*/
public static final int remote_undone=0x7f050226;
public static final int remove_sms=0x7f05035b;
public static final int remove_sms=0x7f05035e;
/** <string name="rename_group_label">Change the name of this group to:</string>
*/
public static final int rename_group_label=0x7f050273;
@ -6011,7 +6018,7 @@ XLATE-ME
/** <string name="sms_ready_text">Tap the receiving device now</string>
*/
public static final int sms_ready_text=0x7f050288;
public static final int sms_send_failed=0x7f05035d;
public static final int sms_send_failed=0x7f050360;
/** <string name="square_tiles">Square rack tiles</string>
*/
public static final int square_tiles=0x7f050278;
@ -6880,6 +6887,9 @@ string name="str_robot_moved">O robô fez esta jogada:\u0020</string
feature is not yet supported on Android.)
*/
public static final int title_tile_picker=0x7f0501b4;
/** <string name="perms_rationale_title">Android Permissions</string>
*/
public static final int toast_no_permission=0x7f050361;
/** <string name="update_dicts_fmt">Updates are available for one or more
installed wordlists. Would you like to download the new
version[s] of %1$s now?</string>

View file

@ -2727,12 +2727,24 @@
<string name="phone_state_rationale">Crosswords wants to offer you
the option of exchanging moves via SMS \"data\" messages. In order
to determine if your device can send SMS it needs permission to ask
it about itself. If it can\'t send SMS (e.g. because it isn\'t a
phone) or you don\'t ever want to play via SMS (e.g. because you pay
for each message), it\'s safe to permanently deny permission.
to determine if your device can send SMS Crosswords needs permission
to ask your device about itself. If it can\'t send SMS (e.g. because
it isn\'t a phone) or you don\'t ever want to play via SMS
(e.g. because you pay for each message), it\'s safe to permanently
deny permission.
</string>
<string name="phone_lookup_rationale">Crosswords needs your phone
number to initialize a game played via SMS, and needs your
permission now in order to access it.</string>
<!-- Case where SMS is the only way the game can communicate -->
<string name="phone_lookup_rationale_drop">Rematching this SMS-only
game is not possible without this permission.</string>
<!-- Case where SMS is NOT the only way the game can communicate -->
<string name="phone_lookup_rationale_others">Without this permission
rematching will create a game that cannot not play via SMS.</string>
<string name="contacts_rationale">Crosswords want access to your
contacts in order to put a name to phone numbers that send you
invitations via SMS. You\'ll still be able to receive invitations if
@ -2743,4 +2755,7 @@
<string name="contact_not_found">Not in Contacts</string>
<string name="sms_send_failed">SMS send failed</string>
<!-- <string name="perms_rationale_title">Android Permissions</string> -->
<string name="toast_no_permission">Permission not granted</string>
</resources>

View file

@ -2328,11 +2328,21 @@
niaga. Ro uoy nac evomer eht SMS noitacinummoc gnittes.</string>
<string name="phone_state_rationale">Sdrowssorc stnaw ot reffo uoy
eht noitpo fo gnignahcxe sevom aiv SMS \"atad\" segassem. Ni redro
ot enimreted fi ruoy ecived nac dnes SMS ti sdeen noissimrep ot ksa
ti tuoba flesti. Fi ti nac\'t dnes SMS e(.g. esuaceb ti nsi\'t a
)enohp ro uoy nod\'t reve tnaw ot yalp aiv SMS e(.g. esuaceb uoy yap
rof hcae ,)egassem ti\'s efas ot yltnenamrep yned noissimrep.
ot enimreted fi ruoy ecived nac dnes SMS Sdrowssorc sdeen noissimrep
ot ksa ruoy ecived tuoba flesti. Fi ti nac\'t dnes SMS e(.g. esuaceb
ti nsi\'t a )enohp ro uoy nod\'t reve tnaw ot yalp aiv SMS
e(.g. esuaceb uoy yap rof hcae ,)egassem ti\'s efas ot yltnenamrep
yned noissimrep.
</string>
<string name="phone_lookup_rationale">Sdrowssorc sdeen ruoy enohp
rebmun ot ezilaitini a emag deyalp aiv ,SMs dna sdeen ruoy
noissimrep won ni redro ot ssecca ti.</string>
<!-- Case where SMS is the only way the game can communicate -->
<string name="phone_lookup_rationale_drop">Gnihctamer siht YLNo-sms
emag si ton elbissop tuohtiw siht noissimrep.</string>
<!-- Case where SMS is NOT the only way the game can communicate -->
<string name="phone_lookup_rationale_others">Tuohtiw siht noissimrep
gnihctamer lliw etaerc a emag taht tonnac ton yalp aiv SMS.</string>
<string name="contacts_rationale">Sdrowssorc tnaw ssecca ot ruoy
stcatnoc ni redro ot tup a eman ot enohp srebmun taht dnes uoy
snoitativni aiv SMS. Uoy\'ll llits eb elba ot eviecer snoitativni fi
@ -2341,4 +2351,6 @@
<string name="remove_sms">Evomer SMS</string>
<string name="contact_not_found">Ton ni Stcatnoc</string>
<string name="sms_send_failed">SMS dnes deliaf</string>
<!-- <string name="perms_rationale_title">Android Permissions</string> -->
<string name="toast_no_permission">Noissimrep ton detnarg</string>
</resources>

View file

@ -2328,11 +2328,21 @@
AGAIN. OR YOU CAN REMOVE THE SMS COMMUNICATION SETTING.</string>
<string name="phone_state_rationale">CROSSWORDS WANTS TO OFFER YOU
THE OPTION OF EXCHANGING MOVES VIA SMS \"DATA\" MESSAGES. IN ORDER
TO DETERMINE IF YOUR DEVICE CAN SEND SMS IT NEEDS PERMISSION TO ASK
IT ABOUT ITSELF. IF IT CAN\'T SEND SMS (E.G. BECAUSE IT ISN\'T A
PHONE) OR YOU DON\'T EVER WANT TO PLAY VIA SMS (E.G. BECAUSE YOU PAY
FOR EACH MESSAGE), IT\'S SAFE TO PERMANENTLY DENY PERMISSION.
TO DETERMINE IF YOUR DEVICE CAN SEND SMS CROSSWORDS NEEDS PERMISSION
TO ASK YOUR DEVICE ABOUT ITSELF. IF IT CAN\'T SEND SMS (E.G. BECAUSE
IT ISN\'T A PHONE) OR YOU DON\'T EVER WANT TO PLAY VIA SMS
(E.G. BECAUSE YOU PAY FOR EACH MESSAGE), IT\'S SAFE TO PERMANENTLY
DENY PERMISSION.
</string>
<string name="phone_lookup_rationale">CROSSWORDS NEEDS YOUR PHONE
NUMBER TO INITIALIZE A GAME PLAYED VIA SMS, AND NEEDS YOUR
PERMISSION NOW IN ORDER TO ACCESS IT.</string>
<!-- Case where SMS is the only way the game can communicate -->
<string name="phone_lookup_rationale_drop">REMATCHING THIS SMS-ONLY
GAME IS NOT POSSIBLE WITHOUT THIS PERMISSION.</string>
<!-- Case where SMS is NOT the only way the game can communicate -->
<string name="phone_lookup_rationale_others">WITHOUT THIS PERMISSION
REMATCHING WILL CREATE A GAME THAT CANNOT NOT PLAY VIA SMS.</string>
<string name="contacts_rationale">CROSSWORDS WANT ACCESS TO YOUR
CONTACTS IN ORDER TO PUT A NAME TO PHONE NUMBERS THAT SEND YOU
INVITATIONS VIA SMS. YOU\'LL STILL BE ABLE TO RECEIVE INVITATIONS IF
@ -2341,4 +2351,6 @@
<string name="remove_sms">REMOVE SMS</string>
<string name="contact_not_found">NOT IN CONTACTS</string>
<string name="sms_send_failed">SMS SEND FAILED</string>
<!-- <string name="perms_rationale_title">Android Permissions</string> -->
<string name="toast_no_permission">PERMISSION NOT GRANTED</string>
</resources>

View file

@ -71,6 +71,7 @@ public class DlgDelegate {
NEW_GAME_DFLT_NAME,
ENABLE_DUALPANE,
ENABLE_DUALPANE_EXIT,
RETRY_REMATCH,
// BoardDelegate
UNDO_LAST_ACTION,

View file

@ -872,7 +872,7 @@ public class GamesListDelegate extends ListDelegateBase
EditText edit = (EditText)((Dialog)dlg)
.findViewById( R.id.edit );
String gameName = edit.getText().toString();
curThis().startRematchWithName( gameName );
curThis().startRematchWithName( gameName, true );
}
} )
.create();
@ -1326,6 +1326,10 @@ public class GamesListDelegate extends ListDelegateBase
askDefaultName();
break;
case RETRY_REMATCH:
startRematchWithName( (String)params[0], false );
break;
default:
Assert.fail();
}
@ -2162,29 +2166,76 @@ public class GamesListDelegate extends ListDelegateBase
}
}
private void startRematchWithName( String gameName )
private void startRematchWithName( final String gameName,
boolean showRationale )
{
if ( null != gameName && 0 < gameName.length() ) {
Bundle extras = m_rematchExtras;
long srcRowID = extras.getLong( REMATCH_ROWID_EXTRA, -1 );
String btAddr = extras.getString( REMATCH_BTADDR_EXTRA );
String phone = extras.getString( REMATCH_PHONE_EXTRA );
String relayID = extras.getString( REMATCH_RELAYID_EXTRA );
String p2pMacAddress = extras.getString( REMATCH_P2PADDR_EXTRA );
String dict = extras.getString( REMATCH_DICT_EXTRA );
int lang = extras.getInt( REMATCH_LANG_EXTRA, -1 );
String json = extras.getString( REMATCH_PREFS_EXTRA );
int bits = extras.getInt( REMATCH_ADDRS_EXTRA, -1 );
CommsConnTypeSet addrs = new CommsConnTypeSet( bits );
final CommsConnTypeSet addrs = new CommsConnTypeSet( bits );
boolean hasSMS = addrs.contains( CommsConnType.COMMS_CONN_SMS );
if ( !hasSMS || null != SMSService.getPhoneInfo( m_activity ) ) {
rematchWithNameAndPerm( gameName, addrs );
} else {
Perms23.Builder builder =
new Perms23.Builder( Perm.READ_PHONE_STATE );
if ( showRationale ) {
builder.setOnShowRationale( new Perms23.OnShowRationale() {
public void onShouldShowRationale( Set<Perm> perms )
{
int id = (1 == addrs.size())
? R.string.phone_lookup_rationale_drop
: R.string.phone_lookup_rationale_others;
String msg = getString( R.string.phone_lookup_rationale )
+ "\n\n" + getString( id );
makeConfirmThenBuilder( msg, Action.RETRY_REMATCH )
// .setTitle( R.string.perms_rationale_title )
.setParams( gameName )
.show();
}
});
}
builder.asyncQuery( m_activity, new Perms23.PermCbck() {
@Override
public void onPermissionResult( Map<Perm,
Boolean> granted )
{
if ( !granted.get( Perm.READ_PHONE_STATE ) ) {
addrs.remove( CommsConnType.COMMS_CONN_SMS );
}
if ( 0 == addrs.size() ) {
DbgUtils.showf( m_activity, R.string.toast_no_permission );
} else {
rematchWithNameAndPerm( gameName, addrs );
}
}
} );
}
}
}
private void rematchWithNameAndPerm( String gameName, CommsConnTypeSet addrs )
{
if ( null != gameName && 0 < gameName.length() ) {
Bundle extras = m_rematchExtras;
long srcRowID = extras.getLong( REMATCH_ROWID_EXTRA, DBUtils.ROWID_NOTFOUND );
boolean solo = extras.getBoolean( REMATCH_IS_SOLO, true );
long newid;
if ( null == btAddr && null == phone && null == relayID
&& null == p2pMacAddress ) {
if ( solo ) {
newid = GameUtils.dupeGame( m_activity, srcRowID );
if ( DBUtils.ROWID_NOTFOUND != newid ) {
DBUtils.setName( m_activity, newid, gameName );
}
} else {
String btAddr = extras.getString( REMATCH_BTADDR_EXTRA );
String phone = extras.getString( REMATCH_PHONE_EXTRA );
String relayID = extras.getString( REMATCH_RELAYID_EXTRA );
String p2pMacAddress = extras.getString( REMATCH_P2PADDR_EXTRA );
String dict = extras.getString( REMATCH_DICT_EXTRA );
int lang = extras.getInt( REMATCH_LANG_EXTRA, -1 );
String json = extras.getString( REMATCH_PREFS_EXTRA );
long groupID = DBUtils.getGroupForGame( m_activity, srcRowID );
newid = GameUtils.makeNewMultiGame( m_activity, groupID, dict,
lang, json, addrs, gameName );

View file

@ -524,12 +524,14 @@ public class NetLaunchInfo {
public void addSMSInfo( Context context )
{
SMSService.SMSPhoneInfo pi = SMSService.getPhoneInfo( context );
phone = pi.number;
isGSM = pi.isGSM;
if ( null != pi ) {
phone = pi.number;
isGSM = pi.isGSM;
osVers = Integer.valueOf( android.os.Build.VERSION.SDK );
osVers = Integer.valueOf( android.os.Build.VERSION.SDK );
m_addrs.add( CommsConnType.COMMS_CONN_SMS );
m_addrs.add( CommsConnType.COMMS_CONN_SMS );
}
}
public void addP2PInfo( Context context )

View file

@ -112,56 +112,62 @@ public class SMSService extends XWService {
public String number;
public boolean isGSM;
}
private static SMSPhoneInfo s_phoneInfo;
private static SMSPhoneInfo s_phoneInfo;
public static SMSPhoneInfo getPhoneInfo( Context context )
{
if ( null == s_phoneInfo ) {
String number = null;
boolean isGSM = false;
boolean isPhone = false;
TelephonyManager mgr = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
if ( null != mgr ) {
number = mgr.getLine1Number();
int type = mgr.getPhoneType();
isGSM = TelephonyManager.PHONE_TYPE_GSM == type;
isPhone = true;
}
try {
String number = null;
boolean isGSM = false;
boolean isPhone = false;
TelephonyManager mgr = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
if ( null != mgr ) {
number = mgr.getLine1Number(); // needs permission
int type = mgr.getPhoneType();
isGSM = TelephonyManager.PHONE_TYPE_GSM == type;
isPhone = true;
}
String radio = XWPrefs.getPrefsString( context, R.string.key_force_radio );
int[] ids = { R.string.radio_name_real,
R.string.radio_name_tablet,
R.string.radio_name_gsm,
R.string.radio_name_cdma,
};
String radio =
XWPrefs.getPrefsString( context, R.string.key_force_radio );
int[] ids = { R.string.radio_name_real,
R.string.radio_name_tablet,
R.string.radio_name_gsm,
R.string.radio_name_cdma,
};
int id = R.string.radio_name_real; // default so don't crash before set
for ( int ii = 0; ii < ids.length; ++ii ) {
if ( radio.equals(context.getString(ids[ii])) ) {
id = ids[ii];
// default so don't crash before set
int id = R.string.radio_name_real;
for ( int ii = 0; ii < ids.length; ++ii ) {
if ( radio.equals(context.getString(ids[ii])) ) {
id = ids[ii];
break;
}
}
switch( id ) {
case R.string.radio_name_real:
break; // go with above
case R.string.radio_name_tablet:
number = null;
isPhone = false;
break;
case R.string.radio_name_gsm:
case R.string.radio_name_cdma:
isGSM = id == R.string.radio_name_gsm;
if ( null == number ) {
number = "000-000-0000";
}
isPhone = true;
break;
}
}
switch( id ) {
case R.string.radio_name_real:
break; // go with above
case R.string.radio_name_tablet:
number = null;
isPhone = false;
break;
case R.string.radio_name_gsm:
case R.string.radio_name_cdma:
isGSM = id == R.string.radio_name_gsm;
if ( null == number ) {
number = "000-000-0000";
}
isPhone = true;
break;
s_phoneInfo = new SMSPhoneInfo( isPhone, number, isGSM );
} catch ( SecurityException se ) {
DbgUtils.loge( TAG, "got SecurityException" );
}
s_phoneInfo = new SMSPhoneInfo( isPhone, number, isGSM );
}
return s_phoneInfo;
}
@ -654,7 +660,8 @@ public class SMSService extends XWService {
// Try send-to-self
if ( XWPrefs.getSMSToSelfEnabled( this ) ) {
String myPhone = getPhoneInfo( this ).number;
if ( PhoneNumberUtils.compare( phone, myPhone ) ) {
if ( null != myPhone
&& PhoneNumberUtils.compare( phone, myPhone ) ) {
for ( byte[] fragment : fragments ) {
handleFrom( this, fragment, phone );
}

View file

@ -115,7 +115,7 @@ public class Utils {
boolean result = false;
if ( Perms23.havePermission( Perm.READ_PHONE_STATE ) ) {
SMSService.SMSPhoneInfo info = SMSService.getPhoneInfo( context );
result = info.isPhone && info.isGSM;
result = null != info && info.isPhone && info.isGSM;
}
DbgUtils.logd( TAG, "isGSMPhone() => %b", result );
return result;

View file

@ -217,7 +217,8 @@ public class CommsAddrRec {
public CommsAddrRec( CommsConnTypeSet types )
{
conTypes = types;
this();
conTypes.addAll( types );
}
public CommsAddrRec( String host, int port )
@ -359,8 +360,11 @@ public class CommsAddrRec {
break;
case COMMS_CONN_SMS:
SMSService.SMSPhoneInfo pi = SMSService.getPhoneInfo( context );
sms_phone = pi.number;
sms_port = 3; // fix comms already...
// Do we have phone permission? If not, shouldn't be set at all!
if ( null != pi ) {
sms_phone = pi.number;
sms_port = 3; // fix comms already...
}
break;
case COMMS_CONN_P2P:
p2p_addr = WiDirService.getMyMacAddress( context );