diff --git a/xwords4/android/XWords4/archive/R.java b/xwords4/android/XWords4/archive/R.java index cdb1e8da8..6f6e83e17 100644 --- a/xwords4/android/XWords4/archive/R.java +++ b/xwords4/android/XWords4/archive/R.java @@ -5058,6 +5058,7 @@ XLATE-ME */ public static final int phone_label=0x7f050223; + 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. Don't warn, but simply force to skip turn (give 0 points) @@ -5822,7 +5823,7 @@ XLATE-ME */ public static final int remote_undone=0x7f050226; - public static final int remove_sms=0x7f050359; + public static final int remove_sms=0x7f05035a; /** Change the name of this group to: */ public static final int rename_group_label=0x7f050273; diff --git a/xwords4/android/XWords4/res/values/strings.xml b/xwords4/android/XWords4/res/values/strings.xml index e8904e4e7..ab100cdc5 100644 --- a/xwords4/android/XWords4/res/values/strings.xml +++ b/xwords4/android/XWords4/res/values/strings.xml @@ -2725,6 +2725,13 @@ receive moves.\n\nYou can re-open it to be asked for permission again. Or you can remove the SMS communication setting. + Crosswords wants to determine + whether your phone can send SMS \"data\" messages to give you the + option of playing that way. If you don\'t ever want to play via SMS, + e.g. because you pay for each message or have a Verizon phone, it\'s + safe to permanently deny permission. + + Remove SMS diff --git a/xwords4/android/XWords4/res_src/values-ba_CK/strings.xml b/xwords4/android/XWords4/res_src/values-ba_CK/strings.xml index f176d12f5..cec1fde61 100644 --- a/xwords4/android/XWords4/res_src/values-ba_CK/strings.xml +++ b/xwords4/android/XWords4/res_src/values-ba_CK/strings.xml @@ -2326,5 +2326,11 @@ os. Uoy nac llits nepo eht ,emag tub ti yam ton eb elba ot dnes ro eviecer sevom.\n\nUoy nac nepo-er ti ot eb deksa rof noissimrep niaga. Ro uoy nac evomer eht SMS noitacinummoc gnittes. + Sdrowssorc stnaw ot enimreted + rehtehw ruoy enohp nac dnes SMS \"atad\" segassem ot evig uoy eht + noitpo fo gniyalp taht yaw. Fi uoy nod\'t reve tnaw ot yalp aiv ,SMs + e.g. esuaceb uoy yap rof hcae egassem ro evah a Nozirev ,enohp ti\'s + efas ot yltnenamrep yned noissimrep. + Evomer SMS diff --git a/xwords4/android/XWords4/res_src/values-ca_PS/strings.xml b/xwords4/android/XWords4/res_src/values-ca_PS/strings.xml index 58184d46b..7db47b6da 100644 --- a/xwords4/android/XWords4/res_src/values-ca_PS/strings.xml +++ b/xwords4/android/XWords4/res_src/values-ca_PS/strings.xml @@ -2326,5 +2326,11 @@ SO. YOU CAN STILL OPEN THE GAME, BUT IT MAY NOT BE ABLE TO SEND OR RECEIVE MOVES.\n\nYOU CAN RE-OPEN IT TO BE ASKED FOR PERMISSION AGAIN. OR YOU CAN REMOVE THE SMS COMMUNICATION SETTING. + CROSSWORDS WANTS TO DETERMINE + WHETHER YOUR PHONE CAN SEND SMS \"DATA\" MESSAGES TO GIVE YOU THE + OPTION OF PLAYING THAT WAY. IF YOU DON\'T EVER WANT TO PLAY VIA SMS, + E.G. BECAUSE YOU PAY FOR EACH MESSAGE OR HAVE A VERIZON PHONE, IT\'S + SAFE TO PERMANENTLY DENY PERMISSION. + REMOVE SMS 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 19a4c40f8..b4af54e64 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java @@ -42,7 +42,12 @@ import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; +import java.util.ArrayList; +import java.util.Iterator; import java.util.Map; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Semaphore; import junit.framework.Assert; @@ -68,10 +73,6 @@ import org.eehouse.android.xw4.jni.UtilCtxtImpl; import org.eehouse.android.xw4.jni.XwJNI.GamePtr; import org.eehouse.android.xw4.jni.XwJNI; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.concurrent.Semaphore; - public class BoardDelegate extends DelegateBase implements TransportProcs.TPMsgHandler, View.OnClickListener, DwnldDelegate.DownloadFinishedListener, @@ -405,8 +406,8 @@ public class BoardDelegate extends DelegateBase if ( self.m_summary.hasRematchInfo() ) { self.tryRematchInvites( true ); } else { - self.showInviteChoicesThen( Action.LAUNCH_INVITE_ACTION, - self.m_sentInfo ); + self.callInviteChoices( Action.LAUNCH_INVITE_ACTION, + self.m_sentInfo, true ); } } else { self.askDropRelay(); @@ -714,6 +715,43 @@ public class BoardDelegate extends DelegateBase } } + // Invitations need to check phone state to decide whether to offer SMS + // invitation. Complexity (showRationale) boolean is to prevent infinite + // loop of showing the rationale over and over. Android will always tell + // us to show the rationale, but if we've done it already we need to go + // straight to asking for the permission. + private void callInviteChoices( final Action action, + final DBUtils.SentInvitesInfo info, + boolean showRationale ) + { + Perms23.Builder builder = + new Perms23.Builder( Perms23.Perm.READ_PHONE_STATE ); + + if ( showRationale ) { + builder.setOnShowRationale( new Perms23.OnShowRationale() { + @Override + public void onShouldShowRationale( Set perms ) + { + makeOkOnlyBuilder( R.string.phone_state_rationale ) + .setAction( Action.RETRY_PHONE_STATE_ACTION ) + .setParams( action, info ) + .show(); + } + } ); + } + + builder.asyncQuery( m_activity, new Perms23.PermCbck() { + @Override + public void onPermissionResult( Map perms ) + { + // Do the work regardless of result; just won't have + // SMS option + showInviteChoicesThen( action, info ); + } + }); + } + @Override public void orientationChanged() { @@ -1006,6 +1044,10 @@ public class BoardDelegate extends DelegateBase } }, 10 ); } + } else if ( Action.RETRY_PHONE_STATE_ACTION == action ) { + Action stateAction = (Action)params[0]; + DBUtils.SentInvitesInfo info = (DBUtils.SentInvitesInfo)params[1]; + callInviteChoices( stateAction, info, false ); } else if ( positive ) { handled = true; JNICmd cmd = JNICmd.CMD_NONE; 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 f3603b5fd..1b607eb50 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DlgDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DlgDelegate.java @@ -93,6 +93,7 @@ public class DlgDelegate { NFC_TO_SELF, DROP_RELAY_ACTION, DROP_SMS_ACTION, + RETRY_PHONE_STATE_ACTION, // Dict Browser FINISH_ACTION, 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 ed6203a2a..9e9c659b8 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Perms23.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Perms23.java @@ -60,9 +60,13 @@ public class Perms23 { public interface PermCbck { void onPermissionResult( Map perms ); } + public interface OnShowRationale { + void onShouldShowRationale( Set perms ); + } public static class Builder { private Set m_perms = new HashSet(); + private OnShowRationale m_onShow; public Builder(Set perms) { m_perms.addAll( perms ); @@ -77,11 +81,18 @@ public class Perms23 { return this; } + public Builder setOnShowRationale( OnShowRationale onShow ) + { + m_onShow = onShow; + return this; + } + public void asyncQuery( Activity activity, PermCbck cbck ) { - DbgUtils.logd( TAG, "asyncQuery()" ); + DbgUtils.logd( TAG, "asyncQuery(%s)", m_perms.toString() ); boolean haveAll = true; boolean shouldShow = false; + Set needShow = new HashSet(); ArrayList askStrings = new ArrayList(); for ( Perm perm : m_perms ) { @@ -90,22 +101,22 @@ public class Perms23 { == ContextCompat.checkSelfPermission( activity, permStr ); // For research: ask the OS if we should be printing a rationale - if ( BuildConfig.DEBUG && !haveIt ) { - shouldShow = shouldShow || ActivityCompat - .shouldShowRequestPermissionRationale( activity, permStr ); + if ( !haveIt ) { + askStrings.add( permStr ); + + if ( ActivityCompat + .shouldShowRequestPermissionRationale( activity, + permStr ) ) { + needShow.add( perm ); + } } haveAll = haveAll && haveIt; - if ( !haveIt ) { - askStrings.add( permStr ); - } } - if ( shouldShow ) { - DbgUtils.showf( "Should show rationale!!!" ); - } - - if ( haveAll ) { + if ( 0 < needShow.size() && null != m_onShow ) { + m_onShow.onShouldShowRationale( needShow ); + } else if ( haveAll ) { Map map = new HashMap(); for ( Perm perm : m_perms ) { map.put( perm, true ); @@ -117,7 +128,7 @@ public class Perms23 { ActivityCompat.requestPermissions( activity, permsArray, code ); } - DbgUtils.logd( TAG, "asyncQuery(%s) => %b", m_perms.toString(), haveAll ); + DbgUtils.logd( TAG, "asyncQuery(%s) DONE", m_perms.toString() ); } }