Handle media message friend requests

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

@ -2262,6 +2262,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
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)
.request(Manifest.permission.SEND_SMS, Manifest.permission.READ_SMS)
.ifNecessary(!isSecureText || forceSms)

@ -204,6 +204,22 @@ public class MmsDatabase extends MessagingDatabase {
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) {
try {
addToDocument(messageId, NETWORK_FAILURE, failure, NetworkFailureList.class);

@ -1052,9 +1052,10 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(contactID);
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);
int messageCount = messageDatabase.getMessageCountForThread(threadID);
int messageCount = smsMessageDatabase.getMessageCountForThread(threadID);
if (threadFriendRequestStatus == LokiThreadFriendRequestStatus.REQUEST_SENT) {
// 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
@ -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
// `REQUEST_SENT`.
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);
// Accept the friend request
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_RECEIVED`.
lokiThreadDatabase.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.REQUEST_RECEIVED);
long messageID = messageDatabase.getIDForMessageAtIndex(threadID, messageCount - 1); // The message that was just received
lokiMessageDatabase.setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_PENDING);
long messageID = smsMessageDatabase.getIDForMessageAtIndex(threadID, messageCount - 1); // The message that was just received
if (messageID != -1) {
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.UndeliverableMessageException;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.state.PreKeyBundle;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
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.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
import java.io.FileNotFoundException;
import java.io.IOException;
@ -122,6 +124,8 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
OutgoingMediaMessage message = database.getOutgoingMessage(messageId);
message.isFriendRequest = (DatabaseFactory.getLokiMessageDatabase(context).getFriendRequestStatus(messageId) == LokiMessageFriendRequestStatus.REQUEST_SENDING);
if (database.isSent(messageId)) {
warn(TAG, "Message " + messageId + " was already sent. Ignoring.");
return;
@ -210,18 +214,29 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
Optional<SignalServiceDataMessage.Sticker> sticker = getStickerFor(message);
List<SharedContact> sharedContacts = getSharedContactsFor(message);
List<Preview> previews = getPreviewsFor(message);
SignalServiceDataMessage mediaMessage = SignalServiceDataMessage.newBuilder()
.withBody(message.getBody())
.withAttachments(serviceAttachments)
.withTimestamp(message.getSentTimeMillis())
.withExpiration((int)(message.getExpiresIn() / 1000))
.withProfileKey(profileKey.orNull())
.withQuote(quote.orNull())
.withSticker(sticker.orNull())
.withSharedContacts(sharedContacts)
.withPreviews(previews)
.asExpirationUpdate(message.isExpirationUpdate())
.build();
// 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()
.withBody(message.getBody())
.withAttachments(serviceAttachments)
.withTimestamp(message.getSentTimeMillis())
.withExpiration((int)(message.getExpiresIn() / 1000))
.withProfileKey(profileKey.orNull())
.withQuote(quote.orNull())
.withSticker(sticker.orNull())
.withSharedContacts(sharedContacts)
.withPreviews(previews)
.asExpirationUpdate(message.isExpirationUpdate())
.withPreKeyBundle(preKeyBundle)
.asFriendRequest(message.isFriendRequest)
.build();
if (address.getNumber().equals(TextSecurePreferences.getLocalNumber(context))) {
Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);

@ -12,7 +12,6 @@ import android.widget.TextView
import network.loki.messenger.R
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.SmsMessageRecord
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus
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 contactID = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(message!!.threadId)!!.address.toString()
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)
if (!message.isOutgoing) {
visibility = if (friendRequestStatus == LokiMessageFriendRequestStatus.NONE) View.GONE else View.VISIBLE

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

@ -117,6 +117,10 @@ public class MessageSender {
try {
message.getAttachments().add(attachment);
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());
} catch (Exception e) {
Log.w(TAG, e);
@ -125,6 +129,10 @@ public class MessageSender {
} else {
try {
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());
} catch (MmsException e) {
Log.w(TAG, e);
@ -135,6 +143,10 @@ public class MessageSender {
} else {
try {
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());
} catch (MmsException e) {
Log.w(TAG, e);

@ -9,7 +9,7 @@ public class OutgoingTextMessage {
private final String message;
private final int subscriptionId;
private final long expiresIn;
public boolean isFriendRequest = false;
public boolean isFriendRequest = false;
public OutgoingTextMessage(Recipient recipient, String message, int subscriptionId) {
this(recipient, message, 0, subscriptionId);

Loading…
Cancel
Save