Merge remote-tracking branch 'upstream/dev' into origin/fix_resources

This commit is contained in:
Harris
2021-05-19 10:57:47 +10:00
188 changed files with 418 additions and 774 deletions

View File

@@ -1,5 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.session.libsession">
</manifest>
<manifest package="org.session.libsession" />

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.avatars;
package org.session.libsession.avatars;
import android.content.Context;
@@ -7,7 +7,7 @@ import androidx.annotation.Nullable;
import com.annimon.stream.Stream;
import org.session.libsession.messaging.threads.Address;
import org.session.libsession.utilities.Address;
import java.io.File;
import java.io.FileInputStream;

View File

@@ -1,8 +1,8 @@
package org.session.libsession.messaging.avatars;
package org.session.libsession.avatars;
import androidx.annotation.NonNull;
import org.session.libsession.utilities.color.MaterialColor;
import org.session.libsession.utilities.MaterialColor;
import java.util.ArrayList;
import java.util.Arrays;

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.avatars;
package org.session.libsession.avatars;
import android.content.Context;
import android.net.Uri;

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.avatars;
package org.session.libsession.avatars;
import android.content.Context;
import android.graphics.drawable.Drawable;

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.avatars;
package org.session.libsession.avatars;
import android.content.Context;
import android.graphics.Color;

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.avatars;
package org.session.libsession.avatars;
import android.content.Context;
import android.net.Uri;
@@ -7,9 +7,9 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.session.libsession.messaging.MessagingModuleConfiguration;
import org.session.libsession.messaging.StorageProtocol;
import org.session.libsession.messaging.threads.Address;
import org.session.libsession.messaging.threads.GroupRecord;
import org.session.libsession.database.StorageProtocol;
import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.GroupRecord;
import org.session.libsession.utilities.Conversions;
import org.session.libsignal.utilities.guava.Optional;

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.avatars;
package org.session.libsession.avatars;
import android.content.Context;
import android.net.Uri;
@@ -6,7 +6,7 @@ import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.session.libsession.messaging.threads.Address;
import org.session.libsession.utilities.Address;
import java.io.IOException;
import java.io.InputStream;

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.avatars;
package org.session.libsession.avatars;
import android.content.Context;
import android.graphics.Color;

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.avatars;
package org.session.libsession.avatars;
import android.content.Context;
import android.net.Uri;
@@ -7,7 +7,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.session.libsession.messaging.threads.Address;
import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.Conversions;
import java.io.FileNotFoundException;

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.avatars;
package org.session.libsession.avatars;
import android.content.Context;
import android.graphics.drawable.Drawable;

View File

@@ -2,7 +2,7 @@ package org.session.libsession.database
import org.session.libsession.messaging.open_groups.OpenGroup
import org.session.libsession.messaging.sending_receiving.attachments.*
import org.session.libsession.messaging.threads.Address
import org.session.libsession.utilities.Address
import org.session.libsession.messaging.utilities.DotNetAPI
import org.session.libsignal.messages.SignalServiceAttachmentPointer
import org.session.libsignal.messages.SignalServiceAttachmentStream

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging
package org.session.libsession.database
import android.content.Context
@@ -16,9 +16,9 @@ import org.session.libsession.messaging.sending_receiving.data_extraction.DataEx
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
import org.session.libsession.messaging.threads.Address
import org.session.libsession.messaging.threads.GroupRecord
import org.session.libsession.messaging.threads.recipients.Recipient.RecipientSettings
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.GroupRecord
import org.session.libsession.utilities.recipients.Recipient.RecipientSettings
import org.session.libsignal.crypto.ecc.ECKeyPair
import org.session.libsignal.messages.SignalServiceAttachmentPointer
import org.session.libsignal.messages.SignalServiceGroup
@@ -92,7 +92,7 @@ interface StorageProtocol {
fun removeLastDeletionServerId(room: String, server: String)
// Message Handling
fun isDuplicateMessage(timestamp: Long, sender: String): Boolean
fun isDuplicateMessage(timestamp: Long): Boolean
fun getReceivedMessageTimestamps(): Set<Long>
fun addReceivedMessageTimestamp(timestamp: Long)
fun removeReceivedMessageTimestamps(timestamps: Set<Long>)

View File

@@ -2,19 +2,20 @@ package org.session.libsession.messaging
import android.content.Context
import org.session.libsession.database.MessageDataProvider
import org.session.libsession.database.StorageProtocol
class MessagingModuleConfiguration(
val context: Context,
val storage: StorageProtocol,
val messageDataProvider: MessageDataProvider
val context: Context,
val storage: StorageProtocol,
val messageDataProvider: MessageDataProvider
) {
companion object {
lateinit var shared: MessagingModuleConfiguration
fun configure(context: Context,
storage: StorageProtocol,
messageDataProvider: MessageDataProvider
storage: StorageProtocol,
messageDataProvider: MessageDataProvider
) {
if (Companion::shared.isInitialized) { return }
shared = MessagingModuleConfiguration(context, storage, messageDataProvider)

View File

@@ -7,7 +7,7 @@ import org.session.libsession.messaging.sending_receiving.handle
import org.session.libsession.messaging.utilities.Data
import org.session.libsignal.utilities.Log
class MessageReceiveJob(val data: ByteArray, val isBackgroundPoll: Boolean, val openGroupMessageServerID: Long? = null, val openGroupID: String? = null) : Job {
class MessageReceiveJob(val data: ByteArray, val openGroupMessageServerID: Long? = null, val openGroupID: String? = null) : Job {
override var delegate: JobDelegate? = null
override var id: String? = null
override var failureCount: Int = 0
@@ -69,7 +69,6 @@ class MessageReceiveJob(val data: ByteArray, val isBackgroundPoll: Boolean, val
override fun serialize(): Data {
val builder = Data.Builder().putByteArray(DATA_KEY, data)
.putBoolean(IS_BACKGROUND_POLL_KEY, isBackgroundPoll)
openGroupMessageServerID?.let { builder.putLong(OPEN_GROUP_MESSAGE_SERVER_ID_KEY, it) }
openGroupID?.let { builder.putString(OPEN_GROUP_ID_KEY, it) }
return builder.build();
@@ -84,7 +83,6 @@ class MessageReceiveJob(val data: ByteArray, val isBackgroundPoll: Boolean, val
override fun create(data: Data): MessageReceiveJob {
return MessageReceiveJob(
data.getByteArray(DATA_KEY),
data.getBoolean(IS_BACKGROUND_POLL_KEY),
data.getLong(OPEN_GROUP_MESSAGE_SERVER_ID_KEY),
data.getString(OPEN_GROUP_ID_KEY)
)

View File

@@ -3,7 +3,7 @@ package org.session.libsession.messaging.messages
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.open_groups.OpenGroupV2
import org.session.libsession.messaging.open_groups.OpenGroup
import org.session.libsession.messaging.threads.Address
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.GroupUtil
import org.session.libsignal.utilities.toHexString

View File

@@ -2,8 +2,8 @@ package org.session.libsession.messaging.messages.control
import com.google.protobuf.ByteString
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.threads.Address
import org.session.libsession.messaging.threads.recipients.Recipient
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.GroupUtil
import org.session.libsignal.crypto.ecc.DjbECPrivateKey
import org.session.libsignal.crypto.ecc.DjbECPublicKey

View File

@@ -2,10 +2,10 @@ package org.session.libsession.messaging.messages.control
import com.google.protobuf.ByteString
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.threads.Address
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.preferences.ProfileKeyUtil
import org.session.libsession.utilities.ProfileKeyUtil
import org.session.libsignal.crypto.ecc.DjbECPrivateKey
import org.session.libsignal.crypto.ecc.DjbECPublicKey
import org.session.libsignal.crypto.ecc.ECKeyPair

View File

@@ -4,8 +4,8 @@ import org.session.libsession.messaging.messages.visible.VisibleMessage;
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment;
import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage;
import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact;
import org.session.libsession.messaging.threads.Address;
import org.session.libsession.utilities.Contact;
import org.session.libsession.utilities.Address;
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview;
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel;
import org.session.libsession.utilities.GroupUtil;

View File

@@ -7,7 +7,7 @@ import androidx.annotation.Nullable;
import org.session.libsession.messaging.messages.visible.OpenGroupInvitation;
import org.session.libsession.messaging.messages.visible.VisibleMessage;
import org.session.libsession.messaging.threads.Address;
import org.session.libsession.utilities.Address;
import org.session.libsession.messaging.utilities.UpdateMessageData;
import org.session.libsession.utilities.GroupUtil;
import org.session.libsignal.utilities.guava.Optional;

View File

@@ -1,8 +1,8 @@
package org.session.libsession.messaging.messages.signal;
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
import org.session.libsession.messaging.threads.DistributionTypes;
import org.session.libsession.messaging.threads.recipients.Recipient;
import org.session.libsession.utilities.DistributionTypes;
import org.session.libsession.utilities.recipients.Recipient;
import java.util.Collections;
import java.util.LinkedList;

View File

@@ -3,12 +3,12 @@ package org.session.libsession.messaging.messages.signal;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.session.libsession.messaging.threads.DistributionTypes;
import org.session.libsession.utilities.DistributionTypes;
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact;
import org.session.libsession.utilities.Contact;
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview;
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel;
import org.session.libsession.messaging.threads.recipients.Recipient;
import org.session.libsession.utilities.recipients.Recipient;
import java.util.LinkedList;
import java.util.List;

View File

@@ -4,14 +4,14 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.session.libsession.messaging.messages.visible.VisibleMessage;
import org.session.libsession.messaging.threads.DistributionTypes;
import org.session.libsession.database.documents.IdentityKeyMismatch;
import org.session.libsession.database.documents.NetworkFailure;
import org.session.libsession.utilities.DistributionTypes;
import org.session.libsession.utilities.IdentityKeyMismatch;
import org.session.libsession.utilities.NetworkFailure;
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact;
import org.session.libsession.utilities.Contact;
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview;
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel;
import org.session.libsession.messaging.threads.recipients.Recipient;
import org.session.libsession.utilities.recipients.Recipient;
import java.util.Collections;
import java.util.LinkedList;

View File

@@ -4,10 +4,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact;
import org.session.libsession.utilities.Contact;
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview;
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel;
import org.session.libsession.messaging.threads.recipients.Recipient;
import org.session.libsession.utilities.recipients.Recipient;
import java.util.Collections;
import java.util.List;

View File

@@ -2,7 +2,7 @@ package org.session.libsession.messaging.messages.signal;
import org.session.libsession.messaging.messages.visible.OpenGroupInvitation;
import org.session.libsession.messaging.messages.visible.VisibleMessage;
import org.session.libsession.messaging.threads.recipients.Recipient;
import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsession.messaging.utilities.UpdateMessageData;
public class OutgoingTextMessage {

View File

@@ -4,8 +4,8 @@ import com.goterl.lazycode.lazysodium.BuildConfig
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.messages.Message
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
import org.session.libsession.messaging.threads.Address
import org.session.libsession.messaging.threads.recipients.Recipient
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.GroupUtil
import org.session.libsignal.protos.SignalServiceProtos
import org.session.libsignal.utilities.Log

View File

@@ -38,12 +38,6 @@ object MessageReceiver {
val isOpenGroupMessage = (openGroupServerID != null)
// Parse the envelope
val envelope = SignalServiceProtos.Envelope.parseFrom(data)
// If the message failed to process the first time around we retry it later (if the error is retryable). In this case the timestamp
// will already be in the database but we don't want to treat the message as a duplicate. The isRetry flag is a simple workaround
// for this issue.
if (storage.isDuplicateMessage(envelope.timestamp, GroupUtil.doubleEncodeGroupID(envelope.source)) && !isRetry) {
throw Error.DuplicateMessage
}
// Decrypt the contents
val ciphertext = envelope.content ?: throw Error.NoData
var plaintext: ByteArray? = null
@@ -90,8 +84,6 @@ object MessageReceiver {
else -> throw Error.UnknownEnvelopeType
}
}
// Don't process the envelope any further if the message has been handled already
if (storage.isDuplicateMessage(envelope.timestamp, sender!!) && !isRetry) throw Error.DuplicateMessage
// Don't process the envelope any further if the sender is blocked
if (isBlocked(sender!!)) throw Error.SenderBlocked
// Parse the proto
@@ -119,6 +111,19 @@ object MessageReceiver {
var isValid = message.isValid()
if (message is VisibleMessage && !isValid && proto.dataMessage.attachmentsCount != 0) { isValid = true }
if (!isValid) { throw Error.InvalidMessage }
// If the message failed to process the first time around we retry it later (if the error is retryable). In this case the timestamp
// will already be in the database but we don't want to treat the message as a duplicate. The isRetry flag is a simple workaround
// for this issue.
if (message is ClosedGroupControlMessage && message.kind is ClosedGroupControlMessage.Kind.New) {
// Allow duplicates in this case to avoid the following situation:
// • The app performed a background poll or received a push notification
// • This method was invoked and the received message timestamps table was updated
// • Processing wasn't finished
// • The user doesn't see the new closed group
} else {
if (storage.isDuplicateMessage(envelope.timestamp)) { throw Error.DuplicateMessage }
storage.addReceivedMessageTimestamp(envelope.timestamp)
}
// Return
return Pair(message, proto)
}

View File

@@ -13,7 +13,7 @@ import org.session.libsession.messaging.messages.control.ConfigurationMessage
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
import org.session.libsession.messaging.messages.visible.*
import org.session.libsession.messaging.open_groups.*
import org.session.libsession.messaging.threads.Address
import org.session.libsession.utilities.Address
import org.session.libsession.messaging.utilities.MessageWrapper
import org.session.libsession.snode.RawResponsePromise
import org.session.libsession.snode.SnodeAPI

View File

@@ -9,7 +9,7 @@ import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.messages.control.ClosedGroupControlMessage
import org.session.libsession.messaging.sending_receiving.MessageSender.Error
import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI
import org.session.libsession.messaging.threads.Address
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.crypto.ecc.Curve
@@ -54,8 +54,14 @@ fun MessageSender.create(name: String, members: Collection<String>): Promise<Str
for (member in members) {
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupUpdateKind)
closedGroupControlMessage.sentTimestamp = sentTime
sendNonDurably(closedGroupControlMessage, Address.fromSerialized(member)).get()
try {
sendNonDurably(closedGroupControlMessage, Address.fromSerialized(member)).get()
} catch (e: Exception) {
deferred.reject(e)
return@queue
}
}
// Add the group to the user's set of public keys to poll for
storage.addClosedGroupPublicKey(groupPublicKey)
// Store the encryption key pair

View File

@@ -13,13 +13,13 @@ import org.session.libsession.messaging.sending_receiving.data_extraction.DataEx
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
import org.session.libsession.messaging.threads.Address
import org.session.libsession.messaging.threads.GroupRecord
import org.session.libsession.messaging.threads.recipients.Recipient
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.GroupRecord
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.preferences.ProfileKeyUtil
import org.session.libsession.utilities.ProfileKeyUtil
import org.session.libsignal.crypto.ecc.DjbECPrivateKey
import org.session.libsignal.crypto.ecc.DjbECPublicKey
import org.session.libsignal.crypto.ecc.ECKeyPair

View File

@@ -1,7 +1,7 @@
package org.session.libsession.messaging.sending_receiving.notifications
import android.content.Context
import org.session.libsession.messaging.threads.recipients.Recipient
import org.session.libsession.utilities.recipients.Recipient
interface MessageNotifier {
fun setVisibleThread(threadId: Long)

View File

@@ -70,7 +70,7 @@ class ClosedGroupPoller {
return@successBackground
}
messages.forEach { envelope ->
val job = MessageReceiveJob(envelope.toByteArray(), false)
val job = MessageReceiveJob(envelope.toByteArray())
JobQueue.shared.add(job)
}
}

View File

@@ -9,7 +9,7 @@ import org.session.libsession.messaging.jobs.MessageReceiveJob
import org.session.libsession.messaging.open_groups.OpenGroup
import org.session.libsession.messaging.open_groups.OpenGroupAPI
import org.session.libsession.messaging.open_groups.OpenGroupMessage
import org.session.libsession.messaging.threads.Address
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.GroupUtil
import org.session.libsignal.protos.SignalServiceProtos.*
import org.session.libsignal.utilities.Log
@@ -172,7 +172,7 @@ class OpenGroupPoller(private val openGroup: OpenGroup, private val executorServ
builder.timestamp = message.timestamp
builder.serverTimestamp = message.serverTimestamp
val envelope = builder.build()
val job = MessageReceiveJob(envelope.toByteArray(), isBackgroundPoll, messageServerID, openGroup.id)
val job = MessageReceiveJob(envelope.toByteArray(), messageServerID, openGroup.id)
Log.d("Loki", "Scheduling Job $job")
if (isBackgroundPoll) {
job.executeAsync().always { deferred.resolve(Unit) }

View File

@@ -7,7 +7,7 @@ import org.session.libsession.messaging.jobs.MessageReceiveJob
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
import org.session.libsession.messaging.open_groups.OpenGroupMessageV2
import org.session.libsession.messaging.open_groups.OpenGroupV2
import org.session.libsession.messaging.threads.Address
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.GroupUtil
import org.session.libsignal.protos.SignalServiceProtos
import org.session.libsignal.utilities.Log
@@ -99,7 +99,7 @@ class OpenGroupV2Poller(private val openGroups: List<OpenGroupV2>, private val e
builder.content = message.toProto().toByteString()
builder.timestamp = message.sentTimestamp
val envelope = builder.build()
val job = MessageReceiveJob(envelope.toByteArray(), isBackgroundPoll, message.serverID, serverRoomId)
val job = MessageReceiveJob(envelope.toByteArray(), message.serverID, serverRoomId)
Log.d("Loki", "Scheduling Job $job")
if (isBackgroundPoll) {
job.executeAsync()

View File

@@ -92,7 +92,7 @@ class Poller {
} else {
val messages = SnodeAPI.parseRawMessagesResponse(rawResponse, snode, userPublicKey)
messages.forEach { envelope ->
val job = MessageReceiveJob(envelope.toByteArray(), false)
val job = MessageReceiveJob(envelope.toByteArray())
JobQueue.shared.add(job)
}
poll(snode, deferred)

View File

@@ -1,7 +1,7 @@
package org.session.libsession.messaging.sending_receiving.quotes
import org.session.libsession.messaging.sending_receiving.attachments.Attachment
import org.session.libsession.messaging.threads.Address
import org.session.libsession.utilities.Address
class QuoteModel(val id: Long,
val author: Address,

View File

@@ -7,7 +7,7 @@ import nl.komponents.kovenant.*
import nl.komponents.kovenant.functional.bind
import nl.komponents.kovenant.functional.map
import org.session.libsession.messaging.utilities.MessageWrapper
import org.session.libsession.snode.utilities.getRandomElement
import org.session.libsignal.crypto.getRandomElement
import org.session.libsignal.protos.SignalServiceProtos
import org.session.libsignal.utilities.Snode
import org.session.libsignal.utilities.HTTP

View File

@@ -1,19 +0,0 @@
package org.session.libsession.snode.utilities
import java.security.SecureRandom
/**
* Uses `SecureRandom` to pick an element from this collection.
*/
fun <T> Collection<T>.getRandomElementOrNull(): T? {
if (isEmpty()) return null
val index = SecureRandom().nextInt(size) // SecureRandom() should be cryptographically secure
return elementAtOrNull(index)
}
/**
* Uses `SecureRandom` to pick an element from this collection.
*/
fun <T> Collection<T>.getRandomElement(): T {
return getRandomElementOrNull()!!
}

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.threads
package org.session.libsession.utilities
import android.content.Context
import android.os.Parcel
@@ -25,8 +25,6 @@ class Address private constructor(address: String) : Parcelable, Comparable<Addr
get() = GroupUtil.isClosedGroup(address)
val isOpenGroup: Boolean
get() = GroupUtil.isOpenGroup(address)
val isMmsGroup: Boolean
get() = GroupUtil.isMmsGroup(address)
val isContact: Boolean
get() = !isGroup

View File

@@ -1,4 +1,4 @@
package org.session.libsession.utilities.color.spans;
package org.session.libsession.utilities;
import androidx.annotation.NonNull;
import android.text.TextPaint;

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.sending_receiving.sharecontacts;
package org.session.libsession.utilities;
import android.net.Uri;
import android.os.Parcel;
@@ -17,7 +17,6 @@ import org.session.libsession.messaging.sending_receiving.attachments.Attachment
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId;
import org.session.libsession.messaging.sending_receiving.attachments.UriAttachment;
import org.session.libsignal.utilities.JsonUtil;
import org.session.libsession.utilities.MediaTypes;
import java.io.IOException;
import java.util.Collections;

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.threads
package org.session.libsession.utilities
object DistributionTypes {
const val DEFAULT = 2

View File

@@ -1,4 +1,4 @@
package org.session.libsession.database.documents;
package org.session.libsession.utilities;
import java.util.List;

View File

@@ -1,15 +1,15 @@
package org.session.libsession.messaging.threads
package org.session.libsession.utilities
import android.text.TextUtils
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.Address
import java.io.IOException
import java.util.*
class GroupRecord(
val encodedId: String, val title: String, members: String?, val avatar: ByteArray?,
val avatarId: Long?, val avatarKey: ByteArray?, val avatarContentType: String?,
val relay: String?, val isActive: Boolean, val avatarDigest: ByteArray?, val isMms: Boolean,
val url: String?, admins: String?, val formationTimestamp: Long
val encodedId: String, val title: String, members: String?, val avatar: ByteArray?,
val avatarId: Long?, val avatarKey: ByteArray?, val avatarContentType: String?,
val relay: String?, val isActive: Boolean, val avatarDigest: ByteArray?, val isMms: Boolean,
val url: String?, admins: String?, val formationTimestamp: Long
) {
var members: List<Address> = LinkedList<Address>()
var admins: List<Address> = LinkedList<Address>()

View File

@@ -7,7 +7,6 @@ import kotlin.jvm.Throws
object GroupUtil {
const val CLOSED_GROUP_PREFIX = "__textsecure_group__!"
const val MMS_GROUP_PREFIX = "__signal_mms_group__!"
const val OPEN_GROUP_PREFIX = "__loki_public_chat_group__!"
@JvmStatic
@@ -20,11 +19,6 @@ object GroupUtil {
return CLOSED_GROUP_PREFIX + Hex.toStringCondensed(groupID)
}
@JvmStatic
fun getEncodedMMSGroupID(groupID: ByteArray): String {
return MMS_GROUP_PREFIX + Hex.toStringCondensed(groupID)
}
@JvmStatic
fun getEncodedId(group: SignalServiceGroup): String {
val groupId = group.groupId
@@ -52,12 +46,7 @@ object GroupUtil {
}
fun isEncodedGroup(groupId: String): Boolean {
return groupId.startsWith(CLOSED_GROUP_PREFIX) || groupId.startsWith(MMS_GROUP_PREFIX) || groupId.startsWith(OPEN_GROUP_PREFIX)
}
@JvmStatic
fun isMmsGroup(groupId: String): Boolean {
return groupId.startsWith(MMS_GROUP_PREFIX)
return groupId.startsWith(CLOSED_GROUP_PREFIX) || groupId.startsWith(OPEN_GROUP_PREFIX)
}
@JvmStatic

View File

@@ -1,4 +1,4 @@
package org.session.libsession.database.documents;
package org.session.libsession.utilities;
import org.session.libsignal.utilities.Log;
@@ -13,7 +13,7 @@ import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.session.libsession.messaging.threads.Address;
import org.session.libsession.utilities.Address;
import org.session.libsignal.utilities.Base64;
import org.session.libsignal.crypto.IdentityKey;
import org.session.libsignal.exceptions.InvalidKeyException;

View File

@@ -1,4 +1,4 @@
package org.session.libsession.database.documents;
package org.session.libsession.utilities;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

View File

@@ -53,8 +53,8 @@ object KeyPairUtilities {
}
data class KeyPairGenerationResult(
val seed: ByteArray,
val ed25519KeyPair: KeyPair,
val x25519KeyPair: ECKeyPair
val seed: ByteArray,
val ed25519KeyPair: KeyPair,
val x25519KeyPair: ECKeyPair
)
}

View File

@@ -1,4 +1,4 @@
package org.session.libsession.utilities.color;
package org.session.libsession.utilities;
import android.content.Context;
import android.graphics.Color;

View File

@@ -1,9 +1,9 @@
package org.session.libsession.database.documents;
package org.session.libsession.utilities;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.session.libsession.messaging.threads.Address;
import org.session.libsession.utilities.Address;
public class NetworkFailure {

View File

@@ -1,4 +1,4 @@
package org.session.libsession.database.documents;
package org.session.libsession.utilities;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

View File

@@ -1,4 +1,4 @@
package org.session.libsession.utilities.preferences;
package org.session.libsession.utilities;
public class NotificationPrivacyPreference {

View File

@@ -1,19 +0,0 @@
package org.session.libsession.utilities
import android.telephony.PhoneNumberUtils
import android.util.Patterns
object NumberUtil {
private val emailPattern = Patterns.EMAIL_ADDRESS
@JvmStatic
fun isValidEmail(number: String): Boolean {
val matcher = emailPattern.matcher(number)
return matcher.matches()
}
@JvmStatic
fun isValidSmsOrEmail(number: String): Boolean {
return PhoneNumberUtils.isWellFormedSmsAddress(number) || isValidEmail(number)
}
}

View File

@@ -1,4 +1,4 @@
package org.session.libsession.utilities.preferences;
package org.session.libsession.utilities;
import android.content.Context;
import androidx.annotation.NonNull;

View File

@@ -1,5 +1,5 @@
package org.session.libsession.utilities
import org.session.libsession.messaging.threads.recipients.Recipient
import org.session.libsession.utilities.recipients.Recipient
data class ProfilePictureModifiedEvent(val recipient: Recipient)

View File

@@ -5,7 +5,6 @@ import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.deferred
import okio.Buffer
import org.session.libsession.messaging.file_server.FileServerAPIV2
import org.session.libsession.utilities.preferences.ProfileKeyUtil
import org.session.libsignal.streams.ProfileCipherOutputStream
import org.session.libsignal.utilities.ProfileAvatarData
import org.session.libsignal.streams.DigestingRequestBody

View File

@@ -3,15 +3,15 @@ package org.session.libsession.utilities
import android.content.Context
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier
import org.session.libsession.messaging.threads.Address
import org.session.libsession.messaging.threads.recipients.Recipient
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.recipients.Recipient
class SSKEnvironment(
val typingIndicators: TypingIndicatorsProtocol,
val readReceiptManager: ReadReceiptManagerProtocol,
val profileManager: ProfileManagerProtocol,
val notificationManager: MessageNotifier,
val messageExpirationManager: MessageExpirationManagerProtocol
val typingIndicators: TypingIndicatorsProtocol,
val readReceiptManager: ReadReceiptManagerProtocol,
val profileManager: ProfileManagerProtocol,
val notificationManager: MessageNotifier,
val messageExpirationManager: MessageExpirationManagerProtocol
) {
interface TypingIndicatorsProtocol {

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.sending_receiving.sharecontacts;
package org.session.libsession.utilities;
public interface Selectable {
void setSelected(boolean selected);

View File

@@ -1,4 +1,4 @@
package org.session.libsession.utilities.views;
package org.session.libsession.utilities;
import android.view.ViewStub;

View File

@@ -11,7 +11,6 @@ import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import org.session.libsession.R
import org.session.libsession.utilities.preferences.NotificationPrivacyPreference
import org.session.libsignal.utilities.Log
import java.io.IOException
import java.util.*

View File

@@ -38,7 +38,6 @@ import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
import org.session.libsignal.utilities.ListenableFuture;
import org.session.libsignal.utilities.SettableFuture;
import org.session.libsession.utilities.views.Stub;
public class ViewUtil {
@SuppressWarnings("deprecation")

View File

@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.session.libsession.messaging.threads.recipients;
package org.session.libsession.utilities.recipients;
import android.content.Context;
import android.graphics.drawable.Drawable;
@@ -29,20 +29,20 @@ import com.annimon.stream.function.Consumer;
import org.greenrobot.eventbus.EventBus;
import org.session.libsession.messaging.MessagingModuleConfiguration;
import org.session.libsession.messaging.avatars.TransparentContactPhoto;
import org.session.libsession.messaging.threads.Address;
import org.session.libsession.messaging.threads.GroupRecord;
import org.session.libsession.messaging.threads.recipients.RecipientProvider.RecipientDetails;
import org.session.libsession.avatars.TransparentContactPhoto;
import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.GroupRecord;
import org.session.libsession.utilities.recipients.RecipientProvider.RecipientDetails;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.Util;
import org.session.libsession.utilities.color.MaterialColor;
import org.session.libsession.utilities.MaterialColor;
import org.session.libsignal.utilities.Log;
import org.session.libsignal.utilities.guava.Optional;
import org.session.libsession.messaging.avatars.ContactColors;
import org.session.libsession.messaging.avatars.ContactPhoto;
import org.session.libsession.messaging.avatars.GroupRecordContactPhoto;
import org.session.libsession.messaging.avatars.ProfileContactPhoto;
import org.session.libsession.messaging.avatars.SystemContactPhoto;
import org.session.libsession.avatars.ContactColors;
import org.session.libsession.avatars.ContactPhoto;
import org.session.libsession.avatars.GroupRecordContactPhoto;
import org.session.libsession.avatars.ProfileContactPhoto;
import org.session.libsession.avatars.SystemContactPhoto;
import org.session.libsession.utilities.ProfilePictureModifiedEvent;
import org.session.libsession.utilities.FutureTaskListener;
import org.session.libsession.utilities.ListenableFutureTask;
@@ -289,7 +289,7 @@ public class Recipient implements RecipientModifiedListener {
String displayName = MessagingModuleConfiguration.shared.getStorage().getDisplayName(this.address.toString());
if (displayName != null) { return displayName; }
if (this.name == null && isMmsGroupRecipient()) {
if (this.name == null && isGroupRecipient()) {
List<String> names = new LinkedList<>();
for (Recipient recipient : participants) {
@@ -408,12 +408,8 @@ public class Recipient implements RecipientModifiedListener {
return address.isOpenGroup();
}
public boolean isMmsGroupRecipient() {
return address.isMmsGroup();
}
public boolean isPushGroupRecipient() {
return address.isGroup() && !address.isMmsGroup();
return address.isGroup();
}
public @NonNull synchronized List<Recipient> getParticipants() {
@@ -593,7 +589,6 @@ public class Recipient implements RecipientModifiedListener {
public synchronized RegisteredState getRegistered() {
if (isPushGroupRecipient()) return RegisteredState.REGISTERED;
else if (isMmsGroupRecipient()) return RegisteredState.NOT_REGISTERED;
return registered;
}

View File

@@ -1,10 +1,10 @@
package org.session.libsession.messaging.threads.recipients;
package org.session.libsession.utilities.recipients;
import android.content.Intent;
import android.provider.ContactsContract;
import android.text.TextUtils;
import org.session.libsession.messaging.threads.Address;
import org.session.libsession.utilities.Address;
import static android.content.Intent.ACTION_INSERT_OR_EDIT;

View File

@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.session.libsession.messaging.threads.recipients;
package org.session.libsession.utilities.recipients;
public class RecipientFormattingException extends Exception {
public RecipientFormattingException(String message) {

View File

@@ -1,4 +1,4 @@
package org.session.libsession.messaging.threads.recipients;
package org.session.libsession.utilities.recipients;
public interface RecipientModifiedListener {

View File

@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.session.libsession.messaging.threads.recipients;
package org.session.libsession.utilities.recipients;
import android.content.Context;
import android.net.Uri;
@@ -25,13 +25,13 @@ import androidx.annotation.Nullable;
import org.session.libsession.messaging.MessagingModuleConfiguration;
import org.session.libsignal.utilities.guava.Optional;
import org.session.libsession.utilities.color.MaterialColor;
import org.session.libsession.messaging.threads.Address;
import org.session.libsession.messaging.threads.GroupRecord;
import org.session.libsession.messaging.threads.recipients.Recipient.RecipientSettings;
import org.session.libsession.messaging.threads.recipients.Recipient.RegisteredState;
import org.session.libsession.messaging.threads.recipients.Recipient.UnidentifiedAccessMode;
import org.session.libsession.messaging.threads.recipients.Recipient.VibrateState;
import org.session.libsession.utilities.MaterialColor;
import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.GroupRecord;
import org.session.libsession.utilities.recipients.Recipient.RecipientSettings;
import org.session.libsession.utilities.recipients.Recipient.RegisteredState;
import org.session.libsession.utilities.recipients.Recipient.UnidentifiedAccessMode;
import org.session.libsession.utilities.recipients.Recipient.VibrateState;
import org.session.libsession.utilities.ListenableFutureTask;
import org.session.libsession.utilities.SoftHashMap;
import org.session.libsession.utilities.TextSecurePreferences;
@@ -148,10 +148,6 @@ class RecipientProvider {
members.add(getRecipient(context, memberAddress, Optional.absent(), Optional.absent(), asynchronous));
}
if (!groupId.isMmsGroup() && title == null) {
title = context.getString(R.string.RecipientProvider_unnamed_group);
}
if (groupRecord.get().getAvatar() != null && groupRecord.get().getAvatar().length > 0) {
avatarId = groupRecord.get().getAvatarId();
}