mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-05 07:05:38 +00:00
Make sure we have SEND_SMS permission before sending an SMS
Fixes #7246
This commit is contained in:
parent
8686691a5a
commit
27e11e9627
@ -1313,6 +1313,7 @@
|
|||||||
<string name="CallNotificationBuilder_connecting">Connecting...</string>
|
<string name="CallNotificationBuilder_connecting">Connecting...</string>
|
||||||
<string name="Permissions_permission_required">Permission required</string>
|
<string name="Permissions_permission_required">Permission required</string>
|
||||||
<string name="Permissions_continue">Continue</string>
|
<string name="Permissions_continue">Continue</string>
|
||||||
|
<string name="ConversationActivity_signal_needs_sms_permission_in_order_to_send_an_sms">Signal needs SMS permission in order to send an SMS, but it has been permanently denied. Please continue to app settings, select \"Permissions\" and enable \"SMS\".</string>
|
||||||
|
|
||||||
|
|
||||||
<!-- EOF -->
|
<!-- EOF -->
|
||||||
|
@ -112,7 +112,6 @@ import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus;
|
|||||||
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
|
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsColumns.Types;
|
import org.thoughtcrime.securesms.database.MmsSmsColumns.Types;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
||||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
|
||||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||||
import org.thoughtcrime.securesms.database.identity.IdentityRecordList;
|
import org.thoughtcrime.securesms.database.identity.IdentityRecordList;
|
||||||
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
|
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
|
||||||
@ -1663,40 +1662,38 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
sendMediaMessage(forceSms, getMessage(), attachmentManager.buildSlideDeck(), expiresIn, subscriptionId, initiating);
|
sendMediaMessage(forceSms, getMessage(), attachmentManager.buildSlideDeck(), expiresIn, subscriptionId, initiating);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ListenableFuture<Void> sendMediaMessage(final boolean forceSms, String body, SlideDeck slideDeck, final long expiresIn, final int subscriptionId, final boolean initiating)
|
private ListenableFuture<Void> sendMediaMessage(final boolean forceSms, String body, SlideDeck slideDeck, final long expiresIn, final int subscriptionId, final boolean initiating) {
|
||||||
throws InvalidMessageException
|
|
||||||
{
|
OutgoingMediaMessage outgoingMessageCandidate = new OutgoingMediaMessage(recipient, slideDeck, body, System.currentTimeMillis(), subscriptionId, expiresIn, distributionType);
|
||||||
|
|
||||||
final SettableFuture<Void> future = new SettableFuture<>();
|
final SettableFuture<Void> future = new SettableFuture<>();
|
||||||
final Context context = getApplicationContext();
|
final Context context = getApplicationContext();
|
||||||
OutgoingMediaMessage outgoingMessage = new OutgoingMediaMessage(recipient,
|
|
||||||
slideDeck,
|
final OutgoingMediaMessage outgoingMessage;
|
||||||
body,
|
|
||||||
System.currentTimeMillis(),
|
|
||||||
subscriptionId,
|
|
||||||
expiresIn,
|
|
||||||
distributionType);
|
|
||||||
|
|
||||||
if (isSecureText && !forceSms) {
|
if (isSecureText && !forceSms) {
|
||||||
outgoingMessage = new OutgoingSecureMediaMessage(outgoingMessage);
|
outgoingMessage = new OutgoingSecureMediaMessage(outgoingMessageCandidate);
|
||||||
|
} else {
|
||||||
|
outgoingMessage = outgoingMessageCandidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Permissions.with(this)
|
||||||
|
.request(Manifest.permission.SEND_SMS)
|
||||||
|
.ifNecessary(isSecureText || forceSms)
|
||||||
|
.withPermanentDenialDialog(getString(R.string.ConversationActivity_signal_needs_sms_permission_in_order_to_send_an_sms))
|
||||||
|
.onAllGranted(() -> {
|
||||||
attachmentManager.clear(glideRequests, false);
|
attachmentManager.clear(glideRequests, false);
|
||||||
composeText.setText("");
|
composeText.setText("");
|
||||||
final long id = fragment.stageOutgoingMessage(outgoingMessage);
|
final long id = fragment.stageOutgoingMessage(outgoingMessage);
|
||||||
|
|
||||||
new AsyncTask<OutgoingMediaMessage, Void, Long>() {
|
new AsyncTask<Void, Void, Long>() {
|
||||||
@Override
|
@Override
|
||||||
protected Long doInBackground(OutgoingMediaMessage... messages) {
|
protected Long doInBackground(Void... param) {
|
||||||
if (initiating) {
|
if (initiating) {
|
||||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
|
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return MessageSender.send(context, masterSecret, messages[0], threadId, forceSms, new SmsDatabase.InsertListener() {
|
return MessageSender.send(context, masterSecret, outgoingMessage, threadId, forceSms, () -> fragment.releaseOutgoingMessage(id));
|
||||||
@Override
|
|
||||||
public void onComplete() {
|
|
||||||
fragment.releaseOutgoingMessage(id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1704,7 +1701,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
sendComplete(result);
|
sendComplete(result);
|
||||||
future.set(null);
|
future.set(null);
|
||||||
}
|
}
|
||||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, outgoingMessage);
|
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
})
|
||||||
|
.onAnyDenied(() -> future.set(null))
|
||||||
|
.execute();
|
||||||
|
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
@ -1713,14 +1713,21 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
throws InvalidMessageException
|
throws InvalidMessageException
|
||||||
{
|
{
|
||||||
final Context context = getApplicationContext();
|
final Context context = getApplicationContext();
|
||||||
|
final String messageBody = getMessage();
|
||||||
|
|
||||||
OutgoingTextMessage message;
|
OutgoingTextMessage message;
|
||||||
|
|
||||||
if (isSecureText && !forceSms) {
|
if (isSecureText && !forceSms) {
|
||||||
message = new OutgoingEncryptedMessage(recipient, getMessage(), expiresIn);
|
message = new OutgoingEncryptedMessage(recipient, messageBody, expiresIn);
|
||||||
} else {
|
} else {
|
||||||
message = new OutgoingTextMessage(recipient, getMessage(), expiresIn, subscriptionId);
|
message = new OutgoingTextMessage(recipient, messageBody, expiresIn, subscriptionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Permissions.with(this)
|
||||||
|
.request(Manifest.permission.SEND_SMS)
|
||||||
|
.ifNecessary(forceSms || !isSecureText)
|
||||||
|
.withPermanentDenialDialog(getString(R.string.ConversationActivity_signal_needs_sms_permission_in_order_to_send_an_sms))
|
||||||
|
.onAllGranted(() -> {
|
||||||
this.composeText.setText("");
|
this.composeText.setText("");
|
||||||
final long id = fragment.stageOutgoingMessage(message);
|
final long id = fragment.stageOutgoingMessage(message);
|
||||||
|
|
||||||
@ -1731,12 +1738,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
|
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return MessageSender.send(context, masterSecret, messages[0], threadId, forceSms, new SmsDatabase.InsertListener() {
|
return MessageSender.send(context, masterSecret, messages[0], threadId, forceSms, () -> fragment.releaseOutgoingMessage(id));
|
||||||
@Override
|
|
||||||
public void onComplete() {
|
|
||||||
fragment.releaseOutgoingMessage(id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1744,6 +1746,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
sendComplete(result);
|
sendComplete(result);
|
||||||
}
|
}
|
||||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, message);
|
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, message);
|
||||||
|
|
||||||
|
})
|
||||||
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateToggleButtonState() {
|
private void updateToggleButtonState() {
|
||||||
@ -1830,7 +1835,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
future.addListener(new ListenableFuture.Listener<Pair<Uri, Long>>() {
|
future.addListener(new ListenableFuture.Listener<Pair<Uri, Long>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final @NonNull Pair<Uri, Long> result) {
|
public void onSuccess(final @NonNull Pair<Uri, Long> result) {
|
||||||
try {
|
|
||||||
boolean forceSms = sendButton.isManualSelection() && sendButton.getSelectedTransport().isSms();
|
boolean forceSms = sendButton.isManualSelection() && sendButton.getSelectedTransport().isSms();
|
||||||
int subscriptionId = sendButton.getSelectedTransport().getSimSubscriptionId().or(-1);
|
int subscriptionId = sendButton.getSelectedTransport().getSimSubscriptionId().or(-1);
|
||||||
long expiresIn = recipient.getExpireMessages() * 1000;
|
long expiresIn = recipient.getExpireMessages() * 1000;
|
||||||
@ -1851,10 +1855,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (InvalidMessageException e) {
|
|
||||||
Log.w(TAG, e);
|
|
||||||
Toast.makeText(ConversationActivity.this, R.string.ConversationActivity_error_sending_voice_message, Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -118,6 +118,9 @@ public class SmsSendJob extends SendJob {
|
|||||||
Log.w(TAG, npe);
|
Log.w(TAG, npe);
|
||||||
throw new UndeliverableMessageException(npe2);
|
throw new UndeliverableMessageException(npe2);
|
||||||
}
|
}
|
||||||
|
} catch (SecurityException se) {
|
||||||
|
Log.w(TAG, se);
|
||||||
|
throw new UndeliverableMessageException(se);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,8 @@ public class Permissions {
|
|||||||
|
|
||||||
private boolean ifNecesary;
|
private boolean ifNecesary;
|
||||||
|
|
||||||
|
private boolean condition = true;
|
||||||
|
|
||||||
PermissionsBuilder(PermissionObject permissionObject) {
|
PermissionsBuilder(PermissionObject permissionObject) {
|
||||||
this.permissionObject = permissionObject;
|
this.permissionObject = permissionObject;
|
||||||
}
|
}
|
||||||
@ -78,6 +80,12 @@ public class Permissions {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PermissionsBuilder ifNecessary(boolean condition) {
|
||||||
|
this.ifNecesary = true;
|
||||||
|
this.condition = condition;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public PermissionsBuilder withRationaleDialog(@NonNull String message, @NonNull @DrawableRes int... headers) {
|
public PermissionsBuilder withRationaleDialog(@NonNull String message, @NonNull @DrawableRes int... headers) {
|
||||||
this.rationalDialogHeader = headers;
|
this.rationalDialogHeader = headers;
|
||||||
this.rationaleDialogMessage = message;
|
this.rationaleDialogMessage = message;
|
||||||
@ -128,7 +136,7 @@ public class Permissions {
|
|||||||
PermissionsRequest request = new PermissionsRequest(allGrantedListener, anyDeniedListener, anyPermanentlyDeniedListener, anyResultListener,
|
PermissionsRequest request = new PermissionsRequest(allGrantedListener, anyDeniedListener, anyPermanentlyDeniedListener, anyResultListener,
|
||||||
someGrantedListener, someDeniedListener, somePermanentlyDeniedListener);
|
someGrantedListener, someDeniedListener, somePermanentlyDeniedListener);
|
||||||
|
|
||||||
if (ifNecesary && permissionObject.hasAll(requestedPermissions)) {
|
if (ifNecesary && (permissionObject.hasAll(requestedPermissions) || !condition)) {
|
||||||
executePreGrantedPermissionsRequest(request);
|
executePreGrantedPermissionsRequest(request);
|
||||||
} else if (rationaleDialogMessage != null && rationalDialogHeader != null) {
|
} else if (rationaleDialogMessage != null && rationalDialogHeader != null) {
|
||||||
executePermissionsRequestWithRationale(request);
|
executePermissionsRequestWithRationale(request);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user