Handle media message friend requests

pull/26/head
Niels Andriesse 6 years ago
parent 14508971ed
commit 96dadbaaa8

@ -2262,6 +2262,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
outgoingMessage = outgoingMessageCandidate; outgoingMessage = outgoingMessageCandidate;
} }
// Loki - Send a friend request if we're not yet friends with the user in question
LokiThreadFriendRequestStatus friendRequestStatus = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadId);
outgoingMessage.isFriendRequest = (friendRequestStatus != LokiThreadFriendRequestStatus.FRIENDS); // Needed for stageOutgoingMessage(...)
Permissions.with(this) Permissions.with(this)
.request(Manifest.permission.SEND_SMS, Manifest.permission.READ_SMS) .request(Manifest.permission.SEND_SMS, Manifest.permission.READ_SMS)
.ifNecessary(!isSecureText || forceSms) .ifNecessary(!isSecureText || forceSms)

@ -204,6 +204,22 @@ public class MmsDatabase extends MessagingDatabase {
return 0; return 0;
} }
public long getIDForMessageAtIndex(long threadID, int index) {
SQLiteDatabase database = databaseHelper.getReadableDatabase();
Cursor cursor = null;
try {
cursor = database.query(TABLE_NAME, null, THREAD_ID + " = ?", new String[] { threadID + "" }, null, null, null);
if (cursor != null && cursor.moveToPosition(index)) {
return cursor.getLong(0);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return -1;
}
public void addFailures(long messageId, List<NetworkFailure> failure) { public void addFailures(long messageId, List<NetworkFailure> failure) {
try { try {
addToDocument(messageId, NETWORK_FAILURE, failure, NetworkFailureList.class); addToDocument(messageId, NETWORK_FAILURE, failure, NetworkFailureList.class);

@ -1052,9 +1052,10 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context); LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(contactID); long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(contactID);
LokiThreadFriendRequestStatus threadFriendRequestStatus = lokiThreadDatabase.getFriendRequestStatus(threadID); LokiThreadFriendRequestStatus threadFriendRequestStatus = lokiThreadDatabase.getFriendRequestStatus(threadID);
SmsDatabase messageDatabase = DatabaseFactory.getSmsDatabase(context); SmsDatabase smsMessageDatabase = DatabaseFactory.getSmsDatabase(context);
MmsDatabase mmsMessageDatabase = DatabaseFactory.getMmsDatabase(context);
LokiMessageDatabase lokiMessageDatabase= DatabaseFactory.getLokiMessageDatabase(context); LokiMessageDatabase lokiMessageDatabase= DatabaseFactory.getLokiMessageDatabase(context);
int messageCount = messageDatabase.getMessageCountForThread(threadID); int messageCount = smsMessageDatabase.getMessageCountForThread(threadID);
if (threadFriendRequestStatus == LokiThreadFriendRequestStatus.REQUEST_SENT) { if (threadFriendRequestStatus == LokiThreadFriendRequestStatus.REQUEST_SENT) {
// This can happen if Alice sent Bob a friend request, Bob declined, but then Bob changed his // This can happen if Alice sent Bob a friend request, Bob declined, but then Bob changed his
// mind and sent a friend request to Alice. In this case we want Alice to auto-accept the request // mind and sent a friend request to Alice. In this case we want Alice to auto-accept the request
@ -1067,7 +1068,8 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
// we can end up in a deadlock where both users' threads' friend request statuses are // we can end up in a deadlock where both users' threads' friend request statuses are
// `REQUEST_SENT`. // `REQUEST_SENT`.
lokiThreadDatabase.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.FRIENDS); lokiThreadDatabase.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.FRIENDS);
long messageID = messageDatabase.getIDForMessageAtIndex(threadID, messageCount - 2); // The message before the one that was just received long messageID = smsMessageDatabase.getIDForMessageAtIndex(threadID, messageCount - 2); // The message before the one that was just received
// TODO: MMS
lokiMessageDatabase.setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_ACCEPTED); lokiMessageDatabase.setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_ACCEPTED);
// Accept the friend request // Accept the friend request
sendBackgroundMessage(content.getSender()); sendBackgroundMessage(content.getSender());
@ -1078,8 +1080,13 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
// request. Alice's thread's friend request status is reset to // request. Alice's thread's friend request status is reset to
// `REQUEST_RECEIVED`. // `REQUEST_RECEIVED`.
lokiThreadDatabase.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.REQUEST_RECEIVED); lokiThreadDatabase.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.REQUEST_RECEIVED);
long messageID = messageDatabase.getIDForMessageAtIndex(threadID, messageCount - 1); // The message that was just received long messageID = smsMessageDatabase.getIDForMessageAtIndex(threadID, messageCount - 1); // The message that was just received
if (messageID != -1) {
lokiMessageDatabase.setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_PENDING); lokiMessageDatabase.setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_PENDING);
} else {
// TODO: The code below is ugly due to Java limitations
lokiMessageDatabase.setFriendRequestStatus(mmsMessageDatabase.getIDForMessageAtIndex(threadID, 0), LokiMessageFriendRequestStatus.REQUEST_PENDING);
}
} }
} }

@ -29,6 +29,7 @@ import org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException;
import org.thoughtcrime.securesms.transport.RetryLaterException; import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.transport.UndeliverableMessageException; import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.state.PreKeyBundle;
import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
@ -40,6 +41,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSy
import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.messages.shared.SharedContact;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@ -122,6 +124,8 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
MmsDatabase database = DatabaseFactory.getMmsDatabase(context); MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
OutgoingMediaMessage message = database.getOutgoingMessage(messageId); OutgoingMediaMessage message = database.getOutgoingMessage(messageId);
message.isFriendRequest = (DatabaseFactory.getLokiMessageDatabase(context).getFriendRequestStatus(messageId) == LokiMessageFriendRequestStatus.REQUEST_SENDING);
if (database.isSent(messageId)) { if (database.isSent(messageId)) {
warn(TAG, "Message " + messageId + " was already sent. Ignoring."); warn(TAG, "Message " + messageId + " was already sent. Ignoring.");
return; return;
@ -210,6 +214,15 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
Optional<SignalServiceDataMessage.Sticker> sticker = getStickerFor(message); Optional<SignalServiceDataMessage.Sticker> sticker = getStickerFor(message);
List<SharedContact> sharedContacts = getSharedContactsFor(message); List<SharedContact> sharedContacts = getSharedContactsFor(message);
List<Preview> previews = getPreviewsFor(message); List<Preview> previews = getPreviewsFor(message);
// Loki - Include a pre key bundle if the message is a friend request or an end session message
PreKeyBundle preKeyBundle;
if (message.isFriendRequest) {
preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(address.getNumber());
} else {
preKeyBundle = null;
}
SignalServiceDataMessage mediaMessage = SignalServiceDataMessage.newBuilder() SignalServiceDataMessage mediaMessage = SignalServiceDataMessage.newBuilder()
.withBody(message.getBody()) .withBody(message.getBody())
.withAttachments(serviceAttachments) .withAttachments(serviceAttachments)
@ -221,6 +234,8 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
.withSharedContacts(sharedContacts) .withSharedContacts(sharedContacts)
.withPreviews(previews) .withPreviews(previews)
.asExpirationUpdate(message.isExpirationUpdate()) .asExpirationUpdate(message.isExpirationUpdate())
.withPreKeyBundle(preKeyBundle)
.asFriendRequest(message.isFriendRequest)
.build(); .build();
if (address.getNumber().equals(TextSecurePreferences.getLocalNumber(context))) { if (address.getNumber().equals(TextSecurePreferences.getLocalNumber(context))) {

@ -12,7 +12,6 @@ import android.widget.TextView
import network.loki.messenger.R import network.loki.messenger.R
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.SmsMessageRecord
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus
class FriendRequestView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : LinearLayout(context, attrs, defStyleAttr) { class FriendRequestView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : LinearLayout(context, attrs, defStyleAttr) {
@ -108,8 +107,6 @@ class FriendRequestView(context: Context, attrs: AttributeSet?, defStyleAttr: In
val lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context) val lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context)
val contactID = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(message!!.threadId)!!.address.toString() val contactID = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(message!!.threadId)!!.address.toString()
val contactDisplayName = DatabaseFactory.getLokiUserDatabase(context).getDisplayName(contactID) ?: contactID val contactDisplayName = DatabaseFactory.getLokiUserDatabase(context).getDisplayName(contactID) ?: contactID
val isTextMessage = message is SmsMessageRecord
if (!isTextMessage) { visibility = View.GONE; return }
val friendRequestStatus = lokiMessageDatabase.getFriendRequestStatus(message.id) val friendRequestStatus = lokiMessageDatabase.getFriendRequestStatus(message.id)
if (!message.isOutgoing) { if (!message.isOutgoing) {
visibility = if (friendRequestStatus == LokiMessageFriendRequestStatus.NONE) View.GONE else View.VISIBLE visibility = if (friendRequestStatus == LokiMessageFriendRequestStatus.NONE) View.GONE else View.VISIBLE

@ -23,6 +23,7 @@ public class OutgoingMediaMessage {
private final int distributionType; private final int distributionType;
private final int subscriptionId; private final int subscriptionId;
private final long expiresIn; private final long expiresIn;
public boolean isFriendRequest = false;
private final QuoteModel outgoingQuote; private final QuoteModel outgoingQuote;
private final List<NetworkFailure> networkFailures = new LinkedList<>(); private final List<NetworkFailure> networkFailures = new LinkedList<>();

@ -117,6 +117,10 @@ public class MessageSender {
try { try {
message.getAttachments().add(attachment); message.getAttachments().add(attachment);
long messageID = database.insertMessageOutbox(message, allocatedThreadId, forceSms, insertListener); long messageID = database.insertMessageOutbox(message, allocatedThreadId, forceSms, insertListener);
// Loki - Set the message's friend request status as soon as it has hit the database
if (message.isFriendRequest) {
DatabaseFactory.getLokiMessageDatabase(context).setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_SENDING);
}
sendMediaMessage(context, recipient, forceSms, messageID, message.getExpiresIn()); sendMediaMessage(context, recipient, forceSms, messageID, message.getExpiresIn());
} catch (Exception e) { } catch (Exception e) {
Log.w(TAG, e); Log.w(TAG, e);
@ -125,6 +129,10 @@ public class MessageSender {
} else { } else {
try { try {
long messageID = database.insertMessageOutbox(message, allocatedThreadId, forceSms, insertListener); long messageID = database.insertMessageOutbox(message, allocatedThreadId, forceSms, insertListener);
// Loki - Set the message's friend request status as soon as it has hit the database
if (message.isFriendRequest) {
DatabaseFactory.getLokiMessageDatabase(context).setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_SENDING);
}
sendMediaMessage(context, recipient, forceSms, messageID, message.getExpiresIn()); sendMediaMessage(context, recipient, forceSms, messageID, message.getExpiresIn());
} catch (MmsException e) { } catch (MmsException e) {
Log.w(TAG, e); Log.w(TAG, e);
@ -135,6 +143,10 @@ public class MessageSender {
} else { } else {
try { try {
long messageID = database.insertMessageOutbox(message, allocatedThreadId, forceSms, insertListener); long messageID = database.insertMessageOutbox(message, allocatedThreadId, forceSms, insertListener);
// Loki - Set the message's friend request status as soon as it has hit the database
if (message.isFriendRequest) {
DatabaseFactory.getLokiMessageDatabase(context).setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_SENDING);
}
sendMediaMessage(context, recipient, forceSms, messageID, message.getExpiresIn()); sendMediaMessage(context, recipient, forceSms, messageID, message.getExpiresIn());
} catch (MmsException e) { } catch (MmsException e) {
Log.w(TAG, e); Log.w(TAG, e);

Loading…
Cancel
Save