mirror of
https://github.com/oxen-io/session-android.git
synced 2025-03-27 07:12:13 +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="Permissions_permission_required">Permission required</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 -->
|
||||
|
@ -112,7 +112,6 @@ import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsColumns.Types;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.database.identity.IdentityRecordList;
|
||||
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
|
||||
@ -1663,48 +1662,49 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
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)
|
||||
throws InvalidMessageException
|
||||
{
|
||||
final SettableFuture<Void> future = new SettableFuture<>();
|
||||
final Context context = getApplicationContext();
|
||||
OutgoingMediaMessage outgoingMessage = new OutgoingMediaMessage(recipient,
|
||||
slideDeck,
|
||||
body,
|
||||
System.currentTimeMillis(),
|
||||
subscriptionId,
|
||||
expiresIn,
|
||||
distributionType);
|
||||
private ListenableFuture<Void> sendMediaMessage(final boolean forceSms, String body, SlideDeck slideDeck, final long expiresIn, final int subscriptionId, final boolean initiating) {
|
||||
|
||||
OutgoingMediaMessage outgoingMessageCandidate = new OutgoingMediaMessage(recipient, slideDeck, body, System.currentTimeMillis(), subscriptionId, expiresIn, distributionType);
|
||||
|
||||
final SettableFuture<Void> future = new SettableFuture<>();
|
||||
final Context context = getApplicationContext();
|
||||
|
||||
final OutgoingMediaMessage outgoingMessage;
|
||||
|
||||
if (isSecureText && !forceSms) {
|
||||
outgoingMessage = new OutgoingSecureMediaMessage(outgoingMessage);
|
||||
outgoingMessage = new OutgoingSecureMediaMessage(outgoingMessageCandidate);
|
||||
} else {
|
||||
outgoingMessage = outgoingMessageCandidate;
|
||||
}
|
||||
|
||||
attachmentManager.clear(glideRequests, false);
|
||||
composeText.setText("");
|
||||
final long id = fragment.stageOutgoingMessage(outgoingMessage);
|
||||
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);
|
||||
composeText.setText("");
|
||||
final long id = fragment.stageOutgoingMessage(outgoingMessage);
|
||||
|
||||
new AsyncTask<OutgoingMediaMessage, Void, Long>() {
|
||||
@Override
|
||||
protected Long doInBackground(OutgoingMediaMessage... messages) {
|
||||
if (initiating) {
|
||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
|
||||
}
|
||||
new AsyncTask<Void, Void, Long>() {
|
||||
@Override
|
||||
protected Long doInBackground(Void... param) {
|
||||
if (initiating) {
|
||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
|
||||
}
|
||||
|
||||
return MessageSender.send(context, masterSecret, messages[0], threadId, forceSms, new SmsDatabase.InsertListener() {
|
||||
@Override
|
||||
public void onComplete() {
|
||||
fragment.releaseOutgoingMessage(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
return MessageSender.send(context, masterSecret, outgoingMessage, threadId, forceSms, () -> fragment.releaseOutgoingMessage(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Long result) {
|
||||
sendComplete(result);
|
||||
future.set(null);
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, outgoingMessage);
|
||||
@Override
|
||||
protected void onPostExecute(Long result) {
|
||||
sendComplete(result);
|
||||
future.set(null);
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
})
|
||||
.onAnyDenied(() -> future.set(null))
|
||||
.execute();
|
||||
|
||||
return future;
|
||||
}
|
||||
@ -1712,38 +1712,43 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
private void sendTextMessage(final boolean forceSms, final long expiresIn, final int subscriptionId, final boolean initiatingConversation)
|
||||
throws InvalidMessageException
|
||||
{
|
||||
final Context context = getApplicationContext();
|
||||
final Context context = getApplicationContext();
|
||||
final String messageBody = getMessage();
|
||||
|
||||
OutgoingTextMessage message;
|
||||
|
||||
if (isSecureText && !forceSms) {
|
||||
message = new OutgoingEncryptedMessage(recipient, getMessage(), expiresIn);
|
||||
message = new OutgoingEncryptedMessage(recipient, messageBody, expiresIn);
|
||||
} else {
|
||||
message = new OutgoingTextMessage(recipient, getMessage(), expiresIn, subscriptionId);
|
||||
message = new OutgoingTextMessage(recipient, messageBody, expiresIn, subscriptionId);
|
||||
}
|
||||
|
||||
this.composeText.setText("");
|
||||
final long id = fragment.stageOutgoingMessage(message);
|
||||
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("");
|
||||
final long id = fragment.stageOutgoingMessage(message);
|
||||
|
||||
new AsyncTask<OutgoingTextMessage, Void, Long>() {
|
||||
@Override
|
||||
protected Long doInBackground(OutgoingTextMessage... messages) {
|
||||
if (initiatingConversation) {
|
||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
|
||||
}
|
||||
new AsyncTask<OutgoingTextMessage, Void, Long>() {
|
||||
@Override
|
||||
protected Long doInBackground(OutgoingTextMessage... messages) {
|
||||
if (initiatingConversation) {
|
||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
|
||||
}
|
||||
|
||||
return MessageSender.send(context, masterSecret, messages[0], threadId, forceSms, new SmsDatabase.InsertListener() {
|
||||
@Override
|
||||
public void onComplete() {
|
||||
fragment.releaseOutgoingMessage(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
return MessageSender.send(context, masterSecret, messages[0], threadId, forceSms, () -> fragment.releaseOutgoingMessage(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Long result) {
|
||||
sendComplete(result);
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, message);
|
||||
@Override
|
||||
protected void onPostExecute(Long result) {
|
||||
sendComplete(result);
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, message);
|
||||
|
||||
})
|
||||
.execute();
|
||||
}
|
||||
|
||||
private void updateToggleButtonState() {
|
||||
@ -1830,31 +1835,26 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
future.addListener(new ListenableFuture.Listener<Pair<Uri, Long>>() {
|
||||
@Override
|
||||
public void onSuccess(final @NonNull Pair<Uri, Long> result) {
|
||||
try {
|
||||
boolean forceSms = sendButton.isManualSelection() && sendButton.getSelectedTransport().isSms();
|
||||
int subscriptionId = sendButton.getSelectedTransport().getSimSubscriptionId().or(-1);
|
||||
long expiresIn = recipient.getExpireMessages() * 1000;
|
||||
boolean initiating = threadId == -1;
|
||||
AudioSlide audioSlide = new AudioSlide(ConversationActivity.this, result.first, result.second, MediaUtil.AUDIO_AAC, true);
|
||||
SlideDeck slideDeck = new SlideDeck();
|
||||
slideDeck.addSlide(audioSlide);
|
||||
boolean forceSms = sendButton.isManualSelection() && sendButton.getSelectedTransport().isSms();
|
||||
int subscriptionId = sendButton.getSelectedTransport().getSimSubscriptionId().or(-1);
|
||||
long expiresIn = recipient.getExpireMessages() * 1000;
|
||||
boolean initiating = threadId == -1;
|
||||
AudioSlide audioSlide = new AudioSlide(ConversationActivity.this, result.first, result.second, MediaUtil.AUDIO_AAC, true);
|
||||
SlideDeck slideDeck = new SlideDeck();
|
||||
slideDeck.addSlide(audioSlide);
|
||||
|
||||
sendMediaMessage(forceSms, "", slideDeck, expiresIn, subscriptionId, initiating).addListener(new AssertedSuccessListener<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void nothing) {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
PersistentBlobProvider.getInstance(ConversationActivity.this).delete(result.first);
|
||||
return null;
|
||||
}
|
||||
}.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();
|
||||
}
|
||||
sendMediaMessage(forceSms, "", slideDeck, expiresIn, subscriptionId, initiating).addListener(new AssertedSuccessListener<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void nothing) {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
PersistentBlobProvider.getInstance(ConversationActivity.this).delete(result.first);
|
||||
return null;
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -118,6 +118,9 @@ public class SmsSendJob extends SendJob {
|
||||
Log.w(TAG, npe);
|
||||
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 condition = true;
|
||||
|
||||
PermissionsBuilder(PermissionObject permissionObject) {
|
||||
this.permissionObject = permissionObject;
|
||||
}
|
||||
@ -78,6 +80,12 @@ public class Permissions {
|
||||
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) {
|
||||
this.rationalDialogHeader = headers;
|
||||
this.rationaleDialogMessage = message;
|
||||
@ -128,7 +136,7 @@ public class Permissions {
|
||||
PermissionsRequest request = new PermissionsRequest(allGrantedListener, anyDeniedListener, anyPermanentlyDeniedListener, anyResultListener,
|
||||
someGrantedListener, someDeniedListener, somePermanentlyDeniedListener);
|
||||
|
||||
if (ifNecesary && permissionObject.hasAll(requestedPermissions)) {
|
||||
if (ifNecesary && (permissionObject.hasAll(requestedPermissions) || !condition)) {
|
||||
executePreGrantedPermissionsRequest(request);
|
||||
} else if (rationaleDialogMessage != null && rationalDialogHeader != null) {
|
||||
executePermissionsRequestWithRationale(request);
|
||||
|
Loading…
x
Reference in New Issue
Block a user