kopia lustrzana https://github.com/ryukoposting/Signal-Android
Add urgency flag to message sends.
rodzic
c7cd261641
commit
dc04c8ed98
|
@ -6,6 +6,8 @@ import net.zetetic.database.sqlcipher.SQLiteConstraintException
|
|||
import org.signal.core.util.CursorUtil
|
||||
import org.signal.core.util.SqlUtil
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.requireBoolean
|
||||
import org.signal.core.util.toInt
|
||||
import org.thoughtcrime.securesms.database.model.MessageId
|
||||
import org.thoughtcrime.securesms.database.model.MessageLogEntry
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
|
@ -67,13 +69,15 @@ class MessageSendLogDatabase constructor(context: Context?, databaseHelper: Sign
|
|||
const val DATE_SENT = "date_sent"
|
||||
const val CONTENT = "content"
|
||||
const val CONTENT_HINT = "content_hint"
|
||||
const val URGENT = "urgent"
|
||||
|
||||
const val CREATE_TABLE = """
|
||||
CREATE TABLE $TABLE_NAME (
|
||||
$ID INTEGER PRIMARY KEY,
|
||||
$DATE_SENT INTEGER NOT NULL,
|
||||
$CONTENT BLOB NOT NULL,
|
||||
$CONTENT_HINT INTEGER NOT NULL
|
||||
$CONTENT_HINT INTEGER NOT NULL,
|
||||
$URGENT INTEGER NOT NULL DEFAULT 1
|
||||
)
|
||||
"""
|
||||
|
||||
|
@ -152,31 +156,31 @@ class MessageSendLogDatabase constructor(context: Context?, databaseHelper: Sign
|
|||
}
|
||||
|
||||
/** @return The ID of the inserted entry, or -1 if none was inserted. Can be used with [addRecipientToExistingEntryIfPossible] */
|
||||
fun insertIfPossible(recipientId: RecipientId, sentTimestamp: Long, sendMessageResult: SendMessageResult, contentHint: ContentHint, messageId: MessageId): Long {
|
||||
fun insertIfPossible(recipientId: RecipientId, sentTimestamp: Long, sendMessageResult: SendMessageResult, contentHint: ContentHint, messageId: MessageId, urgent: Boolean): Long {
|
||||
if (!FeatureFlags.retryReceipts()) return -1
|
||||
|
||||
if (sendMessageResult.isSuccess && sendMessageResult.success.content.isPresent) {
|
||||
val recipientDevice = listOf(RecipientDevice(recipientId, sendMessageResult.success.devices))
|
||||
return insert(recipientDevice, sentTimestamp, sendMessageResult.success.content.get(), contentHint, listOf(messageId))
|
||||
return insert(recipientDevice, sentTimestamp, sendMessageResult.success.content.get(), contentHint, listOf(messageId), urgent)
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
/** @return The ID of the inserted entry, or -1 if none was inserted. Can be used with [addRecipientToExistingEntryIfPossible] */
|
||||
fun insertIfPossible(recipientId: RecipientId, sentTimestamp: Long, sendMessageResult: SendMessageResult, contentHint: ContentHint, messageIds: List<MessageId>): Long {
|
||||
fun insertIfPossible(recipientId: RecipientId, sentTimestamp: Long, sendMessageResult: SendMessageResult, contentHint: ContentHint, messageIds: List<MessageId>, urgent: Boolean): Long {
|
||||
if (!FeatureFlags.retryReceipts()) return -1
|
||||
|
||||
if (sendMessageResult.isSuccess && sendMessageResult.success.content.isPresent) {
|
||||
val recipientDevice = listOf(RecipientDevice(recipientId, sendMessageResult.success.devices))
|
||||
return insert(recipientDevice, sentTimestamp, sendMessageResult.success.content.get(), contentHint, messageIds)
|
||||
return insert(recipientDevice, sentTimestamp, sendMessageResult.success.content.get(), contentHint, messageIds, urgent)
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
/** @return The ID of the inserted entry, or -1 if none was inserted. Can be used with [addRecipientToExistingEntryIfPossible] */
|
||||
fun insertIfPossible(sentTimestamp: Long, possibleRecipients: List<Recipient>, results: List<SendMessageResult>, contentHint: ContentHint, messageId: MessageId): Long {
|
||||
fun insertIfPossible(sentTimestamp: Long, possibleRecipients: List<Recipient>, results: List<SendMessageResult>, contentHint: ContentHint, messageId: MessageId, urgent: Boolean): Long {
|
||||
if (!FeatureFlags.retryReceipts()) return -1
|
||||
|
||||
val accessList = RecipientAccessList(possibleRecipients)
|
||||
|
@ -194,10 +198,10 @@ class MessageSendLogDatabase constructor(context: Context?, databaseHelper: Sign
|
|||
|
||||
val content: SignalServiceProtos.Content = results.first { it.isSuccess && it.success.content.isPresent }.success.content.get()
|
||||
|
||||
return insert(recipientDevices, sentTimestamp, content, contentHint, listOf(messageId))
|
||||
return insert(recipientDevices, sentTimestamp, content, contentHint, listOf(messageId), urgent)
|
||||
}
|
||||
|
||||
fun addRecipientToExistingEntryIfPossible(payloadId: Long, recipientId: RecipientId, sentTimestamp: Long, sendMessageResult: SendMessageResult, contentHint: ContentHint, messageId: MessageId): Long {
|
||||
fun addRecipientToExistingEntryIfPossible(payloadId: Long, recipientId: RecipientId, sentTimestamp: Long, sendMessageResult: SendMessageResult, contentHint: ContentHint, messageId: MessageId, urgent: Boolean): Long {
|
||||
if (!FeatureFlags.retryReceipts()) return payloadId
|
||||
|
||||
if (sendMessageResult.isSuccess && sendMessageResult.success.content.isPresent) {
|
||||
|
@ -218,9 +222,9 @@ class MessageSendLogDatabase constructor(context: Context?, databaseHelper: Sign
|
|||
db.setTransactionSuccessful()
|
||||
} catch (e: SQLiteConstraintException) {
|
||||
Log.w(TAG, "Failed to append to existing entry. Creating a new one.")
|
||||
val payloadId = insertIfPossible(recipientId, sentTimestamp, sendMessageResult, contentHint, messageId)
|
||||
val newPayloadId = insertIfPossible(recipientId, sentTimestamp, sendMessageResult, contentHint, messageId, urgent)
|
||||
db.setTransactionSuccessful()
|
||||
return payloadId
|
||||
return newPayloadId
|
||||
} finally {
|
||||
db.endTransaction()
|
||||
}
|
||||
|
@ -229,7 +233,7 @@ class MessageSendLogDatabase constructor(context: Context?, databaseHelper: Sign
|
|||
return payloadId
|
||||
}
|
||||
|
||||
private fun insert(recipients: List<RecipientDevice>, dateSent: Long, content: SignalServiceProtos.Content, contentHint: ContentHint, messageIds: List<MessageId>): Long {
|
||||
private fun insert(recipients: List<RecipientDevice>, dateSent: Long, content: SignalServiceProtos.Content, contentHint: ContentHint, messageIds: List<MessageId>, urgent: Boolean): Long {
|
||||
val db = databaseHelper.signalWritableDatabase
|
||||
|
||||
db.beginTransaction()
|
||||
|
@ -238,6 +242,7 @@ class MessageSendLogDatabase constructor(context: Context?, databaseHelper: Sign
|
|||
put(PayloadTable.DATE_SENT, dateSent)
|
||||
put(PayloadTable.CONTENT, content.toByteArray())
|
||||
put(PayloadTable.CONTENT_HINT, contentHint.type)
|
||||
put(PayloadTable.URGENT, urgent.toInt())
|
||||
}
|
||||
|
||||
val payloadId: Long = db.insert(PayloadTable.TABLE_NAME, null, payloadValues)
|
||||
|
@ -304,6 +309,7 @@ class MessageSendLogDatabase constructor(context: Context?, databaseHelper: Sign
|
|||
dateSent = CursorUtil.requireLong(entryCursor, PayloadTable.DATE_SENT),
|
||||
content = SignalServiceProtos.Content.parseFrom(CursorUtil.requireBlob(entryCursor, PayloadTable.CONTENT)),
|
||||
contentHint = ContentHint.fromType(CursorUtil.requireInt(entryCursor, PayloadTable.CONTENT_HINT)),
|
||||
urgent = entryCursor.requireBoolean(PayloadTable.URGENT),
|
||||
relatedMessages = messageIds
|
||||
)
|
||||
}
|
||||
|
|
|
@ -94,7 +94,8 @@ public class PushDatabase extends Database {
|
|||
cursor.getLong(cursor.getColumnIndexOrThrow(SERVER_RECEIVED_TIMESTAMP)),
|
||||
cursor.getLong(cursor.getColumnIndexOrThrow(SERVER_DELIVERED_TIMESTAMP)),
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(SERVER_GUID)),
|
||||
"");
|
||||
"",
|
||||
true);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
|
@ -180,7 +181,8 @@ public class PushDatabase extends Database {
|
|||
serverReceivedTimestamp,
|
||||
serverDeliveredTimestamp,
|
||||
serverGuid,
|
||||
"");
|
||||
"",
|
||||
true);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.conversation.colors.ChatColors
|
|||
import org.thoughtcrime.securesms.conversation.colors.ChatColorsMapper.entrySet
|
||||
import org.thoughtcrime.securesms.database.KeyValueDatabase
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.UrgentMslFlagMigration
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.ReactionList
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.groups.GroupId
|
||||
|
@ -203,8 +204,9 @@ object SignalDatabaseMigrations {
|
|||
private const val QUOTE_INDEX = 147
|
||||
private const val MY_STORY_PRIVACY_MODE = 148
|
||||
private const val EXPIRING_PROFILE_CREDENTIALS = 149
|
||||
private const val URGENT_FLAG = 150
|
||||
|
||||
const val DATABASE_VERSION = 149
|
||||
const val DATABASE_VERSION = 150
|
||||
|
||||
@JvmStatic
|
||||
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
|
@ -2663,6 +2665,10 @@ object SignalDatabaseMigrations {
|
|||
if (oldVersion < EXPIRING_PROFILE_CREDENTIALS) {
|
||||
db.execSQL("UPDATE recipient SET profile_key_credential = NULL")
|
||||
}
|
||||
|
||||
if (oldVersion < URGENT_FLAG) {
|
||||
UrgentMslFlagMigration.migrate(context, db, oldVersion, newVersion)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package org.thoughtcrime.securesms.database.helpers.migration
|
||||
|
||||
import android.app.Application
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabase
|
||||
|
||||
/**
|
||||
* Simple interface for allowing database migrations to live outside of [org.thoughtcrime.securesms.database.helpers.SignalDatabaseMigrations].
|
||||
*/
|
||||
interface SignalDatabaseMigration {
|
||||
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int)
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.thoughtcrime.securesms.database.helpers.migration
|
||||
|
||||
import android.app.Application
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabase
|
||||
|
||||
/**
|
||||
* Adding an urgent flag to message envelopes to help with notifications. Need to track flag in
|
||||
* MSL table so can be resent with the correct urgency.
|
||||
*/
|
||||
object UrgentMslFlagMigration : SignalDatabaseMigration {
|
||||
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
db.execSQL("ALTER TABLE msl_payload ADD COLUMN urgent INTEGER NOT NULL DEFAULT 1")
|
||||
}
|
||||
}
|
|
@ -12,6 +12,8 @@ data class MessageLogEntry(
|
|||
val dateSent: Long,
|
||||
val content: SignalServiceProtos.Content,
|
||||
val contentHint: ContentHint,
|
||||
@get:JvmName("isUrgent")
|
||||
val urgent: Boolean,
|
||||
val relatedMessages: List<MessageId>
|
||||
) {
|
||||
val hasRelatedMessage: Boolean
|
||||
|
|
|
@ -1273,16 +1273,7 @@ final class GroupManagerV2 {
|
|||
GroupId.V2 groupId = GroupId.v2(masterKey);
|
||||
Recipient groupRecipient = Recipient.externalGroupExact(groupId);
|
||||
DecryptedGroupV2Context decryptedGroupV2Context = GroupProtoUtil.createDecryptedGroupV2Context(masterKey, groupMutation, signedGroupChange);
|
||||
OutgoingGroupUpdateMessage outgoingMessage = new OutgoingGroupUpdateMessage(groupRecipient,
|
||||
decryptedGroupV2Context,
|
||||
null,
|
||||
System.currentTimeMillis(),
|
||||
0,
|
||||
false,
|
||||
null,
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList());
|
||||
OutgoingGroupUpdateMessage outgoingMessage = new OutgoingGroupUpdateMessage(groupRecipient, decryptedGroupV2Context, System.currentTimeMillis());
|
||||
|
||||
|
||||
DecryptedGroupChange plainGroupChange = groupMutation.getGroupChange();
|
||||
|
|
|
@ -464,18 +464,8 @@ public class GroupsV2StateProcessor {
|
|||
.addDeleteMembers(UuidUtil.toByteString(selfUuid))
|
||||
.build();
|
||||
|
||||
DecryptedGroupV2Context decryptedGroupV2Context = GroupProtoUtil.createDecryptedGroupV2Context(masterKey, new GroupMutation(decryptedGroup, simulatedGroupChange, simulatedGroupState), null);
|
||||
|
||||
OutgoingGroupUpdateMessage leaveMessage = new OutgoingGroupUpdateMessage(groupRecipient,
|
||||
decryptedGroupV2Context,
|
||||
null,
|
||||
System.currentTimeMillis(),
|
||||
0,
|
||||
false,
|
||||
null,
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList());
|
||||
DecryptedGroupV2Context decryptedGroupV2Context = GroupProtoUtil.createDecryptedGroupV2Context(masterKey, new GroupMutation(decryptedGroup, simulatedGroupChange, simulatedGroupState), null);
|
||||
OutgoingGroupUpdateMessage leaveMessage = new OutgoingGroupUpdateMessage(groupRecipient, decryptedGroupV2Context, System.currentTimeMillis());
|
||||
|
||||
try {
|
||||
MessageDatabase mmsDatabase = SignalDatabase.mms();
|
||||
|
@ -703,7 +693,7 @@ public class GroupsV2StateProcessor {
|
|||
ThreadDatabase threadDatabase = SignalDatabase.threads();
|
||||
RecipientId recipientId = recipientDatabase.getOrInsertFromGroupId(groupId);
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
OutgoingGroupUpdateMessage outgoingMessage = new OutgoingGroupUpdateMessage(recipient, decryptedGroupV2Context, null, timestamp, 0, false, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
|
||||
OutgoingGroupUpdateMessage outgoingMessage = new OutgoingGroupUpdateMessage(recipient, decryptedGroupV2Context, timestamp);
|
||||
long threadId = threadDatabase.getOrCreateThreadIdFor(recipient);
|
||||
long messageId = mmsDatabase.insertMessageOutbox(outgoingMessage, threadId, false, null);
|
||||
|
||||
|
|
|
@ -57,9 +57,9 @@ public class GroupCallUpdateSendJob extends BaseJob {
|
|||
}
|
||||
|
||||
List<RecipientId> recipientIds = Stream.of(RecipientUtil.getEligibleForSending(Recipient.resolvedList(conversationRecipient.getParticipantIds())))
|
||||
.filterNot(Recipient::isSelf)
|
||||
.map(Recipient::getId)
|
||||
.toList();
|
||||
.filterNot(Recipient::isSelf)
|
||||
.map(Recipient::getId)
|
||||
.toList();
|
||||
|
||||
return new GroupCallUpdateSendJob(recipientId,
|
||||
eraId,
|
||||
|
@ -161,7 +161,8 @@ public class GroupCallUpdateSendJob extends BaseJob {
|
|||
nonSelfDestinations,
|
||||
false,
|
||||
ContentHint.DEFAULT,
|
||||
dataMessage);
|
||||
dataMessage,
|
||||
false);
|
||||
|
||||
if (includesSelf) {
|
||||
results.add(ApplicationDependencies.getSignalServiceMessageSender().sendSyncMessage(dataMessage));
|
||||
|
|
|
@ -110,7 +110,7 @@ public final class PaymentNotificationSendJob extends BaseJob {
|
|||
.withPayment(new SignalServiceDataMessage.Payment(new SignalServiceDataMessage.PaymentNotification(payment.getReceipt(), payment.getNote())))
|
||||
.build();
|
||||
|
||||
SendMessageResult sendMessageResult = messageSender.sendDataMessage(address, unidentifiedAccess, ContentHint.DEFAULT, dataMessage, IndividualSendEvents.EMPTY);
|
||||
SendMessageResult sendMessageResult = messageSender.sendDataMessage(address, unidentifiedAccess, ContentHint.DEFAULT, dataMessage, IndividualSendEvents.EMPTY, false);
|
||||
|
||||
if (sendMessageResult.getIdentityFailure() != null) {
|
||||
Log.w(TAG, "Identity failure for " + recipient.getId());
|
||||
|
|
|
@ -153,7 +153,7 @@ public class ProfileKeySendJob extends BaseJob {
|
|||
.withTimestamp(System.currentTimeMillis())
|
||||
.withProfileKey(Recipient.self().resolve().getProfileKey());
|
||||
|
||||
List<SendMessageResult> results = GroupSendUtil.sendUnresendableDataMessage(context, null, destinations, false, ContentHint.IMPLICIT, dataMessage.build());
|
||||
List<SendMessageResult> results = GroupSendUtil.sendUnresendableDataMessage(context, null, destinations, false, ContentHint.IMPLICIT, dataMessage.build(), false);
|
||||
|
||||
return GroupSendJobHelper.getCompletedSends(destinations, results).completed;
|
||||
}
|
||||
|
|
|
@ -292,7 +292,7 @@ public final class PushGroupSendJob extends PushSendJob {
|
|||
.withExpiration(groupRecipient.getExpiresInSeconds())
|
||||
.asGroupMessage(group)
|
||||
.build();
|
||||
return GroupSendUtil.sendResendableDataMessage(context, groupRecipient.requireGroupId().requireV2(), destinations, isRecipientUpdate, ContentHint.IMPLICIT, new MessageId(messageId, true), groupDataMessage);
|
||||
return GroupSendUtil.sendResendableDataMessage(context, groupRecipient.requireGroupId().requireV2(), destinations, isRecipientUpdate, ContentHint.IMPLICIT, new MessageId(messageId, true), groupDataMessage, message.isUrgent());
|
||||
} else {
|
||||
throw new UndeliverableMessageException("Messages can no longer be sent to V1 groups!");
|
||||
}
|
||||
|
@ -351,7 +351,8 @@ public final class PushGroupSendJob extends PushSendJob {
|
|||
isRecipientUpdate,
|
||||
ContentHint.RESENDABLE,
|
||||
new MessageId(messageId, true),
|
||||
groupMessageBuilder.build());
|
||||
groupMessageBuilder.build(),
|
||||
message.isUrgent());
|
||||
}
|
||||
} catch (ServerRejectedException e) {
|
||||
throw new UndeliverableMessageException(e);
|
||||
|
|
|
@ -175,7 +175,7 @@ public final class PushGroupSilentUpdateSendJob extends BaseJob {
|
|||
.asGroupMessage(group)
|
||||
.build();
|
||||
|
||||
List<SendMessageResult> results = GroupSendUtil.sendUnresendableDataMessage(context, groupId, destinations, false, ContentHint.IMPLICIT, groupDataMessage);
|
||||
List<SendMessageResult> results = GroupSendUtil.sendUnresendableDataMessage(context, groupId, destinations, false, ContentHint.IMPLICIT, groupDataMessage, false);
|
||||
|
||||
return GroupSendJobHelper.getCompletedSends(destinations, results).completed;
|
||||
}
|
||||
|
|
|
@ -254,11 +254,11 @@ public class PushMediaSendJob extends PushSendJob {
|
|||
if (Util.equals(SignalStore.account().getAci(), address.getServiceId())) {
|
||||
Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);
|
||||
SendMessageResult result = messageSender.sendSyncMessage(mediaMessage);
|
||||
SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getSentTimeMillis(), result, ContentHint.RESENDABLE, new MessageId(messageId, true));
|
||||
SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getSentTimeMillis(), result, ContentHint.RESENDABLE, new MessageId(messageId, true), false);
|
||||
return syncAccess.isPresent();
|
||||
} else {
|
||||
SendMessageResult result = messageSender.sendDataMessage(address, UnidentifiedAccessUtil.getAccessFor(context, messageRecipient), ContentHint.RESENDABLE, mediaMessage, IndividualSendEvents.EMPTY);
|
||||
SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getSentTimeMillis(), result, ContentHint.RESENDABLE, new MessageId(messageId, true));
|
||||
SendMessageResult result = messageSender.sendDataMessage(address, UnidentifiedAccessUtil.getAccessFor(context, messageRecipient), ContentHint.RESENDABLE, mediaMessage, IndividualSendEvents.EMPTY, message.isUrgent());
|
||||
SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getSentTimeMillis(), result, ContentHint.RESENDABLE, new MessageId(messageId, true), message.isUrgent());
|
||||
return result.getSuccess().isUnidentified();
|
||||
}
|
||||
} catch (UnregisteredUserException e) {
|
||||
|
|
|
@ -194,13 +194,13 @@ public class PushTextSendJob extends PushSendJob {
|
|||
SignalLocalMetrics.IndividualMessageSend.onDeliveryStarted(messageId);
|
||||
SendMessageResult result = messageSender.sendSyncMessage(textSecureMessage);
|
||||
|
||||
SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getDateSent(), result, ContentHint.RESENDABLE, new MessageId(messageId, false));
|
||||
SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getDateSent(), result, ContentHint.RESENDABLE, new MessageId(messageId, false), false);
|
||||
return syncAccess.isPresent();
|
||||
} else {
|
||||
SignalLocalMetrics.IndividualMessageSend.onDeliveryStarted(messageId);
|
||||
SendMessageResult result = messageSender.sendDataMessage(address, unidentifiedAccess, ContentHint.RESENDABLE, textSecureMessage, new MetricEventListener(messageId));
|
||||
SendMessageResult result = messageSender.sendDataMessage(address, unidentifiedAccess, ContentHint.RESENDABLE, textSecureMessage, new MetricEventListener(messageId), true);
|
||||
|
||||
SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getDateSent(), result, ContentHint.RESENDABLE, new MessageId(messageId, false));
|
||||
SignalDatabase.messageLog().insertIfPossible(messageRecipient.getId(), message.getDateSent(), result, ContentHint.RESENDABLE, new MessageId(messageId, false), true);
|
||||
return result.getSuccess().isUnidentified();
|
||||
}
|
||||
} catch (UnregisteredUserException e) {
|
||||
|
|
|
@ -242,7 +242,8 @@ public class ReactionSendJob extends BaseJob {
|
|||
false,
|
||||
ContentHint.RESENDABLE,
|
||||
messageId,
|
||||
dataMessage);
|
||||
dataMessage,
|
||||
true);
|
||||
|
||||
if (includesSelf) {
|
||||
results.add(ApplicationDependencies.getSignalServiceMessageSender().sendSyncMessage(dataMessage));
|
||||
|
|
|
@ -214,7 +214,8 @@ public class RemoteDeleteSendJob extends BaseJob {
|
|||
false,
|
||||
ContentHint.RESENDABLE,
|
||||
new MessageId(messageId, isMms),
|
||||
dataMessage);
|
||||
dataMessage,
|
||||
true);
|
||||
|
||||
return GroupSendJobHelper.getCompletedSends(destinations, results);
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ public class ResendMessageJob extends BaseJob {
|
|||
private final long sentTimestamp;
|
||||
private final Content content;
|
||||
private final ContentHint contentHint;
|
||||
private final boolean urgent;
|
||||
private final GroupId.V2 groupId;
|
||||
private final DistributionId distributionId;
|
||||
|
||||
|
@ -58,6 +59,7 @@ public class ResendMessageJob extends BaseJob {
|
|||
private static final String KEY_SENT_TIMESTAMP = "sent_timestamp";
|
||||
private static final String KEY_CONTENT = "content";
|
||||
private static final String KEY_CONTENT_HINT = "content_hint";
|
||||
private static final String KEY_URGENT = "urgent";
|
||||
private static final String KEY_GROUP_ID = "group_id";
|
||||
private static final String KEY_DISTRIBUTION_ID = "distribution_id";
|
||||
|
||||
|
@ -65,6 +67,7 @@ public class ResendMessageJob extends BaseJob {
|
|||
long sentTimestamp,
|
||||
@NonNull Content content,
|
||||
@NonNull ContentHint contentHint,
|
||||
boolean urgent,
|
||||
@Nullable GroupId.V2 groupId,
|
||||
@Nullable DistributionId distributionId)
|
||||
{
|
||||
|
@ -72,6 +75,7 @@ public class ResendMessageJob extends BaseJob {
|
|||
sentTimestamp,
|
||||
content,
|
||||
contentHint,
|
||||
urgent,
|
||||
groupId,
|
||||
distributionId,
|
||||
new Parameters.Builder().setQueue(recipientId.toQueueKey())
|
||||
|
@ -85,6 +89,7 @@ public class ResendMessageJob extends BaseJob {
|
|||
long sentTimestamp,
|
||||
@NonNull Content content,
|
||||
@NonNull ContentHint contentHint,
|
||||
boolean urgent,
|
||||
@Nullable GroupId.V2 groupId,
|
||||
@Nullable DistributionId distributionId,
|
||||
@NonNull Parameters parameters)
|
||||
|
@ -95,6 +100,7 @@ public class ResendMessageJob extends BaseJob {
|
|||
this.sentTimestamp = sentTimestamp;
|
||||
this.content = content;
|
||||
this.contentHint = contentHint;
|
||||
this.urgent = urgent;
|
||||
this.groupId = groupId;
|
||||
this.distributionId = distributionId;
|
||||
}
|
||||
|
@ -106,6 +112,7 @@ public class ResendMessageJob extends BaseJob {
|
|||
.putLong(KEY_SENT_TIMESTAMP, sentTimestamp)
|
||||
.putBlobAsString(KEY_CONTENT, content.toByteArray())
|
||||
.putInt(KEY_CONTENT_HINT, contentHint.getType())
|
||||
.putBoolean(KEY_URGENT, urgent)
|
||||
.putBlobAsString(KEY_GROUP_ID, groupId != null ? groupId.getDecodedId() : null)
|
||||
.putString(KEY_DISTRIBUTION_ID, distributionId != null ? distributionId.toString() : null)
|
||||
.build();
|
||||
|
@ -152,7 +159,7 @@ public class ResendMessageJob extends BaseJob {
|
|||
contentToSend = contentToSend.toBuilder().setSenderKeyDistributionMessage(distributionBytes).build();
|
||||
}
|
||||
|
||||
SendMessageResult result = messageSender.resendContent(address, access, sentTimestamp, contentToSend, contentHint, Optional.ofNullable(groupId).map(GroupId::getDecodedId));
|
||||
SendMessageResult result = messageSender.resendContent(address, access, sentTimestamp, contentToSend, contentHint, Optional.ofNullable(groupId).map(GroupId::getDecodedId), urgent);
|
||||
|
||||
if (result.isSuccess() && distributionId != null) {
|
||||
List<SignalProtocolAddress> addresses = result.getSuccess()
|
||||
|
@ -195,6 +202,7 @@ public class ResendMessageJob extends BaseJob {
|
|||
data.getLong(KEY_SENT_TIMESTAMP),
|
||||
content,
|
||||
ContentHint.fromType(data.getInt(KEY_CONTENT_HINT)),
|
||||
data.getBooleanOrDefault(KEY_URGENT, true),
|
||||
groupId,
|
||||
distributionId,
|
||||
parameters);
|
||||
|
|
|
@ -122,7 +122,7 @@ public class SendDeliveryReceiptJob extends BaseJob {
|
|||
receiptMessage);
|
||||
|
||||
if (messageId != null) {
|
||||
SignalDatabase.messageLog().insertIfPossible(recipientId, timestamp, result, ContentHint.IMPLICIT, messageId);
|
||||
SignalDatabase.messageLog().insertIfPossible(recipientId, timestamp, result, ContentHint.IMPLICIT, messageId, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ public class SendReadReceiptJob extends BaseJob {
|
|||
receiptMessage);
|
||||
|
||||
if (Util.hasItems(messageIds)) {
|
||||
SignalDatabase.messageLog().insertIfPossible(recipientId, timestamp, result, ContentHint.IMPLICIT, messageIds);
|
||||
SignalDatabase.messageLog().insertIfPossible(recipientId, timestamp, result, ContentHint.IMPLICIT, messageIds, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ public class SendViewedReceiptJob extends BaseJob {
|
|||
receiptMessage);
|
||||
|
||||
if (Util.hasItems(messageIds)) {
|
||||
SignalDatabase.messageLog().insertIfPossible(recipientId, timestamp, result, ContentHint.IMPLICIT, messageIds);
|
||||
SignalDatabase.messageLog().insertIfPossible(recipientId, timestamp, result, ContentHint.IMPLICIT, messageIds, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ public final class SenderKeyDistributionSendJob extends BaseJob {
|
|||
SenderKeyDistributionMessage message = messageSender.getOrCreateNewGroupSession(distributionId);
|
||||
List<Optional<UnidentifiedAccessPair>> access = UnidentifiedAccessUtil.getAccessFor(context, Collections.singletonList(recipient));
|
||||
|
||||
SendMessageResult result = messageSender.sendSenderKeyDistributionMessage(distributionId, address, access, message, Optional.of(groupId.getDecodedId())).get(0);
|
||||
SendMessageResult result = messageSender.sendSenderKeyDistributionMessage(distributionId, address, access, message, Optional.of(groupId.getDecodedId()), false).get(0);
|
||||
|
||||
if (result.isSuccess()) {
|
||||
List<SignalProtocolAddress> addresses = result.getSuccess()
|
||||
|
|
|
@ -88,10 +88,11 @@ public final class GroupSendUtil {
|
|||
boolean isRecipientUpdate,
|
||||
ContentHint contentHint,
|
||||
@NonNull MessageId messageId,
|
||||
@NonNull SignalServiceDataMessage message)
|
||||
@NonNull SignalServiceDataMessage message,
|
||||
boolean urgent)
|
||||
throws IOException, UntrustedIdentityException
|
||||
{
|
||||
return sendMessage(context, groupId, getDistributionId(groupId), messageId, allTargets, isRecipientUpdate, DataSendOperation.resendable(message, contentHint, messageId), null);
|
||||
return sendMessage(context, groupId, getDistributionId(groupId), messageId, allTargets, isRecipientUpdate, DataSendOperation.resendable(message, contentHint, messageId, urgent), null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,10 +110,11 @@ public final class GroupSendUtil {
|
|||
@NonNull List<Recipient> allTargets,
|
||||
boolean isRecipientUpdate,
|
||||
ContentHint contentHint,
|
||||
@NonNull SignalServiceDataMessage message)
|
||||
@NonNull SignalServiceDataMessage message,
|
||||
boolean urgent)
|
||||
throws IOException, UntrustedIdentityException
|
||||
{
|
||||
return sendMessage(context, groupId, getDistributionId(groupId), null, allTargets, isRecipientUpdate, DataSendOperation.unresendable(message, contentHint), null);
|
||||
return sendMessage(context, groupId, getDistributionId(groupId), null, allTargets, isRecipientUpdate, DataSendOperation.unresendable(message, contentHint, urgent), null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -295,7 +297,7 @@ public final class GroupSendUtil {
|
|||
Log.d(TAG, "Successfully sent using sender key to " + successCount + "/" + targets.size() + " sender key targets.");
|
||||
|
||||
if (sendOperation.shouldIncludeInMessageLog()) {
|
||||
SignalDatabase.messageLog().insertIfPossible(sendOperation.getSentTimestamp(), senderKeyTargets, results, sendOperation.getContentHint(), sendOperation.getRelatedMessageId());
|
||||
SignalDatabase.messageLog().insertIfPossible(sendOperation.getSentTimestamp(), senderKeyTargets, results, sendOperation.getContentHint(), sendOperation.getRelatedMessageId(), sendOperation.isUrgent());
|
||||
}
|
||||
|
||||
if (relatedMessageId != null) {
|
||||
|
@ -353,9 +355,9 @@ public final class GroupSendUtil {
|
|||
|
||||
synchronized (entryId) {
|
||||
if (entryId.get() == -1) {
|
||||
entryId.set(messageLogDatabase.insertIfPossible(recipients.requireRecipientId(result.getAddress()), sendOperation.getSentTimestamp(), result, sendOperation.getContentHint(), sendOperation.getRelatedMessageId()));
|
||||
entryId.set(messageLogDatabase.insertIfPossible(recipients.requireRecipientId(result.getAddress()), sendOperation.getSentTimestamp(), result, sendOperation.getContentHint(), sendOperation.getRelatedMessageId(), sendOperation.isUrgent()));
|
||||
} else {
|
||||
entryId.set(messageLogDatabase.addRecipientToExistingEntryIfPossible(entryId.get(), recipients.requireRecipientId(result.getAddress()), sendOperation.getSentTimestamp(), result, sendOperation.getContentHint(), sendOperation.getRelatedMessageId()));
|
||||
entryId.set(messageLogDatabase.addRecipientToExistingEntryIfPossible(entryId.get(), recipients.requireRecipientId(result.getAddress()), sendOperation.getSentTimestamp(), result, sendOperation.getContentHint(), sendOperation.getRelatedMessageId(), sendOperation.isUrgent()));
|
||||
}
|
||||
}
|
||||
}, cancelationSignal);
|
||||
|
@ -424,6 +426,7 @@ public final class GroupSendUtil {
|
|||
long getSentTimestamp();
|
||||
boolean shouldIncludeInMessageLog();
|
||||
@NonNull MessageId getRelatedMessageId();
|
||||
boolean isUrgent();
|
||||
}
|
||||
|
||||
private static class DataSendOperation implements SendOperation {
|
||||
|
@ -431,20 +434,22 @@ public final class GroupSendUtil {
|
|||
private final ContentHint contentHint;
|
||||
private final MessageId relatedMessageId;
|
||||
private final boolean resendable;
|
||||
private final boolean urgent;
|
||||
|
||||
public static DataSendOperation resendable(@NonNull SignalServiceDataMessage message, @NonNull ContentHint contentHint, @NonNull MessageId relatedMessageId) {
|
||||
return new DataSendOperation(message, contentHint, true, relatedMessageId);
|
||||
public static DataSendOperation resendable(@NonNull SignalServiceDataMessage message, @NonNull ContentHint contentHint, @NonNull MessageId relatedMessageId, boolean urgent) {
|
||||
return new DataSendOperation(message, contentHint, true, relatedMessageId, urgent);
|
||||
}
|
||||
|
||||
public static DataSendOperation unresendable(@NonNull SignalServiceDataMessage message, @NonNull ContentHint contentHint) {
|
||||
return new DataSendOperation(message, contentHint, false, null);
|
||||
public static DataSendOperation unresendable(@NonNull SignalServiceDataMessage message, @NonNull ContentHint contentHint, boolean urgent) {
|
||||
return new DataSendOperation(message, contentHint, false, null, urgent);
|
||||
}
|
||||
|
||||
private DataSendOperation(@NonNull SignalServiceDataMessage message, @NonNull ContentHint contentHint, boolean resendable, @Nullable MessageId relatedMessageId) {
|
||||
this.message = message;
|
||||
this.contentHint = contentHint;
|
||||
this.resendable = resendable;
|
||||
this.relatedMessageId = relatedMessageId;
|
||||
private DataSendOperation(@NonNull SignalServiceDataMessage message, @NonNull ContentHint contentHint, boolean resendable, @Nullable MessageId relatedMessageId, boolean urgent) {
|
||||
this.message = message;
|
||||
this.contentHint = contentHint;
|
||||
this.resendable = resendable;
|
||||
this.relatedMessageId = relatedMessageId;
|
||||
this.urgent = urgent;
|
||||
|
||||
if (resendable && relatedMessageId == null) {
|
||||
throw new IllegalArgumentException("If a message is resendable, it must have a related message ID!");
|
||||
|
@ -460,7 +465,7 @@ public final class GroupSendUtil {
|
|||
throws NoSessionException, UntrustedIdentityException, InvalidKeyException, IOException, InvalidRegistrationIdException
|
||||
{
|
||||
SenderKeyGroupEvents listener = relatedMessageId != null ? new SenderKeyMetricEventListener(relatedMessageId.getId()) : SenderKeyGroupEvents.EMPTY;
|
||||
return messageSender.sendGroupDataMessage(distributionId, targets, access, isRecipientUpdate, contentHint, message, listener);
|
||||
return messageSender.sendGroupDataMessage(distributionId, targets, access, isRecipientUpdate, contentHint, message, listener, urgent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -473,7 +478,7 @@ public final class GroupSendUtil {
|
|||
throws IOException, UntrustedIdentityException
|
||||
{
|
||||
LegacyGroupEvents listener = relatedMessageId != null ? new LegacyMetricEventListener(relatedMessageId.getId()) : LegacyGroupEvents.EMPTY;
|
||||
return messageSender.sendDataMessage(targets, access, isRecipientUpdate, contentHint, message, listener, partialListener, cancelationSignal);
|
||||
return messageSender.sendDataMessage(targets, access, isRecipientUpdate, contentHint, message, listener, partialListener, cancelationSignal, urgent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -499,6 +504,11 @@ public final class GroupSendUtil {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUrgent() {
|
||||
return urgent;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TypingSendOperation implements SendOperation {
|
||||
|
@ -553,6 +563,11 @@ public final class GroupSendUtil {
|
|||
public @NonNull MessageId getRelatedMessageId() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUrgent() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CallSendOperation implements SendOperation {
|
||||
|
@ -605,6 +620,11 @@ public final class GroupSendUtil {
|
|||
public @NonNull MessageId getRelatedMessageId() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUrgent() {
|
||||
return message.isUrgent();
|
||||
}
|
||||
}
|
||||
|
||||
public static class StorySendOperation implements SendOperation {
|
||||
|
@ -670,6 +690,11 @@ public final class GroupSendUtil {
|
|||
public @NonNull MessageId getRelatedMessageId() {
|
||||
return relatedMessageId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUrgent() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SenderKeyMetricEventListener implements SenderKeyGroupEvents {
|
||||
|
|
|
@ -2694,6 +2694,7 @@ public final class MessageContentProcessor {
|
|||
messageLogEntry.getDateSent(),
|
||||
messageLogEntry.getContent(),
|
||||
messageLogEntry.getContentHint(),
|
||||
messageLogEntry.isUrgent(),
|
||||
groupId,
|
||||
distributionId));
|
||||
} else {
|
||||
|
@ -2735,6 +2736,7 @@ public final class MessageContentProcessor {
|
|||
messageLogEntry.getDateSent(),
|
||||
messageLogEntry.getContent(),
|
||||
messageLogEntry.getContentHint(),
|
||||
messageLogEntry.isUrgent(),
|
||||
null,
|
||||
null));
|
||||
} else if (archivedSession) {
|
||||
|
|
|
@ -32,4 +32,8 @@ public class OutgoingExpirationUpdateMessage extends OutgoingSecureMediaMessage
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUrgent() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,16 +67,9 @@ public final class OutgoingGroupUpdateMessage extends OutgoingSecureMediaMessage
|
|||
|
||||
public OutgoingGroupUpdateMessage(@NonNull Recipient recipient,
|
||||
@NonNull DecryptedGroupV2Context group,
|
||||
@Nullable final Attachment avatar,
|
||||
long sentTimeMillis,
|
||||
long expireIn,
|
||||
boolean viewOnce,
|
||||
@Nullable QuoteModel quote,
|
||||
@NonNull List<Contact> contacts,
|
||||
@NonNull List<LinkPreview> previews,
|
||||
@NonNull List<Mention> mentions)
|
||||
long sentTimeMillis)
|
||||
{
|
||||
this(recipient, new MessageGroupContext(group), getAttachments(avatar), sentTimeMillis, expireIn, viewOnce, quote, contacts, previews, mentions);
|
||||
this(recipient, new MessageGroupContext(group), Collections.emptyList(), sentTimeMillis, 0, false, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -100,6 +93,11 @@ public final class OutgoingGroupUpdateMessage extends OutgoingSecureMediaMessage
|
|||
return messageGroupContext.requireGroupV2Properties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUrgent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static List<Attachment> getAttachments(@Nullable Attachment avatar) {
|
||||
return avatar == null ? Collections.emptyList() : Collections.singletonList(avatar);
|
||||
}
|
||||
|
|
|
@ -249,6 +249,10 @@ public class OutgoingMediaMessage {
|
|||
return giftBadge;
|
||||
}
|
||||
|
||||
public boolean isUrgent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String buildMessage(SlideDeck slideDeck, String message) {
|
||||
if (!TextUtils.isEmpty(message) && !TextUtils.isEmpty(slideDeck.getBody())) {
|
||||
return slideDeck.getBody() + "\n\n" + message;
|
||||
|
|
|
@ -225,7 +225,8 @@ public class SignalServiceMessageReceiver {
|
|||
entity.getServerTimestamp(),
|
||||
messageResult.getServerDeliveredTimestamp(),
|
||||
entity.getServerUuid(),
|
||||
entity.getDestinationUuid());
|
||||
entity.getDestinationUuid(),
|
||||
entity.isUrgent());
|
||||
} else {
|
||||
envelope = new SignalServiceEnvelope(entity.getType(),
|
||||
entity.getTimestamp(),
|
||||
|
@ -234,7 +235,8 @@ public class SignalServiceMessageReceiver {
|
|||
entity.getServerTimestamp(),
|
||||
messageResult.getServerDeliveredTimestamp(),
|
||||
entity.getServerUuid(),
|
||||
entity.getDestinationUuid());
|
||||
entity.getDestinationUuid(),
|
||||
entity.isUrgent());
|
||||
}
|
||||
|
||||
callback.onMessage(envelope);
|
||||
|
|
|
@ -203,7 +203,7 @@ public class SignalServiceMessageSender {
|
|||
Content content = createReceiptContent(message);
|
||||
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.IMPLICIT, Optional.empty());
|
||||
|
||||
return sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), message.getWhen(), envelopeContent, false, null);
|
||||
return sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), message.getWhen(), envelopeContent, false, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,7 +219,7 @@ public class SignalServiceMessageSender {
|
|||
PlaintextContent content = new PlaintextContent(errorMessage);
|
||||
EnvelopeContent envelopeContent = EnvelopeContent.plaintext(content, groupId);
|
||||
|
||||
sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null);
|
||||
sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -234,7 +234,7 @@ public class SignalServiceMessageSender {
|
|||
Content content = createTypingContent(message);
|
||||
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.IMPLICIT, Optional.empty());
|
||||
|
||||
sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), message.getTimestamp(), envelopeContent, true, null, cancelationSignal);
|
||||
sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), message.getTimestamp(), envelopeContent, true, null, cancelationSignal, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -247,7 +247,7 @@ public class SignalServiceMessageSender {
|
|||
throws IOException, UntrustedIdentityException, InvalidKeyException, NoSessionException, InvalidRegistrationIdException
|
||||
{
|
||||
Content content = createTypingContent(message);
|
||||
sendGroupMessage(distributionId, recipients, unidentifiedAccess, message.getTimestamp(), content, ContentHint.IMPLICIT, message.getGroupId(), true, SenderKeyGroupEvents.EMPTY);
|
||||
sendGroupMessage(distributionId, recipients, unidentifiedAccess, message.getTimestamp(), content, ContentHint.IMPLICIT, message.getGroupId(), true, SenderKeyGroupEvents.EMPTY, false);
|
||||
}
|
||||
|
||||
public List<SendMessageResult> sendStory(List<SignalServiceAddress> recipients,
|
||||
|
@ -260,7 +260,7 @@ public class SignalServiceMessageSender {
|
|||
{
|
||||
Content content = createStoryContent(message);
|
||||
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.RESENDABLE, Optional.empty());
|
||||
List<SendMessageResult> sendMessageResults = sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, null, null);
|
||||
List<SendMessageResult> sendMessageResults = sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, null, null, false);
|
||||
|
||||
if (store.isMultiDevice()) {
|
||||
SignalServiceSyncMessage syncMessage = createSelfSendSyncMessageForStory(message, timestamp, isRecipientUpdate, manifest);
|
||||
|
@ -284,7 +284,7 @@ public class SignalServiceMessageSender {
|
|||
throws IOException, UntrustedIdentityException, InvalidKeyException, NoSessionException, InvalidRegistrationIdException
|
||||
{
|
||||
Content content = createStoryContent(message);
|
||||
List<SendMessageResult> sendMessageResults = sendGroupMessage(distributionId, recipients, unidentifiedAccess, timestamp, content, ContentHint.RESENDABLE, groupId, false, SenderKeyGroupEvents.EMPTY);
|
||||
List<SendMessageResult> sendMessageResults = sendGroupMessage(distributionId, recipients, unidentifiedAccess, timestamp, content, ContentHint.RESENDABLE, groupId, false, SenderKeyGroupEvents.EMPTY, false);
|
||||
|
||||
if (store.isMultiDevice()) {
|
||||
SignalServiceSyncMessage syncMessage = createSelfSendSyncMessageForStory(message, timestamp, isRecipientUpdate, manifest);
|
||||
|
@ -310,7 +310,7 @@ public class SignalServiceMessageSender {
|
|||
Content content = createCallContent(message);
|
||||
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.DEFAULT, Optional.empty());
|
||||
|
||||
sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null);
|
||||
sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null, message.isUrgent());
|
||||
}
|
||||
|
||||
public List<SendMessageResult> sendCallMessage(List<SignalServiceAddress> recipients,
|
||||
|
@ -321,7 +321,7 @@ public class SignalServiceMessageSender {
|
|||
Content content = createCallContent(message);
|
||||
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.DEFAULT, Optional.empty());
|
||||
|
||||
return sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null, null);
|
||||
return sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null, null, message.isUrgent());
|
||||
}
|
||||
|
||||
public List<SendMessageResult> sendCallMessage(DistributionId distributionId,
|
||||
|
@ -331,7 +331,7 @@ public class SignalServiceMessageSender {
|
|||
throws IOException, UntrustedIdentityException, InvalidKeyException, NoSessionException, InvalidRegistrationIdException
|
||||
{
|
||||
Content content = createCallContent(message);
|
||||
return sendGroupMessage(distributionId, recipients, unidentifiedAccess, message.getTimestamp().get(), content, ContentHint.IMPLICIT, message.getGroupId(), false, SenderKeyGroupEvents.EMPTY);
|
||||
return sendGroupMessage(distributionId, recipients, unidentifiedAccess, message.getTimestamp().get(), content, ContentHint.IMPLICIT, message.getGroupId(), false, SenderKeyGroupEvents.EMPTY, message.isUrgent());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -360,7 +360,8 @@ public class SignalServiceMessageSender {
|
|||
Optional<UnidentifiedAccessPair> unidentifiedAccess,
|
||||
ContentHint contentHint,
|
||||
SignalServiceDataMessage message,
|
||||
IndividualSendEvents sendEvents)
|
||||
IndividualSendEvents sendEvents,
|
||||
boolean urgent)
|
||||
throws UntrustedIdentityException, IOException
|
||||
{
|
||||
Log.d(TAG, "[" + message.getTimestamp() + "] Sending a data message.");
|
||||
|
@ -371,7 +372,7 @@ public class SignalServiceMessageSender {
|
|||
sendEvents.onMessageEncrypted();
|
||||
|
||||
long timestamp = message.getTimestamp();
|
||||
SendMessageResult result = sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, null);
|
||||
SendMessageResult result = sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, null, urgent);
|
||||
|
||||
sendEvents.onMessageSent();
|
||||
|
||||
|
@ -379,7 +380,7 @@ public class SignalServiceMessageSender {
|
|||
Content syncMessage = createMultiDeviceSentTranscriptContent(content, Optional.of(recipient), timestamp, Collections.singletonList(result), false, Collections.emptySet());
|
||||
EnvelopeContent syncMessageContent = EnvelopeContent.encrypted(syncMessage, ContentHint.IMPLICIT, Optional.empty());
|
||||
|
||||
sendMessage(localAddress, Optional.empty(), timestamp, syncMessageContent, false, null);
|
||||
sendMessage(localAddress, Optional.empty(), timestamp, syncMessageContent, false, null, false);
|
||||
}
|
||||
|
||||
sendEvents.onSyncMessageSent();
|
||||
|
@ -403,7 +404,8 @@ public class SignalServiceMessageSender {
|
|||
List<SignalServiceAddress> recipients,
|
||||
List<Optional<UnidentifiedAccessPair>> unidentifiedAccess,
|
||||
SenderKeyDistributionMessage message,
|
||||
Optional<byte[]> groupId)
|
||||
Optional<byte[]> groupId,
|
||||
boolean urgent)
|
||||
throws IOException
|
||||
{
|
||||
ByteString distributionBytes = ByteString.copyFrom(message.serialize());
|
||||
|
@ -412,7 +414,7 @@ public class SignalServiceMessageSender {
|
|||
long timestamp = System.currentTimeMillis();
|
||||
|
||||
Log.d(TAG, "[" + timestamp + "] Sending SKDM to " + recipients.size() + " recipients for DistributionId " + distributionId);
|
||||
return sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, null, null);
|
||||
return sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, null, null, urgent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -430,13 +432,14 @@ public class SignalServiceMessageSender {
|
|||
long timestamp,
|
||||
Content content,
|
||||
ContentHint contentHint,
|
||||
Optional<byte[]> groupId)
|
||||
Optional<byte[]> groupId,
|
||||
boolean urgent)
|
||||
throws UntrustedIdentityException, IOException
|
||||
{
|
||||
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, contentHint, groupId);
|
||||
Optional<UnidentifiedAccess> access = unidentifiedAccess.isPresent() ? unidentifiedAccess.get().getTargetUnidentifiedAccess() : Optional.empty();
|
||||
|
||||
return sendMessage(address, access, timestamp, envelopeContent, false, null);
|
||||
return sendMessage(address, access, timestamp, envelopeContent, false, null, urgent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -448,14 +451,15 @@ public class SignalServiceMessageSender {
|
|||
boolean isRecipientUpdate,
|
||||
ContentHint contentHint,
|
||||
SignalServiceDataMessage message,
|
||||
SenderKeyGroupEvents sendEvents)
|
||||
SenderKeyGroupEvents sendEvents,
|
||||
boolean urgent)
|
||||
throws IOException, UntrustedIdentityException, NoSessionException, InvalidKeyException, InvalidRegistrationIdException
|
||||
{
|
||||
Log.d(TAG, "[" + message.getTimestamp() + "] Sending a group data message to " + recipients.size() + " recipients using DistributionId " + distributionId);
|
||||
|
||||
Content content = createMessageContent(message);
|
||||
Optional<byte[]> groupId = message.getGroupId();
|
||||
List<SendMessageResult> results = sendGroupMessage(distributionId, recipients, unidentifiedAccess, message.getTimestamp(), content, contentHint, groupId, false, sendEvents);
|
||||
List<SendMessageResult> results = sendGroupMessage(distributionId, recipients, unidentifiedAccess, message.getTimestamp(), content, contentHint, groupId, false, sendEvents, urgent);
|
||||
|
||||
sendEvents.onMessageSent();
|
||||
|
||||
|
@ -463,7 +467,7 @@ public class SignalServiceMessageSender {
|
|||
Content syncMessage = createMultiDeviceSentTranscriptContent(content, Optional.empty(), message.getTimestamp(), results, isRecipientUpdate, Collections.emptySet());
|
||||
EnvelopeContent syncMessageContent = EnvelopeContent.encrypted(syncMessage, ContentHint.IMPLICIT, Optional.empty());
|
||||
|
||||
sendMessage(localAddress, Optional.empty(), message.getTimestamp(), syncMessageContent, false, null);
|
||||
sendMessage(localAddress, Optional.empty(), message.getTimestamp(), syncMessageContent, false, null, false);
|
||||
}
|
||||
|
||||
sendEvents.onSyncMessageSent();
|
||||
|
@ -484,7 +488,8 @@ public class SignalServiceMessageSender {
|
|||
SignalServiceDataMessage message,
|
||||
LegacyGroupEvents sendEvents,
|
||||
PartialSendCompleteListener partialListener,
|
||||
CancelationSignal cancelationSignal)
|
||||
CancelationSignal cancelationSignal,
|
||||
boolean urgent)
|
||||
throws IOException, UntrustedIdentityException
|
||||
{
|
||||
Log.d(TAG, "[" + message.getTimestamp() + "] Sending a data message to " + recipients.size() + " recipients.");
|
||||
|
@ -492,7 +497,7 @@ public class SignalServiceMessageSender {
|
|||
Content content = createMessageContent(message);
|
||||
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, contentHint, message.getGroupId());
|
||||
long timestamp = message.getTimestamp();
|
||||
List<SendMessageResult> results = sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, partialListener, cancelationSignal);
|
||||
List<SendMessageResult> results = sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, partialListener, cancelationSignal, urgent);
|
||||
boolean needsSyncInResults = false;
|
||||
|
||||
sendEvents.onMessageSent();
|
||||
|
@ -513,7 +518,7 @@ public class SignalServiceMessageSender {
|
|||
Content syncMessage = createMultiDeviceSentTranscriptContent(content, recipient, timestamp, results, isRecipientUpdate, Collections.emptySet());
|
||||
EnvelopeContent syncMessageContent = EnvelopeContent.encrypted(syncMessage, ContentHint.IMPLICIT, Optional.empty());
|
||||
|
||||
sendMessage(localAddress, Optional.empty(), timestamp, syncMessageContent, false, null);
|
||||
sendMessage(localAddress, Optional.empty(), timestamp, syncMessageContent, false, null, false);
|
||||
}
|
||||
|
||||
sendEvents.onSyncMessageSent();
|
||||
|
@ -531,14 +536,15 @@ public class SignalServiceMessageSender {
|
|||
throws IOException, UntrustedIdentityException
|
||||
{
|
||||
Content content;
|
||||
boolean urgent = false;
|
||||
|
||||
if (message.getContacts().isPresent()) {
|
||||
content = createMultiDeviceContactsContent(message.getContacts().get().getContactsStream().asStream(),
|
||||
message.getContacts().get().isComplete());
|
||||
content = createMultiDeviceContactsContent(message.getContacts().get().getContactsStream().asStream(), message.getContacts().get().isComplete());
|
||||
} else if (message.getGroups().isPresent()) {
|
||||
content = createMultiDeviceGroupsContent(message.getGroups().get().asStream());
|
||||
} else if (message.getRead().isPresent()) {
|
||||
content = createMultiDeviceReadContent(message.getRead().get());
|
||||
urgent = true;
|
||||
} else if (message.getViewed().isPresent()) {
|
||||
content = createMultiDeviceViewedContent(message.getViewed().get());
|
||||
} else if (message.getViewOnceOpen().isPresent()) {
|
||||
|
@ -563,6 +569,7 @@ public class SignalServiceMessageSender {
|
|||
return sendVerifiedSyncMessage(message.getVerified().get());
|
||||
} else if (message.getRequest().isPresent()) {
|
||||
content = createRequestContent(message.getRequest().get().getRequest());
|
||||
urgent = message.getRequest().get().isUrgent();
|
||||
} else if (message.getPniIdentity().isPresent()) {
|
||||
content = createPniIdentityContent(message.getPniIdentity().get());
|
||||
} else {
|
||||
|
@ -574,7 +581,7 @@ public class SignalServiceMessageSender {
|
|||
|
||||
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.IMPLICIT, Optional.empty());
|
||||
|
||||
return sendMessage(localAddress, Optional.empty(), timestamp, envelopeContent, false, null);
|
||||
return sendMessage(localAddress, Optional.empty(), timestamp, envelopeContent, false, null, urgent);
|
||||
}
|
||||
|
||||
public void setSoTimeoutMillis(long soTimeoutMillis) {
|
||||
|
@ -711,13 +718,13 @@ public class SignalServiceMessageSender {
|
|||
|
||||
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.IMPLICIT, Optional.empty());
|
||||
|
||||
SendMessageResult result = sendMessage(message.getDestination(), Optional.empty(), message.getTimestamp(), envelopeContent, false, null);
|
||||
SendMessageResult result = sendMessage(message.getDestination(), Optional.empty(), message.getTimestamp(), envelopeContent, false, null, false);
|
||||
|
||||
if (result.getSuccess().isNeedsSync()) {
|
||||
Content syncMessage = createMultiDeviceVerifiedContent(message, nullMessage.toByteArray());
|
||||
EnvelopeContent syncMessageContent = EnvelopeContent.encrypted(syncMessage, ContentHint.IMPLICIT, Optional.empty());
|
||||
|
||||
sendMessage(localAddress, Optional.empty(), message.getTimestamp(), syncMessageContent, false, null);
|
||||
sendMessage(localAddress, Optional.empty(), message.getTimestamp(), syncMessageContent, false, null, false);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -741,7 +748,7 @@ public class SignalServiceMessageSender {
|
|||
|
||||
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.IMPLICIT, Optional.empty());
|
||||
|
||||
return sendMessage(address, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null);
|
||||
return sendMessage(address, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null, false);
|
||||
}
|
||||
|
||||
private Content createTypingContent(SignalServiceTypingMessage message) {
|
||||
|
@ -1616,7 +1623,8 @@ public class SignalServiceMessageSender {
|
|||
EnvelopeContent content,
|
||||
boolean online,
|
||||
PartialSendCompleteListener partialListener,
|
||||
CancelationSignal cancelationSignal)
|
||||
CancelationSignal cancelationSignal,
|
||||
boolean urgent)
|
||||
throws IOException
|
||||
{
|
||||
Log.d(TAG, "[" + timestamp + "] Sending to " + recipients.size() + " recipients.");
|
||||
|
@ -1631,7 +1639,7 @@ public class SignalServiceMessageSender {
|
|||
SignalServiceAddress recipient = recipientIterator.next();
|
||||
Optional<UnidentifiedAccess> access = unidentifiedAccessIterator.next();
|
||||
futureResults.add(executor.submit(() -> {
|
||||
SendMessageResult result = sendMessage(recipient, access, timestamp, content, online, cancelationSignal);
|
||||
SendMessageResult result = sendMessage(recipient, access, timestamp, content, online, cancelationSignal, urgent);
|
||||
if (partialListener != null) {
|
||||
partialListener.onPartialSendComplete(result);
|
||||
}
|
||||
|
@ -1698,7 +1706,8 @@ public class SignalServiceMessageSender {
|
|||
long timestamp,
|
||||
EnvelopeContent content,
|
||||
boolean online,
|
||||
CancelationSignal cancelationSignal)
|
||||
CancelationSignal cancelationSignal,
|
||||
boolean urgent)
|
||||
throws UntrustedIdentityException, IOException
|
||||
{
|
||||
enforceMaxContentSize(content);
|
||||
|
@ -1711,7 +1720,7 @@ public class SignalServiceMessageSender {
|
|||
}
|
||||
|
||||
try {
|
||||
OutgoingPushMessageList messages = getEncryptedMessages(socket, recipient, unidentifiedAccess, timestamp, content, online);
|
||||
OutgoingPushMessageList messages = getEncryptedMessages(socket, recipient, unidentifiedAccess, timestamp, content, online, urgent);
|
||||
|
||||
if (content.getContent().isPresent() && content.getContent().get().getSyncMessage() != null && content.getContent().get().getSyncMessage().hasSent()) {
|
||||
Log.d(TAG, "[sendMessage][" + timestamp + "] Sending a sent sync message to devices: " + messages.getDevices());
|
||||
|
@ -1796,7 +1805,8 @@ public class SignalServiceMessageSender {
|
|||
ContentHint contentHint,
|
||||
Optional<byte[]> groupId,
|
||||
boolean online,
|
||||
SenderKeyGroupEvents sendEvents)
|
||||
SenderKeyGroupEvents sendEvents,
|
||||
boolean urgent)
|
||||
throws IOException, UntrustedIdentityException, NoSessionException, InvalidKeyException, InvalidRegistrationIdException
|
||||
{
|
||||
if (recipients.isEmpty()) {
|
||||
|
@ -1833,7 +1843,7 @@ public class SignalServiceMessageSender {
|
|||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<SendMessageResult> results = sendSenderKeyDistributionMessage(distributionId, needsSenderKey, access, message, groupId);
|
||||
List<SendMessageResult> results = sendSenderKeyDistributionMessage(distributionId, needsSenderKey, access, message, groupId, urgent);
|
||||
|
||||
List<SignalServiceAddress> successes = results.stream()
|
||||
.filter(SendMessageResult::isSuccess)
|
||||
|
@ -1895,7 +1905,7 @@ public class SignalServiceMessageSender {
|
|||
|
||||
try {
|
||||
try {
|
||||
SendGroupMessageResponse response = new MessagingService.SendResponseProcessor<>(messagingService.sendToGroup(ciphertext, joinedUnidentifiedAccess, timestamp, online).blockingGet()).getResultOrThrow();
|
||||
SendGroupMessageResponse response = new MessagingService.SendResponseProcessor<>(messagingService.sendToGroup(ciphertext, joinedUnidentifiedAccess, timestamp, online, urgent).blockingGet()).getResultOrThrow();
|
||||
return transformGroupResponseToMessageResults(targetInfo.devices, response, content);
|
||||
} catch (InvalidUnidentifiedAccessHeaderException | NotFoundException | GroupMismatchedDevicesException | GroupStaleDevicesException e) {
|
||||
// Non-technical failures shouldn't be retried with socket
|
||||
|
@ -1906,7 +1916,7 @@ public class SignalServiceMessageSender {
|
|||
Log.w(TAG, "[sendGroupMessage][" + timestamp + "] Pipe failed, falling back... (" + e.getClass().getSimpleName() + ": " + e.getMessage() + ")");
|
||||
}
|
||||
|
||||
SendGroupMessageResponse response = socket.sendGroupMessage(ciphertext, joinedUnidentifiedAccess, timestamp, online);
|
||||
SendGroupMessageResponse response = socket.sendGroupMessage(ciphertext, joinedUnidentifiedAccess, timestamp, online, urgent);
|
||||
return transformGroupResponseToMessageResults(targetInfo.devices, response, content);
|
||||
} catch (GroupMismatchedDevicesException e) {
|
||||
Log.w(TAG, "[sendGroupMessage][" + timestamp + "] Handling mismatched devices. (" + e.getMessage() + ")");
|
||||
|
@ -2070,7 +2080,8 @@ public class SignalServiceMessageSender {
|
|||
Optional<UnidentifiedAccess> unidentifiedAccess,
|
||||
long timestamp,
|
||||
EnvelopeContent plaintext,
|
||||
boolean online)
|
||||
boolean online,
|
||||
boolean urgent)
|
||||
throws IOException, InvalidKeyException, UntrustedIdentityException
|
||||
{
|
||||
List<OutgoingPushMessage> messages = new LinkedList<>();
|
||||
|
@ -2091,7 +2102,7 @@ public class SignalServiceMessageSender {
|
|||
}
|
||||
}
|
||||
|
||||
return new OutgoingPushMessageList(recipient.getIdentifier(), timestamp, messages, online);
|
||||
return new OutgoingPushMessageList(recipient.getIdentifier(), timestamp, messages, online, urgent);
|
||||
}
|
||||
|
||||
private OutgoingPushMessage getEncryptedMessage(PushServiceSocket socket,
|
||||
|
|
|
@ -65,14 +65,16 @@ public class SignalServiceEnvelope {
|
|||
long serverReceivedTimestamp,
|
||||
long serverDeliveredTimestamp,
|
||||
String uuid,
|
||||
String destinationUuid)
|
||||
String destinationUuid,
|
||||
boolean urgent)
|
||||
{
|
||||
Envelope.Builder builder = Envelope.newBuilder()
|
||||
.setType(Envelope.Type.valueOf(type))
|
||||
.setSourceDevice(senderDevice)
|
||||
.setTimestamp(timestamp)
|
||||
.setServerTimestamp(serverReceivedTimestamp)
|
||||
.setDestinationUuid(destinationUuid);
|
||||
.setDestinationUuid(destinationUuid)
|
||||
.setUrgent(urgent);
|
||||
|
||||
if (sender.isPresent()) {
|
||||
builder.setSourceUuid(sender.get().getServiceId().toString());
|
||||
|
@ -100,13 +102,15 @@ public class SignalServiceEnvelope {
|
|||
long serverReceivedTimestamp,
|
||||
long serverDeliveredTimestamp,
|
||||
String uuid,
|
||||
String destinationUuid)
|
||||
String destinationUuid,
|
||||
boolean urgent)
|
||||
{
|
||||
Envelope.Builder builder = Envelope.newBuilder()
|
||||
.setType(Envelope.Type.valueOf(type))
|
||||
.setTimestamp(timestamp)
|
||||
.setServerTimestamp(serverReceivedTimestamp)
|
||||
.setDestinationUuid(destinationUuid);
|
||||
.setDestinationUuid(destinationUuid)
|
||||
.setUrgent(urgent);
|
||||
|
||||
if (uuid != null) {
|
||||
builder.setServerGuid(uuid);
|
||||
|
@ -273,6 +277,9 @@ public class SignalServiceEnvelope {
|
|||
return envelope.getDestinationUuid();
|
||||
}
|
||||
|
||||
public boolean isUrgent() {
|
||||
return envelope.getUrgent();
|
||||
}
|
||||
|
||||
private SignalServiceEnvelopeProto.Builder serializeToProto() {
|
||||
SignalServiceEnvelopeProto.Builder builder = SignalServiceEnvelopeProto.newBuilder()
|
||||
|
@ -280,7 +287,8 @@ public class SignalServiceEnvelope {
|
|||
.setDeviceId(getSourceDevice())
|
||||
.setTimestamp(getTimestamp())
|
||||
.setServerReceivedTimestamp(getServerReceivedTimestamp())
|
||||
.setServerDeliveredTimestamp(getServerDeliveredTimestamp());
|
||||
.setServerDeliveredTimestamp(getServerDeliveredTimestamp())
|
||||
.setUrgent(isUrgent());
|
||||
|
||||
if (getSourceUuid().isPresent()) {
|
||||
builder.setSourceUuid(getSourceUuid().get());
|
||||
|
@ -330,6 +338,7 @@ public class SignalServiceEnvelope {
|
|||
proto.getServerReceivedTimestamp(),
|
||||
proto.getServerDeliveredTimestamp(),
|
||||
proto.getServerGuid(),
|
||||
proto.getDestinationUuid());
|
||||
proto.getDestinationUuid(),
|
||||
proto.getUrgent());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,4 +198,10 @@ public class SignalServiceCallMessage {
|
|||
public Optional<Long> getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public boolean isUrgent() {
|
||||
return offerMessage.isPresent() ||
|
||||
hangupMessage.isPresent() ||
|
||||
opaqueMessage.map(m -> m.getUrgency() == OpaqueMessage.Urgency.HANDLE_IMMEDIATELY).orElse(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,4 +47,8 @@ public class RequestMessage {
|
|||
public boolean isPniIdentityRequest() {
|
||||
return request.getType() == Request.Type.PNI_IDENTITY;
|
||||
}
|
||||
|
||||
public boolean isUrgent() {
|
||||
return isContactsRequest() || isKeysRequest() || isPniIdentityRequest();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,13 +72,13 @@ public class MessagingService {
|
|||
.onErrorReturn(ServiceResponse::forUnknownError);
|
||||
}
|
||||
|
||||
public Single<ServiceResponse<SendGroupMessageResponse>> sendToGroup(byte[] body, byte[] joinedUnidentifiedAccess, long timestamp, boolean online) {
|
||||
public Single<ServiceResponse<SendGroupMessageResponse>> sendToGroup(byte[] body, byte[] joinedUnidentifiedAccess, long timestamp, boolean online, boolean urgent) {
|
||||
List<String> headers = new LinkedList<String>() {{
|
||||
add("content-type:application/vnd.signal-messenger.mrm");
|
||||
add("Unidentified-Access-Key:" + Base64.encodeBytes(joinedUnidentifiedAccess));
|
||||
}};
|
||||
|
||||
String path = String.format(Locale.US, "/v1/messages/multi_recipient?ts=%s&online=%s", timestamp, online);
|
||||
String path = String.format(Locale.US, "/v1/messages/multi_recipient?ts=%s&online=%s&urgent=%s", timestamp, online, urgent);
|
||||
|
||||
WebSocketRequestMessage requestMessage = WebSocketRequestMessage.newBuilder()
|
||||
.setId(new SecureRandom().nextLong())
|
||||
|
|
|
@ -26,15 +26,20 @@ public class OutgoingPushMessageList {
|
|||
@JsonProperty
|
||||
private boolean online;
|
||||
|
||||
@JsonProperty
|
||||
private boolean urgent;
|
||||
|
||||
public OutgoingPushMessageList(String destination,
|
||||
long timestamp,
|
||||
List<OutgoingPushMessage> messages,
|
||||
boolean online)
|
||||
boolean online,
|
||||
boolean urgent)
|
||||
{
|
||||
this.timestamp = timestamp;
|
||||
this.destination = destination;
|
||||
this.messages = messages;
|
||||
this.online = online;
|
||||
this.urgent = urgent;
|
||||
}
|
||||
|
||||
public String getDestination() {
|
||||
|
@ -53,6 +58,10 @@ public class OutgoingPushMessageList {
|
|||
return online;
|
||||
}
|
||||
|
||||
public boolean isUrgent() {
|
||||
return urgent;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public List<Integer> getDevices() {
|
||||
return messages.stream().map(OutgoingPushMessage::getDestinationDeviceId).collect(Collectors.toList());
|
||||
|
|
|
@ -212,7 +212,7 @@ public class PushServiceSocket {
|
|||
|
||||
private static final String DIRECTORY_AUTH_PATH = "/v1/directory/auth";
|
||||
private static final String MESSAGE_PATH = "/v1/messages/%s";
|
||||
private static final String GROUP_MESSAGE_PATH = "/v1/messages/multi_recipient?ts=%s&online=%s";
|
||||
private static final String GROUP_MESSAGE_PATH = "/v1/messages/multi_recipient?ts=%s&online=%s&urgent=%s";
|
||||
private static final String SENDER_ACK_MESSAGE_PATH = "/v1/messages/%s/%d";
|
||||
private static final String UUID_ACK_MESSAGE_PATH = "/v1/messages/uuid/%s";
|
||||
private static final String ATTACHMENT_V2_PATH = "/v2/attachments/form/upload";
|
||||
|
@ -463,12 +463,12 @@ public class PushServiceSocket {
|
|||
return JsonUtil.fromJson(responseText, SenderCertificate.class).getCertificate();
|
||||
}
|
||||
|
||||
public SendGroupMessageResponse sendGroupMessage(byte[] body, byte[] joinedUnidentifiedAccess, long timestamp, boolean online)
|
||||
public SendGroupMessageResponse sendGroupMessage(byte[] body, byte[] joinedUnidentifiedAccess, long timestamp, boolean online, boolean urgent)
|
||||
throws IOException
|
||||
{
|
||||
ServiceConnectionHolder connectionHolder = (ServiceConnectionHolder) getRandom(serviceClients, random);
|
||||
|
||||
String path = String.format(Locale.US, GROUP_MESSAGE_PATH, timestamp, online);
|
||||
String path = String.format(Locale.US, GROUP_MESSAGE_PATH, timestamp, online, urgent);
|
||||
|
||||
Request.Builder requestBuilder = new Request.Builder();
|
||||
requestBuilder.url(String.format("%s%s", connectionHolder.getUrl(), path));
|
||||
|
|
|
@ -37,6 +37,9 @@ public class SignalServiceEnvelopeEntity {
|
|||
@JsonProperty
|
||||
private String guid;
|
||||
|
||||
@JsonProperty
|
||||
private Boolean urgent;
|
||||
|
||||
public SignalServiceEnvelopeEntity() {}
|
||||
|
||||
public int getType() {
|
||||
|
@ -86,4 +89,8 @@ public class SignalServiceEnvelopeEntity {
|
|||
public String getDestinationUuid() {
|
||||
return destinationUuid;
|
||||
}
|
||||
|
||||
public boolean isUrgent() {
|
||||
return urgent == null || urgent;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ message SignalServiceEnvelopeProto {
|
|||
optional int64 serverDeliveredTimestamp = 9;
|
||||
optional string serverGuid = 10;
|
||||
optional string destinationUuid = 11;
|
||||
optional bool urgent = 12 [default = true];
|
||||
}
|
||||
|
||||
message MetadataProto {
|
||||
|
|
|
@ -33,7 +33,8 @@ message Envelope {
|
|||
optional bytes content = 8; // Contains an encrypted Content
|
||||
optional string serverGuid = 9;
|
||||
optional uint64 serverTimestamp = 10;
|
||||
// NEXT ID: 14
|
||||
optional bool urgent = 14 [default = true];
|
||||
// NEXT ID: 15
|
||||
}
|
||||
|
||||
message Content {
|
||||
|
|
Ładowanie…
Reference in New Issue