Add pre-release config flag and client version detection

This commit is contained in:
charles 2022-12-08 13:38:53 +11:00
parent b06ef713c2
commit d70bfe5614
9 changed files with 62 additions and 10 deletions

View File

@ -53,6 +53,7 @@ import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.messaging.mentions.Mention import org.session.libsession.messaging.mentions.Mention
import org.session.libsession.messaging.mentions.MentionsManager import org.session.libsession.messaging.mentions.MentionsManager
import org.session.libsession.messaging.messages.ExpirationConfiguration
import org.session.libsession.messaging.messages.control.DataExtractionNotification import org.session.libsession.messaging.messages.control.DataExtractionNotification
import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage
import org.session.libsession.messaging.messages.signal.OutgoingTextMessage import org.session.libsession.messaging.messages.signal.OutgoingTextMessage
@ -570,7 +571,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
private fun setUpOutdatedClientBanner() { private fun setUpOutdatedClientBanner() {
val recipient = viewModel.recipient ?: return val recipient = viewModel.recipient ?: return
if (recipient.expireMessages == 0) { return } if (recipient.expireMessages == 0 || !ExpirationConfiguration.isNewConfigEnabled) { return }
binding?.outdatedBannerTextView?.text = binding?.outdatedBannerTextView?.text =
resources.getString(R.string.activity_conversation_outdated_client_banner_text, recipient.name) resources.getString(R.string.activity_conversation_outdated_client_banner_text, recipient.name)
binding?.outdatedBanner?.isVisible = true binding?.outdatedBanner?.isVisible = true

View File

@ -13,6 +13,7 @@ import com.annimon.stream.Stream;
import net.sqlcipher.database.SQLiteDatabase; import net.sqlcipher.database.SQLiteDatabase;
import org.jetbrains.annotations.NotNull;
import org.session.libsession.utilities.Address; import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.MaterialColor; import org.session.libsession.utilities.MaterialColor;
import org.session.libsession.utilities.Util; import org.session.libsession.utilities.Util;
@ -47,6 +48,7 @@ public class RecipientDatabase extends Database {
private static final String SEEN_INVITE_REMINDER = "seen_invite_reminder"; private static final String SEEN_INVITE_REMINDER = "seen_invite_reminder";
private static final String DEFAULT_SUBSCRIPTION_ID = "default_subscription_id"; private static final String DEFAULT_SUBSCRIPTION_ID = "default_subscription_id";
static final String EXPIRE_MESSAGES = "expire_messages"; static final String EXPIRE_MESSAGES = "expire_messages";
private static final String DISAPPEARING_STATE = "disappearing_state";
private static final String REGISTERED = "registered"; private static final String REGISTERED = "registered";
private static final String PROFILE_KEY = "profile_key"; private static final String PROFILE_KEY = "profile_key";
private static final String SYSTEM_DISPLAY_NAME = "system_display_name"; private static final String SYSTEM_DISPLAY_NAME = "system_display_name";
@ -415,6 +417,14 @@ public class RecipientDatabase extends Database {
return returnList; return returnList;
} }
public void setDisappearingState(@NotNull Recipient recipient, @NotNull Recipient.DisappearingState disappearingState) {
ContentValues values = new ContentValues();
values.put(DISAPPEARING_STATE, disappearingState.getId());
updateOrInsert(recipient.getAddress(), values);
recipient.resolve().setDisappearingState(disappearingState);
notifyRecipientListeners();
}
public static class RecipientReader implements Closeable { public static class RecipientReader implements Closeable {
private final Context context; private final Context context;

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.net.Uri import android.net.Uri
import org.session.libsession.database.StorageProtocol import org.session.libsession.database.StorageProtocol
import org.session.libsession.messaging.BlindedIdMapping import org.session.libsession.messaging.BlindedIdMapping
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.calls.CallMessageType import org.session.libsession.messaging.calls.CallMessageType
import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.messaging.jobs.AttachmentUploadJob import org.session.libsession.messaging.jobs.AttachmentUploadJob
@ -974,4 +975,8 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
return emptyList() return emptyList()
} }
override fun updateDisappearingState(address: String, disappearingState: Recipient.DisappearingState) {
val recipient = Recipient.from(MessagingModuleConfiguration.shared.context, fromSerialized(address), false)
DatabaseComponent.get(context).recipientDatabase().setDisappearingState(recipient, disappearingState);
}
} }

View File

@ -202,4 +202,5 @@ interface StorageProtocol {
fun getExpirationConfiguration(threadId: Long): ExpirationConfiguration? fun getExpirationConfiguration(threadId: Long): ExpirationConfiguration?
fun addExpirationConfiguration(config: ExpirationConfiguration) fun addExpirationConfiguration(config: ExpirationConfiguration)
fun getExpiringMessages(messageIds: LongArray): List<Pair<String, Int>> fun getExpiringMessages(messageIds: LongArray): List<Pair<String, Int>>
fun updateDisappearingState(address: String, disappearingState: Recipient.DisappearingState)
} }

View File

@ -1,6 +1,7 @@
package org.session.libsession.messaging.jobs package org.session.libsession.messaging.jobs
import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.messages.ExpirationConfiguration
import org.session.libsession.messaging.messages.control.SyncedExpiriesMessage import org.session.libsession.messaging.messages.control.SyncedExpiriesMessage
import org.session.libsession.messaging.messages.control.SyncedExpiry import org.session.libsession.messaging.messages.control.SyncedExpiry
import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.messaging.sending_receiving.MessageSender
@ -16,6 +17,7 @@ class DisappearingMessagesJob(val messageIds: LongArray = longArrayOf(), val sta
override val maxFailureCount: Int = 1 override val maxFailureCount: Int = 1
override fun execute() { override fun execute() {
if (!ExpirationConfiguration.isNewConfigEnabled) return
val userPublicKey = MessagingModuleConfiguration.shared.storage.getUserPublicKey() ?: return val userPublicKey = MessagingModuleConfiguration.shared.storage.getUserPublicKey() ?: return
val module = MessagingModuleConfiguration.shared val module = MessagingModuleConfiguration.shared
try { try {

View File

@ -9,4 +9,7 @@ class ExpirationConfiguration(
val updatedTimestampMs: Long = 0 val updatedTimestampMs: Long = 0
) { ) {
val isEnabled = durationSeconds > 0 val isEnabled = durationSeconds > 0
companion object {
val isNewConfigEnabled = System.currentTimeMillis() > 1_671_062_400_000 // 15/12/2022
}
} }

View File

@ -1,6 +1,7 @@
package org.session.libsession.messaging.messages.control package org.session.libsession.messaging.messages.control
import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.messages.ExpirationConfiguration
import org.session.libsession.messaging.messages.visible.VisibleMessage import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.session.libsignal.protos.SignalServiceProtos import org.session.libsignal.protos.SignalServiceProtos
@ -17,7 +18,7 @@ class ExpirationTimerUpdate() : ControlMessage() {
override fun isValid(): Boolean { override fun isValid(): Boolean {
if (!super.isValid()) return false if (!super.isValid()) return false
return duration != null return duration != null || ExpirationConfiguration.isNewConfigEnabled
} }
companion object { companion object {
@ -28,7 +29,7 @@ class ExpirationTimerUpdate() : ControlMessage() {
val isExpirationTimerUpdate = dataMessageProto.flags.and(SignalServiceProtos.DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE) != 0 val isExpirationTimerUpdate = dataMessageProto.flags.and(SignalServiceProtos.DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE) != 0
if (!isExpirationTimerUpdate) return null if (!isExpirationTimerUpdate) return null
val syncTarget = dataMessageProto.syncTarget val syncTarget = dataMessageProto.syncTarget
val duration = dataMessageProto.expireTimer val duration = if (proto.hasExpirationTimer()) proto.expirationTimer else dataMessageProto.expireTimer
return ExpirationTimerUpdate(syncTarget, duration) return ExpirationTimerUpdate(syncTarget, duration)
} }
} }
@ -44,14 +45,9 @@ class ExpirationTimerUpdate() : ControlMessage() {
} }
override fun toProto(): SignalServiceProtos.Content? { override fun toProto(): SignalServiceProtos.Content? {
val duration = duration
if (duration == null) {
Log.w(TAG, "Couldn't construct expiration timer update proto from: $this")
return null
}
val dataMessageProto = SignalServiceProtos.DataMessage.newBuilder() val dataMessageProto = SignalServiceProtos.DataMessage.newBuilder()
dataMessageProto.flags = SignalServiceProtos.DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE dataMessageProto.flags = SignalServiceProtos.DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE
dataMessageProto.expireTimer = duration duration?.let { dataMessageProto.expireTimer = it }
// Sync target // Sync target
if (syncTarget != null) { if (syncTarget != null) {
dataMessageProto.syncTarget = syncTarget dataMessageProto.syncTarget = syncTarget

View File

@ -39,6 +39,7 @@ import org.session.libsession.utilities.ProfileKeyUtil
import org.session.libsession.utilities.SSKEnvironment import org.session.libsession.utilities.SSKEnvironment
import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.recipients.Recipient.DisappearingState
import org.session.libsignal.crypto.ecc.DjbECPrivateKey import org.session.libsignal.crypto.ecc.DjbECPrivateKey
import org.session.libsignal.crypto.ecc.DjbECPublicKey import org.session.libsignal.crypto.ecc.DjbECPublicKey
import org.session.libsignal.crypto.ecc.ECKeyPair import org.session.libsignal.crypto.ecc.ECKeyPair
@ -83,8 +84,10 @@ fun MessageReceiver.handle(message: Message, proto: SignalServiceProtos.Content,
} }
fun updateExpirationConfigurationIfNeeded(message: Message, proto: SignalServiceProtos.Content, openGroupID: String?) { fun updateExpirationConfigurationIfNeeded(message: Message, proto: SignalServiceProtos.Content, openGroupID: String?) {
if (!proto.hasLastDisappearingMessageChangeTimestamp()) return
val storage = MessagingModuleConfiguration.shared.storage val storage = MessagingModuleConfiguration.shared.storage
val disappearingState = if (proto.hasExpirationTimer()) DisappearingState.UPDATED else DisappearingState.LEGACY
storage.updateDisappearingState(message.sender!!, disappearingState)
if (!proto.hasLastDisappearingMessageChangeTimestamp() || !ExpirationConfiguration.isNewConfigEnabled) return
val threadID = storage.getOrCreateThreadIdFor(message.sender!!, message.groupPublicKey, openGroupID) val threadID = storage.getOrCreateThreadIdFor(message.sender!!, message.groupPublicKey, openGroupID)
if (threadID <= 0) return if (threadID <= 0) return
val localConfig = storage.getExpirationConfiguration(threadID) val localConfig = storage.getExpirationConfiguration(threadID)

View File

@ -86,6 +86,7 @@ public class Recipient implements RecipientModifiedListener {
private boolean blocked = false; private boolean blocked = false;
private boolean approved = false; private boolean approved = false;
private boolean approvedMe = false; private boolean approvedMe = false;
private DisappearingState disappearingState = DisappearingState.LEGACY;
private VibrateState messageVibrate = VibrateState.DEFAULT; private VibrateState messageVibrate = VibrateState.DEFAULT;
private VibrateState callVibrate = VibrateState.DEFAULT; private VibrateState callVibrate = VibrateState.DEFAULT;
private int expireMessages = 0; private int expireMessages = 0;
@ -653,6 +654,18 @@ public class Recipient implements RecipientModifiedListener {
notifyListeners(); notifyListeners();
} }
public synchronized DisappearingState getDisappearingState() {
return disappearingState;
}
public void setDisappearingState(DisappearingState disappearingState) {
synchronized (this) {
this.disappearingState = disappearingState;
}
notifyListeners();
}
public synchronized RegisteredState getRegistered() { public synchronized RegisteredState getRegistered() {
if (isPushGroupRecipient()) return RegisteredState.REGISTERED; if (isPushGroupRecipient()) return RegisteredState.REGISTERED;
@ -787,6 +800,24 @@ public class Recipient implements RecipientModifiedListener {
} }
} }
public enum DisappearingState {
LEGACY(0), UPDATED(1);
private final int id;
DisappearingState(int id) {
this.id = id;
}
public int getId() {
return id;
}
public static DisappearingState fromId(int id) {
return values()[id];
}
}
public enum RegisteredState { public enum RegisteredState {
UNKNOWN(0), REGISTERED(1), NOT_REGISTERED(2); UNKNOWN(0), REGISTERED(1), NOT_REGISTERED(2);