diff --git a/app/src/main/java/org/session/libsession/messaging/messages/signal/IncomingMediaMessage.kt b/app/src/main/java/org/session/libsession/messaging/messages/signal/IncomingMediaMessage.kt index 8e45afc698..727cdbbe42 100644 --- a/app/src/main/java/org/session/libsession/messaging/messages/signal/IncomingMediaMessage.kt +++ b/app/src/main/java/org/session/libsession/messaging/messages/signal/IncomingMediaMessage.kt @@ -7,13 +7,11 @@ 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.quotes.QuoteModel import org.session.libsession.utilities.Address -import org.session.libsession.utilities.Contact import org.thoughtcrime.securesms.database.model.content.MessageContent class IncomingMediaMessage( val from: Address, val sentTimeMillis: Long, - val subscriptionId: Int, val expiresIn: Long, val expireStartedAt: Long, val isMessageRequestResponse: Boolean, @@ -24,7 +22,6 @@ class IncomingMediaMessage( val proFeatures: ProFeatures, val messageContent: MessageContent?, val quote: QuoteModel?, - val sharedContacts: List, val linkPreviews: List, val dataExtractionNotification: DataExtractionNotificationInfoMessage?, ) { @@ -41,7 +38,6 @@ class IncomingMediaMessage( ): this( from = from, sentTimeMillis = message.sentTimestamp!!, - subscriptionId = -1, expiresIn = expiresIn, expireStartedAt = expireStartedAt, isMessageRequestResponse = false, @@ -52,7 +48,6 @@ class IncomingMediaMessage( proFeatures = message.proFeatures, messageContent = null, quote = quote, - sharedContacts = emptyList(), linkPreviews = linkPreviews, dataExtractionNotification = null ) diff --git a/app/src/main/java/org/session/libsession/messaging/messages/signal/IncomingTextMessage.kt b/app/src/main/java/org/session/libsession/messaging/messages/signal/IncomingTextMessage.kt index 37e7e22a8a..a229663295 100644 --- a/app/src/main/java/org/session/libsession/messaging/messages/signal/IncomingTextMessage.kt +++ b/app/src/main/java/org/session/libsession/messaging/messages/signal/IncomingTextMessage.kt @@ -11,13 +11,11 @@ import java.util.EnumSet data class IncomingTextMessage( val message: String?, val sender: Address, - val senderDeviceId: Int, val sentTimestampMillis: Long, val group: Address.GroupLike?, val push: Boolean, val expiresInMillis: Long, val expireStartedAt: Long, - val unidentified: Boolean, val callType: Int, val hasMention: Boolean, val isOpenGroupInvitation: Boolean, @@ -26,21 +24,6 @@ data class IncomingTextMessage( val isGroupMessage: Boolean = false, val isGroupUpdateMessage: Boolean = false, ) { - // Legacy code - val protocol: Int get() = 31337 - - // Legacy code - val serviceCenterAddress: String get() = "GCM" - - // Legacy code - val replyPathPresent: Boolean get() = true - - // Legacy code - val pseudoSubject: String get() = "" - - // Legacy code - val subscriptionId: Int get() = -1 - val callMessageType: CallMessageType? get() = CallMessageType.entries.getOrNull(callType) @@ -65,17 +48,15 @@ data class IncomingTextMessage( expiresInMillis: Long, expireStartedAt: Long, ): this( + message = message.text, sender = sender, - senderDeviceId = 1, sentTimestampMillis = message.sentTimestamp!!, - message = message.text, group = group, + push = true, expiresInMillis = expiresInMillis, expireStartedAt = expireStartedAt, - unidentified = false, - hasMention = message.hasMention, - push = true, callType = -1, + hasMention = message.hasMention, isOpenGroupInvitation = false, isSecureMessage = false, proFeatures = message.proFeatures, @@ -90,13 +71,11 @@ data class IncomingTextMessage( ): this( message = null, sender = sender, - senderDeviceId = 1, sentTimestampMillis = sentTimestampMillis, group = group, push = false, expiresInMillis = expiresInMillis, expireStartedAt = expireStartedAt, - unidentified = false, callType = callMessageType.ordinal, hasMention = false, isOpenGroupInvitation = false, @@ -120,13 +99,11 @@ data class IncomingTextMessage( return IncomingTextMessage( message = body, sender = sender, - senderDeviceId = 1, sentTimestampMillis = sentTimestampMillis, group = null, push = true, expiresInMillis = expiresInMillis, expireStartedAt = expireStartedAt, - unidentified = false, callType = -1, hasMention = false, isOpenGroupInvitation = true, diff --git a/app/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingMediaMessage.kt b/app/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingMediaMessage.kt index 988d65fea0..c304453493 100644 --- a/app/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingMediaMessage.kt +++ b/app/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingMediaMessage.kt @@ -6,10 +6,6 @@ import org.session.libsession.messaging.sending_receiving.attachments.Attachment import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel import org.session.libsession.utilities.Address -import org.session.libsession.utilities.Contact -import org.session.libsession.utilities.DistributionTypes -import org.session.libsession.utilities.IdentityKeyMismatch -import org.session.libsession.utilities.NetworkFailure import org.thoughtcrime.securesms.database.model.content.MessageContent class OutgoingMediaMessage( @@ -17,15 +13,10 @@ class OutgoingMediaMessage( val body: String?, val attachments: List, val sentTimeMillis: Long, - val distributionType: Int, - val subscriptionId: Int, val expiresInMillis: Long, val expireStartedAtMillis: Long, val outgoingQuote: QuoteModel?, val messageContent: MessageContent?, - val networkFailures: List, - val identityKeyMismatches: List, - val contacts: List, val linkPreviews: List, val group: Address.GroupLike?, val isGroupUpdateMessage: Boolean, @@ -50,16 +41,11 @@ class OutgoingMediaMessage( body = message.text, attachments = attachments, sentTimeMillis = message.sentTimestamp!!, - subscriptionId = -1, expiresInMillis = expiresInMillis, expireStartedAtMillis = expireStartedAt, - distributionType = DistributionTypes.DEFAULT, outgoingQuote = outgoingQuote, - contacts = emptyList(), messageContent = null, linkPreviews = linkPreview?.let { listOf(it) } ?: emptyList(), - networkFailures = emptyList(), - identityKeyMismatches = emptyList(), group = null, isGroupUpdateMessage = false, ) @@ -74,7 +60,6 @@ class OutgoingMediaMessage( expireStartedAtMillis: Long, isGroupUpdateMessage: Boolean, quote: QuoteModel?, - contacts: List, previews: List, messageContent: MessageContent?, ) : this( @@ -82,15 +67,10 @@ class OutgoingMediaMessage( body = body, attachments = avatar?.let { listOf(it) } ?: emptyList(), sentTimeMillis = sentTimeMillis, - distributionType = DistributionTypes.CONVERSATION, - subscriptionId = -1, expiresInMillis = expiresInMillis, expireStartedAtMillis = expireStartedAtMillis, outgoingQuote = quote, messageContent = messageContent, - networkFailures = emptyList(), - identityKeyMismatches = emptyList(), - contacts = contacts, linkPreviews = previews, group = group, isGroupUpdateMessage = isGroupUpdateMessage, diff --git a/app/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingTextMessage.kt b/app/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingTextMessage.kt index a81a094162..56e24b1a5a 100644 --- a/app/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingTextMessage.kt +++ b/app/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingTextMessage.kt @@ -11,7 +11,6 @@ data class OutgoingTextMessage( val message: String?, val expiresInMillis: Long, val expireStartedAtMillis: Long, - val subscriptionId: Int = -1, val sentTimestampMillis: Long, val isOpenGroupInvitation: Boolean, val proFeatures: ProFeatures = ProFeatures.NONE, diff --git a/app/src/main/java/org/session/libsession/messaging/sending_receiving/MessageRequestResponseHandler.kt b/app/src/main/java/org/session/libsession/messaging/sending_receiving/MessageRequestResponseHandler.kt index 46be6917ba..8a4976bac0 100644 --- a/app/src/main/java/org/session/libsession/messaging/sending_receiving/MessageRequestResponseHandler.kt +++ b/app/src/main/java/org/session/libsession/messaging/sending_receiving/MessageRequestResponseHandler.kt @@ -154,7 +154,6 @@ class MessageRequestResponseHandler @Inject constructor( retrieved = IncomingMediaMessage( from = messageSender.address, sentTimeMillis = messageTimestampMs, - subscriptionId = -1, expiresIn = 0L, expireStartedAt = 0L, isMessageRequestResponse = true, @@ -165,7 +164,6 @@ class MessageRequestResponseHandler @Inject constructor( proFeatures = ProFeatures.NONE, messageContent = null, quote = null, - sharedContacts = emptyList(), linkPreviews = emptyList(), dataExtractionNotification = null ), diff --git a/app/src/main/java/org/session/libsession/utilities/Contact.java b/app/src/main/java/org/session/libsession/utilities/Contact.java deleted file mode 100644 index 4bd0c1e01a..0000000000 --- a/app/src/main/java/org/session/libsession/utilities/Contact.java +++ /dev/null @@ -1,666 +0,0 @@ -package org.session.libsession.utilities; - -import android.net.Uri; -import android.os.Parcel; -import android.os.Parcelable; -import android.text.TextUtils; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; - -import org.session.libsession.messaging.sending_receiving.attachments.Attachment; -import org.session.libsession.messaging.sending_receiving.attachments.AttachmentState; -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 java.io.IOException; -import java.util.Collections; -import java.util.List; - -public class Contact implements Parcelable { - - @JsonProperty - private final Name name; - - @JsonProperty - private final String organization; - - @JsonProperty - private final List phoneNumbers; - - @JsonProperty - private final List emails; - - @JsonProperty - private final List postalAddresses; - - @JsonProperty - private final Avatar avatar; - - public Contact(@JsonProperty("name") @NonNull Name name, - @JsonProperty("organization") @Nullable String organization, - @JsonProperty("phoneNumbers") @NonNull List phoneNumbers, - @JsonProperty("emails") @NonNull List emails, - @JsonProperty("postalAddresses") @NonNull List postalAddresses, - @JsonProperty("avatar") @Nullable Avatar avatar) - { - this.name = name; - this.organization = organization; - this.phoneNumbers = Collections.unmodifiableList(phoneNumbers); - this.emails = Collections.unmodifiableList(emails); - this.postalAddresses = Collections.unmodifiableList(postalAddresses); - this.avatar = avatar; - } - - public Contact(@NonNull Contact contact, @Nullable Avatar avatar) { - this(contact.getName(), - contact.getOrganization(), - contact.getPhoneNumbers(), - contact.getEmails(), - contact.getPostalAddresses(), - avatar); - } - - private Contact(Parcel in) { - this(in.readParcelable(Name.class.getClassLoader()), - in.readString(), - in.createTypedArrayList(Phone.CREATOR), - in.createTypedArrayList(Email.CREATOR), - in.createTypedArrayList(PostalAddress.CREATOR), - in.readParcelable(Avatar.class.getClassLoader())); - } - - public @NonNull Name getName() { - return name; - } - - public @Nullable String getOrganization() { - return organization; - } - - public @NonNull List getPhoneNumbers() { - return phoneNumbers; - } - - public @NonNull List getEmails() { - return emails; - } - - public @NonNull List getPostalAddresses() { - return postalAddresses; - } - - public @Nullable Avatar getAvatar() { - return avatar; - } - - @JsonIgnore - public @Nullable Attachment getAvatarAttachment() { - return avatar != null ? avatar.getAttachment() : null; - } - - public String serialize() throws IOException { - return JsonUtil.toJsonThrows(this); - } - - public static Contact deserialize(@NonNull String serialized) throws IOException { - return JsonUtil.fromJson(serialized, Contact.class); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(name, flags); - dest.writeString(organization); - dest.writeTypedList(phoneNumbers); - dest.writeTypedList(emails); - dest.writeTypedList(postalAddresses); - dest.writeParcelable(avatar, flags); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Contact createFromParcel(Parcel in) { - return new Contact(in); - } - - @Override - public Contact[] newArray(int size) { - return new Contact[size]; - } - }; - - public static class Name implements Parcelable { - - @JsonProperty - private final String displayName; - - @JsonProperty - private final String givenName; - - @JsonProperty - private final String familyName; - - @JsonProperty - private final String prefix; - - @JsonProperty - private final String suffix; - - @JsonProperty - private final String middleName; - - public Name(@JsonProperty("displayName") @Nullable String displayName, - @JsonProperty("givenName") @Nullable String givenName, - @JsonProperty("familyName") @Nullable String familyName, - @JsonProperty("prefix") @Nullable String prefix, - @JsonProperty("suffix") @Nullable String suffix, - @JsonProperty("middleName") @Nullable String middleName) - { - this.displayName = displayName; - this.givenName = givenName; - this.familyName = familyName; - this.prefix = prefix; - this.suffix = suffix; - this.middleName = middleName; - } - - private Name(Parcel in) { - this(in.readString(), in.readString(), in.readString(), in.readString(), in.readString(), in.readString()); - } - - public @Nullable String getDisplayName() { - return displayName; - } - - public @Nullable String getGivenName() { - return givenName; - } - - public @Nullable String getFamilyName() { - return familyName; - } - - public @Nullable String getPrefix() { - return prefix; - } - - public @Nullable String getSuffix() { - return suffix; - } - - public @Nullable String getMiddleName() { - return middleName; - } - - public boolean isEmpty() { - return TextUtils.isEmpty(displayName) && - TextUtils.isEmpty(givenName) && - TextUtils.isEmpty(familyName) && - TextUtils.isEmpty(prefix) && - TextUtils.isEmpty(suffix) && - TextUtils.isEmpty(middleName); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(displayName); - dest.writeString(givenName); - dest.writeString(familyName); - dest.writeString(prefix); - dest.writeString(suffix); - dest.writeString(middleName); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Name createFromParcel(Parcel in) { - return new Name(in); - } - - @Override - public Name[] newArray(int size) { - return new Name[size]; - } - }; - } - - public static class Phone implements Selectable, Parcelable { - - @JsonProperty - private final String number; - - @JsonProperty - private final Type type; - - @JsonProperty - private final String label; - - @JsonIgnore - private boolean selected; - - public Phone(@JsonProperty("number") @NonNull String number, - @JsonProperty("type") @NonNull Type type, - @JsonProperty("label") @Nullable String label) - { - this.number = number; - this.type = type; - this.label = label; - this.selected = true; - } - - private Phone(Parcel in) { - this(in.readString(), Type.valueOf(in.readString()), in.readString()); - } - - public @NonNull String getNumber() { - return number; - } - - public @NonNull Type getType() { - return type; - } - - public @Nullable String getLabel() { - return label; - } - - @Override - public void setSelected(boolean selected) { - this.selected = selected; - } - - @Override - public boolean isSelected() { - return selected; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(number); - dest.writeString(type.name()); - dest.writeString(label); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Phone createFromParcel(Parcel in) { - return new Phone(in); - } - - @Override - public Phone[] newArray(int size) { - return new Phone[size]; - } - }; - - public enum Type { - HOME, MOBILE, WORK, CUSTOM - } - } - - public static class Email implements Selectable, Parcelable { - - @JsonProperty - private final String email; - - @JsonProperty - private final Type type; - - @JsonProperty - private final String label; - - @JsonIgnore - private boolean selected; - - public Email(@JsonProperty("email") @NonNull String email, - @JsonProperty("type") @NonNull Type type, - @JsonProperty("label") @Nullable String label) - { - this.email = email; - this.type = type; - this.label = label; - this.selected = true; - } - - private Email(Parcel in) { - this(in.readString(), Type.valueOf(in.readString()), in.readString()); - } - - public @NonNull String getEmail() { - return email; - } - - public @NonNull Type getType() { - return type; - } - - public @NonNull String getLabel() { - return label; - } - - @Override - public void setSelected(boolean selected) { - this.selected = selected; - } - - @Override - public boolean isSelected() { - return selected; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(email); - dest.writeString(type.name()); - dest.writeString(label); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Email createFromParcel(Parcel in) { - return new Email(in); - } - - @Override - public Email[] newArray(int size) { - return new Email[size]; - } - }; - - public enum Type { - HOME, MOBILE, WORK, CUSTOM - } - } - - public static class PostalAddress implements Selectable, Parcelable { - - @JsonProperty - private final Type type; - - @JsonProperty - private final String label; - - @JsonProperty - private final String street; - - @JsonProperty - private final String poBox; - - @JsonProperty - private final String neighborhood; - - @JsonProperty - private final String city; - - @JsonProperty - private final String region; - - @JsonProperty - private final String postalCode; - - @JsonProperty - private final String country; - - @JsonIgnore - private boolean selected; - - public PostalAddress(@JsonProperty("type") @NonNull Type type, - @JsonProperty("label") @Nullable String label, - @JsonProperty("street") @Nullable String street, - @JsonProperty("poBox") @Nullable String poBox, - @JsonProperty("neighborhood") @Nullable String neighborhood, - @JsonProperty("city") @Nullable String city, - @JsonProperty("region") @Nullable String region, - @JsonProperty("postalCode") @Nullable String postalCode, - @JsonProperty("country") @Nullable String country) - { - this.type = type; - this.label = label; - this.street = street; - this.poBox = poBox; - this.neighborhood = neighborhood; - this.city = city; - this.region = region; - this.postalCode = postalCode; - this.country = country; - this.selected = true; - } - - private PostalAddress(Parcel in) { - this(Type.valueOf(in.readString()), - in.readString(), - in.readString(), - in.readString(), - in.readString(), - in.readString(), - in.readString(), - in.readString(), - in.readString()); - } - - public @NonNull Type getType() { - return type; - } - - public @Nullable String getLabel() { - return label; - } - - public @Nullable String getStreet() { - return street; - } - - public @Nullable String getPoBox() { - return poBox; - } - - public @Nullable String getNeighborhood() { - return neighborhood; - } - - public @Nullable String getCity() { - return city; - } - - public @Nullable String getRegion() { - return region; - } - - public @Nullable String getPostalCode() { - return postalCode; - } - - public @Nullable String getCountry() { - return country; - } - - @Override - public void setSelected(boolean selected) { - this.selected = selected; - } - - @Override - public boolean isSelected() { - return selected; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(type.name()); - dest.writeString(label); - dest.writeString(street); - dest.writeString(poBox); - dest.writeString(neighborhood); - dest.writeString(city); - dest.writeString(region); - dest.writeString(postalCode); - dest.writeString(country); - } - - public static final Creator CREATOR = new Creator() { - @Override - public PostalAddress createFromParcel(Parcel in) { - return new PostalAddress(in); - } - - @Override - public PostalAddress[] newArray(int size) { - return new PostalAddress[size]; - } - }; - - @Override - public @NonNull String toString() { - StringBuilder builder = new StringBuilder(); - - if (!TextUtils.isEmpty(street)) { - builder.append(street).append('\n'); - } - - if (!TextUtils.isEmpty(poBox)) { - builder.append(poBox).append('\n'); - } - - if (!TextUtils.isEmpty(neighborhood)) { - builder.append(neighborhood).append('\n'); - } - - if (!TextUtils.isEmpty(city) && !TextUtils.isEmpty(region)) { - builder.append(city).append(", ").append(region); - } else if (!TextUtils.isEmpty(city)) { - builder.append(city).append(' '); - } else if (!TextUtils.isEmpty(region)) { - builder.append(region).append(' '); - } - - if (!TextUtils.isEmpty(postalCode)) { - builder.append(postalCode); - } - - if (!TextUtils.isEmpty(country)) { - builder.append('\n').append(country); - } - - return builder.toString().trim(); - } - - public enum Type { - HOME, WORK, CUSTOM - } - } - - public static class Avatar implements Selectable, Parcelable { - - @JsonProperty - private final AttachmentId attachmentId; - - @JsonProperty - private final boolean isProfile; - - @JsonIgnore - private final Attachment attachment; - - @JsonIgnore - private boolean selected; - - public Avatar(@Nullable AttachmentId attachmentId, @Nullable Attachment attachment, boolean isProfile) { - this.attachmentId = attachmentId; - this.attachment = attachment; - this.isProfile = isProfile; - this.selected = true; - } - - Avatar(@Nullable Uri attachmentUri, boolean isProfile) { - this(null, attachmentFromUri(attachmentUri), isProfile); - } - - @JsonCreator - private Avatar(@JsonProperty("attachmentId") @Nullable AttachmentId attachmentId, @JsonProperty("isProfile") boolean isProfile) { - this(attachmentId, null, isProfile); - } - - private Avatar(Parcel in) { - this((Uri) in.readParcelable(Uri.class.getClassLoader()), in.readByte() != 0); - } - - public @Nullable AttachmentId getAttachmentId() { - return attachmentId; - } - - public @Nullable Attachment getAttachment() { - return attachment; - } - - public boolean isProfile() { - return isProfile; - } - - @Override - public void setSelected(boolean selected) { - this.selected = selected; - } - - @Override - public boolean isSelected() { - return selected; - } - - @Override - public int describeContents() { - return 0; - } - - private static Attachment attachmentFromUri(@Nullable Uri uri) { - if (uri == null) return null; - return new UriAttachment(uri, MediaTypes.IMAGE_JPEG, AttachmentState.DONE.getValue(), 0, null, false, false, null); - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(attachment != null ? attachment.getDataUri() : null, flags); - dest.writeByte((byte) (isProfile ? 1 : 0)); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Avatar createFromParcel(Parcel in) { - return new Avatar(in); - } - - @Override - public Avatar[] newArray(int size) { - return new Avatar[size]; - } - }; - } -} diff --git a/app/src/main/java/org/session/libsession/utilities/DistributionTypes.kt b/app/src/main/java/org/session/libsession/utilities/DistributionTypes.kt deleted file mode 100644 index c6e8fcfd9d..0000000000 --- a/app/src/main/java/org/session/libsession/utilities/DistributionTypes.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.session.libsession.utilities - -object DistributionTypes { - const val DEFAULT = 2 - const val BROADCAST = 1 - const val CONVERSATION = 2 - const val ARCHIVE = 3 - const val INBOX_ZERO = 4 -} \ No newline at end of file diff --git a/app/src/main/java/org/session/libsession/utilities/IdentityKeyMismatch.java b/app/src/main/java/org/session/libsession/utilities/IdentityKeyMismatch.java deleted file mode 100644 index e317224e59..0000000000 --- a/app/src/main/java/org/session/libsession/utilities/IdentityKeyMismatch.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.session.libsession.utilities; - -import org.session.libsignal.utilities.Log; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -import org.session.libsession.utilities.Address; -import org.session.libsignal.utilities.Base64; -import org.session.libsignal.crypto.IdentityKey; -import org.session.libsignal.exceptions.InvalidKeyException; - -import java.io.IOException; - -public class IdentityKeyMismatch { - - private static final String TAG = IdentityKeyMismatch.class.getSimpleName(); - - @JsonProperty(value = "a") - private String address; - - @JsonProperty(value = "k") - @JsonSerialize(using = IdentityKeySerializer.class) - @JsonDeserialize(using = IdentityKeyDeserializer.class) - private IdentityKey identityKey; - - public IdentityKeyMismatch() {} - - public IdentityKeyMismatch(Address address, IdentityKey identityKey) { - this.address = address.toString(); - this.identityKey = identityKey; - } - - @JsonIgnore - public Address getAddress() { - return Address.fromSerialized(address); - } - - public IdentityKey getIdentityKey() { - return identityKey; - } - - @Override - public boolean equals(Object other) { - if (other == null || !(other instanceof IdentityKeyMismatch)) { - return false; - } - - IdentityKeyMismatch that = (IdentityKeyMismatch)other; - return that.address.equals(this.address) && that.identityKey.equals(this.identityKey); - } - - @Override - public int hashCode() { - return address.hashCode() ^ identityKey.hashCode(); - } - - private static class IdentityKeySerializer extends JsonSerializer { - @Override - public void serialize(IdentityKey value, JsonGenerator jsonGenerator, SerializerProvider serializers) - throws IOException - { - jsonGenerator.writeString(Base64.encodeBytes(value.serialize())); - } - } - - private static class IdentityKeyDeserializer extends JsonDeserializer { - @Override - public IdentityKey deserialize(JsonParser jsonParser, DeserializationContext ctxt) - throws IOException - { - try { - return new IdentityKey(Base64.decode(jsonParser.getValueAsString()), 0); - } catch (InvalidKeyException e) { - Log.w(TAG, e); - throw new IOException(e); - } - } - } -} diff --git a/app/src/main/java/org/session/libsession/utilities/IdentityKeyMismatchList.java b/app/src/main/java/org/session/libsession/utilities/IdentityKeyMismatchList.java deleted file mode 100644 index e1ea2d26e4..0000000000 --- a/app/src/main/java/org/session/libsession/utilities/IdentityKeyMismatchList.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.session.libsession.utilities; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.LinkedList; -import java.util.List; - -public class IdentityKeyMismatchList implements Document { - - @JsonProperty(value = "m") - private List mismatches; - - public IdentityKeyMismatchList() { - this.mismatches = new LinkedList<>(); - } - - public IdentityKeyMismatchList(List mismatches) { - this.mismatches = mismatches; - } - - @Override - public int size() { - if (mismatches == null) return 0; - else return mismatches.size(); - } - - @Override - @JsonIgnore - public List getList() { - return mismatches; - } -} diff --git a/app/src/main/java/org/session/libsession/utilities/NetworkFailure.java b/app/src/main/java/org/session/libsession/utilities/NetworkFailure.java deleted file mode 100644 index f999e92d36..0000000000 --- a/app/src/main/java/org/session/libsession/utilities/NetworkFailure.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.session.libsession.utilities; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; - -import org.session.libsession.utilities.Address; - -public class NetworkFailure { - - @JsonProperty(value = "a") - private String address; - - public NetworkFailure(Address address) { - this.address = address.toString(); - } - - public NetworkFailure() {} - - @JsonIgnore - public Address getAddress() { - return Address.fromSerialized(address); - } - - @Override - public boolean equals(Object other) { - if (other == null || !(other instanceof NetworkFailure)) return false; - - NetworkFailure that = (NetworkFailure)other; - return this.address.equals(that.address); - } - - @Override - public int hashCode() { - return address.hashCode(); - } -} diff --git a/app/src/main/java/org/session/libsession/utilities/NetworkFailureList.java b/app/src/main/java/org/session/libsession/utilities/NetworkFailureList.java deleted file mode 100644 index ef5faa6460..0000000000 --- a/app/src/main/java/org/session/libsession/utilities/NetworkFailureList.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.session.libsession.utilities; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.LinkedList; -import java.util.List; - -public class NetworkFailureList implements Document { - - @JsonProperty(value = "l") - private List failures; - - public NetworkFailureList() { - this.failures = new LinkedList<>(); - } - - public NetworkFailureList(List failures) { - this.failures = failures; - } - - @Override - public int size() { - if (failures == null) return 0; - else return failures.size(); - } - - @Override - @JsonIgnore - public List getList() { - return failures; - } -} diff --git a/app/src/main/java/org/session/libsession/utilities/Selectable.java b/app/src/main/java/org/session/libsession/utilities/Selectable.java deleted file mode 100644 index 8bb77f6242..0000000000 --- a/app/src/main/java/org/session/libsession/utilities/Selectable.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.session.libsession.utilities; - -public interface Selectable { - void setSelected(boolean selected); - boolean isSelected(); -} diff --git a/app/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt b/app/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt index 351d7722b3..c343a43b49 100644 --- a/app/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt +++ b/app/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt @@ -20,6 +20,7 @@ import kotlinx.coroutines.flow.update import kotlinx.serialization.json.Json import network.loki.messenger.BuildConfig import network.loki.messenger.R +import network.loki.messenger.libsession_util.protocol.ProFeatures import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.file_server.FileServer import org.session.libsession.utilities.TextSecurePreferences.Companion.AUTOPLAY_AUDIO_MESSAGES @@ -205,8 +206,8 @@ interface TextSecurePreferences { fun forcedShortTTL(): Boolean fun setForcedShortTTL(value: Boolean) - fun getDebugMessageFeatures(): Set - fun setDebugMessageFeatures(features: Set) + fun getDebugMessageFeatures(): ProFeatures + fun setDebugMessageFeatures(features: ProFeatures) fun getDebugSubscriptionType(): DebugMenuViewModel.DebugSubscriptionStatus? fun setDebugSubscriptionType(status: DebugMenuViewModel.DebugSubscriptionStatus?) @@ -378,7 +379,7 @@ interface TextSecurePreferences { const val IN_APP_REVIEW_STATE = "in_app_review_state" - const val DEBUG_MESSAGE_FEATURES = "debug_message_features" + const val DEBUG_MESSAGE_FEATURES = "debug_message_features_long" const val DEBUG_SUBSCRIPTION_STATUS = "debug_subscription_status" const val DEBUG_PRO_PLAN_STATUS = "debug_pro_plan_status" const val DEBUG_FORCE_NO_BILLING = "debug_pro_has_billing" @@ -1708,13 +1709,12 @@ class AppTextSecurePreferences @Inject constructor( setStringPreference(TextSecurePreferences.DEPRECATING_START_TIME_OVERRIDE, value.toString()) } } - override fun getDebugMessageFeatures(): Set { - return getStringSetPreference( TextSecurePreferences.DEBUG_MESSAGE_FEATURES, emptySet()) - ?.map { ProStatusManager.MessageProFeature.valueOf(it) }?.toSet() ?: emptySet() + override fun getDebugMessageFeatures(): ProFeatures { + return ProFeatures(getLongPreference( TextSecurePreferences.DEBUG_MESSAGE_FEATURES, 0)) } - override fun setDebugMessageFeatures(features: Set) { - setStringSetPreference(TextSecurePreferences.DEBUG_MESSAGE_FEATURES, features.map { it.name }.toSet()) + override fun setDebugMessageFeatures(features: ProFeatures) { + setLongPreference(TextSecurePreferences.DEBUG_MESSAGE_FEATURES, features.rawValue) } override fun getDebugSubscriptionType(): DebugMenuViewModel.DebugSubscriptionStatus? { diff --git a/app/src/main/java/org/session/libsession/utilities/Throttler.java b/app/src/main/java/org/session/libsession/utilities/Throttler.java deleted file mode 100644 index d5ac785bfe..0000000000 --- a/app/src/main/java/org/session/libsession/utilities/Throttler.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.session.libsession.utilities; - -import android.os.Handler; - -/** - * A class that will throttle the number of runnables executed to be at most once every specified - * interval. - * - * Useful for performing actions in response to rapid user input where you want to take action on - * the initial input but prevent follow-up spam. - * - * This is different from {@link Debouncer} in that it will run the first runnable immediately - * instead of waiting for input to die down. - * - * See http://rxmarbles.com/#throttle - */ -public class Throttler { - - private static final int WHAT = 8675309; - - private final Handler handler; - private final long threshold; - - /** - * @param threshold Only one runnable will be executed via {@link #publish(Runnable)} every - * {@code threshold} milliseconds. - */ - public Throttler(long threshold) { - this.handler = new Handler(); - this.threshold = threshold; - } - - public void publish(Runnable runnable) { - if (handler.hasMessages(WHAT)) { - return; - } - - runnable.run(); - handler.sendMessageDelayed(handler.obtainMessage(WHAT), threshold); - } - - public void clear() { - handler.removeCallbacksAndMessages(null); - } -} diff --git a/app/src/main/java/org/session/libsession/utilities/WindowDebouncer.kt b/app/src/main/java/org/session/libsession/utilities/WindowDebouncer.kt deleted file mode 100644 index bec5c93837..0000000000 --- a/app/src/main/java/org/session/libsession/utilities/WindowDebouncer.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.session.libsession.utilities - -import java.util.Timer -import java.util.TimerTask -import java.util.concurrent.atomic.AtomicBoolean -import java.util.concurrent.atomic.AtomicReference - -/** - * Not really a 'debouncer' but named to be similar to the current Debouncer - * designed to queue tasks on a window (if not already queued) like a timer - */ -class WindowDebouncer(private val timeWindowMilliseconds: Long, private val timer: Timer) { - - private val atomicRef: AtomicReference = AtomicReference(null) - private val hasStarted = AtomicBoolean(false) - - private val recursiveRunnable: TimerTask = object:TimerTask() { - override fun run() { - val runnable = atomicRef.getAndSet(null) - runnable?.run() - } - } - - fun publish(runnable: Runnable) { - if (hasStarted.compareAndSet(false, true)) { - timer.scheduleAtFixedRate(recursiveRunnable, 0, timeWindowMilliseconds) - } - atomicRef.compareAndSet(null, runnable) - } - -} \ No newline at end of file diff --git a/app/src/main/java/org/session/libsession/utilities/concurrent/AssertedSuccessListener.java b/app/src/main/java/org/session/libsession/utilities/concurrent/AssertedSuccessListener.java deleted file mode 100644 index 391f53d027..0000000000 --- a/app/src/main/java/org/session/libsession/utilities/concurrent/AssertedSuccessListener.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.session.libsession.utilities.concurrent; - -import org.session.libsignal.utilities.ListenableFuture.Listener; - -import java.util.concurrent.ExecutionException; - -public abstract class AssertedSuccessListener implements Listener { - - @Override - public void onFailure(ExecutionException e) { - throw new AssertionError(e); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index ab33b5b30e..1b681d2c8c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -403,6 +403,7 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate, retryFailedAttachments = viewModel::retryFailedAttachments, glide = glide, threadRecipientProvider = viewModel::recipient, + messageDB = mmsSmsDb, ) adapter.visibleMessageViewDelegate = this adapter @@ -791,7 +792,12 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate, } override fun onCreateLoader(id: Int, bundle: Bundle?): Loader { - return ConversationLoader(viewModel.threadId, false, this@ConversationActivityV2) + return ConversationLoader( + threadID = viewModel.threadId, + reverse = false, + context = this@ConversationActivityV2, + mmsSmsDatabase = mmsSmsDb + ) } override fun onLoadFinished(loader: Loader, cursor: Cursor?) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt index 21efaf7767..38d4b23236 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt @@ -17,7 +17,6 @@ import org.thoughtcrime.securesms.database.MmsSmsColumns import org.thoughtcrime.securesms.database.MmsSmsDatabase import org.thoughtcrime.securesms.database.model.MessageId import org.thoughtcrime.securesms.database.model.MessageRecord -import org.thoughtcrime.securesms.dependencies.DatabaseComponent import java.util.concurrent.atomic.AtomicLong import kotlin.math.min @@ -33,8 +32,8 @@ class ConversationAdapter( private val retryFailedAttachments: (List) -> Unit, private val glide: RequestManager, private val threadRecipientProvider: () -> Recipient, + val messageDB: MmsSmsDatabase, ) : CursorRecyclerViewAdapter(context) { - private val messageDB by lazy { DatabaseComponent.get(context).mmsSmsDatabase() } var selectedItems = mutableSetOf() var isAdmin: Boolean = false private var searchQuery: String? = null diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationLoader.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationLoader.kt index 4692bf7862..c85daf6e23 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationLoader.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationLoader.kt @@ -2,16 +2,17 @@ package org.thoughtcrime.securesms.conversation.v2 import android.content.Context import android.database.Cursor -import org.thoughtcrime.securesms.dependencies.DatabaseComponent +import org.thoughtcrime.securesms.database.MmsSmsDatabase import org.thoughtcrime.securesms.util.AbstractCursorLoader class ConversationLoader( private val threadID: Long, private val reverse: Boolean, - context: Context + context: Context, + val mmsSmsDatabase: MmsSmsDatabase ) : AbstractCursorLoader(context) { override fun getCursor(): Cursor { - return DatabaseComponent.get(context).mmsSmsDatabase().getConversation(threadID, reverse) + return mmsSmsDatabase.getConversation(threadID, reverse) } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt index 07a3f7a709..32ccaaa5bb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt @@ -65,6 +65,7 @@ import dagger.hilt.android.lifecycle.withCreationCallback import kotlinx.coroutines.launch import network.loki.messenger.R import network.loki.messenger.databinding.ViewVisibleMessageContentBinding +import network.loki.messenger.libsession_util.protocol.ProFeature import org.session.libsession.database.StorageProtocol import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment import org.session.libsession.utilities.NonTranslatableStringConstants @@ -372,7 +373,7 @@ fun CellMetadata( @Composable fun MessageProFeatures( - features: Set, + features: Set, badgeClickable: Boolean, sendCommand: (Commands) -> Unit, modifier: Modifier = Modifier, @@ -402,13 +403,13 @@ fun MessageProFeatures( textStyle = LocalType.current.large, padding = PaddingValues(), data = CTAFeature.Icon( - text = when(it){ - ProStatusManager.MessageProFeature.ProBadge -> Phrase.from(LocalContext.current, R.string.appProBadge) + text = when (it){ + ProFeature.PRO_BADGE -> Phrase.from(LocalContext.current, R.string.appProBadge) .put(APP_PRO_KEY, NonTranslatableStringConstants.APP_PRO) .format() .toString() - ProStatusManager.MessageProFeature.LongMessage -> stringResource(id = R.string.proIncreasedMessageLengthFeature) - ProStatusManager.MessageProFeature.AnimatedAvatar -> stringResource(id = R.string.proAnimatedDisplayPictureFeature) + ProFeature.HIGHER_CHARACTER_LIMIT -> stringResource(id = R.string.proIncreasedMessageLengthFeature) + ProFeature.ANIMATED_AVATAR -> stringResource(id = R.string.proAnimatedDisplayPictureFeature) } ) ) @@ -421,11 +422,7 @@ fun MessageProFeatures( fun PreviewMessageProFeatures(){ PreviewTheme { MessageProFeatures( - features = setOf( - ProStatusManager.MessageProFeature.ProBadge, - ProStatusManager.MessageProFeature.LongMessage, - ProStatusManager.MessageProFeature.AnimatedAvatar - ), + features = ProFeature.entries.toSet(), badgeClickable = false, sendCommand = {} ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailsViewModel.kt index e70e6058c8..3327dc1415 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailsViewModel.kt @@ -25,6 +25,7 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import network.loki.messenger.R +import network.loki.messenger.libsession_util.protocol.ProFeature import org.session.libsession.messaging.groups.LegacyGroupDeprecationManager import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment import org.session.libsession.utilities.Address @@ -47,8 +48,6 @@ import org.thoughtcrime.securesms.mms.ImageSlide import org.thoughtcrime.securesms.mms.Slide import org.thoughtcrime.securesms.pro.ProStatus import org.thoughtcrime.securesms.pro.ProStatusManager -import org.thoughtcrime.securesms.pro.ProStatusManager.MessageProFeature.AnimatedAvatar -import org.thoughtcrime.securesms.pro.ProStatusManager.MessageProFeature.LongMessage import org.thoughtcrime.securesms.ui.GetString import org.thoughtcrime.securesms.ui.TitledText import org.thoughtcrime.securesms.util.AvatarUIData @@ -201,7 +200,7 @@ class MessageDetailsViewModel @AssistedInject constructor( senderIsBlinded = IdPrefix.fromValue(sender.address.toString())?.isBlinded() ?: false, thread = conversation, readOnly = isDeprecatedLegacyGroup, - proFeatures = proStatusManager.getMessageProFeatures(messageRecord.messageId), + proFeatures = proStatusManager.getMessageProFeatures(messageRecord).toSet(), proBadgeClickable = !recipientRepository.getSelf().isPro // no badge click if the current user is pro ) } @@ -285,8 +284,8 @@ class MessageDetailsViewModel @AssistedInject constructor( proBadgeCTA = when{ features.size > 1 -> ProBadgeCTA.Generic(proSubscription) // always show the generic cta when there are more than 1 feature - features.contains(LongMessage) -> ProBadgeCTA.LongMessage(proSubscription) - features.contains(AnimatedAvatar) -> ProBadgeCTA.AnimatedProfile(proSubscription) + features.contains(ProFeature.HIGHER_CHARACTER_LIMIT) -> ProBadgeCTA.LongMessage(proSubscription) + features.contains(ProFeature.ANIMATED_AVATAR) -> ProBadgeCTA.AnimatedProfile(proSubscription) else -> ProBadgeCTA.Generic(proSubscription) } ) @@ -350,7 +349,7 @@ data class MessageDetailsState( val senderIsBlinded: Boolean = false, val thread: Recipient? = null, val readOnly: Boolean = false, - val proFeatures: Set = emptySet(), + val proFeatures: Set = emptySet(), val proBadgeClickable: Boolean = false, ) { val fromTitle = GetString(R.string.from) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt index 38f90ae06a..82a5ce2ecd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt @@ -7,7 +7,6 @@ import com.squareup.phrase.Phrase import dagger.hilt.android.AndroidEntryPoint import network.loki.messenger.R import org.session.libsession.database.StorageProtocol -import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.jobs.AttachmentDownloadJob import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.sending_receiving.attachments.AttachmentState @@ -16,7 +15,6 @@ import org.session.libsession.utilities.StringSubstitutionConstants.CONVERSATION import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.displayName import org.thoughtcrime.securesms.createSessionDialog -import org.thoughtcrime.securesms.database.SessionContactDatabase import javax.inject.Inject /** Shown when receiving media from a contact for the first time, to confirm that @@ -27,7 +25,6 @@ class AutoDownloadDialog(private val threadRecipient: Recipient, ) : DialogFragment() { @Inject lateinit var storage: StorageProtocol - @Inject lateinit var contactDB: SessionContactDatabase @Inject lateinit var attachmentDownloadJobFactory: AttachmentDownloadJob.Factory override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog { @@ -50,7 +47,7 @@ class AutoDownloadDialog(private val threadRecipient: Recipient, val attachmentId = databaseAttachment.attachmentId.rowId if (databaseAttachment.transferState == AttachmentState.PENDING.value - && MessagingModuleConfiguration.shared.storage.getAttachmentUploadJob(attachmentId) == null) { + && storage.getAttachmentUploadJob(attachmentId) == null) { // start download JobQueue.shared.add(attachmentDownloadJobFactory.create(attachmentId, databaseAttachment.mmsId)) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt index e336673488..4d042c6157 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt @@ -36,16 +36,10 @@ import org.session.libsession.messaging.sending_receiving.link_preview.LinkPrevi import org.session.libsession.snode.SnodeAPI import org.session.libsession.utilities.Address.Companion.fromSerialized import org.session.libsession.utilities.Address.Companion.toAddress -import org.session.libsession.utilities.Contact -import org.session.libsession.utilities.IdentityKeyMismatch -import org.session.libsession.utilities.IdentityKeyMismatchList -import org.session.libsession.utilities.NetworkFailure -import org.session.libsession.utilities.NetworkFailureList import org.session.libsession.utilities.TextSecurePreferences.Companion.isReadReceiptsEnabled import org.session.libsession.utilities.isGroupOrCommunity import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.toGroupString -import org.session.libsignal.utilities.JsonUtil import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.ThreadUtils.queue import org.session.libsignal.utilities.guava.Optional @@ -396,43 +390,6 @@ class MmsDatabase @Inject constructor( return result } - private fun getSharedContacts( - cursor: Cursor, - attachments: List - ): List { - val serializedContacts = cursor.getString(cursor.getColumnIndexOrThrow(SHARED_CONTACTS)) - if (serializedContacts.isNullOrEmpty()) { - return emptyList() - } - val attachmentIdMap: MutableMap = HashMap() - for (attachment in attachments) { - attachmentIdMap[attachment.attachmentId] = attachment - } - try { - val contacts: MutableList = LinkedList() - val jsonContacts = JSONArray(serializedContacts) - for (i in 0 until jsonContacts.length()) { - val contact = Contact.deserialize(jsonContacts.getJSONObject(i).toString()) - if (contact.avatar != null && contact.avatar!!.attachmentId != null) { - val attachment = attachmentIdMap[contact.avatar!!.attachmentId] - val updatedAvatar = Contact.Avatar( - contact.avatar!!.attachmentId, - attachment, - contact.avatar!!.isProfile - ) - contacts.add(Contact(contact, updatedAvatar)) - } else { - contacts.add(contact) - } - } - return contacts - } catch (e: JSONException) { - Log.w(TAG, "Failed to parse shared contacts.", e) - } catch (e: IOException) { - Log.w(TAG, "Failed to parse shared contacts.", e) - } - return emptyList() - } private fun getLinkPreviews( cursor: Cursor, @@ -472,9 +429,8 @@ class MmsDatabase @Inject constructor( @Throws(MmsException::class) private fun insertMessageInbox( retrieved: IncomingMediaMessage, - contentLocation: String, - threadId: Long, mailbox: Long, - serverTimestamp: Long, + threadId: Long, + mailbox: Long, serverTimestamp: Long, runThreadUpdate: Boolean ): Optional { if (threadId < 0 ) throw MmsException("No thread ID supplied!") @@ -485,7 +441,6 @@ class MmsDatabase @Inject constructor( contentValues.put(ADDRESS, retrieved.from.toString()) contentValues.put(MESSAGE_BOX, mailbox) contentValues.put(THREAD_ID, threadId) - contentValues.put(CONTENT_LOCATION, contentLocation) contentValues.put(STATUS, Status.DOWNLOAD_INITIALIZED) contentValues.put(PRO_FEATURES, retrieved.proFeatures.rawValue) // In open groups messages should be sorted by their server timestamp @@ -493,12 +448,7 @@ class MmsDatabase @Inject constructor( if (serverTimestamp == 0L) { receivedTimestamp = retrieved.sentTimeMillis } - contentValues.put( - DATE_RECEIVED, - receivedTimestamp - ) // Loki - This is important due to how we handle GIFs - contentValues.put(PART_COUNT, retrieved.attachments.size) - contentValues.put(SUBSCRIPTION_ID, retrieved.subscriptionId) + contentValues.put(DATE_RECEIVED, receivedTimestamp) // Loki - This is important due to how we handle GIFs contentValues.put(EXPIRES_IN, retrieved.expiresIn) contentValues.put(EXPIRE_STARTED, retrieved.expireStartedAt) contentValues.put(HAS_MENTION, retrieved.hasMention) @@ -527,7 +477,6 @@ class MmsDatabase @Inject constructor( messageContent = retrieved.messageContent, attachments = retrieved.attachments, quoteAttachments = quoteAttachments!!, - sharedContacts = retrieved.sharedContacts, linkPreviews = retrieved.linkPreviews, contentValues = contentValues, ) @@ -576,7 +525,7 @@ class MmsDatabase @Inject constructor( if (retrieved.isMessageRequestResponse) { type = type or MmsSmsColumns.Types.MESSAGE_REQUEST_RESPONSE_BIT } - return insertMessageInbox(retrieved, "", threadId, type, serverTimestamp, runThreadUpdate) + return insertMessageInbox(retrieved, threadId, type, serverTimestamp, runThreadUpdate) } @Throws(MmsException::class) @@ -607,7 +556,6 @@ class MmsDatabase @Inject constructor( receivedTimestamp = SnodeAPI.nowWithOffset } contentValues.put(DATE_RECEIVED, receivedTimestamp) - contentValues.put(SUBSCRIPTION_ID, message.subscriptionId) contentValues.put(EXPIRES_IN, message.expiresInMillis) contentValues.put(EXPIRE_STARTED, message.expireStartedAtMillis) contentValues.put(ADDRESS, message.recipient.toString()) @@ -622,10 +570,10 @@ class MmsDatabase @Inject constructor( .sum()) val quoteAttachments: MutableList = LinkedList() if (message.outgoingQuote != null) { - contentValues.put(QUOTE_ID, message.outgoingQuote!!.id) - contentValues.put(QUOTE_AUTHOR, message.outgoingQuote!!.author.toString()) - contentValues.put(QUOTE_MISSING, if (message.outgoingQuote!!.missing) 1 else 0) - quoteAttachments.addAll(message.outgoingQuote!!.attachments!!) + contentValues.put(QUOTE_ID, message.outgoingQuote.id) + contentValues.put(QUOTE_AUTHOR, message.outgoingQuote.author.toString()) + contentValues.put(QUOTE_MISSING, if (message.outgoingQuote.missing) 1 else 0) + quoteAttachments.addAll(message.outgoingQuote.attachments!!) } if (isDuplicate(message, threadId)) { Log.w(TAG, "Ignoring duplicate media message (" + message.sentTimeMillis + ")") @@ -636,7 +584,6 @@ class MmsDatabase @Inject constructor( messageContent = message.messageContent, attachments = message.attachments, quoteAttachments = quoteAttachments, - sharedContacts = message.contacts, linkPreviews = message.linkPreviews, contentValues = contentValues, ) @@ -678,7 +625,6 @@ class MmsDatabase @Inject constructor( messageContent: MessageContent?, attachments: List, quoteAttachments: List, - sharedContacts: List, linkPreviews: List, contentValues: ContentValues, ): Long { @@ -687,17 +633,12 @@ class MmsDatabase @Inject constructor( val allAttachments: MutableList = LinkedList() val thumbnailJobs: MutableList = ArrayList() // Collector for thumbnail jobs - val contactAttachments = - Stream.of(sharedContacts).map { obj: Contact -> obj.avatarAttachment } - .filter { a: Attachment? -> a != null } - .toList() val previewAttachments = Stream.of(linkPreviews).filter { lp: LinkPreview -> lp.getThumbnail().isPresent } .map { lp: LinkPreview -> lp.getThumbnail().get() } .toList() allAttachments.addAll(attachments) - allAttachments.addAll(contactAttachments) allAttachments.addAll(previewAttachments) contentValues.put(BODY, body) @@ -716,25 +657,8 @@ class MmsDatabase @Inject constructor( thumbnailJobs // This will collect all attachment IDs that need thumbnails ) - val serializedContacts = - getSerializedSharedContacts(insertedAttachments, sharedContacts) val serializedPreviews = getSerializedLinkPreviews(insertedAttachments, linkPreviews) - if (!serializedContacts.isNullOrEmpty()) { - val contactValues = ContentValues() - contactValues.put(SHARED_CONTACTS, serializedContacts) - val database = readableDatabase - val rows = database.update( - TABLE_NAME, - contactValues, - "$ID = ?", - arrayOf(messageId.toString()) - ) - if (rows <= 0) { - Log.w(TAG, "Failed to update message with shared contact data.") - } - } - if (!serializedPreviews.isNullOrEmpty()) { val contactValues = ContentValues() contactValues.put(LINK_PREVIEWS, serializedPreviews) @@ -856,36 +780,6 @@ class MmsDatabase @Inject constructor( ) } - private fun getSerializedSharedContacts( - insertedAttachmentIds: Map, - contacts: List - ): String? { - if (contacts.isEmpty()) return null - val sharedContactJson = JSONArray() - for (contact in contacts) { - try { - var attachmentId: AttachmentId? = null - if (contact!!.avatarAttachment != null) { - attachmentId = insertedAttachmentIds[contact.avatarAttachment] - } - val updatedAvatar = Contact.Avatar( - attachmentId, - contact.avatarAttachment, - contact.avatar != null && contact.avatar!! - .isProfile - ) - val updatedContact = Contact( - contact, updatedAvatar - ) - sharedContactJson.put(JSONObject(updatedContact.serialize())) - } catch (e: JSONException) { - Log.w(TAG, "Failed to serialize shared contact. Skipping it.", e) - } catch (e: IOException) { - Log.w(TAG, "Failed to serialize shared contact. Skipping it.", e) - } - } - return sharedContactJson.toString() - } private fun getSerializedLinkPreviews( insertedAttachmentIds: Map, @@ -1091,15 +985,11 @@ class MmsDatabase @Inject constructor( val attachments = attachmentDatabase.getAttachment( cursor ) - val contacts: List = getSharedContacts(cursor, attachments) - val contactAttachments: Set = - contacts.mapNotNull { it?.avatarAttachment }.toSet() val previews: List = getLinkPreviews(cursor, attachments) val previewAttachments: Set = previews.mapNotNull { it?.getThumbnail()?.orNull() }.toSet() val slideDeck = getSlideDeck( attachments - .filterNot { o: DatabaseAttachment? -> o in contactAttachments } .filterNot { o: DatabaseAttachment? -> o in previewAttachments } ) val quote = if (getQuote) getQuote(cursor) else null @@ -1180,6 +1070,7 @@ class MmsDatabase @Inject constructor( const val DATE_SENT: String = "date" const val DATE_RECEIVED: String = "date_received" const val MESSAGE_BOX: String = "msg_box" + @Deprecated("No longer used.") const val CONTENT_LOCATION: String = "ct_l" const val EXPIRY: String = "exp" @@ -1187,14 +1078,18 @@ class MmsDatabase @Inject constructor( const val MESSAGE_TYPE: String = "m_type" const val MESSAGE_SIZE: String = "m_size" const val STATUS: String = "st" + @Deprecated("No longer used.") const val TRANSACTION_ID: String = "tr_id" + @Deprecated("No longer used.") const val PART_COUNT: String = "part_count" + @Deprecated("No longer used.") const val NETWORK_FAILURE: String = "network_failures" const val QUOTE_ID: String = "quote_id" const val QUOTE_AUTHOR: String = "quote_author" const val QUOTE_BODY: String = "quote_body" const val QUOTE_ATTACHMENT: String = "quote_attachment" const val QUOTE_MISSING: String = "quote_missing" + @Deprecated("No longer used.") const val SHARED_CONTACTS: String = "shared_contacts" const val LINK_PREVIEWS: String = "previews" @@ -1305,7 +1200,6 @@ class MmsDatabase @Inject constructor( const val ADD_LAST_MESSAGE_INDEX: String = "CREATE INDEX mms_thread_id_date_sent_index ON $TABLE_NAME ($THREAD_ID, $DATE_SENT)" - private const val RAW_ID_WHERE: String = "$TABLE_NAME._id = ?" const val CREATE_MESSAGE_REQUEST_RESPONSE_COMMAND = "ALTER TABLE $TABLE_NAME ADD COLUMN $MESSAGE_REQUEST_RESPONSE INTEGER DEFAULT 0;" const val CREATE_REACTIONS_UNREAD_COMMAND = "ALTER TABLE $TABLE_NAME ADD COLUMN $REACTIONS_UNREAD INTEGER DEFAULT 0;" const val CREATE_REACTIONS_LAST_SEEN_COMMAND = "ALTER TABLE $TABLE_NAME ADD COLUMN $REACTIONS_LAST_SEEN INTEGER DEFAULT 0;" diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsColumns.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsColumns.java index 887ae3f58d..3ef4d48926 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsColumns.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsColumns.java @@ -15,11 +15,14 @@ public interface MmsSmsColumns { // It is NOT the address of the sender of any given message! public static final String ADDRESS = "address"; + @Deprecated(forRemoval = true) public static final String ADDRESS_DEVICE_ID = "address_device_id"; public static final String DELIVERY_RECEIPT_COUNT = "delivery_receipt_count"; public static final String READ_RECEIPT_COUNT = "read_receipt_count"; + @Deprecated(forRemoval = true) public static final String MISMATCHED_IDENTITIES = "mismatched_identities"; public static final String UNIQUE_ROW_ID = "unique_row_id"; + @Deprecated(forRemoval = true) public static final String SUBSCRIPTION_ID = "subscription_id"; public static final String EXPIRES_IN = "expires_in"; public static final String EXPIRE_STARTED = "expire_started"; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java index 559768c9ad..a881f936ae 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -26,16 +26,13 @@ import android.content.Context; import android.database.Cursor; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import net.zetetic.database.sqlcipher.SQLiteDatabase; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.session.libsession.messaging.utilities.UpdateMessageData; import org.session.libsession.utilities.Address; import org.session.libsession.utilities.GroupUtil; -import org.session.libsession.utilities.Util; import org.session.libsignal.utilities.AccountId; import org.session.libsignal.utilities.Log; import org.thoughtcrime.securesms.auth.LoginStateRepository; @@ -43,7 +40,6 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.database.model.MessageRecord; -import org.thoughtcrime.securesms.dependencies.DatabaseComponent; import java.io.Closeable; import java.util.ArrayList; @@ -51,11 +47,16 @@ import java.util.List; import java.util.Set; +import javax.inject.Inject; import javax.inject.Provider; +import javax.inject.Singleton; +import dagger.Lazy; +import dagger.hilt.android.qualifiers.ApplicationContext; import kotlin.Pair; import kotlin.Triple; +@Singleton public class MmsSmsDatabase extends Database { @SuppressWarnings("unused") @@ -65,56 +66,33 @@ public class MmsSmsDatabase extends Database { public static final String MMS_TRANSPORT = "mms"; public static final String SMS_TRANSPORT = "sms"; - private static final String[] PROJECTION = {MmsSmsColumns.ID, MmsSmsColumns.UNIQUE_ROW_ID, - SmsDatabase.BODY, SmsDatabase.TYPE, MmsSmsColumns.MESSAGE_CONTENT, - MmsSmsColumns.THREAD_ID, - SmsDatabase.ADDRESS, SmsDatabase.ADDRESS_DEVICE_ID, SmsDatabase.SUBJECT, - MmsSmsColumns.NORMALIZED_DATE_SENT, - MmsSmsColumns.NORMALIZED_DATE_RECEIVED, - MmsDatabase.MESSAGE_TYPE, MmsDatabase.MESSAGE_BOX, - SmsDatabase.STATUS, - MmsDatabase.PART_COUNT, - MmsDatabase.CONTENT_LOCATION, MmsDatabase.TRANSACTION_ID, - MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, - MmsDatabase.STATUS, - MmsSmsColumns.DELIVERY_RECEIPT_COUNT, - MmsSmsColumns.READ_RECEIPT_COUNT, - MmsSmsColumns.MISMATCHED_IDENTITIES, - MmsDatabase.NETWORK_FAILURE, - MmsSmsColumns.SUBSCRIPTION_ID, - MmsSmsColumns.EXPIRES_IN, - MmsSmsColumns.EXPIRE_STARTED, - NOTIFIED, - TRANSPORT, - AttachmentDatabase.ATTACHMENT_JSON_ALIAS, - MmsDatabase.QUOTE_ID, - MmsDatabase.QUOTE_AUTHOR, - MmsDatabase.QUOTE_BODY, - MmsDatabase.QUOTE_MISSING, - MmsDatabase.QUOTE_ATTACHMENT, - MmsDatabase.SHARED_CONTACTS, - MmsDatabase.LINK_PREVIEWS, - ReactionDatabase.REACTION_JSON_ALIAS, - MmsSmsColumns.HAS_MENTION, - MmsSmsColumns.SERVER_HASH, - MmsSmsColumns.PRO_FEATURES - }; + private static final String PROJECTION_ALL = "*"; private final LoginStateRepository loginStateRepository; + private final Lazy<@NonNull ThreadDatabase> threadDatabase; + private final Lazy<@NonNull MmsDatabase> mmsDatabase; + private final Lazy<@NonNull SmsDatabase> smsDatabase; - public MmsSmsDatabase(Context context, + @Inject + public MmsSmsDatabase(@ApplicationContext Context context, Provider databaseHelper, - LoginStateRepository loginStateRepository) { + LoginStateRepository loginStateRepository, + Lazy<@NonNull ThreadDatabase> threadDatabase, + Lazy<@NonNull MmsDatabase> mmsDatabase, + Lazy<@NonNull SmsDatabase> smsDatabase) { super(context, databaseHelper); this.loginStateRepository = loginStateRepository; + this.threadDatabase = threadDatabase; + this.mmsDatabase = mmsDatabase; + this.smsDatabase = smsDatabase; } public @Nullable MessageRecord getMessageForTimestamp(long threadId, long timestamp) { final String selection = MmsSmsColumns.NORMALIZED_DATE_SENT + " = " + timestamp + " AND " + MmsSmsColumns.THREAD_ID + " = " + threadId; - try (Cursor cursor = queryTables(PROJECTION, selection, true, null, null, null)) { + try (Cursor cursor = queryTables(PROJECTION_ALL, selection, true, null, null, null)) { MmsSmsDatabase.Reader reader = readerFor(cursor); return reader.getNext(); } @@ -123,7 +101,7 @@ public MmsSmsDatabase(Context context, public @Nullable MessageRecord getMessageById(@NonNull MessageId id) { String selection = ID + " = " + id.getId() + " AND " + TRANSPORT + " = '" + (id.isMms() ? MMS_TRANSPORT : SMS_TRANSPORT) + "'"; - try (MmsSmsDatabase.Reader reader = readerFor(queryTables(PROJECTION, selection, true, null, null, null))) { + try (MmsSmsDatabase.Reader reader = readerFor(queryTables(PROJECTION_ALL, selection, true, null, null, null))) { final MessageRecord messageRecord; if ((messageRecord = reader.getNext()) != null) { return messageRecord; @@ -141,7 +119,7 @@ public MmsSmsDatabase(Context context, String selection = MmsSmsColumns.NORMALIZED_DATE_SENT + " = " + timestamp + " AND " + MmsSmsColumns.THREAD_ID + " = " + threadId; - try (Cursor cursor = queryTables(PROJECTION, selection, true, null, null, null)) { + try (Cursor cursor = queryTables(PROJECTION_ALL, selection, true, null, null, null)) { MmsSmsDatabase.Reader reader = readerFor(cursor, getQuote); MessageRecord messageRecord; @@ -164,7 +142,7 @@ public MmsSmsDatabase(Context context, */ @Deprecated(forRemoval = true) public @Nullable MessageRecord getMessageByTimestamp(long timestamp, String serializedAuthor, boolean getQuote) { - try (Cursor cursor = queryTables(PROJECTION, MmsSmsColumns.NORMALIZED_DATE_SENT + " = " + timestamp, true, null, null, null)) { + try (Cursor cursor = queryTables(PROJECTION_ALL, MmsSmsColumns.NORMALIZED_DATE_SENT + " = " + timestamp, true, null, null, null)) { MmsSmsDatabase.Reader reader = readerFor(cursor, getQuote); MessageRecord messageRecord; @@ -187,7 +165,7 @@ public MessageId getLastSentMessageID(long threadId) { String order = MmsSmsColumns.NORMALIZED_DATE_SENT + " DESC"; String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND NOT " + MmsSmsColumns.IS_DELETED; - try (final Cursor cursor = queryTables(PROJECTION, selection, true, null, order, null)) { + try (final Cursor cursor = queryTables(PROJECTION_ALL, selection, true, null, order, null)) { try (MmsSmsDatabase.Reader reader = readerFor(cursor)) { MessageRecord messageRecord; while ((messageRecord = reader.getNext()) != null) { @@ -210,8 +188,7 @@ public Cursor getConversation(long threadId, boolean reverse, long offset, long String selection = MmsSmsColumns.THREAD_ID + " = " + threadId; String limitStr = limit > 0 || offset > 0 ? offset + ", " + limit : null; - Cursor cursor = queryTables(PROJECTION, selection, true, null, order, limitStr); - return cursor; + return queryTables(PROJECTION_ALL, selection, true, null, order, limitStr); } public Cursor getConversation(long threadId, boolean reverse) { @@ -222,11 +199,11 @@ public Cursor getConversationSnippet(long threadId) { String order = MmsSmsColumns.NORMALIZED_DATE_SENT + " DESC"; String selection = MmsSmsColumns.THREAD_ID + " = " + threadId; - return queryTables(PROJECTION, selection, true, null, order, null); + return queryTables(PROJECTION_ALL, selection, true, null, order, null); } public List getRecentChatMemberAddresses(long threadId, int limit) { - String[] projection = new String[] { "DISTINCT " + MmsSmsColumns.ADDRESS }; + String projection = "DISTINCT " + MmsSmsColumns.ADDRESS; String selection = MmsSmsColumns.THREAD_ID + " = " + threadId; String order = MmsSmsColumns.NORMALIZED_DATE_SENT + " DESC"; String limitStr = String.valueOf(limit); @@ -268,7 +245,7 @@ public Set getAllMessageRecordsFromSenderInThread(long threadId, Set identifiedMessages = new HashSet(); // Try everything with resources so that they auto-close on end of scope - try (Cursor cursor = queryTables(PROJECTION, selection, true, null, null, null)) { + try (Cursor cursor = queryTables(PROJECTION_ALL, selection, true, null, null, null)) { try (MmsSmsDatabase.Reader reader = readerFor(cursor)) { MessageRecord messageRecord; while ((messageRecord = reader.getNext()) != null) { @@ -284,7 +261,7 @@ public List> getAllMessageRecordsBefore(long threadI List> identifiedMessages = new ArrayList<>(); // Try everything with resources so that they auto-close on end of scope - try (Cursor cursor = queryTables(PROJECTION, selection, true, null, null, null)) { + try (Cursor cursor = queryTables(PROJECTION_ALL, selection, true, null, null, null)) { try (MmsSmsDatabase.Reader reader = readerFor(cursor)) { MessageRecord messageRecord; while ((messageRecord = reader.getNext()) != null) { @@ -303,7 +280,7 @@ public List> getAllMessagesWithHash(long threadId) { String selection = MmsSmsColumns.THREAD_ID + " = " + threadId; List> identifiedMessages = new ArrayList<>(); - try (Cursor cursor = queryTables(PROJECTION, selection, true, null, null, null); + try (Cursor cursor = queryTables(PROJECTION_ALL, selection, true, null, null, null); MmsSmsDatabase.Reader reader = readerFor(cursor)) { MessageRecord record; @@ -327,7 +304,7 @@ public MessageRecord getLastMessage(long threadId, boolean includeReactions, boo String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + "NOT " + MmsSmsColumns.IS_DELETED; - try (Cursor cursor = queryTables(PROJECTION, selection, includeReactions, null, order, "1")) { + try (Cursor cursor = queryTables(PROJECTION_ALL, selection, includeReactions, null, order, "1")) { return readerFor(cursor, getQuote).getNext(); } } @@ -367,7 +344,7 @@ public Cursor getUnreadIncomingForNotifications(int maxRows) { String selection = "(" + READ + " = 0 AND " + NOTIFIED + " = 0 AND NOT (" + outgoing + "))"; String order = MmsSmsColumns.NORMALIZED_DATE_SENT + " DESC"; String limitStr = maxRows > 0 ? String.valueOf(maxRows) : null; - return queryTables(PROJECTION, selection, true, null, order, limitStr); + return queryTables(PROJECTION_ALL, selection, true, null, order, limitStr); } public Cursor getOutgoingWithUnseenReactionsForNotifications(int maxRows) { @@ -382,11 +359,11 @@ public Cursor getOutgoingWithUnseenReactionsForNotifications(int maxRows) { String order = MmsSmsColumns.NORMALIZED_DATE_SENT + " DESC"; String limitStr = maxRows > 0 ? String.valueOf(maxRows) : null; - return queryTables(PROJECTION, outgoing, true, reactionSelection, order, limitStr); + return queryTables(PROJECTION_ALL, outgoing, true, reactionSelection, order, limitStr); } public Set
getAllReferencedAddresses() { - final String[] projection = new String[] { "DISTINCT " + MmsSmsColumns.ADDRESS }; + final String projection = "DISTINCT " + MmsSmsColumns.ADDRESS; final String selection = MmsSmsColumns.ADDRESS + " IS NOT NULL" + " AND " + MmsSmsColumns.ADDRESS + " != ''"; @@ -419,17 +396,14 @@ private String buildOutgoingTypesList() { public int getUnreadCount(long threadId) { String selection = READ + " = 0 AND " + NOTIFIED + " = 0 AND " + MmsSmsColumns.THREAD_ID + " = " + threadId; - Cursor cursor = queryTables(new String[] { ID }, selection, true, null, null, null); - try { + try (Cursor cursor = queryTables(ID, selection, true, null, null, null)) { return cursor != null ? cursor.getCount() : 0; - } finally { - if (cursor != null) cursor.close(); } } public void deleteGroupInfoMessage(AccountId groupId, Class kind) { - long threadId = DatabaseComponent.get(context).threadDatabase().getThreadIdIfExistsFor(groupId.getHexString()); + long threadId = threadDatabase.get().getThreadIdIfExistsFor(groupId.getHexString()); if (threadId == -1) { Log.d(TAG, "No thread found for group info message deletion"); return; @@ -447,22 +421,23 @@ public void deleteGroupInfoMessage(AccountId groupId, Class timestampAndDirectionForCurrent(@NotNull Cursor cursor) { + @NonNull + public Pair timestampAndDirectionForCurrent(@NonNull Cursor cursor) { int sentColumn = cursor.getColumnIndex(MmsSmsColumns.NORMALIZED_DATE_SENT); String msgType = cursor.getString(cursor.getColumnIndexOrThrow(TRANSPORT)); long sentTime = cursor.getLong(sentColumn); @@ -663,7 +638,7 @@ public Reader(Cursor cursor, boolean getQuote) { private SmsDatabase.Reader getSmsReader() { if (smsReader == null) { - smsReader = DatabaseComponent.get(context).smsDatabase().readerFor(cursor); + smsReader = smsDatabase.get().readerFor(cursor); } return smsReader; @@ -671,7 +646,7 @@ private SmsDatabase.Reader getSmsReader() { private MmsDatabase.Reader getMmsReader() { if (mmsReader == null) { - mmsReader = DatabaseComponent.get(context).mmsDatabase().readerFor(cursor, getQuote); + mmsReader = mmsDatabase.get().readerFor(cursor, getQuote); } return mmsReader; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabaseSQL.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabaseSQL.kt index 25c243f008..7c04ff12f2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabaseSQL.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabaseSQL.kt @@ -28,7 +28,7 @@ import org.thoughtcrime.securesms.database.model.MessageId * ``` */ fun buildMmsSmsCombinedQuery( - projections: Array, + projection: String, selection: String?, includeReactions: Boolean, reactionSelection: String?, @@ -92,32 +92,23 @@ fun buildMmsSmsCombinedQuery( ${MmsSmsColumns.THREAD_ID}, ${SmsDatabase.TYPE}, ${SmsDatabase.ADDRESS}, - ${SmsDatabase.ADDRESS_DEVICE_ID}, - ${SmsDatabase.SUBJECT}, NULL AS ${MmsDatabase.MESSAGE_TYPE}, NULL AS ${MmsDatabase.MESSAGE_BOX}, ${SmsDatabase.STATUS}, - NULL AS ${MmsDatabase.PART_COUNT}, - NULL AS ${MmsDatabase.CONTENT_LOCATION}, - NULL AS ${MmsDatabase.TRANSACTION_ID}, NULL AS ${MmsDatabase.MESSAGE_SIZE}, NULL AS ${MmsDatabase.EXPIRY}, NULL AS ${MmsDatabase.STATUS}, ${MmsSmsColumns.DELIVERY_RECEIPT_COUNT}, ${MmsSmsColumns.READ_RECEIPT_COUNT}, - ${MmsSmsColumns.MISMATCHED_IDENTITIES}, - ${MmsSmsColumns.SUBSCRIPTION_ID}, ${MmsSmsColumns.EXPIRES_IN}, ${MmsSmsColumns.EXPIRE_STARTED}, ${MmsSmsColumns.NOTIFIED}, - NULL AS ${MmsDatabase.NETWORK_FAILURE}, '${MmsSmsDatabase.SMS_TRANSPORT}' AS ${MmsSmsDatabase.TRANSPORT}, NULL AS ${MmsDatabase.QUOTE_ID}, NULL AS ${MmsDatabase.QUOTE_AUTHOR}, NULL AS ${MmsDatabase.QUOTE_BODY}, NULL AS ${MmsDatabase.QUOTE_MISSING}, NULL AS ${MmsDatabase.QUOTE_ATTACHMENT}, - NULL AS ${MmsDatabase.SHARED_CONTACTS}, NULL AS ${MmsDatabase.LINK_PREVIEWS}, ${MmsSmsColumns.HAS_MENTION}, ($smsHashQuery) AS ${MmsSmsColumns.SERVER_HASH}, @@ -191,32 +182,23 @@ fun buildMmsSmsCombinedQuery( ${MmsSmsColumns.THREAD_ID}, NULL AS ${SmsDatabase.TYPE}, ${MmsSmsColumns.ADDRESS}, - ${MmsSmsColumns.ADDRESS_DEVICE_ID}, - NULL AS ${SmsDatabase.SUBJECT}, ${MmsDatabase.MESSAGE_TYPE}, ${MmsDatabase.MESSAGE_BOX}, NULL AS ${SmsDatabase.STATUS}, - ${MmsDatabase.PART_COUNT}, - ${MmsDatabase.CONTENT_LOCATION}, - ${MmsDatabase.TRANSACTION_ID}, ${MmsDatabase.MESSAGE_SIZE}, ${MmsDatabase.EXPIRY}, ${MmsDatabase.STATUS}, ${MmsSmsColumns.DELIVERY_RECEIPT_COUNT}, ${MmsSmsColumns.READ_RECEIPT_COUNT}, - ${MmsSmsColumns.MISMATCHED_IDENTITIES}, - ${MmsSmsColumns.SUBSCRIPTION_ID}, ${MmsSmsColumns.EXPIRES_IN}, ${MmsSmsColumns.EXPIRE_STARTED}, ${MmsSmsColumns.NOTIFIED}, - ${MmsDatabase.NETWORK_FAILURE}, '${MmsSmsDatabase.MMS_TRANSPORT}' AS ${MmsSmsDatabase.TRANSPORT}, ${MmsDatabase.QUOTE_ID}, ${MmsDatabase.QUOTE_AUTHOR}, ${MmsDatabase.QUOTE_BODY}, ${MmsDatabase.QUOTE_MISSING}, ${MmsDatabase.QUOTE_ATTACHMENT}, - ${MmsDatabase.SHARED_CONTACTS}, ${MmsDatabase.LINK_PREVIEWS}, ${MmsSmsColumns.HAS_MENTION}, ($mmsHashQuery) AS ${MmsSmsColumns.SERVER_HASH}, @@ -235,7 +217,7 @@ fun buildMmsSmsCombinedQuery( $mmsQuery ) - SELECT ${projections.joinToString(", ")} + SELECT $projection FROM combined $orderStatement $limitStatement diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java index fee95babea..49e0117fd5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -22,7 +22,6 @@ import android.content.ContentValues; import android.content.Context; import android.database.Cursor; -import android.text.TextUtils; import com.annimon.stream.Stream; @@ -74,11 +73,14 @@ public class SmsDatabase extends MessagingDatabase { public static final String PERSON = "person"; static final String DATE_RECEIVED = "date"; static final String DATE_SENT = "date_sent"; + @Deprecated(forRemoval = true) public static final String PROTOCOL = "protocol"; public static final String STATUS = "status"; public static final String TYPE = "type"; + @Deprecated(forRemoval = true) public static final String REPLY_PATH_PRESENT = "reply_path_present"; public static final String SUBJECT = "subject"; + @Deprecated(forRemoval = true) public static final String SERVICE_CENTER = "service_center"; private static final String IS_DELETED_COLUMN_DEF = IS_DELETED + " GENERATED ALWAYS AS ((" + TYPE + @@ -103,14 +105,14 @@ public class SmsDatabase extends MessagingDatabase { "CREATE INDEX IF NOT EXISTS sms_thread_date_index ON " + TABLE_NAME + " (" + THREAD_ID + ", " + DATE_RECEIVED + ");" }; - public static String CREATE_REACTIONS_UNREAD_COMMAND = "ALTER TABLE "+ TABLE_NAME + " " + + public static final String CREATE_REACTIONS_UNREAD_COMMAND = "ALTER TABLE "+ TABLE_NAME + " " + "ADD COLUMN " + REACTIONS_UNREAD + " INTEGER DEFAULT 0;"; - public static String CREATE_HAS_MENTION_COMMAND = "ALTER TABLE "+ TABLE_NAME + " " + + public static final String CREATE_HAS_MENTION_COMMAND = "ALTER TABLE "+ TABLE_NAME + " " + "ADD COLUMN " + HAS_MENTION + " INTEGER DEFAULT 0;"; - private static String COMMA_SEPARATED_COLUMNS = ID + ", " + THREAD_ID + ", " + ADDRESS + ", " + ADDRESS_DEVICE_ID + ", " + PERSON + ", " + DATE_RECEIVED + ", " + DATE_SENT + ", " + PROTOCOL + ", " + READ + ", " + STATUS + ", " + TYPE + ", " + REPLY_PATH_PRESENT + ", " + DELIVERY_RECEIPT_COUNT + ", " + SUBJECT + ", " + BODY + ", " + MISMATCHED_IDENTITIES + ", " + SERVICE_CENTER + ", " + SUBSCRIPTION_ID + ", " + EXPIRES_IN + ", " + EXPIRE_STARTED + ", " + NOTIFIED + ", " + READ_RECEIPT_COUNT + ", " + UNIDENTIFIED + ", " + REACTIONS_UNREAD + ", " + HAS_MENTION; - private static String TEMP_TABLE_NAME = "TEMP_TABLE_NAME"; + private static final String COMMA_SEPARATED_COLUMNS = ID + ", " + THREAD_ID + ", " + ADDRESS + ", " + ADDRESS_DEVICE_ID + ", " + PERSON + ", " + DATE_RECEIVED + ", " + DATE_SENT + ", " + PROTOCOL + ", " + READ + ", " + STATUS + ", " + TYPE + ", " + REPLY_PATH_PRESENT + ", " + DELIVERY_RECEIPT_COUNT + ", " + SUBJECT + ", " + BODY + ", " + MISMATCHED_IDENTITIES + ", " + SERVICE_CENTER + ", " + SUBSCRIPTION_ID + ", " + EXPIRES_IN + ", " + EXPIRE_STARTED + ", " + NOTIFIED + ", " + READ_RECEIPT_COUNT + ", " + UNIDENTIFIED + ", " + REACTIONS_UNREAD + ", " + HAS_MENTION; + private static final String TEMP_TABLE_NAME = "TEMP_TABLE_NAME"; public static final String[] ADD_AUTOINCREMENT = new String[]{ "ALTER TABLE " + TABLE_NAME + " RENAME TO " + TEMP_TABLE_NAME, @@ -169,42 +171,27 @@ public long getThreadIdForMessage(long id) { String[] sqlArgs = new String[] {id+""}; SQLiteDatabase db = getReadableDatabase(); - Cursor cursor = null; - - try { - cursor = db.rawQuery(sql, sqlArgs); - if (cursor != null && cursor.moveToFirst()) - return cursor.getLong(0); - else - return -1; - } finally { - if (cursor != null) - cursor.close(); + try (Cursor cursor = db.rawQuery(sql, sqlArgs)) { + if (cursor != null && cursor.moveToFirst()) + return cursor.getLong(0); + else + return -1; } } public int getMessageCountForThread(long threadId) { SQLiteDatabase db = getReadableDatabase(); - Cursor cursor = null; - try { - cursor = db.query(TABLE_NAME, new String[] {"COUNT(*)"}, THREAD_ID + " = ?", - new String[] {threadId+""}, null, null, null); + try (Cursor cursor = db.query(TABLE_NAME, new String[]{"COUNT(*)"}, THREAD_ID + " = ?", + new String[]{threadId + ""}, null, null, null)) { - if (cursor != null && cursor.moveToFirst()) - return cursor.getInt(0); - } finally { - if (cursor != null) - cursor.close(); + if (cursor != null && cursor.moveToFirst()) + return cursor.getInt(0); } return 0; } - public void markAsDecryptFailed(long id) { - updateTypeBitmask(id, Types.ENCRYPTION_MASK, Types.ENCRYPTION_REMOTE_FAILED_BIT); - } - @Override public void markAsSent(long id, boolean isSent) { updateTypeBitmask(id, Types.BASE_TYPE_MASK, Types.BASE_SENT_TYPE | (isSent ? Types.PUSH_MESSAGE_BIT | Types.SECURE_MESSAGE_BIT : 0)); @@ -370,19 +357,11 @@ public List setMessagesRead(long threadId) { return setMessagesRead(THREAD_ID + " = ? AND (" + READ + " = 0)", new String[] {String.valueOf(threadId)}); } - public List setAllMessagesRead() { - return setMessagesRead(READ + " = 0", null); - } - private List setMessagesRead(String where, String[] arguments) { SQLiteDatabase database = getWritableDatabase(); List results = new LinkedList<>(); - Cursor cursor = null; - database.beginTransaction(); - try { - cursor = database.query(TABLE_NAME, new String[] {ID, ADDRESS, DATE_SENT, TYPE, EXPIRES_IN, EXPIRE_STARTED}, where, arguments, null, null, null); - + try (final Cursor cursor = database.query(TABLE_NAME, new String[] {ID, ADDRESS, DATE_SENT, TYPE, EXPIRES_IN, EXPIRE_STARTED}, where, arguments, null, null, null)) { while (cursor != null && cursor.moveToNext()) { long timestamp = cursor.getLong(2); SyncMessageId syncMessageId = new SyncMessageId(Address.fromSerialized(cursor.getString(1)), timestamp); @@ -398,7 +377,6 @@ private List setMessagesRead(String where, String[] arguments database.update(TABLE_NAME, contentValues, where, arguments); database.setTransactionSuccessful(); } finally { - if (cursor != null) cursor.close(); database.endTransaction(); } @@ -440,25 +418,15 @@ protected Optional insertMessageInbox(IncomingTextMessage message, ContentValues values = new ContentValues(6); values.put(ADDRESS, message.getSender().toString()); - values.put(ADDRESS_DEVICE_ID, message.getSenderDeviceId()); // In open groups messages should be sorted by their server timestamp long receivedTimestamp = serverTimestamp; if (serverTimestamp == 0) { receivedTimestamp = message.getSentTimestampMillis(); } values.put(DATE_RECEIVED, receivedTimestamp); // Loki - This is important due to how we handle GIFs values.put(DATE_SENT, message.getSentTimestampMillis()); - values.put(PROTOCOL, message.getProtocol()); values.put(READ, unread ? 0 : 1); - values.put(SUBSCRIPTION_ID, message.getSubscriptionId()); values.put(EXPIRES_IN, message.getExpiresInMillis()); values.put(EXPIRE_STARTED, message.getExpireStartedAt()); - values.put(UNIDENTIFIED, message.getUnidentified()); values.put(HAS_MENTION, message.getHasMention()); - - if (!TextUtils.isEmpty(message.getPseudoSubject())) - values.put(SUBJECT, message.getPseudoSubject()); - - values.put(REPLY_PATH_PRESENT, message.getReplyPathPresent()); - values.put(SERVICE_CENTER, message.getServiceCenterAddress()); values.put(BODY, message.getMessage()); values.put(TYPE, type); values.put(THREAD_ID, threadId); @@ -539,7 +507,6 @@ public long insertMessageOutbox(long threadId, OutgoingTextMessage message, contentValues.put(DATE_SENT, message.getSentTimestampMillis()); contentValues.put(READ, 1); contentValues.put(TYPE, type); - contentValues.put(SUBSCRIPTION_ID, message.getSubscriptionId()); contentValues.put(EXPIRES_IN, message.getExpiresInMillis()); contentValues.put(EXPIRE_STARTED, message.getExpireStartedAtMillis()); contentValues.put(DELIVERY_RECEIPT_COUNT, Stream.of(earlyDeliveryReceipts.values()).mapToLong(Long::longValue).sum()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 35ccd55c86..3cfbd203aa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -806,7 +806,6 @@ open class Storage @Inject constructor( expireStartedAtMillis = expireStartedAt, isGroupUpdateMessage = true, quote = null, - contacts = listOf(), previews = listOf(), messageContent = null ) @@ -824,17 +823,15 @@ open class Storage @Inject constructor( return MessageId(infoMessageID, mms = true) } else { val m = IncomingTextMessage( + message = inviteJson, sender = fromSerialized(senderPublicKey), - senderDeviceId = 1, sentTimestampMillis = sentTimestamp, - message = inviteJson, group = Address.Group(closedGroup), + push = true, expiresInMillis = expiresInMillis, expireStartedAt = expireStartedAt, - unidentified = true, - hasMention = false, - push = true, callType = -1, + hasMention = false, isOpenGroupInvitation = false, isSecureMessage = false, proFeatures = ProFeatures.NONE, @@ -1047,7 +1044,6 @@ open class Storage @Inject constructor( val mediaMessage = IncomingMediaMessage( address, sentTimestamp, - -1, expiresInMillis, expireStartedAt, false, @@ -1059,7 +1055,6 @@ open class Storage @Inject constructor( null, null, emptyList(), - emptyList(), message ) @@ -1075,7 +1070,6 @@ open class Storage @Inject constructor( val message = IncomingMediaMessage( from = fromSerialized(userPublicKey), sentTimeMillis = clock.currentTimeMills(), - subscriptionId = -1, expiresIn = 0, expireStartedAt = 0, isMessageRequestResponse = true, @@ -1086,7 +1080,6 @@ open class Storage @Inject constructor( proFeatures = ProFeatures.NONE, messageContent = null, quote = null, - sharedContacts = emptyList(), linkPreviews = emptyList(), dataExtractionNotification = null ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java index 8c85d55df5..068ab51fbc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -38,7 +38,6 @@ import org.session.libsession.utilities.AddressKt; import org.session.libsession.utilities.ConfigFactoryProtocol; import org.session.libsession.utilities.ConfigFactoryProtocolKt; -import org.session.libsession.utilities.DistributionTypes; import org.session.libsession.utilities.GroupUtil; import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.Util; @@ -57,7 +56,6 @@ import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.SlideDeck; import org.thoughtcrime.securesms.notifications.MarkReadProcessor; -import org.thoughtcrime.securesms.notifications.MarkReadReceiver; import org.thoughtcrime.securesms.util.SharedConfigUtilsKt; import java.io.Closeable; @@ -493,22 +491,6 @@ public void setCreationDates(@NonNull final Map dates) { } } - public int getDistributionType(long threadId) { - SQLiteDatabase db = getReadableDatabase(); - Cursor cursor = db.query(TABLE_NAME, new String[]{DISTRIBUTION_TYPE}, ID_WHERE, new String[]{String.valueOf(threadId)}, null, null, null); - - try { - if (cursor != null && cursor.moveToNext()) { - return cursor.getInt(cursor.getColumnIndexOrThrow(DISTRIBUTION_TYPE)); - } - - return DistributionTypes.DEFAULT; - } finally { - if (cursor != null) cursor.close(); - } - - } - @NonNull public List getThreads(@Nullable Collection addresses) { if (addresses == null || addresses.isEmpty()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java index 3d3f775263..3bd0c62eec 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/MessageRecord.java @@ -31,8 +31,6 @@ import org.session.libsession.messaging.utilities.UpdateMessageData; import org.session.libsession.utilities.Address; import org.session.libsession.utilities.AddressKt; -import org.session.libsession.utilities.IdentityKeyMismatch; -import org.session.libsession.utilities.NetworkFailure; import org.session.libsession.utilities.ThemeUtil; import org.session.libsession.utilities.recipients.Recipient; import org.session.libsignal.utilities.AccountId; diff --git a/app/src/main/java/org/thoughtcrime/securesms/debugmenu/DebugMenu.kt b/app/src/main/java/org/thoughtcrime/securesms/debugmenu/DebugMenu.kt index 1212c0c5b1..abeee2c813 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/debugmenu/DebugMenu.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/debugmenu/DebugMenu.kt @@ -53,6 +53,8 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import network.loki.messenger.BuildConfig import network.loki.messenger.R +import network.loki.messenger.libsession_util.protocol.ProFeature +import network.loki.messenger.libsession_util.protocol.ProFeatures import org.session.libsession.messaging.groups.LegacyGroupDeprecationManager import org.thoughtcrime.securesms.debugmenu.DebugMenuViewModel.Commands.ChangeEnvironment import org.thoughtcrime.securesms.debugmenu.DebugMenuViewModel.Commands.ClearTrustedDownloads @@ -348,45 +350,21 @@ fun DebugMenu( ) AnimatedVisibility(uiState.forceIncomingMessagesAsPro) { - Column{ - DebugCheckboxRow( - text = "Message Feature: Pro Badge", - minHeight = 30.dp, - checked = uiState.messageProFeature.contains(ProStatusManager.MessageProFeature.ProBadge), - onCheckedChange = { - sendCommand( - DebugMenuViewModel.Commands.SetMessageProFeature( - ProStatusManager.MessageProFeature.ProBadge, it - ) - ) - } - ) - - DebugCheckboxRow( - text = "Message Feature: Long Message", - minHeight = 30.dp, - checked = uiState.messageProFeature.contains(ProStatusManager.MessageProFeature.LongMessage), - onCheckedChange = { - sendCommand( - DebugMenuViewModel.Commands.SetMessageProFeature( - ProStatusManager.MessageProFeature.LongMessage, it - ) - ) - } - ) - - DebugCheckboxRow( - text = "Message Feature: Animated Avatar", - minHeight = 30.dp, - checked = uiState.messageProFeature.contains(ProStatusManager.MessageProFeature.AnimatedAvatar), - onCheckedChange = { - sendCommand( - DebugMenuViewModel.Commands.SetMessageProFeature( - ProStatusManager.MessageProFeature.AnimatedAvatar, it + Column { + for (feature in ProFeature.entries) { + DebugCheckboxRow( + text = "Message Feature: ${feature.name}", + minHeight = 30.dp, + checked = uiState.messageProFeature.contains(feature), + onCheckedChange = { + sendCommand( + DebugMenuViewModel.Commands.SetMessageProFeature( + feature, it + ) ) - ) - } - ) + } + ) + } } } @@ -873,7 +851,7 @@ fun PreviewDebugMenu() { forceOtherUsersAsPro = false, forcePostPro = false, forceShortTTl = false, - messageProFeature = setOf(ProStatusManager.MessageProFeature.AnimatedAvatar), + messageProFeature = ProFeatures.from(listOf(ProFeature.ANIMATED_AVATAR)), dbInspectorState = DebugMenuViewModel.DatabaseInspectorState.STARTED, debugSubscriptionStatuses = setOf(DebugMenuViewModel.DebugSubscriptionStatus.AUTO_GOOGLE), selectedDebugSubscriptionStatus = DebugMenuViewModel.DebugSubscriptionStatus.AUTO_GOOGLE, diff --git a/app/src/main/java/org/thoughtcrime/securesms/debugmenu/DebugMenuViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/debugmenu/DebugMenuViewModel.kt index e2fcd316fc..084466c707 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/debugmenu/DebugMenuViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/debugmenu/DebugMenuViewModel.kt @@ -25,6 +25,8 @@ import kotlinx.coroutines.withContext import network.loki.messenger.libsession_util.ConfigBase.Companion.PRIORITY_HIDDEN import network.loki.messenger.libsession_util.ConfigBase.Companion.PRIORITY_VISIBLE import network.loki.messenger.libsession_util.ED25519 +import network.loki.messenger.libsession_util.protocol.ProFeature +import network.loki.messenger.libsession_util.protocol.ProFeatures import network.loki.messenger.libsession_util.util.BlindKeyAPI import org.session.libsession.database.StorageProtocol import org.session.libsession.messaging.file_server.FileServer @@ -44,7 +46,6 @@ import org.thoughtcrime.securesms.database.AttachmentDatabase import org.thoughtcrime.securesms.database.RecipientSettingsDatabase import org.thoughtcrime.securesms.database.model.ThreadRecord import org.thoughtcrime.securesms.dependencies.ConfigFactory -import org.thoughtcrime.securesms.pro.ProStatusManager import org.thoughtcrime.securesms.pro.subscription.SubscriptionManager import org.thoughtcrime.securesms.repository.ConversationRepository import org.thoughtcrime.securesms.tokenpage.TokenPageNotificationManager @@ -341,11 +342,12 @@ class DebugMenuViewModel @AssistedInject constructor( } is Commands.SetMessageProFeature -> { - val features = _uiState.value.messageProFeature.toMutableSet() + val features = _uiState.value.messageProFeature.toSet().toMutableSet() if(command.set) features.add(command.feature) else features.remove(command.feature) - textSecurePreferences.setDebugMessageFeatures(features) + val newFeatures = ProFeatures.from(features) + textSecurePreferences.setDebugMessageFeatures(newFeatures) _uiState.update { - it.copy(messageProFeature = features) + it.copy(messageProFeature = newFeatures) } } @@ -554,7 +556,7 @@ class DebugMenuViewModel @AssistedInject constructor( val forceCurrentUserAsPro: Boolean, val forceOtherUsersAsPro: Boolean, val forceIncomingMessagesAsPro: Boolean, - val messageProFeature: Set, + val messageProFeature: ProFeatures, val forcePostPro: Boolean, val forceShortTTl: Boolean, val forceDeprecationState: LegacyGroupDeprecationManager.DeprecationState?, @@ -615,7 +617,7 @@ class DebugMenuViewModel @AssistedInject constructor( data class WithinQuickRefund(val set: Boolean) : Commands() data class ForcePostPro(val set: Boolean) : Commands() data class ForceShortTTl(val set: Boolean) : Commands() - data class SetMessageProFeature(val feature: ProStatusManager.MessageProFeature, val set: Boolean) : Commands() + data class SetMessageProFeature(val feature: ProFeature, val set: Boolean) : Commands() data class ShowDeprecationChangeDialog(val state: LegacyGroupDeprecationManager.DeprecationState?) : Commands() object HideDeprecationChangeDialog : Commands() object OverrideDeprecationState : Commands() diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt index 08ec99a3d8..d4bd5bd54a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt @@ -30,7 +30,6 @@ interface DatabaseComponent { fun threadDatabase(): ThreadDatabase fun mmsSmsDatabase(): MmsSmsDatabase fun groupDatabase(): GroupDatabase - fun recipientDatabase(): RecipientDatabase fun lokiAPIDatabase(): LokiAPIDatabase fun lokiMessageDatabase(): LokiMessageDatabase fun reactionDatabase(): ReactionDatabase diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt index 3e893df342..7fd87b5397 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt @@ -6,13 +6,10 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent -import org.session.libsession.database.MessageDataProvider -import org.thoughtcrime.securesms.attachments.DatabaseAttachmentProvider import org.thoughtcrime.securesms.auth.LoginStateRepository import org.thoughtcrime.securesms.crypto.AttachmentSecret import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider import org.thoughtcrime.securesms.database.AttachmentDatabase -import org.thoughtcrime.securesms.database.BlindedIdMappingDatabase import org.thoughtcrime.securesms.database.ConfigDatabase import org.thoughtcrime.securesms.database.DraftDatabase import org.thoughtcrime.securesms.database.EmojiSearchDatabase @@ -23,14 +20,11 @@ import org.thoughtcrime.securesms.database.GroupReceiptDatabase import org.thoughtcrime.securesms.database.LokiAPIDatabase import org.thoughtcrime.securesms.database.LokiBackupFilesDatabase import org.thoughtcrime.securesms.database.LokiMessageDatabase -import org.thoughtcrime.securesms.database.LokiUserDatabase import org.thoughtcrime.securesms.database.MediaDatabase -import org.thoughtcrime.securesms.database.MmsSmsDatabase import org.thoughtcrime.securesms.database.PushDatabase import org.thoughtcrime.securesms.database.ReactionDatabase import org.thoughtcrime.securesms.database.RecipientDatabase import org.thoughtcrime.securesms.database.SearchDatabase -import org.thoughtcrime.securesms.database.SessionContactDatabase import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.migration.DatabaseMigrationManager import javax.inject.Provider @@ -65,15 +59,11 @@ object DatabaseModule { fun provideMediaDatbase(@ApplicationContext context: Context, openHelper: Provider) = MediaDatabase(context, openHelper) - @Provides - @Singleton - fun provideMmsSms(@ApplicationContext context: Context, openHelper: Provider, loginStateRepository: LoginStateRepository) - = MmsSmsDatabase(context, openHelper, loginStateRepository) - @Provides @Singleton fun provideDraftDatabase(@ApplicationContext context: Context, openHelper: Provider) = DraftDatabase(context, openHelper) + @Provides @Singleton fun providePushDatabase(@ApplicationContext context: Context, openHelper: Provider) = PushDatabase(context,openHelper) @@ -83,10 +73,6 @@ object DatabaseModule { fun provideGroupDatabase(@ApplicationContext context: Context, openHelper: Provider, loginStateRepository: LoginStateRepository) = GroupDatabase(context,openHelper, loginStateRepository) - @Provides - @Singleton - fun provideRecipientDatabase(@ApplicationContext context: Context, openHelper: Provider) = RecipientDatabase(context,openHelper) - @Provides @Singleton fun provideGroupReceiptDatabase(@ApplicationContext context: Context, openHelper: Provider) = GroupReceiptDatabase(context,openHelper) @@ -103,23 +89,12 @@ object DatabaseModule { @Singleton fun provideLokiMessageDatabase(@ApplicationContext context: Context, openHelper: Provider) = LokiMessageDatabase(context,openHelper) - @Provides - @Singleton - fun provideLokiUserDatabase(@ApplicationContext context: Context, openHelper: Provider) = LokiUserDatabase(context,openHelper) @Provides @Singleton fun provideLokiBackupFilesDatabase(@ApplicationContext context: Context, openHelper: Provider) = LokiBackupFilesDatabase(context,openHelper) - @Provides - @Singleton - fun provideSessionContactDatabase(@ApplicationContext context: Context, openHelper: Provider) = SessionContactDatabase(context,openHelper) - - @Provides - @Singleton - fun provideBlindedIdMappingDatabase(@ApplicationContext context: Context, openHelper: Provider) = BlindedIdMappingDatabase(context, openHelper) - @Provides @Singleton fun provideGroupMemberDatabase(@ApplicationContext context: Context, openHelper: Provider) = GroupMemberDatabase(context, openHelper) diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadProcessor.kt index ba0795b630..04cfd04597 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadProcessor.kt @@ -9,7 +9,6 @@ import org.session.libsession.database.userAuth import org.session.libsession.messaging.messages.control.ReadReceipt import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.snode.SnodeAPI -import org.session.libsession.snode.SnodeAPI.nowWithOffset import org.session.libsession.snode.SnodeClock import org.session.libsession.utilities.TextSecurePreferences.Companion.isReadReceiptsEnabled import org.session.libsession.utilities.associateByNotNull @@ -18,12 +17,14 @@ import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.RecipientData import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.conversation.disappearingmessages.ExpiryType +import org.thoughtcrime.securesms.database.LokiMessageDatabase import org.thoughtcrime.securesms.database.MarkedMessageInfo +import org.thoughtcrime.securesms.database.MmsDatabase import org.thoughtcrime.securesms.database.MmsSmsDatabase import org.thoughtcrime.securesms.database.RecipientRepository +import org.thoughtcrime.securesms.database.SmsDatabase import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.database.model.content.DisappearingMessageUpdate -import org.thoughtcrime.securesms.dependencies.DatabaseComponent import javax.inject.Inject class MarkReadProcessor @Inject constructor( @@ -31,9 +32,12 @@ class MarkReadProcessor @Inject constructor( private val recipientRepository: RecipientRepository, private val messageSender: MessageSender, private val mmsSmsDatabase: MmsSmsDatabase, + private val mmsDatabase: MmsDatabase, + private val smsDatabase: SmsDatabase, private val threadDb: ThreadDatabase, private val storage: StorageProtocol, private val snodeClock: SnodeClock, + private val lokiMessageDatabase: LokiMessageDatabase, ) { fun process( markedReadMessages: List @@ -55,12 +59,12 @@ class MarkReadProcessor @Inject constructor( } .forEach { val db = if (it.expirationInfo.id.mms) { - DatabaseComponent.get(context).mmsDatabase() + mmsDatabase } else { - DatabaseComponent.get(context).smsDatabase() + smsDatabase } - db.markExpireStarted(it.expirationInfo.id.id, nowWithOffset) + db.markExpireStarted(it.expirationInfo.id.id, snodeClock.currentTimeMills()) } hashToDisappearAfterReadMessage(context, markedReadMessages)?.let { hashToMessages -> @@ -78,11 +82,9 @@ class MarkReadProcessor @Inject constructor( context: Context, markedReadMessages: List ): Map? { - val loki = DatabaseComponent.get(context).lokiMessageDatabase() - return markedReadMessages .filter { it.expiryType == ExpiryType.AFTER_READ } - .associateByNotNull { it.expirationInfo.run { loki.getMessageServerHash(id) } } + .associateByNotNull { it.expirationInfo.run { lokiMessageDatabase.getMessageServerHash(id) } } .takeIf { it.isNotEmpty() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/pro/ProStatusManager.kt b/app/src/main/java/org/thoughtcrime/securesms/pro/ProStatusManager.kt index 55c2cbb49f..8596c696af 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/pro/ProStatusManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/pro/ProStatusManager.kt @@ -1,7 +1,5 @@ package org.thoughtcrime.securesms.pro -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -21,6 +19,7 @@ import kotlinx.coroutines.withTimeout import network.loki.messenger.libsession_util.pro.BackendRequests import network.loki.messenger.libsession_util.pro.BackendRequests.PAYMENT_PROVIDER_APP_STORE import network.loki.messenger.libsession_util.pro.BackendRequests.PAYMENT_PROVIDER_GOOGLE_PLAY +import network.loki.messenger.libsession_util.protocol.ProFeatures import org.session.libsession.messaging.messages.visible.VisibleMessage import org.session.libsession.snode.SnodeClock import org.session.libsession.utilities.TextSecurePreferences @@ -28,7 +27,8 @@ import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.auth.LoginStateRepository import org.thoughtcrime.securesms.database.RecipientRepository -import org.thoughtcrime.securesms.database.model.MessageId +import org.thoughtcrime.securesms.database.model.MessageRecord +import org.thoughtcrime.securesms.database.model.proFeatures import org.thoughtcrime.securesms.debugmenu.DebugLogGroup import org.thoughtcrime.securesms.debugmenu.DebugMenuViewModel import org.thoughtcrime.securesms.dependencies.ManagerScope @@ -48,7 +48,6 @@ import javax.inject.Singleton @Singleton class ProStatusManager @Inject constructor( - @ApplicationContext private val context: Context, private val prefs: TextSecurePreferences, recipientRepository: RecipientRepository, @param:ManagerScope private val scope: CoroutineScope, @@ -196,42 +195,40 @@ class ProStatusManager @Inject constructor( /** * This will calculate the pro features of an outgoing message */ - fun calculateMessageProFeatures(isPro: Boolean, shouldShowProBadge: Boolean, message: String): List{ - if (!isPro){ - return emptyList() - } - - val features = mutableListOf() - - // check for pro badge display - if (shouldShowProBadge){ - features.add(MessageProFeature.ProBadge) - } - - // check for "long message" feature - if(message.length > MAX_CHARACTER_REGULAR){ - features.add(MessageProFeature.LongMessage) - } + fun calculateMessageProFeatures(isPro: Boolean, shouldShowProBadge: Boolean, message: String) { +// if (!isPro){ +// return emptyList() +// } +// +// val features = mutableListOf() +// +// // check for pro badge display +// if (shouldShowProBadge){ +// features.add(MessageProFeature.ProBadge) +// } +// +// // check for "long message" feature +// if(message.length > MAX_CHARACTER_REGULAR){ +// features.add(MessageProFeature.LongMessage) +// } // check is the user has an animated avatar //todo PRO check for animated avatar here and add appropriate feature - return features +// return features } /** * This will get the list of Pro features from an incoming message */ - fun getMessageProFeatures(messageId: MessageId): Set{ - //todo PRO implement once we have data - + fun getMessageProFeatures(message: MessageRecord): ProFeatures { // use debug values if any if(prefs.forceIncomingMessagesAsPro()){ return prefs.getDebugMessageFeatures() } - return emptySet() + return message.proFeatures } @OptIn(ExperimentalCoroutinesApi::class) @@ -306,10 +303,6 @@ class ProStatusManager @Inject constructor( throw SubscriptionManager.PaymentServerException() } - enum class MessageProFeature { - ProBadge, LongMessage, AnimatedAvatar - } - companion object { const val MAX_CHARACTER_PRO = 10000 // max characters in a message for pro users private const val MAX_CHARACTER_REGULAR = 2000 // max characters in a message for non pro users diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.kt b/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.kt index 9e31662708..98c9453f8a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.kt @@ -18,10 +18,7 @@ import org.session.libsession.snode.SnodeClock import org.session.libsession.utilities.Address import org.session.libsession.utilities.Address.Companion.fromSerialized import org.session.libsession.utilities.Address.Companion.toAddress -import org.session.libsession.utilities.DistributionTypes -import org.session.libsession.utilities.GroupUtil.doubleEncodeGroupID import org.session.libsession.utilities.SSKEnvironment.MessageExpirationManagerProtocol -import org.session.libsignal.utilities.IdPrefix import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.auth.LoginStateRepository import org.thoughtcrime.securesms.database.MessagingDatabase @@ -95,7 +92,6 @@ class ExpiringMessageManager @Inject constructor( val mediaMessage = IncomingMediaMessage( from = address, sentTimeMillis = sentTimestamp!!, - subscriptionId = -1, expiresIn = expiresInMillis, expireStartedAt = 0, // Marking expiryStartedAt as 0 as expiration logic will be universally applied on received messages // We no longer set this to true anymore as it won't be used in the future, @@ -107,7 +103,6 @@ class ExpiringMessageManager @Inject constructor( proFeatures = ProFeatures.NONE, messageContent = DisappearingMessageUpdate(message.expiryMode), quote = null, - sharedContacts = emptyList(), linkPreviews = emptyList(), dataExtractionNotification = null ) @@ -145,7 +140,6 @@ class ExpiringMessageManager @Inject constructor( expireStartedAtMillis = 0, // Marking as 0 as expiration shouldn't start until we send the message isGroupUpdateMessage = false, quote = null, - contacts = emptyList(), previews = emptyList(), messageContent = content ) else OutgoingMediaMessage( @@ -153,15 +147,10 @@ class ExpiringMessageManager @Inject constructor( body = "", attachments = emptyList(), sentTimeMillis = sentTimestamp!!, - distributionType = DistributionTypes.CONVERSATION, - subscriptionId = -1, expiresInMillis = duration, expireStartedAtMillis = 0, // Marking as 0 as expiration shouldn't start until we send the message outgoingQuote = null, messageContent = content, - networkFailures = emptyList(), - identityKeyMismatches = emptyList(), - contacts = emptyList(), linkPreviews = emptyList(), group = null, isGroupUpdateMessage = false